{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 5. Spheres and spherical coordinates in higher dimensions\n",
"\n",
"This notebook is part of the [Introduction to manifolds in SageMath](https://sagemanifolds.obspm.fr/intro_to_manifolds.html) by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'SageMath version 9.6, Release Date: 2022-05-15'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"version()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"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).\n",
" \n",
"
\n",
" \n",
" **Example 5.1**\n",
" \n",
" Let us demonstrate spherical coordinates for $n=3$."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"x1 = r*cos(ph)*sin(th)\n",
"x2 = r*sin(ph)*sin(th)\n",
"x3 = r*cos(th)"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"E.=EuclideanSpace(3,\"E\") # Euclidean space E^3\n",
"cart=E.cartesian_coordinates() # Cartesian coordinates\n",
"spher. = E.spherical_coordinates() # spherical coordinates\n",
"E.coord_change(spher, cart).display() # transition spher -> cart "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"r = sqrt(x1^2 + x2^2 + x3^2)\n",
"th = arctan2(sqrt(x1^2 + x2^2), x3)\n",
"ph = arctan2(x2, x1)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"E.coord_change(cart, spher).display() # transition cart -> spher"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"The `manifolds.Sphere` module allows for **higher dimensions**.\n",
"\n",
"\n",
"\n",
"We can use predefined embeddings and transition functions on higher dimensional spheres.\n",
"\n",
"\n",
"
\n",
"\n",
"**Example 5.2**\n",
"\n",
"Let us demonstrate the case of 3-dimensional sphere in $E^4$."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\begin{array}{llcl} \\iota:& \\mathbb{S}^{3} & \\longrightarrow & \\mathbb{E}^{4} \\\\ \\mbox{on}\\ A : & \\left(\\chi, \\theta, \\phi\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\cos\\left(\\phi\\right) \\sin\\left(\\chi\\right) \\sin\\left(\\theta\\right), \\sin\\left(\\chi\\right) \\sin\\left(\\phi\\right) \\sin\\left(\\theta\\right), \\cos\\left(\\theta\\right) \\sin\\left(\\chi\\right), \\cos\\left(\\chi\\right)\\right) \\end{array}\\)"
],
"text/latex": [
"$\\displaystyle \\begin{array}{llcl} \\iota:& \\mathbb{S}^{3} & \\longrightarrow & \\mathbb{E}^{4} \\\\ \\mbox{on}\\ A : & \\left(\\chi, \\theta, \\phi\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\cos\\left(\\phi\\right) \\sin\\left(\\chi\\right) \\sin\\left(\\theta\\right), \\sin\\left(\\chi\\right) \\sin\\left(\\phi\\right) \\sin\\left(\\theta\\right), \\cos\\left(\\theta\\right) \\sin\\left(\\chi\\right), \\cos\\left(\\chi\\right)\\right) \\end{array}$"
],
"text/plain": [
"iota: S^3 → E^4\n",
"on A: (chi, theta, phi) ↦ (x1, x2, x3, x4) = (cos(phi)*sin(chi)*sin(theta), sin(chi)*sin(phi)*sin(theta), cos(theta)*sin(chi), cos(chi))"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%display latex\n",
"dim=3 # dimension of the sphere (not the Euclidean space)\n",
"Sph=manifolds.Sphere(dim) # sphere S^3\n",
"spher = Sph.spherical_coordinates() # spherical coordinates on S^3\n",
"Sph.embedding().disp() # embedding S^3 -> E^4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"The **stereographic projections** are also accessible in higher dimensions.\n",
"\n",
"
\n",
"\n",
"**Example 5.3**\n",
"\n",
"**Stereographic coordinates in $S^3$**."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\begin{array}{llcl} \\iota:& \\mathbb{S}^{3} & \\longrightarrow & \\mathbb{E}^{4} \\\\ \\mbox{on}\\ A : & \\left(\\chi, \\theta, \\phi\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\cos\\left(\\phi\\right) \\sin\\left(\\chi\\right) \\sin\\left(\\theta\\right), \\sin\\left(\\chi\\right) \\sin\\left(\\phi\\right) \\sin\\left(\\theta\\right), \\cos\\left(\\theta\\right) \\sin\\left(\\chi\\right), \\cos\\left(\\chi\\right)\\right) \\\\ \\mbox{on}\\ \\mathbb{S}^{3}\\setminus\\{\\mathrm{NP}\\} : & \\left(u, v, w\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\frac{2 \\, u}{u^{2} + v^{2} + w^{2} + 1}, \\frac{2 \\, v}{u^{2} + v^{2} + w^{2} + 1}, \\frac{2 \\, w}{u^{2} + v^{2} + w^{2} + 1}, \\frac{u^{2} + v^{2} + w^{2} - 1}{u^{2} + v^{2} + w^{2} + 1}\\right) \\\\ \\mbox{on}\\ \\mathbb{S}^{3}\\setminus\\{\\mathrm{SP}\\} : & \\left({u'}, {v'}, {w'}\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\frac{2 \\, {u'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, \\frac{2 \\, {v'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, \\frac{2 \\, {w'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, -\\frac{{u'}^{2} + {v'}^{2} + {w'}^{2} - 1}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}\\right) \\end{array}\\)"
],
"text/latex": [
"$\\displaystyle \\begin{array}{llcl} \\iota:& \\mathbb{S}^{3} & \\longrightarrow & \\mathbb{E}^{4} \\\\ \\mbox{on}\\ A : & \\left(\\chi, \\theta, \\phi\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\cos\\left(\\phi\\right) \\sin\\left(\\chi\\right) \\sin\\left(\\theta\\right), \\sin\\left(\\chi\\right) \\sin\\left(\\phi\\right) \\sin\\left(\\theta\\right), \\cos\\left(\\theta\\right) \\sin\\left(\\chi\\right), \\cos\\left(\\chi\\right)\\right) \\\\ \\mbox{on}\\ \\mathbb{S}^{3}\\setminus\\{\\mathrm{NP}\\} : & \\left(u, v, w\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\frac{2 \\, u}{u^{2} + v^{2} + w^{2} + 1}, \\frac{2 \\, v}{u^{2} + v^{2} + w^{2} + 1}, \\frac{2 \\, w}{u^{2} + v^{2} + w^{2} + 1}, \\frac{u^{2} + v^{2} + w^{2} - 1}{u^{2} + v^{2} + w^{2} + 1}\\right) \\\\ \\mbox{on}\\ \\mathbb{S}^{3}\\setminus\\{\\mathrm{SP}\\} : & \\left({u'}, {v'}, {w'}\\right) & \\longmapsto & \\left({x_{1}}, {x_{2}}, {x_{3}}, {x_{4}}\\right) = \\left(\\frac{2 \\, {u'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, \\frac{2 \\, {v'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, \\frac{2 \\, {w'}}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}, -\\frac{{u'}^{2} + {v'}^{2} + {w'}^{2} - 1}{{u'}^{2} + {v'}^{2} + {w'}^{2} + 1}\\right) \\end{array}$"
],
"text/plain": [
"iota: S^3 → E^4\n",
"on A: (chi, theta, phi) ↦ (x1, x2, x3, x4) = (cos(phi)*sin(chi)*sin(theta), sin(chi)*sin(phi)*sin(theta), cos(theta)*sin(chi), cos(chi))\n",
"on S^3-{NP}: (u, v, w) ↦ (x1, x2, x3, x4) = (2*u/(u^2 + v^2 + w^2 + 1), 2*v/(u^2 + v^2 + w^2 + 1), 2*w/(u^2 + v^2 + w^2 + 1), (u^2 + v^2 + w^2 - 1)/(u^2 + v^2 + w^2 + 1))\n",
"on S^3-{SP}: (up, vp, wp) ↦ (x1, x2, x3, x4) = (2*up/(up^2 + vp^2 + wp^2 + 1), 2*vp/(up^2 + vp^2 + wp^2 + 1), 2*wp/(up^2 + vp^2 + wp^2 + 1), -(up^2 + vp^2 + wp^2 - 1)/(up^2 + vp^2 + wp^2 + 1))"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# continuation\n",
"%display latex\n",
"stereoN, stereoS = Sph.coordinate_charts('stereographic',\n",
" names=['u','v','w']) # stereographic projections in S^3\n",
"Sph.embedding().disp() # show embeddings into E^4"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We have also the corresponding transitions in $S^3$ predefined."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left\\{\\begin{array}{lcl} u & = & \\frac{{u'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\\\ v & = & \\frac{{v'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\\\ w & = & \\frac{{w'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\end{array}\\right.\\)"
],
"text/latex": [
"$\\displaystyle \\left\\{\\begin{array}{lcl} u & = & \\frac{{u'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\\\ v & = & \\frac{{v'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\\\ w & = & \\frac{{w'}}{{u'}^{2} + {v'}^{2} + {w'}^{2}} \\end{array}\\right.$"
],
"text/plain": [
"u = up/(up^2 + vp^2 + wp^2)\n",
"v = vp/(up^2 + vp^2 + wp^2)\n",
"w = wp/(up^2 + vp^2 + wp^2)"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"A = spher.domain() # domain of spherical coordinates\n",
"# intersection of domains of stereoN and stereoS coordinates:\n",
"W = Sph._stereoN_dom.intersection(Sph._stereoS_dom)\n",
"# intersection of domains of stereoN,stereoS and spher coordinates:\n",
"V=W.intersection(A) \n",
" # transition spher -> stereoN:\n",
"F1=Sph.coord_change(spher.restrict(V), stereoN.restrict(V))\n",
" # transition stereoN -> spher:\n",
"F2=Sph.coord_change( stereoN.restrict(V),spher.restrict(V))\n",
" # transition spher -> stereoS \n",
"F3=Sph.coord_change(spher.restrict(V), stereoS.restrict(V))\n",
" # transition stereoS -> spher\n",
"F4=Sph.coord_change( stereoS.restrict(V),spher.restrict(V))\n",
" # transition stereoN -> stereoS\n",
"F5=Sph.coord_change( stereoN.restrict(V),stereoS.restrict(V))\n",
" # transition stereoS -> stereoN\n",
"F6=Sph.coord_change( stereoS.restrict(V),stereoN.restrict(V))\n",
"F6.disp()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left\\{\\begin{array}{lcl} {u'} & = & \\frac{u}{u^{2} + v^{2} + w^{2}} \\\\ {v'} & = & \\frac{v}{u^{2} + v^{2} + w^{2}} \\\\ {w'} & = & \\frac{w}{u^{2} + v^{2} + w^{2}} \\end{array}\\right.\\)"
],
"text/latex": [
"$\\displaystyle \\left\\{\\begin{array}{lcl} {u'} & = & \\frac{u}{u^{2} + v^{2} + w^{2}} \\\\ {v'} & = & \\frac{v}{u^{2} + v^{2} + w^{2}} \\\\ {w'} & = & \\frac{w}{u^{2} + v^{2} + w^{2}} \\end{array}\\right.$"
],
"text/plain": [
"up = u/(u^2 + v^2 + w^2)\n",
"vp = v/(u^2 + v^2 + w^2)\n",
"wp = w/(u^2 + v^2 + w^2)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"F5.disp()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 5.4**\n",
"\n",
"**Spherical coordinates in $R^4$**."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can use `manifolds.Sphere` to obtain the transition from spherical to Cartesian coordinates in $R^4$."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(r*cos(phi)*sin(chi)*sin(theta),\n",
" r*sin(chi)*sin(phi)*sin(theta),\n",
" r*cos(theta)*sin(chi),\n",
" r*cos(chi))"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%display plain # to obtain output which can be re-used in the code\n",
"dim=3 # dimension of the sphere\n",
"r=var('r') # symbolic variable\n",
"Sph=manifolds.Sphere(dim,radius=r) # 3-dim sphere with radius r\n",
"Phi=Sph.embedding() # embedding into E^4\n",
"E=Sph.ambient() # ambient space E^4\n",
"fun=Phi.coord_functions() # embedding functions\n",
"fun.expr() # show embedding functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The result can be used to define the transition spherU -> cartU in $R^4$."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"x1 = r*cos(phi)*sin(chi)*sin(theta)\n",
"x2 = r*sin(chi)*sin(phi)*sin(theta)\n",
"x3 = r*cos(theta)*sin(chi)\n",
"x4 = r*cos(chi)"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"R4=Manifold(4,'R^4',start_index=1) # manifold R^4\n",
"cart.=R4.chart() # Cartesian coordinates in R^4\n",
"U=R4.open_subset('U', # open subset of R^4 with half-\n",
" coord_def={cart: (x2!=0, x1<0)}) # plane {x2 = 0, x1 ≥ 0} excluded\n",
"cartU=cart.restrict(U) # restrict cart to U\n",
" # spherical coordinates on U, use\n",
" # names from the previous output!\n",
"spherU.=U.chart(r'r:(0,+oo) chi:(0,pi):\\chi\\\n",
" theta:(0,pi):\\theta phi:(-pi,pi):periodic:\\phi')\n",
" # transition spherU -> cartU\n",
"spher_to_cart = spherU.transition_map(cartU,fun.expr())\n",
"spher_to_cart.disp() # show transition"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"# spher_to_cart.inverse() does not work"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Inverse transition can be defined as follows:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Check of the inverse coordinate transformation:\n",
" r == r *passed*\n",
" chi == arctan2(r*sin(chi), r*cos(chi)) **failed**\n",
" theta == arctan2(r*sin(chi)*sin(theta), r*cos(theta)*sin(chi)) **failed**\n",
" phi == arctan2(r*sin(chi)*sin(phi)*sin(theta), r*cos(phi)*sin(chi)*sin(theta)) **failed**\n",
" x1 == x1 *passed*\n",
" x2 == x2 *passed*\n",
" x3 == x3 *passed*\n",
" x4 == x4 *passed*\n",
"NB: a failed report can reflect a mere lack of simplification.\n"
]
}
],
"source": [
"fun=(sqrt(x1^2+x2^2+x3^2+x4^2), # functions defining\n",
" atan2(sqrt(x1^2+x2^2+x3^2),x4), # inverse transition\n",
" atan2(sqrt(x1^2+x2^2),x3), # spher -> cart\n",
" atan2(x2,x1))\n",
"spher_to_cart.set_inverse(*fun) # set inverse trans."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The failed computations reflect a lack of simplification in `SageMath` and can be checked by hand (https://en.wikipedia.org/wiki/Atan2)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 5.5**\n",
"\n",
"**Spherical coordinates in $R^5$**."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"In 5-dimensional Euclidean space E^5\n",
"the spherical coordinates are\n",
"(x1, x2, x3, x4, x5) =\n"
]
},
{
"data": {
"text/plain": [
"(r*cos(phi_4)*sin(phi_1)*sin(phi_2)*sin(phi_3),\n",
" r*sin(phi_1)*sin(phi_2)*sin(phi_3)*sin(phi_4),\n",
" r*cos(phi_3)*sin(phi_1)*sin(phi_2),\n",
" r*cos(phi_2)*sin(phi_1),\n",
" r*cos(phi_1))"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%display plain # We don't want the Latex output\n",
"dim=4 # dimension of the sphere\n",
"r=var('r') # symbolic variable\n",
"Sph=manifolds.Sphere(dim,radius=r) # 4-dim sphere, radius r,in E^5\n",
"Phi=Sph.embedding() # embedding S^4 -> E^5\n",
"E=Sph.ambient() # ambient space E^5\n",
"print(\"In\",E)\n",
"print(\"the spherical coordinates are\")\n",
"print(E.cartesian_coordinates()[:],\"=\")\n",
"Phi.coord_functions()[:] # print coordinate functions"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the result we can define the transition spherU -> cartU in $R^5$."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"x1 = r*cos(phi4)*sin(phi1)*sin(phi2)*sin(phi3)\n",
"x2 = r*sin(phi1)*sin(phi2)*sin(phi3)*sin(phi4)\n",
"x3 = r*cos(phi3)*sin(phi1)*sin(phi2)\n",
"x4 = r*cos(phi2)*sin(phi1)\n",
"x5 = r*cos(phi1)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"R5=Manifold(5,'R^5') # manifold R^5\n",
"cart.=R5.chart() # Cartesian coord. in R^5\n",
"U=R5.open_subset('U', # open subset of R^5,\n",
" coord_def={cart:(x3!=0,x2!=0,x1<0)}) #{x3=0,x2=0,x1>=0} exclud.\n",
"cartU=cart.restrict(U) # restrict Cart.coord.to U\n",
"# use the same names as in the output of the previous command\n",
"spherU.=U.chart(r'r:(0,+oo) phi1:(0,pi):\\phi_1\\\n",
"phi2:(0,pi):\\phi_2 phi3:0,pi):\\phi_3 phi4:(-pi,pi):periodic:\\phi_4')\n",
" # spherical coordinates on U\n",
"spher_to_cart = spherU.transition_map(cartU, # define transition\n",
"(r*cos(phi_4)*sin(phi_1)*sin(phi_2)*sin(phi_3), # spher -> cart\n",
"r*sin(phi_1)*sin(phi_2)*sin(phi_3)*sin(phi_4),\n",
"r*cos(phi_3)*sin(phi_1)*sin(phi_2),\n",
"r*cos(phi_2)*sin(phi_1),\n",
"r*cos(phi_1)))\n",
"\n",
"spher_to_cart.disp() # show transition "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"\n",
"**Inverse transition**:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Check of the inverse coordinate transformation:\n",
" r == r *passed*\n",
" phi1 == arctan2(r*sin(phi1), r*cos(phi1)) **failed**\n",
" phi2 == arctan2(r*sin(phi1)*sin(phi2), r*cos(phi2)*sin(phi1)) **failed**\n",
" phi3 == arctan2(r*abs(sin(phi3))*sin(phi1)*sin(phi2), r*cos(phi3)*sin(phi1)*sin(phi2)) **failed**\n",
" phi4 == arctan2(r*sin(phi1)*sin(phi2)*sin(phi3)*sin(phi4), r*cos(phi4)*sin(phi1)*sin(phi2)*sin(phi3)) **failed**\n",
" x1 == x1 *passed*\n",
" x2 == x2 *passed*\n",
" x3 == x3 *passed*\n",
" x4 == x4 *passed*\n",
" x5 == x5 *passed*\n",
"NB: a failed report can reflect a mere lack of simplification.\n"
]
}
],
"source": [
"fun=(sqrt(x1^2+x2^2+x3^2+x4^2+x5^2), # functions defining the \n",
" atan2(sqrt(x1^2+x2^2+x3^2+x4^2),x5), # inverse transition\n",
" atan2(sqrt(x1^2+x2^2+x3^2),x4),\n",
" atan2(sqrt(x1^2+x2^2),x3),\n",
" atan2(x2,x1))\n",
"cart_to_spher=spher_to_cart.set_inverse(*fun) # define inv. trans."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What's next?\n",
"\n",
"Take a look at the notebook [The notion of module](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/06Manifold_VectSpaces_Modules.ipynb)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 9.6",
"language": "sage",
"name": "sagemath"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}