Move tensor toward or away from the origin

rexdouglass: <p>I have a batch x ndim tensor.</p>
<p>I want to add noise to each observation that pushes it either toward or away from the origin without flipping any of the signs.</p>
<p>Can anyone recommend a good approach?</p>

ptrblck: <p>I’m not sure I understand your use case properly.<br>
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 <code>(0, 1)</code> to it. The direction of this addition (or subtraction) will be towards to (away from) the origin.</p>
<p>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.</p>
<p>Could you clarify the use case a bit?</p>

rexdouglass: <p>Thank you for your interest.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>Here’s the functions I found for doing the conversion<br>
<aside class="onebox githubblob">
  <header class="source">
      <a href="https://github.com/PyAbel/PyAbel/blob/master/abel/tools/polar.py" target="_blank" rel="nofollow noopener">github.com</a>
  </header>
  <article class="onebox-body">
    <h4><a href="https://github.com/PyAbel/PyAbel/blob/master/abel/tools/polar.py" target="_blank" rel="nofollow noopener">PyAbel/PyAbel/blob/master/abel/tools/polar.py</a></h4>
<pre><code class="lang-py"># -*- coding: utf-8 -*-

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import numpy as np
from scipy.ndimage import map_coordinates
from scipy.ndimage.interpolation import shift
from scipy.optimize import curve_fit, minimize


def reproject_image_into_polar(data, origin=None, Jacobian=False,
                               dr=1, dt=None):
    """
    Reprojects a 2D numpy array (``data``) into a polar coordinate system.
    "origin" is a tuple of (x0, y0) relative to the bottom-left image corner,
    and defaults to the center of the image.

</code></pre>

  This file has been truncated. <a href="https://github.com/PyAbel/PyAbel/blob/master/abel/tools/polar.py" target="_blank" rel="nofollow noopener">show original</a>

  </article>
  <div class="onebox-metadata">
    
    
  </div>
  <div style="clear: both"></div>
</aside>
</p>
<p>def cart2polar(x, y):<br>
r = torch.sqrt(x<strong>2 + y</strong>2).to(device)<br>
theta = torch.atan2(y, x).to(device)<br>
return r, theta</p>
<p>def polar2cart(r, theta):<br>
y = r * torch.cos(theta).to(device)   # θ referenced to vertical<br>
x = r * torch.sin(theta).to(device)<br>
return x, y</p>
<p>And here’s the code in the forward pass that applies the noise</p>
<pre><code class="lang-auto">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]
</code></pre>