Spaces:
Sleeping
Sleeping
# Author: Qiuyi | |
import torch | |
import torch.nn.functional as F | |
from sklearn.decomposition import PCA | |
def cube(n_samples, dim=2): | |
return torch.rand([n_samples, dim]) | |
def sphere(n_samples, dim=1): | |
X = torch.randn([n_samples, dim+1]) | |
return F.normalize(X, dim=-1) | |
def torus(n_samples, R=2, r=1): | |
u, v = (torch.rand([n_samples, 2]) * 2 * torch.pi).chunk(2, -1) | |
x = (R + r * torch.cos(u)) * torch.cos(v) | |
y = (R + r * torch.cos(u)) * torch.sin(v) | |
z = r * torch.sin(u) | |
return torch.cat([x, y, z], dim=-1) | |
def mobius_strip(n_samples): | |
u, v = torch.rand([n_samples, 2]).chunk(2, -1) | |
u *= 2 * torch.pi | |
x = (1 + v/2 * torch.cos(u/2)) * torch.cos(u) | |
y = (1 + v/2 * torch.cos(u/2)) * torch.sin(u) | |
z = v/2 * torch.sin(u/2) | |
return torch.cat([x, y, z], dim=-1) | |
def klein_bottle(n_samples, R=2, P=1, e=0.1): | |
u, v = (torch.rand([n_samples, 2]) * 2 * torch.pi).chunk(2, -1) | |
x = R * (torch.cos(u/2) * torch.cos(v) - torch.sin(u/2) * torch.sin(v*2)) | |
y = R * (torch.sin(u/2) * torch.cos(v) + torch.cos(u/2) * torch.sin(v*2)) | |
z = P * torch.cos(u) * (1 + e * torch.sin(v)) | |
w = P * torch.sin(u) * (1 + e * torch.sin(v)) | |
return torch.cat([x, y, z, w], dim=-1) | |
################################ Immersions ################################ | |
# For nonlinearly embedding datasets into high dimensional ambient spaces. # | |
############################################################################ | |
def polynomial_immersion(dataset, ambient_dim, weight=(1,1,0)): | |
""" | |
The graph of a continous function is homeomorphic to its domain. | |
Immersion is performed by polynomial function. | |
""" | |
X = (dataset - dataset.mean(0)) / (dataset.std(0) * 2) | |
XX = (X.unsqueeze(1) * X.unsqueeze(2)).flatten(1) | |
XXX = (X.view(len(X), 1, 1, -1) \ | |
* X.view(len(X), 1, -1, 1) \ | |
* X.view(len(X), -1, 1, 1)).flatten(1) | |
in_dim = dataset.size(-1) | |
out_dim = ambient_dim - in_dim | |
# 2nd order polynomial function Y = f(X) | |
W1 = torch.randn(X.size(-1), out_dim) * weight[0] | |
W2 = torch.randn(XX.size(-1), out_dim) * weight[1] | |
W3 = torch.randn(XXX.size(-1), out_dim) * weight[2] | |
Y = X @ W1 + XX @ W2 + XXX @ W3 | |
# rescaling | |
D = torch.cat([dataset, Y], dim=-1) # graph of polynomial f | |
D = torch.as_tensor(PCA(D.size(-1)).fit_transform(D), dtype=torch.float) | |
s = torch.rand(D.size(-1)) * (1-0.5) + 0.5 | |
D = D / D.std(0).clip(3e-7) * s | |
return D |