inconsistency in computation of differential of a map between manifolds

89 views

Andreas Hermann

Aug 26, 2019, 10:50:02 AM8/26/19
to sage-devel
Hello,

In the following code I define a differentiable map between two manifolds, then restrict it to a subset and then compute the matrix of its differential at a point in the subset (see also the attached jpynb file).
I have noticed that when I execute this code several times by inserting the cursor and pressing Shift+Enter I do not always get the same result. Namely, the first two rows of the matrix are sometimes swapped (try it for about 10 times).

reset()M = Manifold(2, 'M', latex_name=r'\mathcal{M}', start_index=1)M_cartesian.<u,v> = M.chart()U = M.open_subset('U', coord_def={M_cartesian: (v!=0, u>0)})U_cartesian = M_cartesian.restrict(U)U_polar.<r,th> = U.chart(r'r:(0,+oo) th:(-pi,pi):\theta')polar_to_cartesian = U_polar.transition_map(U_cartesian, [r*sin(th), r*cos(th)])polar_to_cartesian.set_inverse(sqrt(u*u+v*v), atan2(v,u))N = Manifold(3, 'N', latex_name=r'\mathcal{N}', start_index=1)N_cartesian.<x,y,z> = N.chart()Phi = M.diff_map(N, [u,v,u^2+v^2], name='Phi', latex_name=r'\Phi')Phi_U=Phi.restrict(U)p=M.point((2,1), name='p')Phi_U.differential(p).matrix()

I would like to know: Where does this inconsistency come from?
In order to answer this question the following observations might be useful:
1. If I compute the differential of the unrestricted map (i.e. Phi.differential(p).matrix()) the problem does not appear.
2. If I insert the line "Phi_U.differential_functions()" before "Phi_U.differential(p).matrix()" the problem does not appear.
3. If in Jupyter notebook I click "Kernel" then "Restart & Run All" the problem does not appear.
Although methods 2 and 3 provide a workaround, it would certainly be great to have this inconsistency cleared. I would appreciate any help.

Best,
Andreas

differential_error.ipynb

Andreas Hermann

Aug 27, 2019, 10:51:20 AM8/27/19
to sage-devel
I am sorry, but this is a stupid mistake. The function defined via set_inverse() is not the inverse function since the first entry of atan2 is by definition the y-coordinate. If one swaps u and v in atan2 then everything is fine.

Eric Gourgoulhon

Aug 27, 2019, 4:19:49 PM8/27/19
to sage-devel
Le mardi 27 août 2019 16:51:20 UTC+2, Andreas Hermann a écrit :
I am sorry, but this is a stupid mistake. The function defined via set_inverse() is not the inverse function since the first entry of atan2 is by definition the y-coordinate. If one swaps u and v in atan2 then everything is fine.

To avoid such mistake, you can run set_inverse() with the option verbose=True. Then the provided inverse transform is checked. In your original example

polar_to_cartesian.set_inverse(sqrt(u*u+v*v), atan2(v,u), verbose=True)

leads to

Check of the inverse coordinate transformation:
r == r
th == arctan2(r*cos(th), r*sin(th))
u == v
v == u


from which we recognize that there is a problem, since the last two lines should be u == u and v == v.

Maybe verbose=True should be the default?

Best wishes,

Eric.

Simon King

Aug 28, 2019, 1:07:03 AM8/28/19
Hi Eric,

On 2019-08-27, Eric Gourgoulhon <egourg...@gmail.com> wrote:
> To avoid such mistake, you can run set_inverse() with the option
> verbose=True. Then the provided inverse transform is checked.

Is the option really called "verbose=True"? Not "check=True", like in
most other cases?

Best regards,
Simon

Eric Gourgoulhon

Aug 28, 2019, 3:29:29 PM8/28/19
to sage-devel
Hi Simon,

Le mercredi 28 août 2019 07:07:03 UTC+2, Simon King a écrit :

Is the option really called "verbose=True"? Not "check=True", like in
most other cases?

You are perfectly right: "check" would be more appropriate than "verbose" in this context.
I'll open a ticket for this and make "check=True" the default.

Best regards,

Eric.