{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 3-sphere: the round metric\n", "\n", "This worksheet demonstrates some differential geometry capabilities of SageMath on the example of the 3-dimensional sphere, $\\mathbb{S}^3$. The corresponding tools have been developed within the [SageManifolds](http://sagemanifolds.obspm.fr) project (version 1.2, as included in SageMath 8.2).\n", "\n", "Click [here](https://raw.githubusercontent.com/sagemanifolds/SageManifolds/master/Worksheets/v1.2/SM_sphere_S3_metric.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 formatting:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To increase the computational speed, we ask for demanding computations to be parallelly performed on 8 cores:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "Parallelism().set(nproc=8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## $\\mathbb{S}^3$ as a 3-dimensional Riemannian manifold\n", "\n", "We start by declaring $\\mathbb{S}^3$ as a Riemannian manifold of dimension 3:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "S3 = Manifold(3, 'S^3', latex_name=r'\\mathbb{S}^3', structure='Riemannian', \n", " start_index=1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first argument, `3`, is the dimension of the manifold, while the second argument is the symbol used to label the manifold, with the LaTeX output specified by the argument `latex_name`. 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,3\\}$; the default value is `start_index=0`, yielding to $\\{0,1,2\\}$." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "print(S3)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "3-dimensional Riemannian manifold S^3" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Coordinate charts on $\\mathbb{S}^3$\n", "\n", "The 3-sphere cannot be covered by a single chart. At least two charts are necessary, for instance the charts associated with the stereographic projections from two distinct points, $N$ and $S$ say,\n", "which we may call the *North pole* and the *South pole* respectively. Let us introduce the open subsets covered by these two charts: \n", "$$ U := \\mathbb{S}^3\\setminus\\{N\\} $$ \n", "$$ V := \\mathbb{S}^3\\setminus\\{S\\} $$" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset U of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "U = S3.open_subset('U') ; print(U)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset V of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "V = S3.open_subset('V') ; print(V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We declare that $\\mathbb{S}^3 = U \\cup V$:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "S3.declare_union(U, V)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Then we introduce the stereographic chart on $U$, denoting by $(x,y,z)$ the coordinates resulting from the stereographic projection from the North pole onto the equatorial plane:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (U, (x, y, z))" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN. = U.chart()\n", "stereoN" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x: (-oo, +oo); y: (-oo, +oo); z: (-oo, +oo)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoN.coord_range()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, we introduce on $V$ the coordinates $(x',y',z')$ corresponding to the stereographic projection from the South pole onto the equatorial plane:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (V, (xp, yp, zp))" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS. = V.chart(\"xp:x' yp:y' zp:z'\")\n", "stereoS" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "xp: (-oo, +oo); yp: (-oo, +oo); zp: (-oo, +oo)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS.coord_range()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have to specify the **transition map** between the charts `stereoN` = $(U,(x,y,z))$ and `stereoS` = $(V,(x',y',z'))$; it is given by the standard inversion formulas:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "xp = x/(x^2 + y^2 + z^2)\n", "yp = y/(x^2 + y^2 + z^2)\n", "zp = z/(x^2 + y^2 + z^2)" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r2 = x^2+y^2+z^2\n", "stereoN_to_S = stereoN.transition_map(stereoS, \n", " (x/r2, y/r2, z/r2), \n", " intersection_name='W',\n", " restrictions1= x^2+y^2+z^2!=0, \n", " restrictions2= xp^2+yp^2+zp^2!=0)\n", "stereoN_to_S.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above declaration, `'W'` is the name given to the open subset where the two charts overlap: $W := U\\cap V$, the condition $x^2+y^2+z^2\\not=0$ defines $W$ as a subset of $U$, and the condition $x'^2+y'^2+z'^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": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = xp/(xp^2 + yp^2 + zp^2)\n", "y = yp/(xp^2 + yp^2 + zp^2)\n", "z = zp/(xp^2 + yp^2 + zp^2)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS_to_N = stereoN_to_S.inverse()\n", "stereoS_to_N.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that the situation is of course perfectly symmetric regarding the coordinates $(x,y,z)$ and $(x',y',z')$.\n", "\n", "At this stage, the user's atlas has four charts:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Chart (U, (x, y, z)),\n", " Chart (V, (xp, yp, zp)),\n", " Chart (W, (x, y, z)),\n", " Chart (W, (xp, yp, zp))]" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "S3.atlas()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For future reference, we store $W=U\\cap V$ into a Python variable:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset W of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "W = U.intersection(V)\n", "print(W)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The North and South poles\n", "\n", "$N$ is the point of $V$ of stereographic coordinates $(x',y',z')=(0,0,0)$:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point N on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "N = V((0,0,0), chart=stereoS, name='N')\n", "print(N)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "while $S$ is the point of $U$ of stereographic coordinates $(x,y,z)=(0,0,0)$:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point S on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "S = U((0,0,0), chart=stereoN, name='S')\n", "print(S)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have of course" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all([N not in U, N in V, S in U, S not in V])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Embedding of $\\mathbb{S}^3$ into $\\mathbb{R}^4$\n", "\n", "Let us first declare $\\mathbb{R}^4$ as a 4-dimensional Riemannian manifold covered by a single chart (the so-called **Cartesian coordinates**):" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (R^4, (T, X, Y, Z))" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R4 = Manifold(4, 'R^4', r'\\mathbb{R}^4', structure='Riemannian', metric_name='h')\n", "X4. = R4.chart()\n", "X4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The embedding of $\\mathbb{S}^3$ into $\\mathbb{R}^4$ is then defined by the standard formulas relating the stereographic coordinates to the ambient Cartesian ones when considering a **stereographic projection** from the point $(-1,0,0,0)$ to the equatorial plane $T=0$:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^3 --> R^4\n", "on U: (x, y, z) |--> (T, X, Y, Z) = (-(x^2 + y^2 + z^2 - 1)/(x^2 + y^2 + z^2 + 1), 2*x/(x^2 + y^2 + z^2 + 1), 2*y/(x^2 + y^2 + z^2 + 1), 2*z/(x^2 + y^2 + z^2 + 1))\n", "on V: (xp, yp, zp) |--> (T, X, Y, Z) = ((xp^2 + yp^2 + zp^2 - 1)/(xp^2 + yp^2 + zp^2 + 1), 2*xp/(xp^2 + yp^2 + zp^2 + 1), 2*yp/(xp^2 + yp^2 + zp^2 + 1), 2*zp/(xp^2 + yp^2 + zp^2 + 1))" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rp2 = xp^2 + yp^2 + zp^2\n", "Phi = S3.diff_map(R4, {(stereoN, X4): \n", " [(1-r2)/(r2+1), 2*x/(r2+1), \n", " 2*y/(r2+1), 2*z/(r2+1)],\n", " (stereoS, X4):\n", " [(rp2-1)/(rp2+1), 2*xp/(rp2+1), \n", " 2*yp/(rp2+1), 2*zp/(rp2+1)]},\n", " name='Phi', latex_name=r'\\Phi')\n", "Phi.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hyperspherical coordinates\n", "\n", "The hyperspherical coordinates $(\\chi, \\theta, \\phi)$ generalize the standard spherical coordinates $(\\theta, \\phi)$ on $\\mathbb{S}^2$. They are defined on the open domain $A\\subset W \\subset \\mathbb{S}^3$ that is the complement of the \"origin meridian\"; since the latter is defined by $y=0$ and $x\\geq 0$, we declare:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset A of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "A = W.open_subset('A', coord_def={stereoN.restrict(W): (y!=0, x<0), \n", " stereoS.restrict(W): (yp!=0, xp<0)})\n", "print(A)" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (A, (ch, th, ph))" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher. = A.chart(r'ch:(0,pi):\\chi th:(0,pi):\\theta ph:(0,2*pi):\\phi')\n", "spher" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = cos(ph)*sin(ch)*sin(th)/(cos(ch) + 1)\n", "y = sin(ch)*sin(ph)*sin(th)/(cos(ch) + 1)\n", "z = cos(th)*sin(ch)/(cos(ch) + 1)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "den = 1 + cos(ch)\n", "spher_to_stereoN = spher.transition_map(stereoN.restrict(A), \n", " (sin(ch)*sin(th)*cos(ph)/den,\n", " sin(ch)*sin(th)*sin(ph)/den,\n", " sin(ch)*cos(th)/den))\n", "spher_to_stereoN.display()" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Check of the inverse coordinate transformation:\n", " ch == 2*arctan(sqrt(-cos(ch) + 1)/sqrt(cos(ch) + 1))\n", " th == arctan2(sqrt(-cos(ch) + 1)*sin(th)/sqrt(cos(ch) + 1), cos(th)*sin(ch)/(cos(ch) + 1))\n", " ph == pi - arctan2(sin(ch)*sin(ph)*sin(th)/(cos(ch) + 1), -cos(ph)*sin(ch)*sin(th)/(cos(ch) + 1))\n", " x == x\n", " y == y\n", " z == z\n" ] } ], "source": [ "spher_to_stereoN.set_inverse(2*atan(sqrt(x^2+y^2+z^2)),\n", " atan2(sqrt(x^2+y^2), z),\n", " atan2(-y, -x)+pi,\n", " verbose=True)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "ch = 2*arctan(sqrt(x^2 + y^2 + z^2))\n", "th = arctan2(sqrt(x^2 + y^2), z)\n", "ph = pi + arctan2(-y, -x)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher_to_stereoN.inverse().display()" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "xp = (cos(ch) + 1)*cos(ph)*sin(th)/sin(ch)\n", "yp = (cos(ch) + 1)*sin(ph)*sin(th)/sin(ch)\n", "zp = (cos(ch) + 1)*cos(th)/sin(ch)" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spher_to_stereoS = stereoN_to_S.restrict(A) * spher_to_stereoN\n", "spher_to_stereoS.display()" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "ch = 2*arctan(1/sqrt(xp^2 + yp^2 + zp^2))\n", "th = arctan2(sqrt(xp^2 + yp^2)/(xp^2 + yp^2 + zp^2), zp/(xp^2 + yp^2 + zp^2))\n", "ph = pi - arctan2(yp/(xp^2 + yp^2 + zp^2), -xp/(xp^2 + yp^2 + zp^2))" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "stereoS_to_spher = spher_to_stereoN.inverse() * stereoS_to_N.restrict(A)\n", "stereoS_to_spher.display()" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^3 --> R^4\n", "on A: (x, y, z) |--> (T, X, Y, Z) = (-(x^2 + y^2 + z^2 - 1)/(x^2 + y^2 + z^2 + 1), 2*x/(x^2 + y^2 + z^2 + 1), 2*y/(x^2 + y^2 + z^2 + 1), 2*z/(x^2 + y^2 + z^2 + 1))" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.display(stereoN.restrict(A), X4)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^3 --> R^4\n", "on A: (ch, th, ph) |--> (T, X, Y, Z) = (cos(ch), cos(ph)*sin(ch)*sin(th), sin(ch)*sin(ph)*sin(th), cos(th)*sin(ch))" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.display(spher, X4)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Phi: S^3 --> R^4\n", "on U: (x, y, z) |--> (T, X, Y, Z) = (-(x^2 + y^2 + z^2 - 1)/(x^2 + y^2 + z^2 + 1), 2*x/(x^2 + y^2 + z^2 + 1), 2*y/(x^2 + y^2 + z^2 + 1), 2*z/(x^2 + y^2 + z^2 + 1))\n", "on V: (xp, yp, zp) |--> (T, X, Y, Z) = ((xp^2 + yp^2 + zp^2 - 1)/(xp^2 + yp^2 + zp^2 + 1), 2*xp/(xp^2 + yp^2 + zp^2 + 1), 2*yp/(xp^2 + yp^2 + zp^2 + 1), 2*zp/(xp^2 + yp^2 + zp^2 + 1))\n", "on A: (ch, th, ph) |--> (T, X, Y, Z) = (cos(ch), cos(ph)*sin(ch)*sin(th), sin(ch)*sin(ph)*sin(th), cos(th)*sin(ch))" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Phi.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Global left-invariant vector frame on $\\mathbb{S}^3$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The vector frames associated with the two stereographic charts are" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Coordinate frame (U, (d/dx,d/dy,d/dz))" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "frameN = stereoN.frame()\n", "frameN" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Coordinate frame (V, (d/dxp,d/dyp,d/dzp))" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "frameS = stereoS.frame()\n", "frameS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "None of these two frames cover entirely the 3-sphere, since $U$ and $V$ are strict subsets of $\\mathbb{S}^3$. Now, as it is well known, $\\mathbb{S}^3$ admits global vector frames, i.e. $\\mathbb{S}^3$ is a **parallelizable manifold**. Among all the spheres, it shares this remarkable property with $\\mathbb{S}^1$ and $\\mathbb{S}^7$. We shall use a global vector frame $(\\mathbb{S}^3, (\\epsilon_1, \\epsilon_2, \\epsilon_3))$ associated with the Lie group structure of $\\mathbb{S}^3$, namely the left-invariant vector frame constructed in the worksheet \n", "[3-sphere: vector fields and left-invariant parallelization](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/v1.1/SM_sphere_S3_vectors.ipynb). We first declare this vector frame on all $\\mathbb{S}^3$:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Vector frame (S^3, (E_1,E_2,E_3))" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E = S3.vector_frame('E', latex_symbol=r'\\varepsilon')\n", "E" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On $U$, we relate this frame to the stereographic coordinate frame, by means of the formulas obtained in the vector field worksheet mentionned above:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Vector frame (U, (E_1,E_2,E_3))" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E_U = E.restrict(U); E_U" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "E_U[1][frameN,:,stereoN] = \\\n", " [(x^2-y^2-z^2+1)/2, x*y+z, x*z-y]\n", "E_U[2][frameN,:,stereoN] = \\\n", " [x*y-z, (1-x^2+y^2-z^2)/2, x+y*z] \n", "E_U[3][frameN,:,stereoN] = \\\n", " [x*z+y, y*z-x, (1-x^2-y^2+z^2)/2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, on $V$, we relate the global frame with the stereographic coordinate frame from the South pole:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Vector frame (V, (E_1,E_2,E_3))" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E_V = E.restrict(V); E_V" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [], "source": [ "E_V[1][frameS,:, stereoS] = \\\n", " [(yp^2+zp^2-xp^2-1)/2, zp-xp*yp, -yp-xp*zp]\n", "E_V[2][frameS,:, stereoS] = \\\n", " [-zp-xp*yp, (xp^2-yp^2+zp^2-1)/2, xp-yp*zp]\n", "E_V[3][frameS,:, stereoS] = \\\n", " [yp-xp*zp, -xp-yp*zp, (xp^2+yp^2-zp^2-1)/2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us display the links between the various frames:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "E_1 = (1/2*x^2 - 1/2*y^2 - 1/2*z^2 + 1/2) d/dx + (x*y + z) d/dy + (x*z - y) d/dz" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "E_2 = (x*y - z) d/dx + (-1/2*x^2 + 1/2*y^2 - 1/2*z^2 + 1/2) d/dy + (y*z + x) d/dz" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "E_3 = (x*z + y) d/dx + (y*z - x) d/dy + (-1/2*x^2 - 1/2*y^2 + 1/2*z^2 + 1/2) d/dz" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " \n" ] }, { "data": { "text/html": [ "" ], "text/plain": [ "E_1 = (-1/2*xp^2 + 1/2*yp^2 + 1/2*zp^2 - 1/2) d/dxp + (-xp*yp + zp) d/dyp + (-xp*zp - yp) d/dzp" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "E_2 = (-xp*yp - zp) d/dxp + (1/2*xp^2 - 1/2*yp^2 + 1/2*zp^2 - 1/2) d/dyp + (-yp*zp + xp) d/dzp" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "" ], "text/plain": [ "E_3 = (-xp*zp + yp) d/dxp + (-yp*zp - xp) d/dyp + (1/2*xp^2 + 1/2*yp^2 - 1/2*zp^2 - 1/2) d/dzp" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "for i in S3.irange():\n", " show(E[i].display(frameN))\n", "print(\" \")\n", "for i in S3.irange():\n", " show(E[i].display(frameS))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To complete the links, we introduce the change-of-frame operators: first the operator $P$ such that, on $U$, $\\epsilon_i = P(\\partial/\\partial{x^i})$, with $x^i=(x,y,z)$:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "P = U.automorphism_field()\n", "for i in S3.irange():\n", " for j in S3.irange():\n", " P[j,i] = E_U[i][j]" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all([E_U[i] == P(frameN[i]) for i in S3.irange()])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We add $P$ to the known changes of frame on $U$:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "U.set_change_of_frame(frameN, E_U, P)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similarly, on $V$, we introduce the operator $P$ such that $\\epsilon_i = P(\\partial/\\partial {x'}^i)$, with ${x'}^i=(x',y',z')$:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [], "source": [ "P = V.automorphism_field()\n", "for i in S3.irange():\n", " for j in S3.irange():\n", " P[j,i] = E_V[i][j]" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all([E_V[i] == P(frameS[i]) for i in S3.irange()])" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [], "source": [ "V.set_change_of_frame(frameS, E_V, P)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Hopf coordinates" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Despite there does not exist any coordinate chart associated to the global vector frame $(\\mathbb{S}^3, (\\epsilon_1, \\epsilon_2, \\epsilon_3))$, there exist a chart, called the\n", "**Hopf chart**, which has some link to it in the sense that some coordinate lines are integral curves of $\\epsilon_3$. The Hopf coordinates have been introduced in the worksheet [3-sphere: charts, quaternions and Hopf fibration](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/v1.1/SM_sphere_S3_Hopf.ipynb): " ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Open subset B of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "B = U.open_subset('B', coord_def={stereoN.restrict(U): \n", " [x^2+y^2!=0, x^2+y^2+z^2!=1, \n", " (1-x^2-y^2-z^2)*x-2*y*z!=0]})\n", "print(B)" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Chart (B, (eta, alpha, beta))" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Hcoord. = B.chart(r\"eta:(0,pi/2):\\eta alpha:(0,2*pi):\\alpha beta:(0,2*pi):\\beta\")\n", "Hcoord" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "x = cos(alpha + beta)*sin(eta)/(cos(eta)*sin(alpha) + 1)\n", "y = sin(alpha + beta)*sin(eta)/(cos(eta)*sin(alpha) + 1)\n", "z = cos(alpha)*cos(eta)/(cos(eta)*sin(alpha) + 1)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Hcoord_to_stereoN = Hcoord.transition_map(\n", " stereoN.restrict(U),\n", " (sin(eta)*cos(alp+bet)/(1+cos(eta)*sin(alp)),\n", " sin(eta)*sin(alp+bet)/(1+cos(eta)*sin(alp)),\n", " cos(eta)*cos(alp)/(1+cos(eta)*sin(alp))))\n", "Hcoord_to_stereoN.display()" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Check of the inverse coordinate transformation:\n", " eta == arcsin((cos(eta)*sin(alpha) + 1)*sqrt(cos(eta) + 1)*sqrt(-cos(eta) + 1)/abs(cos(eta)*sin(alpha) + 1))\n", " alpha == pi - arctan2(2*cos(eta)*sin(alpha)/(cos(eta)*sin(alpha) + 1), -2*cos(alpha)*cos(eta)/(cos(eta)*sin(alpha) + 1))\n", " beta == arctan2(2*cos(eta)*sin(alpha)/(cos(eta)*sin(alpha) + 1), -2*cos(alpha)*cos(eta)/(cos(eta)*sin(alpha) + 1)) - arctan2((cos(beta)*sin(alpha) + cos(alpha)*sin(beta))*sin(eta)/(cos(eta)*sin(alpha) + 1), -(cos(alpha)*cos(beta) - sin(alpha)*sin(beta))*sin(eta)/(cos(eta)*sin(alpha) + 1))\n", " x == x\n", " y == y\n", " z == z\n" ] } ], "source": [ "Hcoord_to_stereoN.set_inverse(asin(2*sqrt(x^2+y^2)/(1+x^2+y^2+z^2)),\n", " atan2(x^2+y^2+z^2-1, -2*z) + pi,\n", " atan2(-y,-x) - atan2(x^2+y^2+z^2-1, -2*z),\n", " verbose=True)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "eta = arcsin(2*sqrt(x^2 + y^2)/(x^2 + y^2 + z^2 + 1))\n", "alpha = pi + arctan2(x^2 + y^2 + z^2 - 1, -2*z)\n", "beta = -arctan2(x^2 + y^2 + z^2 - 1, -2*z) + arctan2(-y, -x)" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Hcoord_to_stereoN.inverse().display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As explained in the worksheet [3-sphere: vector fields and left-invariant parallelization](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/v1.1/SM_sphere_S3_vectors.ipynb), due to some lack of simplification, it's better to set the components of $\\varepsilon_1$ and $\\varepsilon_2$ by hand:" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "E_1 = sin(2*alpha + beta) d/deta - cos(2*alpha + beta)*tan(eta) d/dalpha + cos(2*alpha + beta)/(cos(eta)*sin(eta)) d/dbeta" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E_U[1].add_comp(Hcoord.frame())[1, Hcoord] = sin(2*alp+bet)\n", "E_U[1].add_comp(Hcoord.frame())[2, Hcoord] = -cos(2*alp+bet) * tan(eta)\n", "E_U[1].add_comp(Hcoord.frame())[3, Hcoord] = cos(2*alp+bet) / (cos(eta)*sin(eta))\n", "E_U[1].display(Hcoord.frame(), Hcoord)" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "E_2 = -cos(2*alpha + beta) d/deta - sin(2*alpha + beta)*tan(eta) d/dalpha + sin(2*alpha + beta)/(cos(eta)*sin(eta)) d/dbeta" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E_U[2].add_comp(Hcoord.frame())[1, Hcoord] = -cos(2*alp+bet)\n", "E_U[2].add_comp(Hcoord.frame())[2, Hcoord] = -sin(2*alp+bet) * tan(eta)\n", "E_U[2].add_comp(Hcoord.frame())[3, Hcoord] = sin(2*alp+bet) / (cos(eta)*sin(eta))\n", "E_U[2].display(Hcoord.frame(), Hcoord)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On the contrary, the components of $\\varepsilon_3$ are particularly simple:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "E_3 = -d/dalpha" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E_U[3].display(Hcoord.frame(), Hcoord)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Round metric on $\\mathbb{S}^3$\n", "\n", "The standard metric on $\\mathbb{S}^3$ is that induced by the Euclidean metric of $\\mathbb{R}^4$. Let us start by defining the latter:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "h = dT*dT + dX*dX + dY*dY + dZ*dZ" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "h = R4.metric()\n", "h[0,0], h[1,1], h[2,2], h[3, 3] = 1, 1, 1, 1\n", "h.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The metric $g$ on $\\mathbb{S}^3$ is the pullback of $h$ by the embedding $\\Phi$:" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Riemannian metric g on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "g = S3.metric()\n", "g.set( Phi.pullback(h) )\n", "print(g)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us display $g$ in terms of the coordinate frame associated with the stereographic chart from the North pole $(U,(x,y,z))$:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dx*dx + 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dy*dy + 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dz*dz" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(frameN)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The components can be factored:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = 4/(x^2 + y^2 + z^2 + 1)^2 dx*dx + 4/(x^2 + y^2 + z^2 + 1)^2 dy*dy + 4/(x^2 + y^2 + z^2 + 1)^2 dz*dz" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for i in S3.irange():\n", " g[frameN, i,i].factor()\n", "g.display(frameN)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = 4/(xp^4 + yp^4 + zp^4 + 2*(xp^2 + 1)*yp^2 + 2*(xp^2 + yp^2 + 1)*zp^2 + 2*xp^2 + 1) dxp*dxp + 4/(xp^4 + yp^4 + zp^4 + 2*(xp^2 + 1)*yp^2 + 2*(xp^2 + yp^2 + 1)*zp^2 + 2*xp^2 + 1) dyp*dyp + 4/(xp^4 + yp^4 + zp^4 + 2*(xp^2 + 1)*yp^2 + 2*(xp^2 + yp^2 + 1)*zp^2 + 2*xp^2 + 1) dzp*dzp" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(frameS)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = 4/(xp^2 + yp^2 + zp^2 + 1)^2 dxp*dxp + 4/(xp^2 + yp^2 + zp^2 + 1)^2 dyp*dyp + 4/(xp^2 + yp^2 + zp^2 + 1)^2 dzp*dzp" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for i in S3.irange():\n", " g[frameS, i,i].factor()\n", "g.display(frameS)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expression of the round metric in the global frame\n", "\n", "The expression of $g$ in terms of the global frame \n", "$(\\varepsilon_1, \\varepsilon_2, \\varepsilon_3)$ is deduced from that w.r.t. the stereographic coordinates on the two domains $U$ and $V$, where the change-of-frame formulas are known:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = E^1*E^1 + E^2*E^2 + E^3*E^3" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(E_U)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = E^1*E^1 + E^2*E^2 + E^3*E^3" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(E_V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We may then set the components globally:" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = E^1*E^1 + E^2*E^2 + E^3*E^3" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for i in S3.irange():\n", " g.add_comp(E)[i, i] = 1\n", "g.display(E)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The above shows that the global frame $(\\varepsilon_1, \\varepsilon_2, \\varepsilon_3)$ is **orthonormal** (w.r.t. to $g$), which is not surprising since this frame is induced by \n", "three vector fields of $\\mathbb{R}^4$ which are clearly orthonormal for the Euclidean metric $h$, namely the three vector fields $E_{\\mathbf{i}}$, $E_{\\mathbf{j}}$ and $E_{\\mathbf{k}}$\n", "in the worksheet [3-sphere: vector fields and left-invariant parallelization](http://nbviewer.jupyter.org/github/sagemanifolds/SageManifolds/blob/master/Worksheets/v1.2/SM_sphere_S3_vectors.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expression of the round metric in terms of the hyperspherical coordinates" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = dch*dch + sin(ch)^2 dth*dth + sin(ch)^2*sin(th)^2 dph*dph" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(spher.frame(), spher)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expression of the round metric in terms of the Hopf coordinates" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "g = deta*deta + dalpha*dalpha + sin(eta)^2 dalpha*dbeta + sin(eta)^2 dbeta*dalpha + sin(eta)^2 dbeta*dbeta" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.display(Hcoord.frame(), Hcoord)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We note that the components of $g$ depend only on $\\eta$. This implies that the tori $\\eta=\\mathrm{const}$ are *flat* tori." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Christoffel symbols" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is necessary for what follows (should be fixed in a future version):" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [], "source": [ "for chart in S3.top_charts():\n", " g.restrict(chart.domain()).inverse()" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Gam^x_xx = -2*x/(x^2 + y^2 + z^2 + 1) \n", "Gam^x_xy = -2*y/(x^2 + y^2 + z^2 + 1) \n", "Gam^x_xz = -2*z/(x^2 + y^2 + z^2 + 1) \n", "Gam^x_yy = 2*x/(x^2 + y^2 + z^2 + 1) \n", "Gam^x_zz = 2*x/(x^2 + y^2 + z^2 + 1) \n", "Gam^y_xx = 2*y/(x^2 + y^2 + z^2 + 1) \n", "Gam^y_xy = -2*x/(x^2 + y^2 + z^2 + 1) \n", "Gam^y_yy = -2*y/(x^2 + y^2 + z^2 + 1) \n", "Gam^y_yz = -2*z/(x^2 + y^2 + z^2 + 1) \n", "Gam^y_zz = 2*y/(x^2 + y^2 + z^2 + 1) \n", "Gam^z_xx = 2*z/(x^2 + y^2 + z^2 + 1) \n", "Gam^z_xz = -2*x/(x^2 + y^2 + z^2 + 1) \n", "Gam^z_yy = 2*z/(x^2 + y^2 + z^2 + 1) \n", "Gam^z_yz = -2*y/(x^2 + y^2 + z^2 + 1) \n", "Gam^z_zz = -2*z/(x^2 + y^2 + z^2 + 1) " ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.christoffel_symbols_display(stereoN)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Gam^ch_th,th = -cos(ch)*sin(ch) \n", "Gam^ch_ph,ph = -cos(ch)*sin(ch)*sin(th)^2 \n", "Gam^th_ch,th = cos(ch)/sin(ch) \n", "Gam^th_ph,ph = -cos(th)*sin(th) \n", "Gam^ph_ch,ph = cos(ch)/sin(ch) \n", "Gam^ph_th,ph = cos(th)/sin(th) " ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.christoffel_symbols_display(spher)" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Gam^eta_alpha,beta = -cos(eta)*sin(eta) \n", "Gam^eta_beta,beta = -cos(eta)*sin(eta) \n", "Gam^alpha_eta,alpha = cos(eta)*sin(eta)/(sin(eta)^2 - 1) \n", "Gam^beta_eta,alpha = 1/(cos(eta)*sin(eta)) \n", "Gam^beta_eta,beta = cos(eta)/sin(eta) " ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "g.christoffel_symbols_display(Hcoord)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Riemann tensor" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tensor field Riem(g) of type (1,3) on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "Riem = g.riemann()\n", "print(Riem)" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Riem(g)^x_yxy = 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) \n", "Riem(g)^x_zxz = 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) \n", "Riem(g)^y_xxy = -4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) \n", "Riem(g)^y_zyz = 4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) \n", "Riem(g)^z_xxz = -4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) \n", "Riem(g)^z_yyz = -4/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) " ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Riem.display_comp(frameN, stereoN, only_nonredundant=True)" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Riem(g)^ch_th,ch,th = sin(ch)^2 \n", "Riem(g)^ch_ph,ch,ph = sin(ch)^2*sin(th)^2 \n", "Riem(g)^th_ch,ch,th = (cos(ch)^2 - 1)/sin(ch)^2 \n", "Riem(g)^th_ph,th,ph = sin(ch)^2*sin(th)^2 \n", "Riem(g)^ph_ch,ch,ph = (cos(ch)^2 - 1)/sin(ch)^2 \n", "Riem(g)^ph_th,th,ph = -sin(ch)^2 " ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Riem.display_comp(spher.frame(), spher, only_nonredundant=True)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Riem(g)^eta_alpha,eta,alpha = 1 \n", "Riem(g)^eta_alpha,eta,beta = (cos(eta)^4 - cos(eta)^2)/(sin(eta)^2 - 1) \n", "Riem(g)^eta_beta,eta,alpha = sin(eta)^2 \n", "Riem(g)^eta_beta,eta,beta = sin(eta)^2 \n", "Riem(g)^alpha_eta,eta,alpha = (sin(eta)^2 - 1)/cos(eta)^2 \n", "Riem(g)^alpha_alpha,alpha,beta = -cos(eta)^2*sin(eta)^2/(sin(eta)^2 - 1) \n", "Riem(g)^alpha_beta,alpha,beta = -cos(eta)^2*sin(eta)^2/(sin(eta)^2 - 1) \n", "Riem(g)^beta_eta,eta,beta = (cos(eta)^2 - 1)/sin(eta)^2 \n", "Riem(g)^beta_alpha,alpha,beta = -1 \n", "Riem(g)^beta_beta,alpha,beta = cos(eta)^2 - 1 " ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Riem.display_comp(Hcoord.frame(), Hcoord, only_nonredundant=True)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Riem(g)^1_212 = 1 \n", "Riem(g)^1_313 = 1 \n", "Riem(g)^2_112 = -1 \n", "Riem(g)^2_323 = 1 \n", "Riem(g)^3_113 = -1 \n", "Riem(g)^3_223 = -1 " ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Riem.display_comp(E_U, stereoN, only_nonredundant=True)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Riem(g) = E_1*E^2*E^1*E^2 - E_1*E^2*E^2*E^1 + E_1*E^3*E^1*E^3 - E_1*E^3*E^3*E^1 - E_2*E^1*E^1*E^2 + E_2*E^1*E^2*E^1 + E_2*E^3*E^2*E^3 - E_2*E^3*E^3*E^2 - E_3*E^1*E^1*E^3 + E_3*E^1*E^3*E^1 - E_3*E^2*E^2*E^3 + E_3*E^2*E^3*E^2" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Riem.display(E_U)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Ricci tensor" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Field of symmetric bilinear forms Ric(g) on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "Ric = g.ricci()\n", "print(Ric)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Ric(g) = 8/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dx*dx + 8/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dy*dy + 8/(x^4 + y^4 + z^4 + 2*(x^2 + 1)*y^2 + 2*(x^2 + y^2 + 1)*z^2 + 2*x^2 + 1) dz*dz" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ric.display(frameN)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Ric(g) = 8/(x^2 + y^2 + z^2 + 1)^2 dx*dx + 8/(x^2 + y^2 + z^2 + 1)^2 dy*dy + 8/(x^2 + y^2 + z^2 + 1)^2 dz*dz" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "for i in S3.irange():\n", " Ric[frameN, i,i].factor()\n", "Ric.display(frameN)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have $Ric(g) = 2 g$:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Ric.restrict(U) == 2 * g.restrict(U)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The Ricci scalar" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Scalar field r(g) on the Open subset A of the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "R_A = g.restrict(A).ricci_scalar()\n", "print(R_A)" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "r(g): A --> R\n", " (xp, yp, zp) |--> 6\n", " (x, y, z) |--> 6\n", " (ch, th, ph) |--> 6" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "R_A.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We note that the Ricci scalar is constant, as for any maximally symmetric space." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The volume 3-form (Levi-Civita tensor)\n", "\n", "We have" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3-form eps_g on the 3-dimensional Riemannian manifold S^3\n" ] }, { "data": { "text/html": [ "" ], "text/plain": [ "eps_g = E^1/\\E^2/\\E^3" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps = S3.volume_form()\n", "print(eps)\n", "eps.display()" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Free module Omega^3(S^3) of 3-forms on the 3-dimensional Riemannian manifold S^3\n" ] } ], "source": [ "print(eps.parent())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Expression of the volume 3-form in terms of the stereographic coordinates" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "eps_g = 8/(x^6 + y^6 + z^6 + 3*(x^2 + 1)*y^4 + 3*(x^2 + y^2 + 1)*z^4 + 3*x^4 + 3*(x^4 + 2*x^2 + 1)*y^2 + 3*(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1)*z^2 + 3*x^2 + 1) dx/\\dy/\\dz" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps.display(frameN, stereoN)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The component $\\epsilon_{xyz}$ can be factored:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "8/(x^6 + y^6 + z^6 + 3*(x^2 + 1)*y^4 + 3*(x^2 + y^2 + 1)*z^4 + 3*x^4 + 3*(x^4 + 2*x^2 + 1)*y^2 + 3*(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1)*z^2 + 3*x^2 + 1)" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps_xyz = eps[frameN, 1,2,3, stereoN]\n", "eps_xyz" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "8/(x^2 + y^2 + z^2 + 1)^3" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps_xyz.factor()" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "eps_g = 8/(x^2 + y^2 + z^2 + 1)^3 dx/\\dy/\\dz" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eps.display(frameN, stereoN)" ] } ], "metadata": { "kernelspec": { "display_name": "SageMath 8.2", "language": "", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.14" } }, "nbformat": 4, "nbformat_minor": 1 }