Anti-de Sitter spacetime

This worksheet demonstrates a few capabilities of SageMath in computations regarding the 4-dimensional anti-de Sitter spacetime. The corresponding tools have been developed within the SageManifolds project (version 1.2, as included in SageMath 8.2).

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

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

In [1]:
'SageMath version 8.2, Release Date: 2018-05-05'

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

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)

Spacetime manifold

We declare the anti-de Sitter spacetime as a 4-dimensional Lorentzian manifold:

In [4]:
M = Manifold(4, 'M', r'\mathcal{M}', structure='Lorentzian')
print(M); M
4-dimensional Lorentzian manifold M

We consider hyperbolic coordinates $(\tau,\rho,\theta,\phi)$ on $\mathcal{M}$. Allowing for the standard coordinate singularities at $\rho=0$, $\theta=0$ or $\theta=\pi$, these coordinates cover the entire spacetime manifold (which is topologically $\mathbb{R}^4$). If we restrict ourselves to regular coordinates (i.e. to considering only mathematically well defined charts), the hyperbolic coordinates cover only an open part of $\mathcal{M}$, which we call $\mathcal{M}_0$, on which $\rho$ spans the open interval $(0,+\infty)$, $\theta$ the open interval $(0,\pi)$ and $\phi$ the open interval $(0,2\pi)$. Therefore, we declare:

In [5]:
M0 = M.open_subset('M_0', r'\mathcal{M}_0' )
X_hyp.<ta,rh,th,ph> = M0.chart(r'ta:\tau rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi')
print(X_hyp) ; X_hyp
Chart (M_0, (ta, rh, th, ph))
In [6]:

$\mathbb{R}^{2,3}$ as an ambient space

The AdS metric can be defined as that induced by the immersion of $\mathcal{M}$ in $\mathbb{R}^{2,3}$, the latter being nothing but $\mathbb{R}^5$ equipped with a flat pseudo-Riemannian metric of signature $(-,-,+,+,+)$. Let us construct $\mathbb{R}^{2,3}$ as a 5-dimensional manifold covered by canonical coordinates:

In [7]:
R23 = Manifold(5, 'R23', r'\mathbb{R}^{2,3}', structure='pseudo-Riemannian', signature=1, 
X23.<U,V,X,Y,Z> = R23.chart()
print(X23); X23
Chart (R23, (U, V, X, Y, Z))

We define the pseudo-Riemannian metric of $\mathbb{R}^{2,3}$:

In [8]:
h = R23.metric()
h[0,0], h[1,1], h[2,2], h[3,3], h[4,4] = -1, -1, 1, 1, 1

The AdS immersion into $\mathbb{R}^{2,3}$ is defined as a differential map $\Phi$ from $\mathcal{M}$ to $\mathbb{R}^{2,3}$, by providing its expression in terms of $\mathcal{M}$'s default chart (which is X_hyp = $(\mathcal{M}_0,(\tau,\rho,\theta,\phi))$ ) and $\mathbb{R}^{2,3}$'s default chart (which is X23 = $(\mathbb{R}^{2,3},(U,V,X,Y,Z))$ ):

In [9]:
var('l', latex_name=r'\ell', domain='real')
Phi = M.diff_map(R23, [l*cosh(rh)*cos(ta/l),
                 name='Phi', latex_name=r'\Phi')
print(Phi); Phi.display()
Differentiable map Phi from the 4-dimensional Lorentzian manifold M to the 5-dimensional pseudo-Riemannian manifold R23

The constant $\ell$ is the AdS length parameter. Considering AdS metric as a solution of vacuum Einstein equation with negative cosmological constant $\Lambda$, one has $\ell = \sqrt{-3/\Lambda}$.

Let us evaluate the image of a point via the map $\Phi$:

In [10]:
p = M((ta, rh, th, ph), name='p'); print(p)
Point p on the 4-dimensional Lorentzian manifold M

The coordinates of $p$ in the chart X_hyp:

In [11]:
In [12]:
q = Phi(p); print(q)
Point Phi(p) on the 5-dimensional pseudo-Riemannian manifold R23
In [13]:

The image of $\mathcal{M}$ by the immersion $\Phi$ is a hyperboloid of one sheet, of equation $$-U^2-V^2+X^2+Y^2+Z^2=-\ell^2.$$ Indeed:

In [14]:
(Uq,Vq,Xq,Yq,Zq) = X23(q)
s = - Uq^2 - Vq^2 + Xq^2 + Yq^2 + Zq^2

We may use the immersion $\Phi$ to draw the coordinate grid $(\tau,\rho)$ in terms of the coordinates $(U,V,X)$ for $\theta=\pi/2$ and $\phi=0$ ($X\geq 0$ part) or $\phi=\pi$ ($X\leq 0$ part). The red (rep. grey) curves are those for which $\rho={\rm const}$ (resp. $\tau={\rm const}$):

In [15]:
graph_hyp = X_hyp.plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th:pi/2, ph:0}, 
                    ranges={ta:(0,2*pi), rh:(0,2)}, number_values=9, 
                    color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, 
                    label_axes=False)  # phi = 0 => X > 0 part
graph_hyp += X_hyp.plot(X23, mapping=Phi, ambient_coords=(V,X,U), fixed_coords={th:pi/2, ph:pi},
                    ranges={ta:(0,2*pi), rh:(0,2)}, number_values=9, 
                    color={ta:'red', rh:'grey'}, thickness=2, parameters={l:1}, 
                    label_axes=False)  # phi = pi => X < 0 part
show(graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True,

To have a nicer picture, we add the plot of the hyperboloid obtained by parametric_plot with $(\tau,\rho)$ as parameters and the expressions of $(U,V,X)$ in terms of $(\tau,\rho)$ deduced from the coordinate representation of $\Phi$:

In [16]:
Phi.coord_functions() # the default pair of charts (X_hyp, X23) is assumed
In [17]:
Ug = Phi.coord_functions()[0](ta,rh,pi/2,0).subs({l:1})  # l=1 substituted to have numerical values
Vg = Phi.coord_functions()[1](ta,rh,pi/2,0).subs({l:1})
Xg = Phi.coord_functions()[2](ta,rh,pi/2,0).subs({l:1})
Ug, Vg, Xg
In [18]:
hyperboloid = parametric_plot3d([Vg, Xg, Ug], (ta,0,2*pi), (rh,-2,2), color=(1.,1.,0.9))
graph_hyp += hyperboloid
show(graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True,

Spacetime metric

As mentionned above, the AdS metric $g$ on $\mathcal{M}$ is that induced by the flat metric $h$ on $\mathbb{R}^{2,3}$, i.e.$g$ is the pullback of $h$ by the differentiable map $\Phi$:

In [19]:
g = M.metric()
g.set( Phi.pullback(h) )

The expression of $g$ in terms of $\mathcal{M}$'s default frame is found to be

In [20]:
In [21]:


The Riemann tensor of $g$ is

In [22]:
Riem = g.riemann()
Tensor field Riem(g) of type (1,3) on the 4-dimensional Lorentzian manifold M
In [23]:

The Ricci tensor:

In [24]:
Ric = g.ricci()
Field of symmetric bilinear forms Ric(g) on the 4-dimensional Lorentzian manifold M
In [25]:

The Ricci scalar:

In [26]:
R = g.ricci_scalar()
Scalar field r(g) on the 4-dimensional Lorentzian manifold M

We recover the fact that AdS spacetime has a constant curvature. It is indeed a maximally symmetric space. In particular, the Riemann tensor is expressible as $$ R^i_{\ \, jlk} = \frac{R}{n(n-1)} \left( \delta^i_{\ \, k} g_{jl} - \delta^i_{\ \, l} g_{jk} \right), $$ where $n$ is the dimension of $\mathcal{M}$: $n=4$ in the present case. Let us check this formula here, under the form $R^i_{\ \, jlk} = -\frac{R}{6} g_{j[k} \delta^i_{\ \, l]}$:

In [27]:
delta = M.tangent_identity_field() 
Riem == - (R/6)*(g*delta).antisymmetrize(2,3)  # 2,3 = last positions of the type-(1,3) tensor g*delta

We may also check that AdS metric is a solution of the vacuum Einstein equation with (negative) cosmological constant $\Lambda = - 3/\ell^2$:

In [28]:
Lambda = -3/l^2
Ric - 1/2*R*g + Lambda*g == 0

Radial null geodesics

Null geodesics that are radial with respect to coordinates $(\tau,\rho,\theta,\phi)$ obey $$ \tau = \pm 2 \ell \left( \mathrm{atan} \left(\mathrm{e}^\rho\right) - \frac{\pi}{4} \right) + \tau_0,$$ where $\tau_0$ is a constant (the value of $\tau$ at $\rho=0$). Note that, due to the homogeneity of AdS spacetime, any null geodesic is a "radial" geodesic with respect to some coordinate system $(\tau',\rho',\theta',\phi')$, as in Minkowski spacetime, any null geodesic is a straight line and one can always find a Minkowskian coordinate system $(t',x',y',z')$ with respect to which the null geodesic is radial.

Let us consider two finite families of radial null geodesics having $\theta=\pi/2$ and $\phi=0$ or $\pi$:

  • null_geod1 has $\phi=\pi$ when $\tau< 0$ and $\phi=0$ when $\tau>0$
  • null_geod2 has $\phi=0$ when $\tau<0$ and $\phi=\pi$ when $\tau>0$
In [29]:
lamb = var('lamb', latex_name=r'\lambda')
null_geod1 = [M.curve({X_hyp: [2*sgn(lamb)*l*(atan(exp(abs(lamb))) - pi/4) + 2*pi*(i-4)/8, 
                                  abs(lamb), pi/2, pi*unit_step(-lamb)]}, 
                         (lamb, -oo, +oo)) for i in range(9)]
null_geod2 = [M.curve({X_hyp: [2*sgn(lamb)*l*(atan(exp(abs(lamb))) - pi/4) + 2*pi*(i-4)/8, 
                                 abs(lamb), pi/2, pi*unit_step(lamb)]}, 
                         (lamb, -oo, +oo)) for i in range(9)]
null_geods = null_geod1 + null_geod2
In [30]:
Curve in the 4-dimensional Lorentzian manifold M
In [31]:
In [32]:

To graphically display these geodesics, we introduce a Cartesian-like coordinate system $(\tau,x_\rho,y_\rho,z_\rho)$ linked to $(\tau,\rho,\theta,\phi)$ by the standard formulas:

In [33]:
X_hyp_graph.<ta,x_rho,y_rho,z_rho> = M0.chart(r'ta:\tau x_rho:x_\rho y_rho:y_\rho z_rho:z_\rho')
hyp_to_hyp_graph = X_hyp.transition_map(X_hyp_graph, [ta, rh*sin(th)*cos(ph), 
                                                      rh*sin(th)*sin(ph), rh*cos(th)])

Let us plot the null geodesics in terms of the coordinates $(\tau,x_\rho)$:

In [34]:
graph_2d = Graphics()
for geod in null_geods:
    geod.expr(geod.domain().canonical_chart(), X_hyp_graph)
    graph_2d += geod.plot(X_hyp_graph, ambient_coords=(x_rho,ta), prange=(-4,4),
                          parameters={l:1}, color='green', thickness=1.5)
graph_2d += X_hyp_graph.plot(X_hyp_graph, ambient_coords=(x_rho,ta), 
                             fixed_coords={th:0, ph:pi}, 
                             ranges={ta:(-pi,pi), x_rho:(-4,4)}, 
                             number_values={ta: 9, x_rho: 9},
                             color={ta:'red', x_rho:'grey'}, parameters={l:1})
show(graph_2d, aspect_ratio=1, ymin=-pi, ymax=pi)

We can also get a 3D view of the radial null geodesics via the isometric immersion $\Phi$:

In [35]:
graph_3d = Graphics()
for geod in null_geods:
    graph_3d += geod.plot(X23, mapping=Phi, ambient_coords=(V,X,U), prange=(-2,2),
                          parameters={l:1}, color='green', thickness=2, 
                          plot_points=20, label_axes=False)
show(graph_3d+graph_hyp, aspect_ratio=1, viewer=viewer3D, online=True,