5.3. Index patterns

In the previous definitions of the vector w[a] we always used the pattern a_ which stands for any possible input, including up-indices and down-indices of any manifold, or even directional or label (or basis or component) indices. Sometimes this is what we want, but often it is not. In the following definitions there are no dummies or conflicts between indices and tensor names, so that we can safely use the usual SetDelayed (:=) definitions to simplify the examples.
The notation for tensors and indices in xTensor` is very simple, but that complicates working with patterns. On the other hand, there are always several ways to represent the same pattern.

Define, for the sake of simplicity:

In[349]:=

dirvup = Dir[v[d]] ;

dirvdown = Dir[v[-d]] ;

This pattern stands for everything. Every w is converted into T:

In[351]:=

w[a_] := T[a]

In[352]:=

{w[a], w[-a], w[dirvdown], w[dirvup], w[A], w[-A]}

Out[352]=

{T_ ^a, T_a^ , T_ ^v, T_v^ , T_ ^A, T_A^ }

In[353]:=

w[a_] =.

Let us first work with the character of the indices: use the functions

UpIndexQ                Detect up-indices
DownIndexQ                Detect down-indices

This pattern matches only up-indices:

In[354]:=

w[a_ ? UpIndexQ] := T[a]

In[355]:=

{w[a], w[-a], w[dirvdown], w[dirvup], w[A], w[-A]}

Out[355]=

{T_ ^a, w_a^ , T_ ^v, w_v^ , T_ ^A, w_A^ }

In[356]:=

w[a_ ? UpIndexQ] =.

This pattern matches only down-indices:

In[357]:=

w[a_ ? DownIndexQ] := T[a]

In[358]:=

{w[a], w[-a], w[dirvdown], w[dirvup], w[A], w[-A]}

Out[358]=

{w_ ^a, T_a^ , w_ ^v, T_v^ , w_ ^A, T_A^ }

In[359]:=

w[a_ ? DownIndexQ] =.

And now we work with the type of index: use the functions

AIndexQ                    Detect abstract indices
BIndexQ                    Detect basis indices
CIndexQ                    Detect component indices
DIndexQ                    Detect directional indices
LIndexQ                    Detect label indices
GIndexQ                    Detect all generalized indices, but not patterns
ABIndexQ                Detect contractible indices (abstract or basis indices)
BCIndexQ                Detect indices associated to a basis or chart (basis or component indices)
CDIndexQ                Detect indices representing a direction (component or directional indices)
PIndexQ                    Detect pattern indices

Detect types of indices.

This pattern matches only abstract indices, from any manifold:

In[360]:=

w[a_ ? AIndexQ] := T[a]

In[361]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[361]=

{T_ ^a, T_a^ , w_v^ , w_ ^v, T_ ^A, T_A^ }

In[362]:=

w[a_ ? AIndexQ] =.

There is a simple and efficient pattern for abstract up-indices or abstract down-indices:

In[363]:=

w[a_Symbol] := T[a]

In[364]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[364]=

{T_ ^a, w_a^ , w_v^ , w_ ^v, T_ ^A, w_A^ }

In[365]:=

w[a_Symbol] =.

In[366]:=

w[-a_Symbol] := T[-a]

In[367]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[367]=

{w_ ^a, T_a^ , w_v^ , w_ ^v, w_ ^A, T_A^ }

In[368]:=

w[-a_Symbol] =.

This pattern matches only directional indices. Recall that directions do not have a sign in front. A message is sent complaining about the character of the vector v.

In[369]:=

w[a_ ? DIndexQ] := T[a]

In[370]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Validate :: error : Invalid character of index in tensor v

Out[370]=

{w_ ^a, w_a^ , T_v^ , T_ ^v, w_ ^A, w_A^ }

In[371]:=

w[a_ ? DIndexQ] =.

There is also a simpler version (which does not find the problem with the position of the ultraindex):

In[372]:=

w[a_Dir] := T[a]

In[373]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[373]=

{w_ ^a, w_a^ , T_v^ , T_ ^v, w_ ^A, w_A^ }

In[374]:=

w[a_Dir] =.

The functions AIndexQ, BIndexQ, CIndexQ, DIndexQ and GIndexQ admit a second argument restricting the manifold to which the indices must belong.

This pattern only matches abstract indices on TangentM3:

In[375]:=

w[a_ ? (AIndexQ[#, TangentM3] &)] := T[a]

In[376]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[376]=

{T_ ^a, T_a^ , w_v^ , w_ ^v, w_ ^A, w_A^ }

In[377]:=

w[a_ ? (AIndexQ[#, TangentM3] &)] =.

Again there are simpler and cleaner versions, also discriminating between upindices and downindices (Q-functions) or not (pmQ-functions). The use of Symbol is not needed now.

In[378]:=

w[a_ ? TangentM3`Q] := T[a]

In[379]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[379]=

{T_ ^a, w_a^ , w_v^ , w_ ^v, w_ ^A, w_A^ }

In[380]:=

w[a_ ? TangentM3`Q] =.

In[381]:=

w[-a_ ? TangentM3`Q] := T[-a]

In[382]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[382]=

{w_ ^a, T_a^ , w_v^ , w_ ^v, w_ ^A, w_A^ }

In[383]:=

w[-a_ ? TangentM3`Q] =.

In[384]:=

w[a_ ? TangentM3`pmQ] := T[a]

In[385]:=

{w[a], w[-a], w[dirvup], w[dirvdown], w[A], w[-A]}

Out[385]=

{T_ ^a, T_a^ , w_v^ , w_ ^v, w_ ^A, w_A^ }

In[386]:=

w[a_ ? TangentM3`pmQ] =.

In case of doubt use the function PatternIndex, which constructs patterns of the required form.

These are examples of different patterns for abstract indices named a. Note the minus sign in front of a for down-indices. The pattern is for the symbol of the index, and not for the whole index.

In[387]:=

PatternIndex[a, AIndex]

Out[387]=

a_ ? AIndexQ

In[388]:=

PatternIndex[a, AIndex, Up]

Out[388]=

a_ ? AIndexQ

In[389]:=

PatternIndex[a, AIndex, Down, TangentM3]

Out[389]=

-a_Symbol ? TangentM3`Q

In[390]:=

PatternIndex[a, AIndex, Null, TangentM3]

Out[390]=

a_ ? TangentM3`pmQ

These are patterns for directional indices named d:

In[391]:=

PatternIndex[d, DIndex]

Out[391]=

d_Dir

In[392]:=

PatternIndex[d, DIndex, Up]

Out[392]=

d_Dir

In[393]:=

PatternIndex[d, DIndex, Down, TangentM3]

Out[393]=

d_Dir ? (DownIndexQ[#1] &&DIndexQ[#1, TangentM3] &)

In[394]:=

PatternIndex[d, DIndex, Null, TangentM3]

Out[394]=

d_Dir ? (DIndexQ[#1, TangentM3] &)


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