2.2. ContractBasis

ContractBasis is responsible for all contractions of Basis with any other object.

ContractBasis[expr, indices]        Perform the contractions of Basis objects involving the specified dummy indices

Contraction of Basis objects with tensors.

We have complete control over which dummy indices should be eliminated. We can select them in several ways, all of which are eventually converted into a list of indices with head IndexList:
    - IndexList[...],        
be careful not to use the normal Mathematica List, which could be mistaken for a BCIndex. IndicesOf[selectors] as a second argument is treated as IndicesOf[selectors][expr] and gives great flexibility, but it is sometimes too long for simple cases. To handle them, several shorthands are defined:
    - ContractBasis[expr,basis]     = ContractBasis[expr,IndicesOf[basis]],
    - ContractBasis[expr,vbundle]    = ContractBasis[expr,IndicesOf[vbundle]],
    - ContractBasis[expr,tensor]    = ContractBasis[expr,IndicesOf[tensor]],
    - ContractBasis[expr,index]        = ContractBasis[expr,IndexList[index]] .
It is important to keep in mind that the second argument gives the list of indices to be contracted,  not their pairs in the Basis object.
All of this is best illustrated through some examples:

In[139]:=

expr

Out[139]=

e_ ( 1)^a  TT_ (1b  a)^(  2c ) + e_ ( 1)^a  e_ ( e)^c  e_d ^( 2) S_B ^( A) S_A ^( B) U_ab  ^(  de)

In[140]:=

expr2 = Basis[{-e, -cartesian}, b] Basis[-A, {1, comp}] S[-B, A] v[{e, cartesian}]

Out[140]=

e_A ^( 1) e_ ( e)^b  S_B ^( A) v_ ^e

The function called with just one argument performs all the possible contractions.

In[141]:=

ContractBasis[expr]

Out[141]=

TT_ (1b  1)^(  2c ) + S_B ^( A) S_A ^( B) U_ (1b  )^(  2c)

If we choose to give the indices directly, we can specifiy either element of the pair

In[142]:=

{{ContractBasis[expr2, A], ContractBasis[expr2, -A]},  {ContractBasis[expr2, {-e, -cartesian}], ContractBasis[expr2, {e, cartesian}]}}//TableForm

Out[142]//TableForm=

e_ ( e)^b  S_B ^( 1) v_ ^e e_ ( e)^b  S_B ^( 1) v_ ^e
e_A ^( 1) S_B ^( A) v_ ^b e_A ^( 1) S_B ^( A) v_ ^b

Nothing happens if we give an invalid index

In[143]:=

ContractBasis[expr2, C]

Out[143]=

e_A ^( 1) e_ ( e)^b  S_B ^( A) v_ ^e

More simple examples

In[144]:=

ContractBasis[expr, IndicesOf[AIndex]]

Out[144]=

TT_ (1b  1)^(  2c ) + e_ ( e)^c  S_B ^( A) S_A ^( B) U_ (1b  )^(  2e)

In[145]:=

ContractBasis[expr, IndicesOf[TT, U]]

Out[145]=

TT_ (1b  1)^(  2c ) + e_ ( e)^c  e_d ^( 2) S_B ^( A) S_A ^( B) U_ (1b  )^(  de)

In[146]:=

ContractBasis[expr, IndicesOf[{TT, U}]]

Out[146]=

TT_ (1b  1)^(  2c ) + S_B ^( A) S_A ^( B) U_ (1b  )^(  2c)

In[147]:=

ContractBasis[expr2, InnerC]

Out[147]=

e_ ( e)^b  S_B ^( 1) v_ ^e

In[148]:=

ContractBasis[expr, IndexList[a, -d]]

Out[148]=

TT_ (1b  1)^(  2c ) + e_ ( e)^c  S_B ^( A) S_A ^( B) U_ (1b  )^(  2e)

In[149]:=

ContractBasis[expr, polar]

Out[149]=

e_ ( 1)^a  TT_ (1b  a)^(  2c ) + e_ ( 1)^a  e_d ^( 2) S_B ^( A) S_A ^( B) U_ab  ^(  dc)

Notice how only the index {-e, -polar} has been supressed. Nothing has been done to a, even though its pair in the Basis object belongs to polar.  If we want to act on that index, we can use

In[150]:=

ContractBasis[expr, IndicesOf[Basis[polar]]]

Out[150]=

TT_ (1b  1)^(  2c ) + e_d ^( 2) S_B ^( A) S_A ^( B) U_ (1b  )^(  dc)

to contract everything that appears in a Basis object that has at least one polar index. Or

In[151]:=

ContractBasis[expr, IndicesOf[Basis[polar], AIndex]]

Out[151]=

TT_ (1b  1)^(  2c ) + e_ ( e)^c  e_d ^( 2) S_B ^( A) S_A ^( B) U_ (1b  )^(  de)

to contract only abstract indices whose pair in Basis belongs to polar. Notice that some specifications can be redundant; IndicesOf[Basis, x] is equivalent to IndicesOf[x], because all the indices that can be contracted by this function already have to appear in Basis.

Contraction of Basis objects can be performed with ContractBasis, or automatized:

In[152]:=

Basis[a, {-b, -cartesian}] Basis[-a, {c, polar}]

Out[152]=

e_a ^( c) e_ ( b)^a

In[153]:=

ContractBasis[%]

Out[153]=

e_b ^( c)

In[154]:=

AutomaticBasisContractionStart[]

In[155]:=

Basis[a, {-b, -cartesian}] Basis[-a, {c, polar}]

Out[155]=

e_b ^( c)

In[156]:=

AutomaticBasisContractionStop[]

The default behaviour of ContractBasis disregards contractions involving derivatives. We must use the option OverDerivatives:

In[157]:=

DefCovD[CD[-a], {"#", "D"}]

** DefCovD: Defining covariant derivative CD[-a] .

** DefTensor: Defining vanishing torsion tensor TorsionCD[a, -b, -c] .

** DefTensor: Defining symmetric Christoffel tensor ChristoffelCD[a, -b, -c] .

** DefTensor: Defining Riemann tensor RiemannCD[-a, -b, -c, d] . Antisymmetric only in the first pair.

** DefTensor: Defining non-symmetric Ricci tensor RicciCD[-a, -b] .

** DefCovD:  Contractions of Riemann automatically replaced by Ricci.

In[158]:=

Basis[{1, polar}, -b] CD[-a][S[c, b]]

Out[158]=

e_b ^( 1) (D_a^ S_  ^cb)

In[159]:=

ContractBasis[%]

Out[159]=

e_b ^( 1) (D_a^ S_  ^cb)

In[160]:=

ContractBasis[%, OverDerivatives→ True]

** DefTensor: Defining tensor ChristoffelCDPDpolar[a, -b, -c] .

Out[160]=

Γ[D, ] _ ( ab)^1   S_  ^cb + D_a^ S_  ^(c1)

A new Christoffel tensor is automatically defined. We shall see more about the interplay between bases and derivatives in Section 5. Any type of derivate exhibits the same behaviour,

In[161]:=

lieexpr = LieD[v[a]][T[-a, -b]] Basis[{1, -polar}, a] Basis[{3, -polar}, b]

Out[161]=

e_ ( 1)^a  e_ ( 3)^b  (ℒ_vT_ab^  )

In[162]:=

{ContractBasis[lieexpr], ContractBasis[lieexpr, OverDerivatives→ True]}//TableForm

Out[162]//TableForm=

e_ ( 1)^a  e_ ( 3)^b  (ℒ_vT_ab^  )
ℒ_vT_ (13)^   + T_ (a3)^   (_1^ v_ ^a) + T_ (1b)^   (_3^ v_ ^b)

In[163]:=

paramexpr = OverDot[T[-a, -b]] Basis[{1, -polar}, a] Basis[{3, -polar}, b]

Out[163]=

e_ ( 1)^a  e_ ( 3)^b  Overscript[T_ab^  , .]

In[164]:=

{ContractBasis[paramexpr], ContractBasis[paramexpr, OverDerivatives→ True]}//TableForm

Out[164]//TableForm=

e_ ( 1)^a  e_ ( 3)^b  Overscript[T_ab^  , .]
Overscript[T_ (13)^  , .] - Overscript[e_ ( 1)^a , .] T_ (a3)^   - Overscript[e_ ( 3)^b , .] T_ (1b)^  

In[165]:=

expr2=.

lieexpr=.

paramexpr=.

In[168]:=

UndefCovD[CD]

** UndefTensor: Undefined symmetric Christoffel tensor ChristoffelCD

** UndefTensor: Undefined tensor ChristoffelCDPDpolar

** UndefTensor: Undefined non-symmetric Ricci tensor RicciCD

** UndefTensor: Undefined Riemann tensor RiemannCD

** UndefTensor: Undefined vanishing torsion tensor TorsionCD

** UndefCovD: Undefined covariant derivative CD

The input expression is automatically expanded (with Expand) before applying ContractBasis. It would be better, in principle, to contract the bases only locally, but this is not yet implemented.

At the moment, the user cannot specify in which order the indices should be contracted. An option ContractFirst is planned but not yet coded.


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