{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Sphere $\\mathbb{S}^2$ (SymPy version)\n", "\n", "This worksheet demonstrates a few capabilities of\n", "[SageManifolds](http://sagemanifolds.obspm.fr) (version 1.2, as included in SageMath 8.2)\n", "on the example of the 2-dimensional sphere, using [SymPy](http://www.sympy.org) as symbolic engine, instead of SageMath's default one (Pynac+Maxima).\n", "\n", "Click [here](https://raw.githubusercontent.com/sagemanifolds/SageManifolds/master/Worksheets/v1.2/SM_sphere_S2_sympy.ipynb) to download the worksheet file (ipynb format). To run it, you must start SageMath with the Jupyter notebook, via the command sage -n jupyter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "*NB:* a version of SageMath at least equal to 8.2 is required to run this worksheet:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SageMath version 8.2, Release Date: 2018-05-05'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "version()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we set up the notebook to display mathematical objects using LaTeX rendering:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%display latex\n", "from sympy import init_printing\n", "init_printing()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also define a viewer for 3D plots (use 'threejs' or 'jmol' for interactive 3D graphics):" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "viewer3D = 'threejs' # must be 'threejs', jmol', 'tachyon' or None (default)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## $\\mathbb{S}^2$ as a 2-dimensional differentiable manifold\n", "\n", "We start by declaring $\\mathbb{S}^2$ as a differentiable manifold of dimension 2 over $\\mathbb{R}$:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "S2 = Manifold(2, 'S^2', latex_name=r'\\mathbb{S}^2', start_index=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The first argument, 2, is the dimension of the manifold, while the second argument is the symbol used to label the manifold.

\n", "

The argument start_index sets the index range to be used on the manifold for labelling components w.r.t. a basis or a frame: start_index=1 corresponds to $\\{1,2\\}$; the default value is start_index=0 and yields to $\\{0,1\\}$.

" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "print(S2)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "2-dimensional differentiable manifold S^2" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The manifold is a Parent object:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "isinstance(S2, Parent)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

in the category of smooth manifolds over $\\mathbb{R}$:

" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Category of smooth manifolds over Real Field with 53 bits of precision" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2.category()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We ask for all symbolic computations to be performed with [SymPy](http://www.sympy.org), instead of SageMath's default symbolic engine (Pynac+Maxima, implemented via SageMath's Symbolic Ring):" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "S2.set_calculus_method('sympy')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Coordinate charts on $\\mathbb{S}^2$\n", "\n", "The sphere cannot be covered by a single chart. At least two charts are necessary, for instance the charts associated with the stereographic projections from the North pole and the South pole respectively. Let us introduce the open subsets covered by these two charts: \n", "$$U := \\mathbb{S}^2\\setminus\\{N\\},$$  \n", "$$V := \\mathbb{S}^2\\setminus\\{S\\},$$\n", "where $N$ is a point of $\\mathbb{S}^2$, which we shall call the North pole, and $S$ is the point of $U$ of stereographic coordinates $(0,0)$, which we call the South pole:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset U of the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "U = S2.open_subset('U') ; print(U)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset V of the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "V = S2.open_subset('V') ; print(V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We declare that $\\mathbb{S}^2 = U \\cup V$:

" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "S2.declare_union(U, V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Then we declare the stereographic chart on $U$, denoting by $(x,y)$ the coordinates resulting from the stereographic projection from the North pole:

" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "stereoN. = U.chart()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The expression . in the left-hand side means that the Python variables x and y are set to the two coordinates of the chart. This allows one to refer subsequently to the coordinates by their names. In the present case, the function chart() has no argument, which implies that the coordinate symbols will be x and y (i.e. exactly the characters appearing in the <...> operator) and that each coordinate range is $(-\\infty,+\\infty)$. As we will see below, for other cases, an argument must be passed to chart() to specify each coordinate symbol and range, as well as some specific LaTeX symbol." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (U, (x, y))" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The coordinates can be accessed individually, either by means of their indices in the chart ( following the convention start_index=1 set in the manifold's definition) or by their names as Python variables:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN[1]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "y is stereoN[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Similarly, we introduce on $V$ the coordinates $(x',y')$ corresponding to the stereographic projection from the South pole:

" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [], "source": [ "stereoS. = V.chart(\"xp:x' yp:y'\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this case, the string argument passed to chart stipulates that the text-only names of the coordinates are xp and yp (same as the Python variables names defined within the <...> operator in the left-hand side), while their LaTeX names are $x'$ and $y'$." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (V, (xp, yp))" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

At this stage, the user's atlas on the manifold has two charts:

" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Chart (U, (x, y)), Chart (V, (xp, yp))]" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We have to specify the transition map between the charts 'stereoN' = $(U,(x,y))$ and 'stereoS' = $(V,(x',y'))$; it is given by the standard inversion formulas:

" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "xp = x/(x^2 + y^2)\n", "yp = y/(x^2 + y^2)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN_to_S = stereoN.transition_map(stereoS, \n", " (x/(x^2+y^2), y/(x^2+y^2)), \n", " intersection_name='W',\n", " restrictions1= x^2+y^2!=0, \n", " restrictions2= xp^2+xp^2!=0)\n", "stereoN_to_S.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above declaration, 'W' is the name given to the chart-overlap subset: $W := U\\cap V$, the condition $x^2+y^2 \\not=0$  defines $W$ as a subset of $U$, and the condition $x'^2+y'^2\\not=0$ defines $W$ as a subset of $V$.\n", "\n", "The inverse coordinate transformation is computed by means of the method inverse():" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = xp/(xp^2 + yp^2)\n", "y = yp/(xp^2 + yp^2)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS_to_N = stereoN_to_S.inverse()\n", "stereoS_to_N.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

In the present case, the situation is of course perfectly symmetric regarding the coordinates $(x,y)$ and $(x',y')$.

\n", "

At this stage, the user's atlas has four charts:

" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Chart (U, (x, y)),\n", " Chart (V, (xp, yp)),\n", " Chart (W, (x, y)),\n", " Chart (W, (xp, yp))]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Let us store $W = U\\cap V$ into a Python variable for future use:

" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "W = U.intersection(V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Similarly we store the charts $(W,(x,y))$ (the restriction of  $(U,(x,y))$ to $W$) and $(W,(x',y'))$ (the restriction of $(V,(x',y'))$ to $W$) into Python variables:

" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (W, (x, y))" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN_W = stereoN.restrict(W)\n", "stereoN_W" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (W, (xp, yp))" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS_W = stereoS.restrict(W)\n", "stereoS_W" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We may plot the chart $(W, (x',y'))$ in terms of itself, as a grid:

More interestingly, let us plot the stereographic chart $(x',y')$ in terms of the stereographic chart $(x,y)$ on the domain $W$ where both systems overlap (we split the plot in four parts to avoid the singularity at $(x',y')=(0,0)$):

### Spherical coordinates

\n", "

The standard spherical (or polar) coordinates $(\\theta,\\phi)$ are defined on the open domain $A\\subset W \\subset \\mathbb{S}^2$ that is the complement of the \"origin meridian\"; since the latter is the half-circle defined by $y=0$ and $x\\geq 0$, we declare:

" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset A of the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "A = W.open_subset('A', coord_def={stereoN_W: (y!=0, x<0), \n", " stereoS_W: (yp!=0, xp<0)})\n", "print(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The restriction of the stereographic chart from the North pole to $A$ is

" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (A, (x, y))" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN_A = stereoN_W.restrict(A)\n", "stereoN_A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We then declare the chart $(A,(\\theta,\\phi))$ by specifying the intervals $(0,\\pi)$ and $(0,2\\pi)$ spanned by respectively $\\theta$ and $\\phi$:

" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (A, (theta, phi))" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher. = A.chart(r'theta:(0,pi):\\theta phi:(0,2*pi):\\phi') ; spher" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The specification of the spherical coordinates is completed by providing the transition map with the stereographic chart $(A,(x,y))$:

" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = -cos(phi)*sin(theta)/(cos(theta) - 1)\n", "y = -sin(phi)*sin(theta)/(cos(theta) - 1)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher_to_stereoN = spher.transition_map(stereoN_A, \n", " (sin(th)*cos(ph)/(1-cos(th)),\n", " sin(th)*sin(ph)/(1-cos(th))))\n", "spher_to_stereoN.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We also provide the inverse transition map, asking to check that the provided formulas are indeed correct (argument verbose=True):" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Check of the inverse coordinate transformation:\n", " theta == -2*atan(1/tan(theta) - 1/sin(theta))\n", " phi == atan2(sin(phi)*sin(theta)/(cos(theta) - 1), sin(theta)*cos(phi)/(cos(theta) - 1)) + pi\n", " x == x\n", " y == y\n" ] } ], "source": [ "spher_to_stereoN.set_inverse(2*atan(1/sqrt(x^2+y^2)), atan2(-y,-x)+pi,\n", " verbose=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The check is passed, modulo some lack of trigonometric simplifications in the first two lines." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "theta = 2*arctan(1/sqrt(x^2 + y^2))\n", "phi = pi + arctan2(-y, -x)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher_to_stereoN.inverse().display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The transition map $(A,(\\theta,\\phi))\\rightarrow (A,(x',y'))$ is obtained by combining the transition maps $(A,(\\theta,\\phi))\\rightarrow (A,(x,y))$ and $(A,(x,y))\\rightarrow (A,(x',y'))$:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "xp = -(cos(theta) - 1)*cos(phi)/sin(theta)\n", "yp = -(cos(theta) - 1)*sin(phi)/sin(theta)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN_to_S_A = stereoN_to_S.restrict(A)\n", "spher_to_stereoS = stereoN_to_S_A * spher_to_stereoN\n", "spher_to_stereoS.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, the transition map $(A,(x',y'))\\rightarrow (A,(\\theta,\\phi))$ is obtained by combining the transition maps $(A,(x',y'))\\rightarrow (A,(x,y))$ and $(A,(x,y))\\rightarrow (A,(\\theta,\\phi))$:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "theta = 2*arctan(sqrt(xp^2 + yp^2))\n", "phi = pi + arctan2(-yp/(xp^2 + yp^2), -xp/(xp^2 + yp^2))" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS_to_N_A = stereoN_to_S.inverse().restrict(A)\n", "stereoS_to_spher = spher_to_stereoN.inverse() * stereoS_to_N_A \n", "stereoS_to_spher.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The user atlas of $\\mathbb{S}^2$ is now

" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Chart (U, (x, y)),\n", " Chart (V, (xp, yp)),\n", " Chart (W, (x, y)),\n", " Chart (W, (xp, yp)),\n", " Chart (A, (x, y)),\n", " Chart (A, (xp, yp)),\n", " Chart (A, (theta, phi))]" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S2.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Let us draw the grid of spherical coordinates $(\\theta,\\phi)$ in terms of stereographic coordinates from the North pole $(x,y)$:

Conversly, we may represent the grid of the stereographic coordinates $(x,y)$ restricted to $A$ in terms of the spherical coordinates $(\\theta,\\phi)$. We limit ourselves to one quarter (cf. the argument ranges):

## Points on $\\mathbb{S}^2$

\n", "

We declare the North pole (resp. the South pole) as the point of coordinates $(0,0)$ in the chart $(V,(x',y'))$ (resp. in the chart $(U,(x,y))$):

" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point N on the 2-dimensional differentiable manifold S^2\n", "Point S on the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "N = V.point((0,0), chart=stereoS, name='N') ; print(N)\n", "S = U.point((0,0), chart=stereoN, name='S') ; print(S)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Since points are Sage Element's, the corresponding Parent being the manifold subsets, an equivalent writing of the above declarations is

" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point N on the 2-dimensional differentiable manifold S^2\n", "Point S on the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "N = V((0,0), chart=stereoS, name='N') ; print(N)\n", "S = U((0,0), chart=stereoN, name='S') ; print(S)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Moreover, since stereoS in the default chart on $V$ and stereoN is the default one on $U$, their mentions can be omitted, so that the above can be shortened to

" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point N on the 2-dimensional differentiable manifold S^2\n", "Point S on the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "N = V((0,0), name='N') ; print(N)\n", "S = U((0,0), name='S') ; print(S)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Open subset V of the 2-dimensional differentiable manifold S^2" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N.parent()" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Open subset U of the 2-dimensional differentiable manifold S^2" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S.parent()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We have of course

" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N in V" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N in S2" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "False" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N in U" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "False" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N in A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Let us introduce some point at the equator:

" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "E = S2((0,1), chart=stereoN, name='E')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The point $E$ is in the open subset $A$:

" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E in A" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We may then ask for its spherical coordinates $(\\theta,\\phi)$:

" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGoAAAAZCAYAAADZl7v4AAAABHNCSVQICAgIfAhkiAAAAz5JREFUaIHt2VuIVVUcx/FPntHREkY0bKKoLGvACPQhSQtjAomJnjKxpHpIIqiXinoLGacoEiKSerLowYqetKLoSpkg9SSRXSCCLk9lN9F8CMrpYe1De3Zn7X3mzNozWztf2LDX/6z1//9/s/a6Dn1OC+bX4POmGnw2kV507sCa6TbajDt7CFbGCF5N7LOJ9KpzId7DJd02GMWuHgJVMYEtBdta7MVbOIzncV4NsWeTmei8FAfRqgoyhE9x5kwyjXAIi3LlEbyDJVl5MQ7gCC6qIf5sMVOdr+D2qiBPYHwGScZYiz0F2+tYWbCtwaSQ7KlICp1X4cuyIAvxG87pLcdSnsZYwfYHfsDygv13/FJDDrNBCp0tHMMVsSBjwrCNsUAYtp2esqmyhc8wULAfxp9YUbAfxYkSf3XTBJ1v46FYoF14poN9Gd7AX8JwjT3XRvxuxLMd7GdhuGC7IPP1YSzJGmmSzifxUizRT3B3wTYgLIT34+oskVuFefQ1bMjeV+OMiN8Xsrbd8Bj+xvou66eiaTofFvqjI9/677ZyK67PlfdiXvb+ZhcJDQq7yJi4PBfjOB7tom5qmqbzHnzVLhTn0uXCvJnn5dz7ME5mz5AwVVRxo3B2mKyoN5jF2i18TbNN03SeFEYc/v1i2kx2sOXZho+y95HMWRVbTf0jxHgO7+KBLurWTRN0LsNP7UKxU45gaaRhC3fh/ax8rupt/BDOF3Y9ZYzja2zP2e6oaFMXTdFZ2lE/infUzYKI9rw5iAtL6sMm7Cv5HW7L8nikYL+mUB4Rznl1M9c621wm1/HFNepjrIo0fNDURfV7QdANeDHS5hbh64yxAU8Ju628jwFT5/pRfCAs8JtK/KVgLnW2mSd04I6Yw434IvLbbuHCsE1LmG8vj9Qfxv5YoIxfxc8q+S9vFX7GdxX+UjCXOttciW/KHA5mTlPcXt8nbDFTMp7YXwrq0LkH91ZVmsDOBMEO4uwEfvI8nthfClLrXCFcQ1X+03YxPle+eFaxUneHxOkwKiz0TSK1zvnCHd/qbhusM/VkPl22C7ucVAxo5mhKrXMC10230Zhw79UL+4SRebqTWmdxF96nT58+/2f+AZFF2fGGaiu9AAAAAElFTkSuQmCC\n", "text/latex": [ "$$\\left ( \\frac{\\pi}{2}, \\quad \\frac{\\pi}{2}\\right )$$" ], "text/plain": [ "(pi/2, pi/2)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E.coord(spher)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

which is not possible for the point $N$:

" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: the point does not belong to the domain of Chart (A, (theta, phi))\n" ] } ], "source": [ "try:\n", " N.coord(spher)\n", "except ValueError as exc:\n", " print('Error: ' + str(exc))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

## Mappings between manifolds: the embedding of $\\mathbb{S}^2$ into $\\mathbb{R}^3$

\n", "

Let us first declare $\\mathbb{R}^3$ as a 3-dimensional manifold covered by a single chart (the so-called Cartesian coordinates):

" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (R^3, (X, Y, Z))" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R3 = Manifold(3, 'R^3', r'\\mathbb{R}^3', start_index=1)\n", "R3.set_calculus_method('sympy')\n", "cart. = R3.chart() ; cart" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

The embedding of the sphere is defined as a differential mapping $\\Phi: \\mathbb{S}^2 \\rightarrow \\mathbb{R}^3$:

" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [], "source": [ "Phi = S2.diff_map(R3, {(stereoN, cart): \n", " [2*x/(1+x^2+y^2), 2*y/(1+x^2+y^2),\n", " (x^2+y^2-1)/(1+x^2+y^2)],\n", " (stereoS, cart): \n", " [2*xp/(1+xp^2+yp^2), 2*yp/(1+xp^2+yp^2),\n", " (1-xp^2-yp^2)/(1+xp^2+yp^2)]},\n", " name='Phi', latex_name=r'\\Phi')" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^2 --> R^3\n", "on U: (x, y) |--> (X, Y, Z) = (2*x/(x**2 + y**2 + 1), 2*y/(x**2 + y**2 + 1), (x**2 + y**2 - 1)/(x**2 + y**2 + 1))\n", "on V: (xp, yp) |--> (X, Y, Z) = (2*xp/(xp**2 + yp**2 + 1), 2*yp/(xp**2 + yp**2 + 1), -(xp**2 + yp**2 - 1)/(xp**2 + yp**2 + 1))" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.display()" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Set of Morphisms from 2-dimensional differentiable manifold S^2 to 3-dimensional differentiable manifold R^3 in Category of smooth manifolds over Real Field with 53 bits of precision" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.parent()" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Set of Morphisms from 2-dimensional differentiable manifold S^2 to 3-dimensional differentiable manifold R^3 in Category of smooth manifolds over Real Field with 53 bits of precision\n" ] } ], "source": [ "print(Phi.parent())" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.parent() is Hom(S2, R3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

$\\Phi$ maps points of $\\mathbb{S}^2$ to points of $\\mathbb{R}^3$:

" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point Phi(N) on the 3-dimensional differentiable manifold R^3\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGEAAAAWCAYAAADQIfLaAAAABHNCSVQICAgIfAhkiAAAAndJREFUaIHt2DloVEEcx/GPZj2IJN6KF4rxQCvxQBAR0lpYCYJHr9hZekAatfNArGw8QATRRlIIoiIqgoWiVoKgYCIaFUVTiHgUsw8mm7frvuzGTLFfWB7///znP7+3//dm5g0tkmU2dkb2SlzHSZzARcwdA10xKWqCdjzL8bfhNKbUk6QDZzGhbE/FW+yOYg7iBSaNVGmDpKgJNuAx/lRpXyE8LP/kDNZG9lF8QCnyzcBP7CssszmkpmkVenEej1QvAvRgT61kS3GrwvcSN3Jin+N2nSKbTYqaMs6rXYRZwnTVljnGVwTsx6XI7sBy9Ock68e6kahskBQ1FeEj+tCdOSqLsBX3I3tx+fo9J9kgOjGxiQLrIUVNRXmAbZkRF2EB5uBV5OssXwdzEmW+ac1UVwcpairKU9EbGxdhibDYxfwqX3/nJMp2T6WcttEkRU1F+SRMqRhahLn4WhE8UCNRtt/91hxddZOipqJ8FrbZGFqEkuFP13thpZ+ek2gKvvj/N5yipqKU8CMz4iIMGH5jg3iCRTmJlglz2/8mRU1FmS6a+uMi9GFmTodebMS4yNcl/AlXK2JXYnJTZNYmRU1FmI03eQ3j8A7zK/zzhFc8/so7JXwYxVvBbmGauNYspTVIUVPGlfKY7TVijuFQtcYL2JHjXyM8fSdxTriphRUxq4Up7XXdchsjJU1zcFM4u/pT/g3gDnblxN/D+mrJNhn+Ohelp8H+o0HPWAuI6MLd2FH5xfxQ2Gt3NTDIWJ5iViMlTQdw5F9By3DZ0EWvXrqxfQT9RpOUNG0R1q662Iy9BQco4XjBPqNNSpracFh0etqiRYsWifEX1YWD0eAy72YAAAAASUVORK5CYII=\n", "text/latex": [ "$$\\left ( 0, \\quad 0, \\quad 1\\right )$$" ], "text/plain": [ "(0, 0, 1)" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "N1 = Phi(N) ; print(N1) ; N1 ; N1.coord()" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point Phi(S) on the 3-dimensional differentiable manifold R^3\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAHgAAAAWCAYAAAALmlj4AAAABHNCSVQICAgIfAhkiAAAAqFJREFUaIHt2U9oVUcUx/FPmmcVJdpYjWgVxUSDLkSqpSBFyNaFq0LBP0tBcefSP5CN7c4/iKsi+AeKILopWRRKLaJS6KIldlUQLDQpNSqKZiGi6WLeg8nNzfO+vHdfBvq+8LjMmTNnfm/m3nNn5tLhf8lK7IvKg7iFsziDq1g1D7piUtRUNosxmmPvxnksKRKkBxexoFpehr9xIPI5jj+wcK5KmyRFTWXzGX7F1Cz1m4Wb/L1cwKdR+TQeoxLZluMNjjQsszWkqKkstmAEl/GL2ScYhnGwXrCN+DFj+xPf5/g+wE8FRbaaFDW1g8vqT/AKIYV31wwfZByO4lpU7sEmjOcEG8eOuahskhQ1pcITjGGoZshO8B7cjcrrq9dXOcEmsRQftlBgEVLUlBL3sLdWiCf4E/ThYWRbWr1O5gSq2T5qpboCpKgpJX4XZbF4gjcIC5eYt9Xru5xAtVV2JaeuTFLUlBJPhVcYpk/wKrzIOE/UCVTbc71sja7CpKgpJZ4J20hMv9MrZj4V/wqrtt6cQEvwXPsHM0VNWbbhEroK+v+GQy3qu4LXcaHGhJmDNlntfF1OoAEh37ebFDVlGRUOJuaDXtGrNk7RY/g4p8EIPjf9buwXBvhGxncQi1oisz4pakqFlfgrr6IL/2BNxr5aSHvxCck54VAh3o4MCanzZquU1iFFTe3guvB/Ftfx+RonZqu8gq9y7NuFp+YsvhUGbG3GZ6uQ5h8VltscKWoqgz78IJyzT1V/E7iN/Tn+d7BztmC7zExxjTLcZPsyGJ5vAW2iHz/HhuxJ1n1hL9nfRCcpfs1JUVMZHMOp9zkN4DvFl/gxQ/hyDu3KJEVNZbBbWIcU4gscbrCDCr5psE3ZpKipDLpxUvQVqUOHDh06JM9/rfmG3Px/SE4AAAAASUVORK5CYII=\n", "text/latex": [ "$$\\left ( 0, \\quad 0, \\quad -1\\right )$$" ], "text/plain": [ "(0, 0, -1)" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S1 = Phi(S) ; print(S1) ; S1 ; S1.coord()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point Phi(E) on the 3-dimensional differentiable manifold R^3\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGEAAAAWCAYAAADQIfLaAAAABHNCSVQICAgIfAhkiAAAAnRJREFUaIHt2EuIjWEcx/HPmOPSaIZxmcktMsPESi4pSc3Wwkoplz3ZWbrUbLAzJCubQUmJjWahhISUBWGlFGVGDCJmITEWzzn1zPHOzPueuZzTmfOt09v//z7P8/+d/7/n8j7UqFgWY29kd+AmunEGl9FaBl1JNOBFuUUYO0f1OIe5aQZrxAXMzNvz8B77ozZH8Qqzx6N6AtiCpxgqs460OVorFGdMzmNjZJ/EJ+Qi3wL8xqHseieEdehFD54ofxGy5KgLB0YbbDXuFPle41ZC25e4m0HoZNGj/EXIkqNFwvJZX3DMKGpwGFciuxFr0J8QoB+bMoqtRrLm6DP60FlwFBdhJx5G9sr882dCgEE0YVZ6vVVJKTl6hF0FIy7CMrTgTeRrigZLCgDzU4qtVkrJ0XPRDImLsErYXGL+5J9/EwIUTk+5hHfTiVJy9EVYwjC8CK34XtR4YJTghfPuj9E1Vj2l5OircKzF8CLk/F/Nj8LJo3mEAN8SAkw3SslRDr8KRlyEgYSBBvEMKxICtAtr23SnlBw1i5b+uAh9WJjQoRdbURf52vJBrxe17cCcsVRPMVOhKUuOCNdC75IGqsMHLC3yLxGmVPyVd1b4EImPXp3CtLyRXvuEcC0ftyHh3VRpSpujAqdwbKTBLmFPgn+DUO1uXBT+1PKiNuuFJe1tOt3jogW3hbuZofxvAPewr0ya0uSowANsHmmgbZKnTxa6xtl/Mugqt4CINtyPHcVfzI+Fs23bOIKU+2Y1iUrSdAQnxmrUjquGbzJp6cTuEvpNJpWkaYewV6RiOw5mDJDD6Yx9JptK0lSP46Lb0xo1atSoMP4BKpCD0d33NDcAAAAASUVORK5CYII=\n", "text/latex": [ "$$\\left ( 0, \\quad 1, \\quad 0\\right )$$" ], "text/plain": [ "(0, 1, 0)" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E1 = Phi(E) ; print(E1) ; E1 ; E1.coord()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

$\\Phi$ has been defined in terms of the stereographic charts $(U,(x,y))$ and $(V,(x',y'))$, but we may ask its expression in terms of spherical coordinates. The latter is then computed by means of the transition map $(A,(x,y))\\rightarrow (A,(\\theta,\\phi))$:

" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\left ( \\frac{2 x}{x^{2} + y^{2} + 1}, \\quad \\frac{2 y}{x^{2} + y^{2} + 1}, \\quad \\frac{x^{2} + y^{2} - 1}{x^{2} + y^{2} + 1}\\right )$$" ], "text/plain": [ "(2*x/(x**2 + y**2 + 1),\n", " 2*y/(x**2 + y**2 + 1),\n", " (x**2 + y**2 - 1)/(x**2 + y**2 + 1))" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.expr(stereoN_A, cart)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/latex": [ "$$\\left ( \\sin{\\left (\\theta \\right )} \\cos{\\left (\\phi \\right )}, \\quad \\sin{\\left (\\phi \\right )} \\sin{\\left (\\theta \\right )}, \\quad \\cos{\\left (\\theta \\right )}\\right )$$" ], "text/plain": [ "(sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta))" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.expr(spher, cart)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^2 --> R^3\n", "on A: (theta, phi) |--> (X, Y, Z) = (sin(theta)*cos(phi), sin(phi)*sin(theta), cos(theta))" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.display(spher, cart)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

Let us use $\\Phi$ to draw the grid of spherical coordinates $(\\theta,\\phi)$ in terms of the Cartesian coordinates $(X,Y,Z)$ of $\\mathbb{R}^3$:

" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph_spher = spher.plot(chart=cart, mapping=Phi, number_values=11, \n", " color='blue', label_axes=False)\n", "show(graph_spher, viewer=viewer3D, online=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

We may also use the embedding $\\Phi$ to display the stereographic coordinate grid in terms of the Cartesian coordinates in $\\mathbb{R}^3$. First for the stereographic coordinates from the North pole:

" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "Graphics3d Object" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "graph_stereoN = stereoN.plot(chart=cart, mapping=Phi, number_values=25, \n", " label_axes=False)\n", "show(graph_stereoN, viewer=viewer3D, online=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

and then have a view with the stereographic coordinates from the South pole superposed (in green):

" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "