Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting tensor indices at 0

Some time ago I wrote a package for tensor calculus in General Relativity. In order to make it easily accessible for others it should be slightly modified.

There are functions like i.e. Christoffel for calculation of Christoffel symbol :

Christoffel[g_, xx_] := 
    Block[{ig, res, n}, 
           n = 4;
           ig = Simplify[Inverse[g]]; 
           res = Table[(1/2)*Sum[ig[[i,s]]*(-D[g[[j,k]], xx[[s]]] + D[g[[j,s]], xx[[k]]] 
                             + D[g[[s,k]], xx[[j]]]), {s, 1, n}], {i, 1, n}, {j, 1, n}, {k, 1, n}];
       res
     ] 

where g and xx are metric tensor and coordinates respectively, which I define in a Mathematica session after uploading the package in a straightforward way putting for example an ansatz for a static spherically symmetric spacetime : metric This way involves drawbacks since index ranges are {1, 2, 3, 4} while the common practice in relativistic physics suggests to put {0, 1, 2, 3} where 0 stands for timelike coordinate, and {1, 2, 3} stand for spacelike ones.
To ilustrate the problem let's define a table where indices start from 0 , i.e.

V = Table[i - j, {i, 0, 3}, {j, 0, 3}] 
{{0, -1, -2, -3}, {1, 0, -1, -2}, {2, 1, 0, -1}, {3, 2, 1, 0}}

but when I evaluate V[[0, 0]] I get Symbol - the head of V,
while for V[[1, 2]] I get -1 as it should be.

My questions are :

  1. How could I redefine V in order be able to evaluate "table" component [0, 0] ?
  2. What would be the most convenient way to introduce matrix g with its indices starting at 0?
  3. Since I have to give up using Part to access tensor components 0,0 how to introduce in a package a freedom of choice of index ranges of other objects like Christoffel (let's say by default index ranges - {0, 1, 2, 3} or if one prefers - {1, 2, 3, 4}) ?

Although these questions seem trivial at first sight but any comprehensive answers are welcome. Anyone using a package shouldn't bother his head about Mathematica subtleties.

like image 292
Artes Avatar asked Dec 04 '22 19:12

Artes


2 Answers

It is not my intention to be trivial or flippant about your concern, however I am having some trouble understanding the significance of your dilemma. Mathematica, or more specifically Part indexes from one, and that is simply the way it is. I am tempted to say use e.g. V[[n+1]] but I have to suppose you have already considered this.


Index 0 is reserved for the head of the expression. While it is far from standard, the flexibility of Mathematica syntax actually allows for this construct:

V = 0[-1, -2, -3][{1, 0, -1, -2}, {2, 1, 0, -1}, {3, 2, 1, 0}];

V[[0,2]]
-2

This works because the heads themselves contains your data. This is not advisable, but presented for academic interest.


In specific answer to your first question, and for explanation of the trick above, you must be familiar with Mathematica heads. Every expression conceptually has a head. In the expression a + b the head is Plus. In {1, 2, 3} it is List. You can see these written out by using FullForm. Other types also have conceptual heads, even if they are not explicit in FullForm. You can determine these using Head. For example:

Head /@ {"abc", 1, Pi, 3.14, 1/2}
{String, Integer, Symbol, Real, Rational}

The Part syntax [[0, 0]] asks for the head of the head. In the case of your array, which is a list of lists, the head is List, and the head of List itself is Symbol, which defines its type.


In reply to your second question, I would define a new Part function that indexes from zero.

myPart[x_, spec__] := Part[x, ##] & @@ ({spec} /. n_Integer :> n + 1)

V = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

myPart[V, 0, 0]
1

This also works with Span:

myPart[V, All, 0 ;; 1]
{{1, 2}, {4, 5}, {7, 8}}
like image 159
Mr.Wizard Avatar answered Jan 07 '23 04:01

Mr.Wizard


(1) Mathematica list indexing, via Part ( [[]] in more common notation) starts at 1. The 0 part is the head of the expression.

(2) Can define a "function" that takes the indices you want and adds 1 to each.

xx = {t, x, \[Theta], \[Phi]}; 
g = {{-E^(2*\[Nu][x]), 0, 0, 0}, {0, E^(2*\[Lambda][x]), 0, 0}, {0, 
    0, x^2, 0}, {0, 0, 0, x^2*Sin[\[Theta]]^2}}; 

gg[indices___] := g[[Sequence @@ ({indices} + 1)]]

Examples:

In[121]:= gg[0]
Out[121]= {-E^(2*\[Nu][x]), 0, 0, 0}

In[123]:= gg[2, 2]
Out[123]= x^2

(3) See (2) for a possible approach. See (1) to understand that Part is NOT the direct way to go.

Daniel Lichtblau

like image 22
Daniel Lichtblau Avatar answered Jan 07 '23 03:01

Daniel Lichtblau