7. Assigning values to components

We need some convenient way to store all the values of the components of a tensor (or, more generally, an arbitrary expression). xCoba` provides several tools to accomplish this, optimised to make full use of the symmetries. This section describes how to store and use these values, but not how to compute them. The latter is the object of Section 9 (not yet fully implemented).

Given a tensor there are several things we need to worry about when working with values:
    - 1. Are we giving values to the components of the tensor itself or to some derivative of it?
    - 2. The slot-symmetry of the expression.
    - 3. What is the character of the c-indices involved?
    - 4. Which bases are we using to form the component?
    - 5. When did we construct a particular set of components?
    - 6. Have we already computed values for all components of the expression?

This section describes a series of functions for the storage of tensor values. After reading it, we think it is very profitable to take a look at the notebook Schwarzschild.nb, by Alfonso García-Parrado, which describes an example computation with the Schwarzschild metric, employing some of the commands described here. This notebook is included in xCoba.tar.gz and can be downloaded from http://metric.iem.csic.es/Martin-Garcia/xAct/index.html.

7.1. FoldedRule and ValID

7.2. ComponentValue and TensorValues without independent values

ComponentValue        Give the value of a single component
TensorValues        List of all values for a given tensor
TensorValIDs        List of all the ValIDs of a given tensor    
DateOfValID            
Time a given ValID was generated
$CVVerbose            Switch verbose output on/off for ComponentValue

Storing values for components

We have seen how xCoba` stores and labels sets of tensor values for different basis configurations; this section describes how these sets are generated. The basic function is ComponentValue, which generates the rule for a single component. ComponentValue can be called with one or two arguments:

In[314]:=

? ComponentValue

We begin by examining how it works with just one argument (i.e. without specifying an independent value). Let us define a totally antisymmetric tensor

In[315]:=

DefTensor[W[a, b, c], M3, Antisymmetric[{a, b, c}]]

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

In[316]:=

SetOptions[CanonicalPerm, MathLink→ True]

Out[316]=

{MathLink→True, TimeVerbose→False, xPermVerbose→False, OrderedBase→True}

Suppose we want to generate a rule for one of its components

In[317]:=

W[{0, polar}, {1, polar}, {2, polar}]

Out[317]=

W_   ^(012)

In[318]:=

ComponentValue[%]

Added independent rule W_   ^(012) →W_   ^(012)  for tensor W

Out[318]=

W_   ^(012) →W_   ^(012)

In[319]:=

TensorValues[W]

Out[319]=

FoldedRule[{}, {W_   ^(012) →W_   ^(012)}]

As we can see, xCoba` has recognised that W^012 is an independent component and has added a rule for it in the second list of the FoldedRule. This rule is trivial, as we have not specified the numerical value of the component. But consider now the following

In[320]:=

ComponentValue[W[{2, polar}, {1, polar}, {0, polar}]]

Added dependent rule W_   ^(210) → -W_   ^(012)  for tensor W

Out[320]=

W_   ^(210) → -W_   ^(012)

In[321]:=

TensorValues[W]

Out[321]=

FoldedRule[{W_   ^(210) → -W_   ^(012)}, {W_   ^(012) →W_   ^(012)}]

xCoba`  sees that W^210 is not an independent component and generates for it a rule in the first list of the FoldedRule. We can easily generate the full set of component values:

In[322]:=

W[{a, polar}, {b, polar}, {c, polar}]//ComponentArray//Flatten

Out[322]=

In[323]:=

ComponentValue/@ %

Added dependent rule W_   ^(000) →0 for tensor W

Added dependent rule W_   ^(001) →0 for tensor W

Added dependent rule W_   ^(002) →0 for tensor W

Added dependent rule W_   ^(010) →0 for tensor W

Added dependent rule W_   ^(011) →0 for tensor W

Added dependent rule W_   ^(020) →0 for tensor W

Added dependent rule W_   ^(021) → -W_   ^(012)  for tensor W

Added dependent rule W_   ^(022) →0 for tensor W

Added dependent rule W_   ^(100) →0 for tensor W

Added dependent rule W_   ^(101) →0 for tensor W

Added dependent rule W_   ^(102) → -W_   ^(012)  for tensor W

Added dependent rule W_   ^(110) →0 for tensor W

Added dependent rule W_   ^(111) →0 for tensor W

Added dependent rule W_   ^(112) →0 for tensor W

Added dependent rule W_   ^(120) →W_   ^(012)  for tensor W

Added dependent rule W_   ^(121) →0 for tensor W

Added dependent rule W_   ^(122) →0 for tensor W

Added dependent rule W_   ^(200) →0 for tensor W

Added dependent rule W_   ^(201) →W_   ^(012)  for tensor W

Added dependent rule W_   ^(202) →0 for tensor W

Added dependent rule W_   ^(211) →0 for tensor W

Added dependent rule W_   ^(212) →0 for tensor W

Added dependent rule W_   ^(220) →0 for tensor W

Added dependent rule W_   ^(221) →0 for tensor W

Added dependent rule W_   ^(222) →0 for tensor W

Out[323]=

As we can see by reading the messages, the rules for W^012 and W^210 have not been recomputed. Now

In[324]:=

TensorValues[W]

Out[324]=

There is only one independent rule. We have one ValID for W^abc, which consists of only one basis configuration

In[325]:=

TensorValIDs[W]

Out[325]=

{ValID[W, {{polar, polar, polar}}]}

ValIDs are timestamped:

In[326]:=

DateOfValID/@ %

Out[326]=

{{2008, 5, 14, 18, 56, 22.950787}}

Let us now consider an example with several bases. Recall that T_ab is a symmetric tensor

In[327]:=

ComponentValue[T[{2, -polar}, {1, -cartesian}]]

Added dependent rule T_ (21)^  →T_ (12)^   for tensor T

Out[327]=

T_ (21)^  →T_ (12)^  

In[328]:=

T[-{a, polar}, -{b, cartesian}] //ComponentArray//Flatten

Out[328]=

In[329]:=

ComponentValue /@ %

Added dependent rule T_ (00)^  →T_ (00)^   for tensor T

Added independent rule T_ (01)^  →T_ (01)^   for tensor T

Added independent rule T_ (02)^  →T_ (02)^   for tensor T

Added dependent rule T_ (10)^  →T_ (01)^   for tensor T

Added dependent rule T_ (11)^  →T_ (11)^   for tensor T

Added independent rule T_ (12)^  →T_ (12)^   for tensor T

Added dependent rule T_ (20)^  →T_ (02)^   for tensor T

Added dependent rule T_ (22)^  →T_ (22)^   for tensor T

Out[329]=

In[330]:=

TensorValIDs[T]

Out[330]=

{ValID[T, {{-cartesian, -polar}, {-polar, -cartesian}}]}

We still do not have all the rules, because our ValID mixes the cases T_ (ab) and T_ (ba):

In[331]:=

T[-{a, cartesian}, -{b, polar}] //ComponentArray//Flatten

Out[331]=

In[332]:=

ComponentValue /@ %

Added independent rule T_ (00)^  →T_ (00)^   for tensor T

Added independent rule T_ (01)^  →T_ (01)^   for tensor T

Added independent rule T_ (02)^  →T_ (02)^   for tensor T

Added dependent rule T_ (10)^  →T_ (01)^   for tensor T

Added independent rule T_ (11)^  →T_ (11)^   for tensor T

Added independent rule T_ (12)^  →T_ (12)^   for tensor T

Added dependent rule T_ (20)^  →T_ (02)^   for tensor T

Added dependent rule T_ (21)^  →T_ (12)^   for tensor T

Added independent rule T_ (22)^  →T_ (22)^   for tensor T

Out[332]=

In[333]:=

TensorValues[T]

Out[333]=

In[334]:=

TensorValIDs[T]

Out[334]=

{ValID[T, {{-cartesian, -polar}, {-polar, -cartesian}}]}

Now we still only have one ValID for T_ab, but it consists of two basis configurations.  As we can see, the FoldedRule returned by TensorValues mixes the cases T_ (ab) and T_ (ba). Another example, now mixing index characters:

In[335]:=

ComponentArray[T[{a, polar}, -{b, cartesian}]] //Flatten

Out[335]=

{T_ ( 0)^0 , T_ ( 1)^0 , T_ ( 2)^0 , T_ ( 0)^1 , T_ ( 1)^1 , T_ ( 2)^1 , T_ ( 0)^2 , T_ ( 1)^2 , T_ ( 2)^2 }

In[336]:=

ComponentValue /@ %

Added dependent rule T_ ( 0)^0 →T_0 ^( 0)  for tensor T

Added independent rule T_ ( 1)^0 →T_ ( 1)^0  for tensor T

Added independent rule T_ ( 2)^0 →T_ ( 2)^0  for tensor T

Added dependent rule T_ ( 0)^1 →T_0 ^( 1)  for tensor T

Added dependent rule T_ ( 1)^1 →T_1 ^( 1)  for tensor T

Added independent rule T_ ( 2)^1 →T_ ( 2)^1  for tensor T

Added dependent rule T_ ( 0)^2 →T_0 ^( 2)  for tensor T

Added dependent rule T_ ( 1)^2 →T_1 ^( 2)  for tensor T

Added dependent rule T_ ( 2)^2 →T_2 ^( 2)  for tensor T

Out[336]=

In[337]:=

ComponentArray[T[{-a, cartesian}, {a, polar}]] //Flatten

Out[337]=

{T_0 ^( 0), T_0 ^( 1), T_0 ^( 2), T_1 ^( 0), T_1 ^( 1), T_1 ^( 2), T_2 ^( 0), T_2 ^( 1), T_2 ^( 2)}

In[338]:=

ComponentValue /@ %

Added independent rule T_0 ^( 0) →T_0 ^( 0)  for tensor T

Added independent rule T_0 ^( 1) →T_0 ^( 1)  for tensor T

Added independent rule T_0 ^( 2) →T_0 ^( 2)  for tensor T

Added dependent rule T_1 ^( 0) →T_ ( 1)^0  for tensor T

Added independent rule T_1 ^( 1) →T_1 ^( 1)  for tensor T

Added independent rule T_1 ^( 2) →T_1 ^( 2)  for tensor T

Added dependent rule T_2 ^( 0) →T_ ( 2)^0  for tensor T

Added dependent rule T_2 ^( 1) →T_ ( 2)^1  for tensor T

Added independent rule T_2 ^( 2) →T_2 ^( 2)  for tensor T

Out[338]=

In[339]:=

TensorValIDs[T]

Out[339]=

{ValID[T, {{-cartesian, polar}, {polar, -cartesian}}], ValID[T, {{-cartesian, -polar}, {-polar, -cartesian}}]}

We have two ValIDs, both consisting of two basis configurations. Notice how newer ValIDs appear first.We can retrieve the TensorValues for either one of them

In[340]:=

TensorValues[T, {{-cartesian, polar}, {polar, -cartesian}}]

Out[340]=

or for all at the same time:

In[341]:=

TensorValues[T]

Out[341]=

We can delete single rules

In[342]:=

ComponentValue[T[{1, -cartesian}, {2, -polar}], Null]

Dropped independent rule T_ (12)^  →T_ (12)^   for tensor T

Out[342]=

T_ (12)^  →Null

We can also easily delete all TensorValues for a given tensor

In[343]:=

DeleteTensorValues[W]

Deleted values for tensor W, derivatives  {}  and bases  {{polar, polar, polar}}  .

or only those for a single ValID

In[344]:=

DeleteTensorValues[T, {{-cartesian, polar}, {polar, -cartesian}}]

Deleted values for tensor T, derivatives  {}  and bases  {{-cartesian, polar}, {polar, -cartesian}}  .

7.3. ComponentValue and TensorValues with independent values

7.4. AllComponentValues

7.5. Components and derivatives

7.6. BasisValues

7.7. Components of the metric, MetricInBasis

7.7. Changing bases or index characters

ChangeComponents        Compute new TensorValues from an already stored index configuration

Changing bases or index characters

Suppose we already have the tensor values for a given ValID and we want to generate the corresponding set for an (inequivalent) index configuration. We may want to perform a typical change of basis like T_ab to T_ab, for example. Or we may want to lower or raise some indices. Given starting and finishing index configurations, xCoba` can compute the best route between them with the function ChangeComponents

A simple example

In[380]:=

ChangeComponents[v[{a, polar}], v[-{a, polar}]]

Computed v_ ^a→g_  ^(ab) v_b^  in 0.010123 Seconds

Out[380]=

In[381]:=

TensorValIDs[v]

Out[381]=

{ValID[v, {{polar}}], ValID[v, {{-polar}}]}

In[382]:=

DeleteTensorValues[v]

Deleted values for tensor v, derivatives  {}  and bases  {{polar}}  .

Deleted values for tensor v, derivatives  {}  and bases  {{-polar}}  .

A more complicated example, with an antisymmetric tensor Y_ab. To keep it shorter we can change the cnumbers of polar to make xCoba` think the manifold is two dimensional

In[383]:=

DefTensor[Y[a, b], M3, Antisymmetric[{1, 2}]]

** DefTensor: Defining tensor Y[a, b] .

In[384]:=

CNumbersOf[polar] ^={1, 2}

Out[384]=

{1, 2}

We set some configuration global variables

In[385]:=

$CVVerbose = True ;

$CVReplace = False ;

$CCSimplify = Expand ;

$UseValues = ToCanonical ;

In[389]:=

ChangeComponents[Y[-{a, polar}, -{b, polar}], Y[{a, polar}, {b, polar}]]

Added dependent rule Y_  ^(11) →0 for tensor Y

Added independent rule Y_  ^(12) →Y_  ^(12)  for tensor Y

Added dependent rule Y_  ^(21) → -Y_  ^(12)  for tensor Y

Added dependent rule Y_  ^(22) →0 for tensor Y

Added independent rule Y_ ( 1)^1 →g_ (12)^   Y_  ^(12)  for tensor Y

Added dependent rule Y_ ( 1)^2 → -Y_1 ^( 2)  for tensor Y

Added independent rule Y_1 ^( 2) →g_ (11)^   Y_  ^(12)  for tensor Y

Added independent rule Y_ ( 2)^1 →g_ (22)^   Y_  ^(12)  for tensor Y

Added independent rule Y_ ( 2)^2 → -g_ (12)^   Y_  ^(12)  for tensor Y

Added dependent rule Y_1 ^( 1) → -Y_ ( 1)^1  for tensor Y

Added dependent rule Y_2 ^( 1) → -Y_ ( 2)^1  for tensor Y

Added dependent rule Y_2 ^( 2) → -Y_ ( 2)^2  for tensor Y

Computed Y_ ( b)^a →g_ (bc)^   Y_  ^(ac)  in 0.536889 Seconds

Added dependent rule Y_ (11)^  →0 for tensor Y

Added independent rule Y_ (12)^  →g_ (11)^   Y_ ( 2)^1 + g_ (12)^   Y_ ( 2)^2  for tensor Y

Added dependent rule Y_ (21)^  → -Y_ (12)^   for tensor Y

Added dependent rule Y_ (22)^  →0 for tensor Y

Computed Y_ (ab)^  →g_ (ac)^   Y_ ( b)^c  in 0.310710 Seconds

Out[389]=

The system prints Value g_ (12)^   Y_ ( 2)^1 +g_ (22)^   Y_ ( 2)^2 expected to be 0 by symmetry.This is because of $UseValues =ToCanonical which tells the system only to use the independent rules at each step. If we had written $UseValues =All instead that message would not have appeared. However, whenever a component is 0 because of the symmetry, the symmetry value is used, so our result is correct.

In[390]:=

TensorValues[Y]

Out[390]=

We can always collapse the FoldedRules, but this may generate very long expressions

In[391]:=

? CollapseFoldedRule

In[392]:=

CollapseFoldedRule[%%, All]

Out[392]=

In[393]:=

CNumbersOf[polar] ^={0, 1, 2}

Out[393]=

{0, 1, 2}

We can also change bases

In[394]:=

ChangeComponents[v[{a, cartesian}], v[{a, polar}]]

Added independent rule v_ ^0→v_ ^0 for tensor v

Added independent rule v_ ^1→v_ ^1 for tensor v

Added independent rule v_ ^2→v_ ^2 for tensor v

Added independent rule v_ ^0→e_ ( 0)^0  v_ ^0 + e_ ( 1)^0  v_ ^1 + e_ ( 2)^0  v_ ^2 for tensor v

Added independent rule v_ ^1→e_0 ^( 1) v_ ^0 + e_ ( 1)^1  v_ ^1 + e_ ( 2)^1  v_ ^2 for tensor v

Added independent rule v_ ^2→e_0 ^( 2) v_ ^0 + e_1 ^( 2) v_ ^1 + e_ ( 2)^2  v_ ^2 for tensor v

Computed v_ ^a→e_ ( b)^a  v_ ^b in 0.293718 Seconds

Out[394]=

7.8. Replacing TensorValues in expressions


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