so3.log gives an incorrect result for some matrix
Closed this issue · 1 comments
The log of a rotation matrix obtained from so3.log
for the following matrix is incorrect:
import torch
import ptlk
mat = torch.Tensor([
[-1.00000396e+00, -9.55433245e-07, 1.04267154e-06],
[ 1.04267254e-06, -9.99052394e-01, 4.36201482e-02],
[ 9.55432245e-07, 4.36191482e-02, 9.99051394e-01]])
print(ptlk.so3.log(mat))
# prints:
# tensor([0., 0., 0.])
print(ptlk.so3.exp(ptlk.so3.log(mat)))
# prints:
# tensor([[1., 0., 0.],
# [0., 1., 0.],
# [0., 0., 1.]])
print(torch.allclose(mat, ptlk.so3.exp(ptlk.so3.log(mat)), atol=1e-2))
# prints:
# False
I tried to change eps
in so3.log
function, but it does not seem to help.
Ok, I think that I understand what happened. Essentially, this is a numerical precision error.
I will close the issue because I did not find any better way to calculate the coefficients in this case.
Here is a detailed explanation, in case one might find it useful in the future.
The generators' coefficients are calculated using the following:
Usually, the second term (red) in (15) is nonzero or far enough from zero. In such a case, we can use:
(Where R=exp(\omega_x) ).
However, when sin(\theta)/(\theta) is zero or very small the above does not work properly. It happens when approximately \theta=(+/-)\pi, as in the case above. In this case, we have to use the quadratic order in \theta (blue in (15), (14) is still valid):
The numerical problem occurs because \omega_1^2=0 but \omega_1\omega_2 is not zero. Unfortunately, it looks like this method is also not stable in this case.
The part in the code of so3
which performs the calculation:
Lines 99 to 116 in 8b851c1
(Especially L102.)
The above is based on:
http://www.ethaneade.org/lie.pdf