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

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)
```

In [4]:

```
Parallelism().set(nproc=8)
```

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)
```

`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)
```

In [7]:

```
S3
```

Out[7]:

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)
```

In [9]:

```
V = S3.open_subset('V') ; print(V)
```

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

In [10]:

```
S3.declare_union(U, V)
```

In [11]:

```
stereoN.<x,y,z> = U.chart()
stereoN
```

Out[11]:

In [12]:

```
stereoN.coord_range()
```

Out[12]:

In [13]:

```
stereoS.<xp,yp,zp> = V.chart("xp:x' yp:y' zp:z'")
stereoS
```

Out[13]:

In [14]:

```
stereoS.coord_range()
```

Out[14]:

**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)
```

$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)
```

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)
```

We have of course

In [21]:

```
all([N not in U, N in V, S in U, S not in V])
```

Out[21]:

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

**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]:

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

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'])
```