9.2. Replace indices

A second, commonly required operation is the change of indices. In principle, the user should never need to replace indices directly in an expression. But sometimes it is needed, either because two expressions with different free indices must be compared, or to avoid problems with the dummy indices. This subsection introduces the basic function ReplaceIndex, and five more functions based on it.
Replacing indices is a basic critical operation: done without care would inmediately lead to wrong results. Whenever possible, we recommend the use of delta contractions to change indices, which is a safer and mathematically clearer operation.

Above all, avoid the temptation of changing indices using normal rules, unless you are sure that index-collisions will not appear.

Let us go back to our expression:

In[892]:=

expr

Out[892]=

4 r_^^2 T_ (  cv)^ab   v_a^  (▽_e^ S_ ( b )^(1 d))

For similar reasons, ReplaceIndex has attribute HoldFirst, and hence we need Evaluate. We can replace a single index:

In[893]:=

ReplaceIndex[Evaluate[expr], a→f]

Out[893]=

4 r_^^2 T_ (  cv)^fb   v_a^  (▽_e^ S_ ( b )^(1 d))

Note that the paired index -a has not been replaced. We need separate rules for that (this gives greater flexibility):

In[894]:=

ReplaceIndex[Evaluate[expr], {a→f, -a→ -f}]

Out[894]=

4 r_^^2 T_ (  cv)^fb   v_f^  (▽_e^ S_ ( b )^(1 d))

We can change the character of an index, or even the type:

In[895]:=

ReplaceIndex[Evaluate[expr], {a→ -f, -a→f, Dir[v[d]] →LI[2]}]

Out[895]=

4 r_^^2 T_ (f c )^( b 2) v_ ^f (▽_e^ S_ ( b )^(1 d))

If the rules do not apply, nothing happens:

In[896]:=

ReplaceIndex[Evaluate[expr], {f→a}]

Out[896]=

4 r_^^2 T_ (  cv)^ab   v_a^  (▽_e^ S_ ( b )^(1 d))

Pattern indices can be changed, but this should never be required:

In[897]:=

ReplaceIndex[T[a_], a→b]

ReplaceIndex :: nopat : Replaced pattern a_. From General. This should not happen: contact JMM.

Out[897]=

T_ ^Underscript[b, _]

The replacement is performed with great care. In the following list T is a tensor, but X is not a tensor:

In[898]:=

ReplaceIndex[{a, T[a], T[-a], X[a]}, a→b]

Out[898]=

{a, T_ ^b, T_a^ , X[a]}

As I said, the user should try to refrain from using ReplaceIndex. If a free index must be changed, use contractions with delta tensors: if we want to change from T[a] to T[b] we can do this:

In[899]:=

T[a] delta[-a, b]

Out[899]=

T_ ^b

In some cases we need to change the dummy indices of an expression. For example when we want to multiply a previous expression by itself. ReplaceDummies is the function which calls ReplaceIndex to manipulate all possible cases with dummies. A particular case, always required in the canonicalization process, is implemented in SameDummies.

Suppose now this scalar expression:

In[900]:=

expr = T[a, b] T[-a, -b]

Out[900]=

T_ab^   T_  ^ab

This is incorrect:

In[901]:=

expr expr

Out[901]=

T_ab^  ^2 T_  ^ab^2

The following is correct. ReplaceDummies changes the dummy by the given indices

In[902]:=

expr ReplaceDummies[expr, IndexList[e, f]]

Out[902]=

T_ab^   T_  ^ab T_ef^   T_  ^ef

If not enough indices (or no index at all) are given, the dummies are replaced by unique  dollar-indices:

In[903]:=

expr ReplaceDummies[expr]

Out[903]=

T_ab^   T_  ^ab T_cd^   T_  ^cd

In[904]:=

IndicesOf[][%]

Out[904]=

{-a, -b, a, b, -h$108555, -h$108556, h$108555, h$108556}

A particular case of dummy manipulation is the minimization of the number of dummies in a sum of terms. This is achieved using SameDummies, which is simply a combined call to FindDummyIndices and ReplaceDummies.

In[905]:=

SameDummies[T[a, b, d, -d] v[-b] + T[a, c, e, -e] v[-c]]

Out[905]=

2 T_ (   c)^abc  v_b^

In parallel, sometimes we need to change the free indices of an expression. This happens for example when we need to compare the results of several independent computations. If we do not know the index translation table which brings one expression to the other, then we need to search among all permutations, what could take quite some time...

This changes the free indices a,c to b,e. The index b was a dummy in the original expression, and hence it must be replaced (by a unique dollar-dummy) before actually changing the free indices:

In[906]:=

ChangeFreeIndices[T[a, b, c, d, -b, -d], {b, e}]

Out[906]=

T_ (    ad)^baed  

It is not obvious to see whether these two expressions are the same or not under a renaming of free indices:

In[907]:=

expr1 = 4U[-a, -b, -c] U[b, -d, -e] T[c, d]

expr2 = 2U[-d, -b, -a] U[a, -f, g] T[d, -g]

Out[907]=

4 T_  ^cd U_abc^    U_ ( de)^b  

Out[908]=

2 T_ ( g)^d  U_ ( f )^(a g) U_dba^   

The function EqualExpressionsQ gives True if one is simply a constant times the other, and False otherwise:

In[909]:=

EqualExpressionsQ[expr1, expr2]

LEFT  ==  -2 RIGHT   with rules:  {-a→ -b, -e→ -f}

Out[909]=

True

In[910]:=

EqualExpressionsQ[expr1, T[] expr2]

Out[910]=

False

Finally, we introduce the operation of index splitting. The key idea is the concept of a splitrule of the form   a -> IndexList[ a1, a2, ... ].  The function SplitIndex is rather efficient because it uses ReplaceIndex only once, replacing the index by a temporary variable, which is later used to do all other replacements with ReplaceAll, which is much faster.

We can construct a list of replacements as follows:

In[911]:=

SplitIndex[expr1, -a→IndexList[-A, -B, -C]]

Out[911]=

or an array:

In[912]:=

SplitIndex[expr1, {-a→IndexList[-A, -B, -C], -b→IndexList[D, F, G, H]}]

Out[912]=

In[913]:=

Dimensions[%]

Out[913]=

{3, 4}

There is also a combined notation for multiple expansions over the same range. Again, this is performed through a single call to ReplaceIndex.

In[914]:=

SplitIndex[expr1, IndexList[-a, -b] →IndexList[LI[1], LI[2], LI[3]]]

Out[914]=

ReplaceIndex            Replace an index by another index in an expression
ReplaceDummies            Replace dummy indices by new dummy indices
SameDummies                Minimize number of different dummy indices among several terms of a sum
ChangeFreeIndices        Change free indices of an expression
EqualExpressionsQ        Check whether two expressions are proportional to each other apart from a renaming of free indices
SplitIndex                Return a list of expressions where an index has been replace by different possibilities in a list
TraceDummy                Return a sum expressions where a dummy pair has been replace by different possibilities in a list

Index replacements.


Created by Mathematica  (May 16, 2008) Valid XHTML 1.1!