Making Fibonacci sphere number of points differentiable

Hey,

I am trying to generate kind of procedural displacement maps using Fibonacci sphere coordinates.

Basically the following code is generating me 2d coordinates I am using later own to create my texture.

seed_nb = torch.tensor(600,device = pyredner.get_device(), requires_grad=True)
goldenRatio = torch.tensor((1 + 5**0.5)/2,device = pyredner.get_device())
i = torch.arange(0, seed_nb.long(),device = pyredner.get_device())
theta = 2 * torch_PI * i / goldenRatio
fibo_phi = torch.acos(torch.ones(1,device = pyredner.get_device()) - torch.tensor(2*(i+0.5)/n,device = pyredner.get_device()))
fibo_theta = (theta%(2torch_PI))-torch_PI
# print(phi.min(),phi.max(),theta.min(),theta.max())
indices_x = (fibo_phi
1800/np.pi).long()
indices_y = ( ((fibo_theta*1800/np.pi)+1800)).long()

The problem is that I want the variable “seed_nb” to be differentiable/learned to be the right value when back-propagating. So I used a long tensor with one value inside. But because or “torch.arange” it sees that the gradient of this tensor is always None, hence nothing is learned.

I am a bit stuck trying to find a way to go around this arange somehow.
Any idea ?

Justin

Hi Justin!

There is no straightforward way to do what you want. The problem is
that the number of points on your sphere is an integer and there is no
sensible way to differentiate with respect to an integer.

Helpfully, pytorch won’t let you do this:

>>> import torch
>>> torch.__version__
'1.9.0'
>>> torch.tensor (600, device = 'cpu', requires_grad = True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Only Tensors of floating point and complex dtype can require gradients

Best.

K. Frank

Hi Frank,

I Figured there wouldn’t straightforward way to do it unfortunately :confused:
I am doing differentiable rendering and thought that perhaps using this float tensor and casting it as an int when using it arange would still let me optimize over it :confused:
I am trying to find an other way, perhaps using some sparse tensor or having a very high number of points and learn some float array dropping part of it, but haven’t found anyway yet.

Justin

Hi Justin!

One general approach – that may not work for your use case – for
making integer stuff differentiable is to blend (interpolate) neighboring
integers together.

Let’s say that a Fibonacci sphere with a certain number of points (say
600) leads to some result, f (600), and a sphere with 601 points leads
to some other result, f (601).

You could have seed_nb to be a floating-point number (rather than
an integer) and then define the corresponding result, f (seed_nb)
via interpolation:

f (600.3)  =  0.7 * f (600)  +  0.3 * f (601)

Whether this could make sense depends on the specifics or your
use case, but it does give you an expression that can be usefully
differentiated with respect to a floating-point seed_nb.

Best.

K. Frank

Hi Frank !

Unfortunately I am not sure there is a way to have this number differentiable, at least not through using this Fibonacci sphere or any method where the localization are integers.
I am going to think about an other solution to that points problem while making it differentiable.
Thank you Frank

Justin