# Plotting transition-of-transition fails with "cannot evaluate symbolic expression"

Hi Manifolds experts, and many thanks in advance for any help.

I am trying to do a simple exercise (as I thought) to understand how SageMath Manifolds "composes" transitions between maps. Actually, I was very impressed this can be done.

To do this myself, I define the usual cartesian coordinates X and spherical coordinates Y. In addition, define spherical orthonormal coordinates H.

Here is my code to set it all up:

from sage.all import *
from IPython.display import display, Math, Latex

%display latex

M = Manifold(4, 'M', latex_name=r'\mathcal{M}', structure='Lorentzian')
X.<t,x,y,z> = M.chart()

U = M.open_subset('U', coord_def={X: (y!=0, x<0)})
X_U = X.restrict(U)
display(Latex(f'$X_U = {latex(X_U)}$'))
Y.<t,r,th,ph> = U.chart(r't:(-oo,+oo) r:(0,+oo) th:(0,+pi):\theta ph:(0,2*pi):\phi')

transit_Y_to_X = Y.transition_map(X, [
t, r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)
])

transit_Y_to_X.set_inverse(
t, sqrt(x^2+y^2+z^2), arccos(z/sqrt(x^2+y^2+z^2)), atan2(y,x)
)

H.<t,r,th_,ph_> = U.chart(r't:(-oo,+oo) r:(0,+oo) th_:(0,+oo):\hat{θ} ph_:(0,+oo):\hat{φ}')
transit_H_to_Y = H.transition_map(Y, [
t, r, th_/r, ph_/(r*sin(th))
])
display(transit_H_to_Y)
display(transit_H_to_Y.display())
transit_H_to_Y.inverse().display()


Then, I introduce the composed transition (the point of my exercise):

transit_H_to_X = transit_Y_to_X * transit_H_to_Y
display(transit_H_to_X)
display(transit_H_to_X.display())

transit_H_to_X.set_inverse(
t,
sqrt(x^2+y^2+z^2),
r*arccos(z/sqrt(x^2+y^2+z^2)),
r*sin(th)*atan2(y,x)
)
transit_X_to_H = transit_H_to_X.inverse()
display(transit_X_to_H)
display(transit_X_to_H.display())


and try to plot H against X:

H.plot(chart=X,
ambient_coords=(x,y,z), fixed_coords={t:0},
ranges={r:(1,1.1), th_:(1.1,1.2)}, number_values=3,
)


This fails with errors TypeError: cannot evaluate symbolic expression numerically. Any ideas on how I can make this work, please? What am I doing wrong?

I am using SageMath 9.5 on Ubuntu 22.04.

Thanks

GPN

edit retag close merge delete

Don't you need to also specify a range for ph_ ?

( 2023-12-07 17:29:56 +0200 )edit

@Max_Alekseyev thanks, tried that again just now. More generally I think if you do not specify a range then it will try the full range, but anyway that did not work. Thanks for the advice.

( 2023-12-07 19:13:24 +0200 )edit

Sort by » oldest newest most voted

Hi,

The composition transit_H_to_X = transit_Y_to_X * transit_H_to_Y works well for me (Sage 10.2): it yields a result that does not depend on sin(th):

t = t
x = r*cos(ph_/(r*sin(th)))*sin(th_/r)
y = r*sin(th_/r)*sin(ph_/(r*sin(th)))
z = r*cos(th_/r)


I think the error in your initial code comes from the spurious sin(th) introduced when setting the inverse:

transit_H_to_X.set_inverse(
t,
sqrt(x^2+y^2+z^2),
r*arccos(z/sqrt(x^2+y^2+z^2)),
r*sin(th)*atan2(y,x)        #  <-- there should be no sin(th) here, nor r
)


The correct definition of the inverse is the one used in your answer:

transit_H_to_X.set_inverse(
t,
sqrt(x^2+y^2+z^2),
sqrt(x^2+y^2+z^2)*arccos(z/sqrt(x^2+y^2+z^2)),
sqrt(x^2+y^2+z^2)*sin(arccos(z/sqrt(x^2+y^2+z^2)))*atan2(y,x)
)


Best wishes,

Eric.

more

First of all, many thanks for reviewing my code so thoroughly. I do believe you found a real mistake in the original set_inverse which is now corrected in the answer below.

Excuse me for picking a nit, but above (in your first box of code)

y = r*sin(th_/r)*sin(ph_/(r*sin(th)))


does seem to depend on th in the last (r*sin(th)).

Apologies if I misunderstood. But that was the reason why I wrote it all out "by hand" - so if it is also something that appears in your 10.2 version then perhaps you want to know about it. I hope this helps.

( 2023-12-09 22:21:09 +0200 )edit

Hi all.

I think I have found an answer, but it is not a "happy" one. The crucial issue was with the line  transit_H_to_X = transit_Y_to_X * transit_H_to_Y  which works but provides a result that depends on sin(θ) rather than fully simplifying and providing a result that depends on sin(θ_) (the θ_ variable is my name for the 'variable with a hat' θ_ = r*θ.

While that result is formally correct, it is insufficiently simplified, and the later plot command crashes because of this insufficient simplification.

Here is the full running code after manually introducing the transition rather than relying on SageMath to calculate the transition:

from sage. All import *
from IPython.display import display, Math, Latex

%display latex

M = Manifold(4, 'M', latex_name=r'\mathcal{M}', structure='Lorentzian')
X.<t,x,y,z> = M.chart()

U = M.open_subset('U', coord_def={X: (y!=0, x<0)})
X_U = X.restrict(U)
display(Latex(f'$X_U = {latex(X_U)}$'))
Y.<t,r,th,ph> = U.chart(r't:(-oo,+oo) r:(0,+oo) th:(0,+pi):\theta ph:(0,2*pi):\phi')
transit_Y_to_X = Y.transition_map(X, [
t, r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)
])
transit_Y_to_X.set_inverse(
t, sqrt(x^2+y^2+z^2), arccos(z/sqrt(x^2+y^2+z^2)), atan2(y,x)
)

H.<t,r,th_,ph_> = U.chart(r't:(-oo,+oo) r:(0,+oo) th_:(0,+oo):\hat{θ} ph_:(0,+oo):\hat{φ}')
transit_H_to_Y = H.transition_map(Y, [
t, r, th_/r, ph_/(r*sin(th))
])
transit_Y_to_H = transit_H_to_Y.inverse()
transit_Y_to_H.display()

# transit_H_to_X = transit_Y_to_X * transit_H_to_Y

display((transit_Y_to_X * transit_H_to_Y).display())
transit_H_to_X = H.transition_map(X, [
t,
r*sin(th_/r)*cos(ph_/(r*sin(th_/r))),
r*sin(th_/r)*sin(ph_/(r*sin(th_/r))),
r*cos(th_/r),
])
display(transit_H_to_X)
display(transit_H_to_X.display())

transit_H_to_X.set_inverse(
t,
sqrt(x^2+y^2+z^2),
sqrt(x^2+y^2+z^2)*arccos(z/sqrt(x^2+y^2+z^2)),
sqrt(x^2+y^2+z^2)*sin(arccos(z/sqrt(x^2+y^2+z^2)))*atan2(y,x)
)
transit_X_to_H = transit_H_to_X.inverse()
display(transit_X_to_H)
display(transit_X_to_H.display())

H.plot(chart=X,
ambient_coords=(x,y,z), fixed_coords={t:0},
ranges={r:(1,1.1), th_:(1.1,1.2), ph_:(1.1,1.2)}, number_values=3,
)


Thanks for viewing and advice, especially @max_alekseyev.

GPN

more