5. Input Expressions

Composite mathematical objects in xTensor`.

5.1. Sum of tensors

There is no special "tensor addition" command. We use the Plus head in Mathematica because this allows us to use many builtins which already know how to handle Plus (in particular the simplification algorithms). Any input expression in xTensor` is assumed to be a sum of terms and most algorithms are threaded over those terms in such a way that each term is manipulated independently.

The use of Plus is not a restriction in the sense that it has all expected properties of a sum of tensors. The only problem might be the attribute Orderless (implementing commutativity) because we cannot control the order in which the terms are placed.

5.2. Tensor product

There is no special "tensor product" command. We use the Times head in Mathematica because this allows us to use many builtins which already know how to handle Times (in particular the simplication algorithms). Any term expression in xTensor` is assumed to be a product of factors. A tensor product can be considered as a single tensor and many algorithms in xTensor` use this idea.

The product of several tensors can be separated into monomials which do not share dummy indices. This can be done with the function BreakInMonomials, which introduces the (inert-) head Monomial.

The use of Times is a restriction in the sense that it is a commutative product (implemented throught its Orderless attribute). There is no natural anticommutative product in Mathematica and xTensor` does not try to introduce it. Apart from that, Times is perfectly general because the abstract indices keep track of the structure of the expression.

5.3. Scalars and the Scalar head

A monomial with no free indices is a scalar field, and it is often convenient to mark scalar fields as such. We do this using the head Scalar (which could be, but has not been, defined as an inert-head). The main property of a Scalar expression is that it hides the indices inside from the computations, so that xTensor` treats a Scalar expression as a block, like it would do with a truly elementary scalar field. For instance, dummy indices can be repeated across different Scalar expression in the same product.

To separate Scalar expressions use the function PutScalar (which is essentially a call to BreakInMonomials), and to remove the Scalar head use NoScalar. Sometimes Scalar expressions can be further subdivided, and this is achieved with the function BreakScalars.

The function ScalarQ detects scalars, that is expressions with no free indices (recall that only indices of types A and B can be free indices; blocked indices are never free indices). An expression with head Scalar is certainly a scalar, but constant-symbols, parameters or any other expression without free indices are also scalars. Similar functions, detecting expressions with just a single free index are UpVectorQ and DownVectorQ.

5.4. Inert heads

We call inert-head a symbol h such that h[expr] has the same tensorial character as expr (same indices with same characters, and same symmetries), even though h is not assumed to be linear in general. Such a symbol will be given type InertHead.

Inert-heads are defined with DefInertHead and undefined with UndefInertHead. There are two particular option at definition: LinearQ, which states whether the inert-head is linear or not (value stored as an upvalue for the function with same name), and ContractThrough, which gives a list of metrics (and/or delta) which can be contracted through the inert-head (value stored as an upvalue for the function ContractThroughQ). Additionally, we have the generic options for all DefType commands: ProtectNewSymbol, Info, Master and PrintAs.

The list of all currently defined inert-heads is stored in the global variable $InertHeads.

Any symbol defined as an inert-head is given a True upvalue for the function InertHeadQ, which is defined as False on any other input.

5.5. Scalar functions

In xTensor` there is a second way in which we can have tensors as arguments of functions: scalar functions of scalar arguments are allowed, and they must be registered before being used. Those functions will be called scalar-functions and their symbols will be given type ScalarFunction.

Scalar-functions are defined with DefScalarFunction and undefined with UndefScalarFunction. There are no particular options at definition time, apart from some of those generic for all DefType commands: ProtectNewSymbol, Info, Master and PrintAs (the latter one is currently not in use).

A second argument at definition time denotes the number of arguments of the scalar-function (default is 1). That number is stored as an upvalue for the function NumberOfArguments.

Scalar-functions cannot be master symbols (i.e. cannot have servants). They cannot have objects either.

The list of all currently defined scalar-functions is stored in the global variable $ScalarFunctions, which is initialized to {Exp,Log,Sin,Cos,Tan,Csc,Sec,Cot,Power,Factorial}.

Any symbol defined as a scalar-function is given a True upvalue for the function ScalarFunctionQ, which is defined as False on any other input.

There is no special formatting rules for scalar-functions.

The arguments of a scalar-function can be wrapped with the Scalar head, but in general this is not necessary.

5.6. Complex conjugation

xTensor` has its own complex-conjugation operator, called Dagger, to avoid overloading the Mathematica builtin Conjugate. All input expressions have a definite behaviour under the Dagger operation, and this is controlled using Dagger as an option in the DefType commands. Possible values are Real (usually the default), Complex, Imaginary, Hermitian and Antihermitian. Special definitions are introduced for the object being defined as specified by the value of that option. The function DaggerQ returns True on expr if Dagger[expr] is different from expr.

Indices can also carry information on the complex properties of the object they belong to. Conjugation of indices is performed by the function DaggerIndex. Tensors with equal numbers of indices on a vbundle and its conjugate can be Hermitian. Their conjugation properties are implemented through the function TransposeDagger.

Finally, by default the conjugated symbol to a given symbol (tensor or index) is formed by adding a character to the original symbol. This character is stored in the global variable $DaggerCharacter, and initially is the dagger character "†".

5.7. Validation

The function Validate checks the syntax of an expression in xTensor`. When doing a computation there are some checks but not many, to save time. In those cases in which the error can be localized in a particular subexpression of the whole expression, that subexpression is returned wrapped with the inert-head ERROR (printed in red in StandardForm).


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