This notebook is part of the Introduction to manifolds in SageMath by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
version()
'SageMath version 9.6, Release Date: 2022-05-15'
In the EuclideanSpace
class, the transitions from spherical to Cartesian and Cartesian to spherical coordinates are predefined in the case $n\leq 3$ (SageMath 9.5).
Example 5.1
Let us demonstrate spherical coordinates for $n=3$.
E.<x1,x2,x3>=EuclideanSpace(3,"E") # Euclidean space E^3
cart=E.cartesian_coordinates() # Cartesian coordinates
spher.<r,th,ph> = E.spherical_coordinates() # spherical coordinates
E.coord_change(spher, cart).display() # transition spher -> cart
x1 = r*cos(ph)*sin(th) x2 = r*sin(ph)*sin(th) x3 = r*cos(th)
E.coord_change(cart, spher).display() # transition cart -> spher
r = sqrt(x1^2 + x2^2 + x3^2) th = arctan2(sqrt(x1^2 + x2^2), x3) ph = arctan2(x2, x1)
The manifolds.Sphere
module allows for higher dimensions.
We can use predefined embeddings and transition functions on higher dimensional spheres.
Example 5.2
Let us demonstrate the case of 3-dimensional sphere in $E^4$.
%display latex
dim=3 # dimension of the sphere (not the Euclidean space)
Sph=manifolds.Sphere(dim) # sphere S^3
spher = Sph.spherical_coordinates() # spherical coordinates on S^3
Sph.embedding().disp() # embedding S^3 -> E^4
The stereographic projections are also accessible in higher dimensions.
Example 5.3
Stereographic coordinates in $S^3$.
# continuation
%display latex
stereoN, stereoS = Sph.coordinate_charts('stereographic',
names=['u','v','w']) # stereographic projections in S^3
Sph.embedding().disp() # show embeddings into E^4
We have also the corresponding transitions in $S^3$ predefined.
A = spher.domain() # domain of spherical coordinates
# intersection of domains of stereoN and stereoS coordinates:
W = Sph._stereoN_dom.intersection(Sph._stereoS_dom)
# intersection of domains of stereoN,stereoS and spher coordinates:
V=W.intersection(A)
# transition spher -> stereoN:
F1=Sph.coord_change(spher.restrict(V), stereoN.restrict(V))
# transition stereoN -> spher:
F2=Sph.coord_change( stereoN.restrict(V),spher.restrict(V))
# transition spher -> stereoS
F3=Sph.coord_change(spher.restrict(V), stereoS.restrict(V))
# transition stereoS -> spher
F4=Sph.coord_change( stereoS.restrict(V),spher.restrict(V))
# transition stereoN -> stereoS
F5=Sph.coord_change( stereoN.restrict(V),stereoS.restrict(V))
# transition stereoS -> stereoN
F6=Sph.coord_change( stereoS.restrict(V),stereoN.restrict(V))
F6.disp()
F5.disp()
Example 5.4
Spherical coordinates in $R^4$.
We can use manifolds.Sphere
to obtain the transition from spherical to Cartesian coordinates in $R^4$.
%display plain # to obtain output which can be re-used in the code
dim=3 # dimension of the sphere
r=var('r') # symbolic variable
Sph=manifolds.Sphere(dim,radius=r) # 3-dim sphere with radius r
Phi=Sph.embedding() # embedding into E^4
E=Sph.ambient() # ambient space E^4
fun=Phi.coord_functions() # embedding functions
fun.expr() # show embedding functions
(r*cos(phi)*sin(chi)*sin(theta), r*sin(chi)*sin(phi)*sin(theta), r*cos(theta)*sin(chi), r*cos(chi))
The result can be used to define the transition spherU -> cartU in $R^4$.
R4=Manifold(4,'R^4',start_index=1) # manifold R^4
cart.<x1,x2,x3,x4>=R4.chart() # Cartesian coordinates in R^4
U=R4.open_subset('U', # open subset of R^4 with half-
coord_def={cart: (x2!=0, x1<0)}) # plane {x2 = 0, x1 ≥ 0} excluded
cartU=cart.restrict(U) # restrict cart to U
# spherical coordinates on U, use
# names from the previous output!
spherU.<r,chi,theta,phi>=U.chart(r'r:(0,+oo) chi:(0,pi):\chi\
theta:(0,pi):\theta phi:(-pi,pi):periodic:\phi')
# transition spherU -> cartU
spher_to_cart = spherU.transition_map(cartU,fun.expr())
spher_to_cart.disp() # show transition
x1 = r*cos(phi)*sin(chi)*sin(theta) x2 = r*sin(chi)*sin(phi)*sin(theta) x3 = r*cos(theta)*sin(chi) x4 = r*cos(chi)
# spher_to_cart.inverse() does not work
Inverse transition can be defined as follows:
fun=(sqrt(x1^2+x2^2+x3^2+x4^2), # functions defining
atan2(sqrt(x1^2+x2^2+x3^2),x4), # inverse transition
atan2(sqrt(x1^2+x2^2),x3), # spher -> cart
atan2(x2,x1))
spher_to_cart.set_inverse(*fun) # set inverse trans.
Check of the inverse coordinate transformation: r == r *passed* chi == arctan2(r*sin(chi), r*cos(chi)) **failed** theta == arctan2(r*sin(chi)*sin(theta), r*cos(theta)*sin(chi)) **failed** phi == arctan2(r*sin(chi)*sin(phi)*sin(theta), r*cos(phi)*sin(chi)*sin(theta)) **failed** x1 == x1 *passed* x2 == x2 *passed* x3 == x3 *passed* x4 == x4 *passed* NB: a failed report can reflect a mere lack of simplification.
The failed computations reflect a lack of simplification in SageMath
and can be checked by hand (https://en.wikipedia.org/wiki/Atan2)
Example 5.5
Spherical coordinates in $R^5$.
%display plain # We don't want the Latex output
dim=4 # dimension of the sphere
r=var('r') # symbolic variable
Sph=manifolds.Sphere(dim,radius=r) # 4-dim sphere, radius r,in E^5
Phi=Sph.embedding() # embedding S^4 -> E^5
E=Sph.ambient() # ambient space E^5
print("In",E)
print("the spherical coordinates are")
print(E.cartesian_coordinates()[:],"=")
Phi.coord_functions()[:] # print coordinate functions
In 5-dimensional Euclidean space E^5 the spherical coordinates are (x1, x2, x3, x4, x5) =
(r*cos(phi_4)*sin(phi_1)*sin(phi_2)*sin(phi_3), r*sin(phi_1)*sin(phi_2)*sin(phi_3)*sin(phi_4), r*cos(phi_3)*sin(phi_1)*sin(phi_2), r*cos(phi_2)*sin(phi_1), r*cos(phi_1))
Using the result we can define the transition spherU -> cartU in $R^5$.
R5=Manifold(5,'R^5') # manifold R^5
cart.<x1,x2,x3,x4,x5>=R5.chart() # Cartesian coord. in R^5
U=R5.open_subset('U', # open subset of R^5,
coord_def={cart:(x3!=0,x2!=0,x1<0)}) #{x3=0,x2=0,x1>=0} exclud.
cartU=cart.restrict(U) # restrict Cart.coord.to U
# use the same names as in the output of the previous command
spherU.<r,phi_1,phi_2,phi_3,phi_4>=U.chart(r'r:(0,+oo) phi1:(0,pi):\phi_1\
phi2:(0,pi):\phi_2 phi3:0,pi):\phi_3 phi4:(-pi,pi):periodic:\phi_4')
# spherical coordinates on U
spher_to_cart = spherU.transition_map(cartU, # define transition
(r*cos(phi_4)*sin(phi_1)*sin(phi_2)*sin(phi_3), # spher -> cart
r*sin(phi_1)*sin(phi_2)*sin(phi_3)*sin(phi_4),
r*cos(phi_3)*sin(phi_1)*sin(phi_2),
r*cos(phi_2)*sin(phi_1),
r*cos(phi_1)))
spher_to_cart.disp() # show transition
x1 = r*cos(phi4)*sin(phi1)*sin(phi2)*sin(phi3) x2 = r*sin(phi1)*sin(phi2)*sin(phi3)*sin(phi4) x3 = r*cos(phi3)*sin(phi1)*sin(phi2) x4 = r*cos(phi2)*sin(phi1) x5 = r*cos(phi1)
Inverse transition:
fun=(sqrt(x1^2+x2^2+x3^2+x4^2+x5^2), # functions defining the
atan2(sqrt(x1^2+x2^2+x3^2+x4^2),x5), # inverse transition
atan2(sqrt(x1^2+x2^2+x3^2),x4),
atan2(sqrt(x1^2+x2^2),x3),
atan2(x2,x1))
cart_to_spher=spher_to_cart.set_inverse(*fun) # define inv. trans.
Check of the inverse coordinate transformation: r == r *passed* phi1 == arctan2(r*sin(phi1), r*cos(phi1)) **failed** phi2 == arctan2(r*sin(phi1)*sin(phi2), r*cos(phi2)*sin(phi1)) **failed** phi3 == arctan2(r*abs(sin(phi3))*sin(phi1)*sin(phi2), r*cos(phi3)*sin(phi1)*sin(phi2)) **failed** phi4 == arctan2(r*sin(phi1)*sin(phi2)*sin(phi3)*sin(phi4), r*cos(phi4)*sin(phi1)*sin(phi2)*sin(phi3)) **failed** x1 == x1 *passed* x2 == x2 *passed* x3 == x3 *passed* x4 == x4 *passed* x5 == x5 *passed* NB: a failed report can reflect a mere lack of simplification.
Take a look at the notebook The notion of module.