Next topic: Symmetries of tensors

A core feature of any CAS is its ability to reduce arbitrary expression to some
standard form (**SF**) in which it is then used everywhere in manipulations. This
approach facilitates comparison and matching of expressions and gives a way for
more robust and fast algorithms for almost all CAS operations. Redberry uses the
same paradigm: any intermediate and resulting expression is guaranteed to be in the
**SF**.

The standard form of indexless expressions is same as in the majority of other CASs. Consider the following examples, which give an idea of **SF** in Redberry:

println '(a-b)+c+(b-a)'.t

> c

println 'c*(a-b)*(b-a)/c'.t

> -(a-b)**2

println '2/3-27**(1/3)/9'.t

> 1/3

println 'Sin[2 + 2.*I]**(1/4)'.t

> 1.38307 - 0.144188*IThe first example demonstrates that Redberry performs the reduction of similar terms. The second — that same (to within a sign) multipliers are collected into powers or reduced. Numbers are always collected and reduced if possible. If expression contains floating-point numbers, then it will be completely reduced (calculated). This behaviour is similar to the majority of “scalar” CASs and needs no more detailed explanation.

The additional conventions on standard form arise in expressions that contain
tensors. The most remarkable convention is on the **SF** of Sum. It is best to
demonstrate it by example:

println 'a*F_mn+(a+b)*F_mn'.t

> (2*a+b)*F_{mn}As one can see, Redberry tries to factor out tensorial and leave “scalar” (with zero sized Indices) parts of products; this is a general rule used by Redberry for bringing sums into standard form. Consider another example:

println '(x_a^a + y_b^b)*X_m*X_n + (z_a^a - y_d^d)*X_m*X_n'.t

> (x_{a}^{a}+z_{a}^{a})*X_{m}*X_{n}Here Redberry factored tensorial part

`X_m*X_n`

since both sums `(x_a^a+y_b^b)`

and `(z_n^n-y_d^d)`

have indices with zero size (because Indices of Sum are free indices of its summands):
println 'x_a^a + y_b^b'.t.indices.size()

> 0On the other hand, the following tensor will not be further reduced:

println 'x_a^a * X_m*X_n + y_a^a * X_m*X_n'.t

> x_a^a * X_m*X_n + y_a^a * X_m*X_nThis is because each multiplier of e.g.

`x_a^a * X_m*X_n`

(and in particular `x_a^a`

) has indices of nonzero size:
def ind = 'x_a^a'.t.indices //only free indices has zero size println [ind.size(), ind.free.size()]

> [2, 0]

Consider the last example:

println '(x_a^a + y_b^b)*X_m*X^m + (z_m^m - y_d^d)*X_a*X^a'.t

> (x_{a}^{a}+z_{a}^{a})*X^{m}*X_{m}Here Redberry factored the same tensorial part (

`X_m*X^m`

equals to `X_a*X^a`

) and collected similar terms in the formed Sum. One can also see that Redberry automatically relabelled conflicting dummy indices.
The important detail is ordering of summands and multipliers within sums and
products. Elements of sums and products are sorted by their 32 bit hash codes.
Hashes for simple tensors (e.g. `x`

or `k_p`

) are generated
randomly at each Redberry run, while hashes of complicated tensors (e.g.
`Sin[x]*k_i`

) are calculated according to certain complex
rules. Actually, hash functions are organised in such a way that they are “insensitive” for particular names of indices but “sensitive” for their contractions. So, renaming of dummy or free indices does not affect hash code, but any modification of structure of contractions (e.g. contraction of two
free indices) does.

Usage of the pseudorandom generator allows to obtain nearly
uniform distribution of hashes of tensors, which significantly improves the
performance. However, the ordering of expressions changes from run to run, and e.g.
product `a*b*c`

will be sorted differently at different runs
(`b*c*a`

or `b*a*c`

etc.). Of course, all similar expressions
will have similar ordering in current session. One can fix
the seed of pseudorandom generator inside, so that expressions will have same
ordering from run to run, by putting the following line in the beginning of the code:

import cc.redberry.core.context.CC import cc.redberry.groovy.Redberry use(Redberry) { CC.resetTensorNames(1) //your code here }

The reduction to **SF** is a light-weight operation which does not perform any time-consuming simplifications.

In contrast to many other open-source tensorial CASs, Redberry not uses so-called *indices canonicalisation* (sorting) approach. It uses another approach for the problem of tensors comparison and simplification, which will be discussed in more detail in Mappings of indices.

User can rely on the fact that inside any calculation all expressions are reduced to the **SF**. This fairly simplifies implementation of custom transformations and algorithms.