Move tensor toward or away from the origin

I have a batch x ndim tensor.

I want to add noise to each observation that pushes it either toward or away from the origin without flipping any of the signs.

Can anyone recommend a good approach?

I’m not sure I understand your use case properly.
If you would like to push a tensor to the origin (or away from it), you could subtract (or add) the same tensor multiplied by a factor in (0, 1) to it. The direction of this addition (or subtraction) will be towards to (away from) the origin.

However, I’m not sure, if that’s what you want. On the other hand you could add e.g. random Gaussian noise, but these changes won’t be applied with respect to the distance to the origin.

Could you clarify the use case a bit?

Thank you for your interest.

My specific use case is that I have an auto-encoder whose bottleneck embedding layer is hyperbolic. I’m adding noise to that embedding as a regularizer.

I have a specific kind of noise in mind which is very straight forward to describe. Grab a point, drag it either toward the middle of the disk or out toward the edge. Don’t change the angle or sign.

I’ve made progress on this problem in the two-dimensional case. I convert euclidian coordinates to polar coordinates, which give a radius and an angle. I then add/substract to the radius, and then convert back.

That was a very straightforward hack in 2d, but it may not have been the most efficient. I also don’t know how to generalize it to N-dimensions.

Here’s the functions I found for doing the conversion

def cart2polar(x, y):
r = torch.sqrt(x2 + y2).to(device)
theta = torch.atan2(y, x).to(device)
return r, theta

def polar2cart(r, theta):
y = r * torch.cos(theta).to(device) # θ referenced to vertical
x = r * torch.sin(theta).to(device)
return x, y

And here’s the code in the forward pass that applies the noise

if self.training:
            new= cart2polar(x[:, 0], x[:, 1])
            r=new[0]
            angle=new[1]          
            distribution = torch.distributions.uniform.Uniform(torch.tensor([0.0]).to(device) , torch.tensor([1.0]).to(device) ) #reducing it to .5 noise
            r_new =  torch.sqrt( ( r - torch.t(distribution.sample(torch.Size([len(r)]))) ) **2).to(device)            
            converted = polar2cart(r_new,angle) #It returns x1 first and then x1
            x_new=x.clone()
            x_new[:,0]=converted[1] #these need to be inverted
            x_new[:,1]=converted[0]