5.1. Unique dummies and screening

One of the most important issues in a tensor packages is how to deal with index contractions, i.e. with dummy indices. Until now this was not a real issue for us because all input expressions were simply canonicalized, a process which does not introduce new indices, but rather, eliminates indices. Now we face the opposite problem: expanding expressions into new expressions with more dummy indices, for example the conversion of a covariant derivative of a tensor in terms of a different covariant derivative. There are three problems with conversions that we must address.
This subsection explains in detail what those three problems are and how they will be solved. Though the explanations might seem a bit technical, it is important to understand them, because they are based on core concepts of Mathematica.
As an aside, there are two ways to define conversions of expressions into new expressions in Mathematica: assignments (Set and its variants SetDelayed, TagSet, UpSet, etc.) and rules (Rule and its variant RuleDelayed). Asignments can be considered as global or automatic rules. Rules can be considered as local assignments. See the Mathematica Help.
First problem. Let us see a simple example using Set:

Define the vector w in terms of T and v. Introduce a simple dummy:

In[310]:=

DefTensor[w[a], M3]

** DefTensor: Defining tensor w[a] .

In[311]:=

w[a_] = T[a, b] v[-b]

Out[311]=

T_  ^ab v_b^

[Note that we have used a Pattern on the right hand side. That is normal Mathematica, and a helpful feature which allows us to indicate the generality of the rule (which indices or tensors are accepted in the rule)].

Then these expressions would be totally wrong:

In[312]:=

w[b]

Out[312]=

T_  ^bb v_b^

In[313]:=

w[a] w[-a]

Out[313]=

T_a ^( b) T_  ^ab v_b^ ^2

Mathematica recommends the following solution to this problem:

Use a Module construct, such that the dummy index b is replaced by a unique symbol denoted with a $ sign, and a unique integer number. Note that we must now use SetDelayed (:=), and not Set (=), to avoid inmediate evaluation of Module:

In[314]:=

w[a_] := Module[{b}, T[a, b] v[-b]]

In[315]:=

w[b]

Out[315]=

T_        ^bb$17552 v_b$17552^       

In[316]:=

w[a] w[-a]

Out[316]=

This solves the first problem but generates two more, which are solved by "screening" the dollar-indices:

ScreenDollarIndices        Hide internal unique dummy indices

Screening of indices.

First, each time we use the assignment we get a different object, what complicates comparisons. The following is not automatically recognized as zero!

In[317]:=

w[a] - w[a]

Out[317]=

In[318]:=

%//InputForm

Out[318]//InputForm=

T[a, b$17555]*v[-b$17555] - T[a, b$17556]*v[-b$17556]

The second problem is purely aesthetical: the dollar-indices are terribly ugly. xTensor` has the function ScreenDollarIndices to convert the dollar-indices into normal-looking indices:

In[319]:=

{w[a], w[b], w[c], w[a] w[-a], w[a] - w[a]}

Out[319]=

In[320]:=

ScreenDollarIndices[%]

Out[320]=

{T_  ^ab v_b^ , T_  ^ba v_a^ , T_  ^ca v_a^ , T_a ^( c) T_  ^ab v_b^  v_c^ , 0}

In[321]:=

InputForm[%]

Out[321]//InputForm=

{T[a, b]*v[-b], T[b, a]*v[-a], T[c, a]*v[-a], T[-a, c]*T[a, b]*v[-b]*v[-c], 0}

The Module construct is not the solution for all problems in tensor conversions. There are two more problems, as seen in the following examples. Second problem:

Objects and indices cannot share the same symbol names. Suppose there were a tensor also called a:

In[322]:=

w[a_] := a[a]

In[323]:=

w[b]

Out[323]=

b[b]

In xTensor`, this is solved by enforcing type declarations. Every object must be defined supplying a symbol, and that symbol is given a type. A symbol cannot have two different types. This can be seen as a restriction, but it is actually a useful safety feature.

The tensor a[b] cannot be defined:

In[324]:=

Catch @ DefTensor[a[b], M3]

ValidateSymbol :: used : Symbol a is already used as an abstract index .

The final (third) problem involves dummies again, and happens in the few cases in which the same symbol represents a dummy on both sides and there are additional dummies on the right. The only possible solution is changing the name of the conflicting dummies either on the left or on the right hand side.

Define the following relation with dummies both on the left and right hand sides. Note that the b dummy is present in both sides and is a pattern on the left hand side:

In[325]:=

w[a_, b_, -b_] := Module[{b, c}, T[a, b, -b, c, -c]]

In[326]:=

w[a, b, -b]

Out[326]=

In[327]:=

w[a, c, -c]

Module :: dups : Conflicting local variables c and c$ found in local variable specification {c, c$} .  More…

Out[327]=

Module[{c, c$}, T_ (  c  c$)^(ac c$  )]

For example, we can change the name of the dummy index b on the right hand side:

In[328]:=

w[a_, b_, -b_] := Module[{d, c}, T[a, d, -d, c, -c]]

In[329]:=

w[a, b, -b]

Out[329]=

In[330]:=

w[a, c, -c]

Out[330]=

As we said, the second problem is solved in xTensor` simply by enforcing type declarations. The first and third problems will be solved introducing a new collection of Index* assignment and rule functions which properly prepare the required Module constructs. They are IndexSet, IndexSetDelayed, IndexRule and IndexRuleDelayed, imitating their respective Mathematica counterparts, and they are described in detail in the next subsections.

We finish this section coming back to the function ScreenDollarIndices. We recommend to automate its use by assigning one of the global variables $Post or $PrePrint to it. There is a small difference between these two global variables (mentioned below), and it is not clear that one of them is always better than the other for screening, but I generally prefer $PrePrint:

Assign $PrePrint:

In[331]:=

$PrePrint = ScreenDollarIndices ;

Now the screening is automatic:

In[332]:=

w[a, c, -c]

Out[332]=

T_ (  c b)^(ac b )

The screening happened after the result was assigned to Out[...] and hence if we temporarily remove $PrePrint, we still see the dollar-indices. (That wouldn't happen using $Post.)

In[333]:=

$PrePrint=.

In[334]:=

%%

Out[334]=

Clean up

In[335]:=

w[a_, b_, -b_] =.

From now on, in this notebook, we shall use automatic screening:

In[336]:=

$PrePrint = ScreenDollarIndices ;


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