#### A few days ago I post in **sage-devel** google group my desire of contribute in the development of a general relativity (perhaps beyond) module.

A search in Google leads me to a class, named **GRPy**, created by Sergei Ossokine. My experience with it was not as pleasant as I’d like, but it’s a beginning for starting my own Module. 🙂 Yeah!!!

However, since I’m not a programmer, there are lot of things to learn in the way.

# The requirements

We are suppose to do symbolic calculations, so a requirement is the python package for doing so, say **sympy**

`import sympy`

For managing arrays, one of the most useful packages is **numpy**, so we could call it,

`import numpy as np`

this line does not import the module… but if we want to use a command of the module, i.e. *array*, we should call it as, *np.array*.

I just learnt that there exist a module for iterate, and in particular allows to define Cartesian products. It is called **itertools**. Let’s import it,

`import itertools`

Finally, from the copy module, let call the **deepcopy** function,

`from copy import deepcopy`

which copy and object and all structures inside it!

# Define a Tensor Class

I’ll follow to Sergei at the beginning… so let’s start as he did.

A tensor is an object, so is should inherit the characteristics of one. Moreover, a tensor has an identifier symbol, and a rank

`class formalTensor(object):`

... def __init__(self,symbol,rank):

... self.symbol = sympy.Symbol(symbol)

... self.rank = rank

I still don’t now how useful is to define this **formalTensor** class. But the next one is the really important,

class Tensor(object): '''A class to represent a tensor in a particular basis''' def __init__(self,symbol,rank,shape,sym=None,coords=None,**args): self.symbol = sympy.Symbol(symbol) # The symbol to represent this Tensor self.coords = coords # The coordinate system we are using for the representation self.shape = shape # The shape of the tensor, for example (-1,1) for k_{a}^{b self.rank = rank # Rank self.contr = rank[0] self.cov = rank[1] # We need to know the dimensionality of our spacetime. For the moment # we will deduce it from the coordinates provide, or if none are given, then # the assumption will be made that it's stored in the optional arguments if coords is not None: self.dim = len(self.coords) else: self.dim = args['dim'] if coords is not None: self.allocate(rank) self.rep = True self.symbolic = formalTensor(symbol,rank) def __setitem__(self,idx,val): self.components[idx]=val def __getitem__(self,idx): return self.components[idx] def allocate(self,rank): '''Allocate the dictionary(hash table) necessary to store the components Note that covariant indices are negative! (except for 0 of course)''' n = rank[0] + rank[1] indc = list(itertools.product(range(self.dim),repeat=n)) mastr=[] for i in range(len(indc)): temp=[] for k in range(len(indc[i])): if self.shape[k] == -1: temp.append(-indc[i][k]) else: temp.append(indc[i][k]) mastr.append(tuple(temp)) self.components = dict(zip(mastr,[0 for i in range(len(indc))])) def _dictkeycopy(self, hay): keys = hay.keys() return dict(zip(keys,[0]*len(keys))) def getNonZero(self): '''Returns only non-zero components of the tensor, if the coordinate system is provided''' if self.rep: nonzerok =[] nonzerov = [] for key in self.components.keys(): if self.components[key] !=0: nonzerok.append(key) nonzerov.append(self.components[key]) d = dict(zip(nonzerok,nonzerov)) keys = d.keys() keys.sort() self.nonzero = [(key,d[key]) for key in keys] return self.nonzero else: print "Attempted to get components that have not been initialized!" def __str__(self): '''Print a "nice" human - readable representation of the tensor''' self.getNonZero() # We will print only non-zero components unless all the components are zero ttl="" if self.nonzero: for i in range(len(self.nonzero)): ttl += str(self.nonzero[i][0]) + " "+str(self.nonzero[i][1])+"\n" else: ttl ="All the components of the tensor are 0!" return ttl

WOW… long way to go explain!

Tensors have,

**Symbol**: for identification.

**Rank**: or number of indices… even if it is a connection

**Shape**: a list in the form (

*a*,

*b*) for denoting a tensor

*a*times contravariant and

*b*times covariant.

**Symmetry**: not implemented!!! 😦

**Coordinate system**: A list with the name of coordinates, example: (

*t*,

*r*,

*theta*,

*phi*).

**Any other arguents**: that’s what

***arg*stands for. Example

*dim=3*would set the dimension to 3.

## The constructor

Any class has a constructor named **__init__**, where the variables of the object are defined and initialized. Additionally, one should call the variables using the prefix **self**. For a nice introduction to classes see for example A primer on scientific programming with Python.

Said so, the first few line can be followed, let’s jump to the first non-so-trivial thing.

## Special Methods

**Methods** are the possible actions defined for objects in our class. Those methods whose names start with underscore are known as special methods.

Above, two of these are used.

**__setitem__**: which set a given component of the tensor,

**__getitem__**: which return the value of a given component.

Ok, it’s midnight in UK and I’m really tired.

Tomorrow I’ll explain the allocate method.

I’m uploading the python file to my page (as usual… at the end of the page, in the attachment section).

So far… GR-module.py (version 1)

Enjoy!

DOX.

on February 6, 2011 at 7:23 am |PacoHi, it would be very interesting having a gr module but I thik it would be a better way having an interface to cadabra which is a research level symbolic algebra system designed for using it with tensors.

on February 6, 2011 at 7:33 am |doxdrumHi Paco.

Somehow I agree with you, I’m not aware whether Cadabra can calculate with tensors, I know you can manipulate them… but so far I’ve never seen a calculation of Einstein equations given a metric ansatz.

Of course, it would be perfect if we can integrate Cadabra manipulations with a GR-module. By the way, I saw there is a experimental Cadabra package for SAGE (I’ve not used it yet).

Finally, If you have some experience with Cadabra, let me know and we could try to integrate GR-module and Cadabra. 🙂

Cheers.

on February 7, 2011 at 7:47 am |Tweets that mention SAGE tip: GR-module. Day 01. « Doxdrum's Blog -- Topsy.com[…] This post was mentioned on Twitter by Sander Demeester, sagemath.org. sagemath.org said: SAGE tip: GR-module. Day 01 https://doxdrum.wordpress.com/2011/02/05/sage-tip-gr-module-day-01/ #sageprimer http://fb.me/Rlx38RI7 […]