3-sphere: charts, quaternions and Hopf fibration

This worksheet demonstrates a few capabilities of SageManifolds (version 1.0, as included in SageMath 7.5) on the example of the 3-dimensional sphere, $\mathbb{S}^3$.

Click here to download the worksheet file (ipynb format). To run it, you must start SageMath with the Jupyter notebook, via the command sage -n jupyter

NB: a version of SageMath at least equal to 7.5 is required to run this worksheet:

In [1]:
version()
Out[1]:
'SageMath version 7.5.1, Release Date: 2017-01-15'

First we set up the notebook to display mathematical objects using LaTeX formatting:

In [2]:
%display latex

We also define a viewer for 3D plots (use 'threejs' or 'jmol' for interactive 3D graphics):

In [3]:
viewer3D = 'threejs' # must be 'threejs', jmol', 'tachyon' or None (default)

To increase the computational speed, we ask for demanding computations to be parallelly performed on 8 cores:

In [4]:
Parallelism().set(nproc=8)

$\mathbb{S}^3$ as a 3-dimensional differentiable manifold

We start by declaring $\mathbb{S}^3$ as a differentiable manifold of dimension 3 over $\mathbb{R}$:

In [5]:
S3 = Manifold(3, 'S^3', latex_name=r'\mathbb{S}^3', start_index=1)

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\}$.

In [6]:
print(S3)
3-dimensional differentiable manifold S^3
In [7]:
S3
Out[7]:

Coordinate charts on $\mathbb{S}^3$

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, which we may call the North pole and the South pole respectively. Let us introduce the open subsets covered by these two charts: $$ U := \mathbb{S}^3\setminus\{N\} $$
$$ V := \mathbb{S}^3\setminus\{S\} $$

In [8]:
U = S3.open_subset('U') ; print(U)
Open subset U of the 3-dimensional differentiable manifold S^3
In [9]:
V = S3.open_subset('V') ; print(V)
Open subset V of the 3-dimensional differentiable manifold S^3

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

In [10]:
S3.declare_union(U, V)

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:

In [11]:
stereoN.<x,y,z> = U.chart()
stereoN
Out[11]:
In [12]:
stereoN.coord_range()
Out[12]:

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

In [13]:
stereoS.<xp,yp,zp> = V.chart("xp:x' yp:y' zp:z'")
stereoS
Out[13]:
In [14]:
stereoS.coord_range()
Out[14]:

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:

In [15]:
r2 = x^2+y^2+z^2
stereoN_to_S = stereoN.transition_map(stereoS, 
                                      (x/r2, y/r2, z/r2), 
                                      intersection_name='W',
                                      restrictions1= x^2+y^2+z^2!=0, 
                                      restrictions2= xp^2+yp^2+zp^2!=0)
stereoN_to_S.display()
Out[15]:

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$.

The inverse coordinate transformation is computed by means of the method inverse():

In [16]:
stereoS_to_N = stereoN_to_S.inverse()
stereoS_to_N.display()
Out[16]:

Note that the situation is of course perfectly symmetric regarding the coordinates $(x,y,z)$ and $(x',y',z')$.

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

In [17]:
S3.atlas()
Out[17]:

For future reference, we store $W=U\cap V$ into a Python variable:

In [18]:
W = U.intersection(V)
print(W)
Open subset W of the 3-dimensional differentiable manifold S^3

The North and South poles

$N$ is the point of $V$ of stereographic coordinates $(x',y',z')=(0,0,0)$:

In [19]:
N = V((0,0,0), chart=stereoS, name='N')
print(N)
Point N on the 3-dimensional differentiable manifold S^3

while $S$ is the point of U of stereographic coordinates $(x,y,z)=(0,0,0)$:

In [20]:
S = U((0,0,0), chart=stereoN, name='S')
print(S)
Point S on the 3-dimensional differentiable manifold S^3

We have of course

In [21]:
all([N not in U, N in V, S in U, S not in V])
Out[21]:

Embedding of $\mathbb{S}^3$ into $\mathbb{R}^4$

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

In [22]:
R4 = Manifold(4, 'R^4', r'\mathbb{R}^4')
X4.<T,X,Y,Z> = R4.chart()
X4
Out[22]:

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$:

In [23]:
rp2 = xp^2 + yp^2 + zp^2
Phi = S3.diff_map(R4, {(stereoN, X4): 
                       [(1-r2)/(r2+1), 2*x/(r2+1), 
                        2*y/(r2+1), 2*z/(r2+1)],
                       (stereoS, X4):
                       [(rp2-1)/(rp2+1), 2*xp/(rp2+1), 
                        2*yp/(rp2+1), 2*zp/(rp2+1)]},
                  name='Phi', latex_name=r'\Phi')
Phi.display()
Out[23]:

From this choice of stereographic projection, the "North" pole is actually the point of coordinates $(-1,0,0,0)$ in $\mathbb{R}^4$:

In [24]:
X4(Phi(N))
Out[24]:

while the "South" pole is the point of coordinates $(1,0,0,0)$:

In [25]:
X4(Phi(S))
Out[25]:

We may use the embedding $\Phi$ to plot the stereographic coordinate grid in terms of the $\mathbb{R}^4$'s Cartesian coordinates:

In [26]:
graph_stereoN = stereoN.plot(chart=X4, mapping=Phi, 
                             ambient_coords=(X,Y,Z),
                             number_values=9,
                             color={x: 'red', y: 'green', z: 'gold'},
                             label_axes=False)
show(graph_stereoN, viewer=viewer3D, axes_labels=['X', 'Y', 'Z'])