Tensor Calculus With Open-Source Software The Sage
Tensor Calculus With Open-Source Software The Sage
1
Laboratoire Univers et Théories, UMR 8102 du CNRS, Observatoire de Paris, Université
Paris Diderot, 92190 Meudon, France
2
Centrum Astronomiczne im. M. Kopernika, ul. Bartycka 18, 00-716 Warsaw, Poland
E-mail: [email protected], [email protected], [email protected]
Abstract. The SageManifolds project aims at extending the mathematics software system
Sage towards differential geometry and tensor calculus. Like Sage, SageManifolds is free, open-
source and is based on the Python programming language. We discuss here some details of
the implementation, which relies on Sage’s parent/element framework, and present a concrete
example of use.
1. Introduction
Computer algebra for general relativity (GR) has a long history, which started almost as soon as
computer algebra itself in the 1960s. The first GR program was GEOM, written by J.G. Fletcher
in 1965 [1]. Its main capability was to compute the Riemann tensor of a given metric. In 1969,
R.A. d’Inverno developed ALAM (for Atlas Lisp Algebraic Manipulator ) and used it to compute
the Riemann and Ricci tensors of the Bondi metric. According to [2], the original calculations
took Bondi and collaborators 6 months to finish, while the computation with ALAM took 4
minutes and yielded the discovery of 6 errors in the original paper. Since then, numerous
packages have been developed: the reader is referred to [3] for a review of computer algebra
systems for GR prior to 2002, and to [4] for a more recent review focused on tensor calculus.
It is also worth to point out the extensive list of tensor calculus packages maintained by J. M.
Martin-Garcia at [5].
3. An overview of Sage
Sage [14] is a free, open-source mathematics software system, which is based on the Python
programming language. It makes use of over 90 open-source packages, among which are Maxima
and Pynac (symbolic calculations), GAP (group theory), PARI/GP (number theory), Singular
(polynomial computations), and matplotlib (high quality 2D figures). Sage provides a uniform
Python interface to all these packages; however, Sage is much more than a mere interface: it
contains a large and increasing part of original code (more than 750,000 lines of Python and
Cython, involving 5344 classes). Sage was created in 2005 by W. Stein [15] and since then its
development has been sustained by more than a hundred researchers (mostly mathematicians).
Very good introductory textbooks about Sage are [16, 17, 18].
Apart from the syntax, which is based on a popular programming language and not a custom
script language, a difference between Sage and, e.g., Maple or Mathematica is the usage of
the parent/element pattern. This framework more closely reflects actual mathematics. For
instance, in Mathematica, all objects are trees of symbols and the program is essentially a set
of sophisticated rules to manipulate symbols. On the contrary, in Sage each object has a given
type (i.e. is an instance of a given Python class1 ), and one distinguishes parent types, which
model mathematical sets with some structure (e.g. algebraic structure), from element types,
which model set elements. Moreover, each parent belongs to some dynamically generated class
that encodes informations about its category, in the mathematical sense of the word (see [19] for
a discussion of Sage’s category framework). Automatic conversion rules, called coercions, prior
to a binary operation, e.g. x + y with x and y having different parents, are implemented.
category: Sets
ManifoldSubset
element: ManifoldPoint
ManifoldPoint
Submanifold RealLine
diagram, each class at the base of some arrow is a subclass (also called derived class) of the class
at the arrowhead. Note however that the actual type of a parent is a dynamically generated class
taking into account the mathematical category to which it belongs. For instance, the actual type
of a smooth manifold is not Manifold, but a subclass of it named Manifold with category,
reflecting the fact that Manifold is declared in the category of Sets2 . Note also that the
class Manifold inherits from Sage’s class UniqueRepresentation, which ensures that there is a
unique manifold instance for a given dimension and given name.
f : U ⊂ M −→ R
(1)
p 7−→ f (p),
2
A tighter category would be topological spaces, but such a category has been not implemented in Sage yet.
UniqueRepresentation Parent CommutativeAlgebraElement
category: CommutativeAlgebras
ScalarFieldAlgebra ScalarField
ring: SR
parent: ScalarFieldAlgebra
element: ScalarField
ZeroScalarField
Native Sage class
parent: ScalarFieldAlgebra
SageManifolds class
(differential part)
where U is some open subset of M. A scalar field has different coordinate representations F ,
F̂ , etc. in different charts X, X̂, etc. defined on U :
Each representation F is an instance of the class FunctionChart, which resembles Sage native
symbolic functions, but involves automatic simplifications in all arithmetic operations.
Given an open subset U ⊂ M, the set C ∞ (U ) of scalar fields defined on U has naturally the
structure of a commutative algebra over R: it is clearly a vector space over R and it is endowed
with a commutative ring structure by pointwise multiplication:
∀v ∈ X (U ), v = v a ea , with v a ∈ C ∞ (U ). (5)
The rank of X (U ) is thus n, i.e. the manifold’s dimension4 . At any point p ∈ U , Eq. (5) gives
birth to an identity in the tangent vector space Tp M:
which means that the set (ea (p))1≤a≤n is a basis of Tp M. Note that if U is covered by a chart
(xa )1≤a≤n , then (∂/∂xa )1≤a≤n is a vector frame on U , usually called coordinate frame or natural
basis. Note also that, being a vector space over R, the tangent space Tp M represents another
kind of free module which occurs naturally in the current context.
It turns out that so far only free modules with a distinguished basis were implemented in
Sage. This means that, given a free module M of rank n, all calculations refer to a single basis
of M . This amounts to identifying M with Rn , where R is the ring over which M is based. This
is unfortunately not sufficient for dealing with smooth manifolds in a coordinate-independent
way. For instance, there is no canonical isomorphism between Tp M and Rn when no coordinate
system is privileged in the neighborhood of p. Therefore we have started a pure algebraic part
of SageManifolds to implement generic free modules, with an arbitrary number of bases, none of
them being distinguished. This resulted in (i) the parent class FiniteRankFreeModule, within
Sage’s category Modules, and (ii) the element class FiniteRankFreeModuleElement. Then both
classes VectorFieldFreeModule (for X (U ), when it is a free module) and TangentSpace (for
Tp M) inherit from FiniteRankFreeModule (see Fig. 3).
les
ca
du
te
go
Mo
r
y:
s
ule
M
:
od
gory
od
:M
ul
y
cate
or
es
a teg
c
TensorFieldModule VectorFieldModule FiniteRankFreeModule
ring: ScalarFieldAlgebra ring: ScalarFieldAlgebra ring: CommutativeRing
element: TensorField element: VectorField element: FiniteRankFreeModuleElement
TangentSpace
VectorFieldFreeModule TensorFreeModule
ring: SR
Native Sage class ring: ScalarFieldAlgebra element:
element:
element: VectorFieldParal FreeModuleTensor
SageManifolds class TangentVector
(algebraic part)
SageManifolds class TensorFieldFreeModule
(differential part) ring: ScalarFieldAlgebra
element: TensorFieldParal
Figure 3. Python classes for modules. For each of them, the class of the base ring is indicated,
as well as the class for the elements.
ModuleElement
parent: Module
TensorField FreeModuleTensor
parent: parent:
TensorFieldModule TensorFreeModule
VectorFieldParal TangentVector
Native Sage class parent: parent:
SageManifolds class VectorFieldFreeModule TangentSpace
(algebraic part)
SageManifolds class
(differential part)
T ab = T (ea , eb ). (9)
Accordingly, the penultimate level of Fig. 5 corresponds to the scalar field storage, as described
by (3). The last level is constituted by Sage’s symbolic expressions (class Expression).
Expression Expression
x1 cos x2 y 1 + y 2 cos y 1 − y 2
Figure 5. Storage of tensor fields in SageManifolds. Each red box represents a Python
dictionary; the dictionary values are depicted by yellow boxes, the keys being indicated at the
left of each box.
5.2. Parallelization
To improve the reactivity of SageManifolds and take advantage of multicore processors, some
tensorial operations are performed by parallel processes. The parallelization is implemented
by means of the Python library multiprocessing, via the built-in Sage decorator @parallel.
Using it permits to define a function that is run on different sub-processes. If n processes are
used, given a function and a list of arguments for it, any process will call the function with an
element of the list, one at time, spanning all the list.
Currently6 , the parallelized operations are tensor algebra, tensor contractions, computation
of the connection coefficient and computation of Riemann tensor.
The parallelization of an operation is achieved by first creating a function which computes
the required operation on a subset of the components of a tensor; second, by creating a list of 2n
(twice the number of used processes) arguments for this function. Then applying this function
to the input list, the calculation is performed in parallel. At the end of the computation a fourth
phase is needed to retrieve the results. The choice to divide the work in 2n is a compromise
between the load balancing and the cost of creating multiple processes. The number of processors
to be used in the parallelization can be controlled by the user.
In what follows, we use SageManifolds to compute the Simon-Mars tensor according to formula
(10) for the Kerr metric and check that we get zero (the “if” part of the above theorem). The
corresponding worksheet can be downloaded from
http://sagemanifolds.obspm.fr/examples/html/SM_Simon-Mars_Kerr.html.
For the sake of clarity, let us recall that, as an object-oriented language, Python (and hence
Sage) makes use of the following postfix notation:
result = object.function(arguments)
In a functional language, this would correspond to result = function(object,arguments).
For instance, the Riemann tensor of a metric g is obtained as riem = g.riemann() (in this case,
there is no extra argument, hence the empty parentheses). With this in mind, let us proceed
with the computation by means of SageManifolds. In the text below, the blue color denotes the
outputs as they appear in the Sage notebook (note that all outputs are automatically LATEX-
formatted by Sage).
The first step is to declare the Kerr spacetime (or more precisely the part of the Kerr spacetime
covered by Boyer-Lindquist coordinates) as a 4-dimensional manifold:
M = Manifold(4, ’M’, latex_name=r’\mathcal{M}’)
print M
4-dimensional manifold ’M’
As a check, we verify that the covariant derivative of g with respect to ∇ vanishes identically:
nab(g).view()
∇g g = 0
As mentionned above, the default vector frame on the spacetime manifold is the coordinate basis
associated with Boyer-Lindquist coordinates:
M.default_frame() is X.frame()
True
X.frame()
∂ ∂ ∂ ∂
M, ∂t , ∂r , ∂θ , ∂φ
print xi
vector field ’d/dt’ on the 4-dimensional manifold ’M’
Equivalently, we check that the Lie derivative of the metric along ξ vanishes:
g.lie_der(xi).view()
0
Instead of invoking g(ξ, ξ), we could have evaluated λ by means of the 1-form ξ acting on the
vector field ξ:
lamb == - xi_form(xi)
True
Let us check that the Kerr metric is a vacuum solution of Einstein equation, i.e. that the Ricci
tensor vanishes identically:
g.ricci().view()
Ric(g) = 0
To form the Simon-Mars tensor, we need the fully covariant form (type-(0,4) tensor) of the Weyl
tensor (i.e. Cαβµν = gασ C σβµν ); we get it by lowering the first index with the metric:
Cd = C.down(g) ; print Cd
tensor field of type (0,4) on the 4-dimensional manifold ’M’
The (monoterm) symmetries of this tensor are those inherited from the Weyl tensor, i.e. the
antisymmetry on the last two indices (position 2 and 3, the first index being at position 0):
Cd.symmetries()
no symmetry; antisymmetry: (2, 3)
Actually, Cd is also antisymmetric with respect to the first two indices (positions 0 and 1), as
we can check:
Cd == Cd.antisymmetrize(0,1)
True
The starting point in the evaluation of Simon-Mars tensor is the self-dual complex 2-form
associated with the Killing 2-form F , i.e. the object F := F + i ∗ F , where ∗ F is the Hodge
dual of F :
FF = F + I * F.hodge_star(g)
FF.set_name(’FF’, r’\mathcal{F}’)
print FF ; FF.view()
2-form
’FF’ on the 4-dimensional
manifold’M’
2
cos(θ)2 +2i amr cos(θ)−mr 2 (i a3 m cos(θ)2 −2 a2 mr cos(θ)−i amr2 ) sin(θ)
F = − a am4 cos(θ) 4
+2 a2 r 2 cos(θ)2 +r 4
dt ∧ dr + a4 cos(θ)4 +2 a2 r 2 cos(θ)2 +r 4
dt ∧ dθ
−4i a4 m2 r 2 cos(θ) sin(θ)4 +(a3 mr 4 −2 am2 r 5 +amr 6 −(a7 m−2 a5 m2 r+a5 mr 2 ) cos(θ)4 ) sin(θ)2
+ a2 r6 −2 mr7 +r8 +(a8 −2 a6 mr+a6 r2 ) cos(θ)6 +3 (a6 r2 −2 a4 mr3 +a4 r4 ) cos(θ)4 +3 (a4 r4 −2 a2 mr5 +a2 r6 ) cos(θ)2
((2i a6 mr+2i a4 mr3 ) cos(θ)3 +(−4i a4 m2 r2 +2i a4 mr3 −4i a2 m2 r4 +2i a2 mr5 ) cos(θ)) sin(θ)2
− a2 r6 −2 mr7 +r8 +(a8 −2 a6 mr+a6 r2 ) cos(θ)6 +3 (a6 r2 −2 a4 mr3 +a4 r4 ) cos(θ)4 +3 (a4 r4 −2 a2 mr5 +a2 r6 ) cos(θ)2 dr ∧ dφ
(i a4 m+i a2 mr2 ) sin(θ)3 +(−i a4 m+i mr4 +2 (a3 mr+amr3 ) cos(θ)) sin(θ)
+ − 4 2
a4 cos(θ) +2 a2 r 2 cos(θ) +r 4
dθ ∧ dφ
To evaluate the right self-dual of the Weyl tensor, we need the tensor αβ γδ :
eps = g.volume_form(2) # 2 = the first 2 indices are contravariant
print eps ; eps.symmetries()
tensor field of type (2,2) on the 4-dimensional manifold ’M’
no symmetry; antisymmetries: [(0, 1), (2, 3)]
CC[0,1,2,3]
(a5 m cos(θ)5 +3i a4 mr cos(θ)4 +3i a2 mr3 +2i mr5 −(3 a5 m+5 a3 mr2 ) cos(θ)3 ) sin(θ)
a6 cos(θ)6 +3 a4 r2 cos(θ)4 +3 a2 r4 cos(θ)2 +r6
4 mr−7i a2 mr 3 cos(θ)2 +3 3 a3 mr 2 +2 amr 4 cos(θ) sin(θ)
((−9i a ) ( ) )
+ a6 cos(θ)6 +3 a4 r2 cos(θ)4 +3 a2 r4 cos(θ)2 +r6
sigma.set_name(’sigma’, r’\sigma’)
print sigma ; sigma.view()
1-form ’sigma’ on the 4-dimensional manifold ’M’
2 a2 m cos(θ)2 +4i amr cos(θ)−2 mr2 (2i a3 m cos(θ)2 −4 a2 mr cos(θ)−2i amr2 ) sin(θ)
σ = − a4 cos(θ)4 +2 a2 r2 cos(θ)2 +r4 dr + a4 cos(θ)4 +2 a2 r2 cos(θ)2 +r4
dθ
a2 cos(θ)2 +r2
dφ ⊗ dφ
(1)
The first part of the Simon-Mars tensor is Sαβγ = 4Cµανβ ξ µ ξ ν σγ :
S1 = 4*( CC.contract(0,xi).contract(1,xi) ) * sigma
print S1
tensor field of type (0,3) on the 4-dimensional manifold ’M’
(2)
The second part is Sαβγ = γαβ Cργµν ξ ρ F µν , which we compute using the index notation to
perform the contractions:
FFuu = FF.up(g)
xiCC = CC[’_.r..’]*xi[’^r’]
S2 = gamma * ( xiCC[’_.mn’]*FFuu[’^mn’] )
print S2
tensor field of type (0,3) on the 4-dimensional manifold ’M’
To get the Simon-Mars tensor, we need to antisymmetrize S (1) and S (2) on their last two indices;
we choose to use the standard index notation to perform this operation (an alternative would
have been to call directly the method antisymmetrize()):
S1A = S1[’_a[bc]’]
S2A = S2[’_a[bc]’]
The Simon-Mars tensor is then
S = = S1A + S2A
S.set_name(’S’)
print S ; S.symmetries()
tensor field ’S’ of type (0,3) on the 4-dimensional manifold ’M’
no symmetry; antisymmetry: (1, 2)
Acknowledgments
This work has benefited from enlightening discussions with Volker Braun, Vincent Delecroix,
Simon King, Sébastien Labbé, José M. Martı́n-Garcı́a, Marc Mezzarobba, Thierry Monteil,
Travis Scrimshaw, Nicolas M. Thiéry and Anne Vaugon. We also thank Stéphane Méné for
his technical help and Tolga Birkandan for fruitful comments about the manuscript. EG
acknowledges the warm hospitality of the Organizers of the Encuentros Relativistas Españoles
2014, where this work was presented.
References
[1] Fletcher J G, Clemens R, Matzner R, Thorne K S and Zimmerman B A 1967 Astrophys. J. 148, L91
[2] Skea J E F 1994 Applications of SHEEP Lecture notes available at http://www.computeralgebra.nl/
systemsoverview/special/tensoranalysis/sheep/
[3] MacCallum M A H 2002 Int. J. Mod. Phys. A 17, 2707
[4] Korol’kova A V, Kulyabov D S and Sevast’yanov L A 2013 Prog. Comput. Soft. 39, 135
[5] http://www.xact.es/links.html
[6] Martin-Garcia J M 2008 Comput. Phys. Commun. 179, 597; http://www.xact.es
[7] http://www.math.washington.edu/~lee/Ricci/
[8] Anderson I M and Torre C G 2012 J. Math. Phys. 53, 013511; http://digitalcommons.usu.edu/dg/
[9] http://grtensor.phy.queensu.ca/
[10] http://digi-area.com/Maple/atlas/
[11] Peeters K 2007 Comput. Phys. Commun. 15, 550; http://cadabra.phi-sci.com/
[12] Culler M, Dunfield N M and Weeks J R, SnapPy, a computer program for studying the geometry and topology
of 3-manifolds, http://snappy.computop.org
[13] Bolotin D A and Poslavsky S V 2013 Introduction to Redberry: the computer algebra system designed for
tensor manipulation Preprint arXiv:1302.1219; http://redberry.cc/
[14] http://sagemath.org/
[15] Stein W and Joyner D 2005 Commun. Comput. Algebra 39, 61
[16] Joyner D and Stein W 2014 Sage Tutorial (CreateSpace)
[17] Zimmermann P et al. 2013 Calcul mathématique avec Sage (CreateSpace); freely downloadable from
http://sagebook.gforge.inria.fr/
[18] Bard G V 2015 Sage for Undergraduates (Americ. Math. Soc.) in press; preprint freely downloadable from
http://www.gregorybard.com/
[19] http://www.sagemath.org/doc/reference/categories/sage/categories/primer.html
[20] http://sagemath.org/doc/reference/tensor/
[21] http://sagemath.org/doc/reference/riemannian_geometry/
[22] http://sagemanifolds.obspm.fr/
[23] Lee J M 2013 Introduction to Smooth Manifolds 2nd edition (New York: Springer)
[24] Steenrod N 1951 The Topology of Fibre Bundles (Princeton: Princeton Univ. Press)
[25] http://sagemanifolds.obspm.fr/examples.html
[26] Apéry F 1986 Adv. Math. 61, 185
[27] Mars M 1999 Class. Quantum Grav. 16, 2507
[28] http://gyoto.obspm.fr/