xAct`Invar`

Invar` is currently a package for efficient simplification of the algebraic and differential polynomial scalars (usually known as invariants) of the Riemann tensor of a metric-compatible connection. The medium term goal is generalizing Invar` to simplify generic polynomial expressions (with free indices) of the Riemann tensor.
Invar` requires the tensor computer algebra system xTensor` when running on Mathematica. There is a twin version for Maple, based on the tensor system Canon. It can be downloaded, under the General Public Licence, from
	http://www.xact.es/
	http://www.lncc.br/~portugal/		(Maple version)

For further information, see the articles
	 The Invar tensor package, J.M. Martín-García, R. Portugal and L.R.U. Manssur, Comp. Phys. Comm. 177, 640 (2007)
	 The Invar tensor package: Differential invariants of Riemann, J.M. Martín-García, D. Yllanes and R. Portugal, Comp. Phys. Comm. (2008)

Subsection 6.3 contains a number of tests designed to check most capabilities of Invar`. They all should give zero.

Invar` can be downloaded as part of the xAct distribution in
	http://www.xact.es/
For a single-user installation under Linux the file xAct_<version>.tar.gz must be unpacked in the directory $Home/.Mathematica/Applications giving a directory xAct. The Invar` package will be a subdirectory then. We assume that configuration in the following. See the Readme file for more information, including installation instructions for other operating systems.

We first load the Mathematica kernel, and the xTensor` package from the default directory

mathRAM=MemoryInUse[]

<<xAct`xTensor`

Note: When loading xTensor` inside a Windows environment, a black DOS-like window may appear. This is caused by the C link used to speed computations and should not be closed.

xtensorRAM=MemoryInUse[]-mathRAM

Then we read the Invar` package.

<<xAct`Invar`

We see that, in Mathematica 5, the MathKernel takes only 2 Mbytes, xTensor` takes 9 Mbytes, and Invar` takes 41 Mbytes:

invarRAM=MemoryInUse[]-mathRAM-xtensorRAM

Remove[mathRAM,xtensorRAM,invarRAM]

Note the structure of the ContextPath. There are six contexts: "xAct`Invar`", xAct`xTensor`, xAct`xPerm` and xAct`ExpressionManipulation` contain the respective reserved words. System` contains Mathematica's reserved words. The current context Global` will contain your definitions and right now it is empty.

$ContextPath

Context[]

?Global`*

This is a simple example of the use of Invar`. The package is very easy to use: all its capabilities can be controlled through 10 basic commands. In addition, you will have to setup a basic xTensor` session, which we proceed to do now. We need to start by defining the manifold and metric of the Riemann tensor. For information on xTensor` see the file xTensorDoc.nb.

Define a 4d manifold M:

DefManifold[M,4,{a,b,c,d,e,f,g,h,i,j,k,l,m,n}]

Define a metric with negative determinant, with associated Levi-Civita connection CD:

DefMetric[-1,metric[-a,-b],CD,{";","▽"},CurvatureRelations->False]

We included the option CurvatureRelations -> False so contractions of Riemanns will not be converted into Riccis. This is essential for the proper use of Invar, and in fact Invar automatically changes the default value for that option, so it was not really necessary to specify it in the latter command. A number of tensors have been automatically defined. In particular there are the three curvature tensor fields

RiemannCD[-a,-b,-c,-d]

RicciCD[-a,-b]

RicciScalarCD[]

and their traceless counterparts:

WeylCD[-a,-b,-c,-d]

TFRicciCD[-a,-b]

with their expected trace properties:

WeylCD[a,-b,-c,-a]

TFRicciCD[-a,a]

The Riemann and Ricci tensors are not automatically replaced when they have contracted indices. Use ContractCurvature to do that:

RiemannCD[a,-b,-c,-a]

ContractCurvature[%]

RicciCD[-b,b]

ContractCurvature[%]

We can change the output form of the tensors (note the use of Mathematica downvalues ^= )

PrintAs[metric]^="g";
PrintAs[epsilonmetric]^="ϵ";
PrintAs[RiemannCD]^="R";
PrintAs[RicciCD]^="R";
PrintAs[RicciScalarCD]^="R";
PrintAs[WeylCD]^="W";
PrintAs[TFRicciCD]^="S";

So much for xTensor`. You will not need many more xTensor` functions to work with Invar`, but you will be able to do it more efficiently if you read the specific documentation for that package. Now we can start using the commands added by the package Invar`:

A typical algebraic Riemann scalar could be

RiemannCD[a,b,-c,e]RiemannCD[-b,-e,-f,d]RiemannCD[c,f,-a,-d]

which simplifies to

RiemannSimplify[%]//Timing

Notice how the different rules are read on the fly. We do not read them automatically because they would need several GB of memory.  They are read only once (note the shorter timing now):

RiemannSimplify[%%]//Timing

The head Scalar is introduced to avoid problems of index collisions.It can be removed using NoScalar:

Last[%]//NoScalar

We can generate random Riemann invariants using the command RandomRiemannMonomial, having as argument the case (see Section 2), in this example {0,4}, meaning one Riemann with no derivatives and another with a fourth derivative:

expr=RandomRiemannMonomial[{0,4}]//NoScalar

Any monomial can be canonicalized into one of a predefined list of canonical invariants. For the case {0,4} the list contains 126 canonical invariants, apart from the trivial canonical 0.

MaxIndex[{0,4}]

In particular, the previous object canonicalizes to

RiemannToInv[expr]

Many of the invariants actually do canonicalize to 0 so we iterate those two commands until we get something different from zero:

inv=0;
While[inv===0,
expr=RandomRiemannMonomial[{0,4}]//NoScalar;
inv=RiemannToInv[expr];
Print[ScreenDollarIndices[expr]," -> ",inv]];

RiemannToInv[expr]

The canonical invariants can be expressed as a polynomial in a basis of indepent invariants, taking into account all the symmetries of the problem. This implies reading rules for additional `steps'

InvSimplify[%]

Finally this expression can be translated back into Riemann invariants.

InvToRiemann[%]

The whole process can be done in a single step using the command RiemannSimplify:

RiemannSimplify[expr]

This is the example expression shown in the first paper:

expr=epsilonmetric[a,b,c,d]RiemannCD[-a,-b,e,f]RiemannCD[-c,-e,-f,g]RiemannCD[-d,h,i,j]RicciCD[-g,-i]RicciCD[-h,-j]+1/8epsilonmetric[a,b,c,d]RiemannCD[-a,-b,e,f]RiemannCD[-c,-d,-e,-f]RiemannCD[g,h,i,j]RicciCD[-g,-i]RicciCD[-h,-j]

RiemannSimplify[expr] //Timing

And this is the example expression shown in the second paper:

expr=CD[-a]@CD[e]@RiemannCD[a,b,c,d]CD[i]@CD[h]@RiemannCD[-b,-e,f,g]CD[-h]@CD[-d]@RiemannCD[-c,-f,-g,-i]-1/8CD[-e]@CD[e]@RiemannCD[a,b,c,d]CD[i]@CD[h]@RiemannCD[-a,-b,f,g]CD[-h]@CD[-i]@RiemannCD[-c,-d,-f,-g]

RiemannSimplify[expr] //Timing

The Riemann tensor obeys two types of symmetries. The first type are permutation (or monoterm) symmetries, for example,
		(Subscript[R, bacd]) = -(Subscript[R, abcd])	and		(Subscript[R, cdab]) = (Subscript[R, abcd])	.
The second type is the cyclic (or multiterm) symmetry:
		(Subscript[R, abcd]) + (Subscript[R, acdb]) + (Subscript[R, adbc]) = 0 .
In order to simplify any polynomial of the Riemann tensor, it is necessary to use both kinds. It is possible to use efficient algorithms of computational group theory to manipulate the former, but there are no known efficient algorithms to manipulate the latter.
If we include covariant derivatives, we have to consider two new classes of relations. We have the Bianchi identity:
		(Subscript[R, ab[cd; e]])=0
and the effect of non commutatity of covariant derivatives:
		(Subscript[∇, d])(Subscript[∇, c])(Subscript[(T^((Subscript[a, 1])... (Subscript[a, n]))), (Subscript[b, 1])...(Subscript[b, n])]) - (Subscript[∇, c])(Subscript[∇, d])(Subscript[(T^((Subscript[a, 1])... (Subscript[a, n]))), (Subscript[b, 1])...(Subscript[b, m])]) =(∑_(k=1)^n)((Subscript[R, cde])^(Subscript[a, k]))(Subscript[(T^((Subscript[a, 1])...e...(Subscript[a, n]))), (Subscript[b, 1])...(Subscript[b, m])])-(∑_(k=1)^n)((Subscript[R, (Subscript[cdb, k])])^e)(Subscript[(T^((Subscript[a, 1])...(Subscript[a, n]))), (Subscript[b, 1])...e...(Subscript[b, m])])
An additional problem is that there are more identities to consider, coming from the fact that some of the polynomial invariants are zero in low-enough dimension. It is possible to show that all these dimension dependent identities are of Lovelock type, that is, they all come from the idea that, on a manifold of dimension dim, antisymmetrizing in dim + 1 indices gives zero. Unfortunately, these last three types of identities cannot be manipulated efficiently either.
The main idea behind Invar` is using the fast canonicalizers of xTensor` and Canon to deal with the permutation symmetries, and then using prestored files of solutions for the other types of identities.

The package is structured as follows:
	1. We shall work with two types of invariants:
		- (non-dual) invariants: fully contracted products of n Riemann tensors (where n will be called the degree of the invariant), possibly including covariant derivatives . 
		- dual invariants: fully contracted products of n Riemann tensors with or without derivatives and one epsilon tensor (n is again called the degree of the dual invariant). There is no need to work with more than one epsilon, because products of two epsilons can be converted into delta tensors. 
We shall separate the set of all monomial invariants of degree n in subsets (Subscript[ℛ, {(Subscript[λ, 1]), ... , (Subscript[λ, n])} ]), where (Subscript[λ, i])is the differentiation order of the i-th Riemann tensor, assuming the tensors have sorted such that (Subscript[λ, i])≤ (Subscript[λ, i+]). An n-tuple {(Subscript[λ, 1]), ..., (Subscript[λ, n])} will be referred to as a case, with the corresponding invariants having N = 4n +(∑_(i=1)^n) (Subscript[λ, i]) indices and order Λ = 2n + (∑_(i=1)^n)(Subscript[λ, i]). Λ is the number of derivatives of the metric, not to be confused with the total number of derivatives of the Riemann tensors (the sum of the (Subscript[λ, i])'s). Both N and Λ are always even numbers because we only consider scalar expressions. For example, an invariant of the case {0,1,3}, hence with N = 16 indices and order Λ = 10, is
		(Subscript[R, abcd])(Subscript[∇, e])(R^( ecfg))(∇^a)(Subscript[∇, f])(Subscript[∇, h])(Subscript[(R^( bdh)), g]).
	2. We shall distinguish six steps or levels of simplification:
		1.- Canonicalization with respect to permutation symmetries.
		2.- Canonicalization with respect to the cyclic symmetry.
		3.- Canonicalization with respect to the Bianchi symmetry.
		4.- Canonicalization with respect to commutation of derivatives.
		5.- Use of all possible dimensionally-dependent identities.
		6.- Conversion of invariants into products of two dual invariants (metric-signature dependent).
	3. Each Riemann monomial can be represented in one of three forms (examples will be given below):
		- As an explicit tensor expression.
		- As a permutation of the indices in canonical order.
		- As an expression RInv[metric][case, index] or DualRInv[metric][case, index] which represents the equivalent canonical monomial after canonicalization with respect to the permutation symmetries. The integer index identifies each particular invariant in the list of invariants, sorted according to some predefined ordering.
	4. Commands are given to change among those three representations, and to simplify the invariants up to some particular level. They are all listed below. Their mutual structure is schematically given by

<<Graphics`Arrow`

SetOptions[Arrow,HeadLength->0.02];
os=0.15;
Show[
Graphics[{Hue[0],Text["Riemann",{0,0}],Text["Perm",{1,0}],Text["Inv",{2,0}]}],
Graphics[{Text["RiemannToPerm",{0.5,0.15}],Text["PermToInv",{1.5,0.15}],Text["InvToPerm",{1.5,-0.16}],Text["PermToRiemann",{0.5,-0.16}]}],Graphics[{Arrow[{os,0.1},{1-os,0.1}],Arrow[{1+os,0.1},{2-os,0.1}],Arrow[{1-os,-0.1},{os,-0.1}],Arrow[{2-os,-0.1},{1+os,-0.1}]}],
Graphics[{Hue[0.55],Line[{{2+os,0.1},{2.4,0.1},{2.4,-0.1}}],Arrow[{2.4,-0.1},{2+os,-0.1}],Text["InvSimplify",{2.4,0.15}]}],
Graphics[{Hue[0.7],Line[{{os,0.3},{2.8,0.3},{2.8,-0.3}}],Arrow[{2.8,-0.3},{os,-0.3}],Text["RiemannSimplify",{2.2,0.35}]}],
PlotRange->{{-0.3,3},{-0.5,0.5}},AspectRatio->Automatic,ImageSize->400]

Invar` currently handles invariants up to and including Λ = 12, plus the single case {0, 0, 0, 0, 0, 0, 0} of order 14. The full list of cases can be generated with the following command,

InvarCases[]

This function admits two additional arguments. The first specifies the order

InvarCases[8]

and the second specifies the degree

InvarCases[8,3]

Canonical invariants

For a given case {(Subscript[λ, 1]), ..., (Subscript[λ, n])}, there will be N! different monomials, where N = 4n +(∑_(i=1)^n) (Subscript[λ, i]), as we saw in the previous section. It is obviously impossible to store them all.

Consider, for example, the numbers of possible permutations taking into acount only algebraic invariants, for wich the number of indices is N = 4n:

TableForm[Table[{n,(4n)!,N[(4n)!]},{n,7}],TableHeadings->{None,{"degree","number of monomials"}}]

We can, however, store the corresponding canonical invariants with respect to permutation symmetries. The numbers of canonical invariants for each case are stored in the functions MaxIndex and MaxDualIndex,

MaxIndex[{0,2,2}]

For example, the values up to order 10 are

MatrixForm[{InvarCases[][[Range[26]]], MaxIndex/@InvarCases[][[Range[26]]]}//Transpose]

MaxDualIndex/@InvarDualCases[]

Array[MaxDualIndex,{5}]

Within each case, the canonical invariants are labeled (Dual)RInv[metric][case, index], where index is an integer ranging from 1 to Max(Dual)Index[case]. Non dual invariants are output as (Subscript[I, case, index]), where case, for brevity and clarity, is not the list {(Subscript[λ, 1]), ..., (Subscript[λ, n])}, but simply the concatenation of its elements (Subscript[λ, 1])(Subscript[λ, 2])...(Subscript[λ, n]). Notice that there is no confusion because the (Subscript[λ, i])are always single digit integers, except for the case {10}, but even then there is no problem, because we always write the (Subscript[λ, i]) in increasing order. Dual invariants are represented by (Subscript[D, case, index]).

Examples:

RInv[metric][{10},100]+RInv[metric][{0,1,3},1]

RInv[metric][{0,1,2},12]-DualRInv[metric][{0,0,0},1]

As we apply more symmetries, the lists of independent (Dual)RInvs get smaller. We can produce the independent invariant at each simplification step with the command (Dual)RInvs[metric][step, case]. The first step produces a list of length MaxIndex[case]

RInvs[metric][1,{2,2}]

RInv[metric][{2},#]&/@Range[MaxIndex[{2,2}]]

After applying the cyclic identity we get

RInvs[metric][2,{2,2}]

After the Bianchi identity

RInvs[metric][3,{2,2}]

After reordering derivatives

RInvs[metric][4,{2,2}]

After the dimensionally dependent identities

RInvs[metric][5,{2,2}]

In this case there are no signature dependent relations (= relations arising from products of dual invariants)

RInvs[metric][6,{2,2}]

The following table reproduces the one in the paper listing the numbers of invariants after each step for all cases up to order 10

Table[Length[RInvs[step,InvarCases[][[case]]]],{step,6},{case,26}];

Transpose[Join[{InvarCases[][[Range[26]]]},%]]//MatrixForm

The simplified notation RInvs[metric][step, n] is automatically translated into RInvs[metric][step, {0, (Overscript[..., n]), 0}], for backwards compatibility with Invar 1.  For instance, these are all the algebraic invariants after step 3 with degree 6 (case {0,0,0,0,0,0}):

RInvs[metric][3,6]

Similar shorthands are available for other commands, such as MaxIndex or RInv

{MaxIndex[7], MaxIndex[{0,0,0,0,0,0,0}]}

RInv[metric][4,1]

DualRInvs[2,4]

If we restrict ourselves to algebraic invariants we can give a basis of only 25 invariants (notice that there is no step 6 for dual invariants)

Flatten[Join[RInvs[metric][6,#]&/@Range[7],DualRInvs[metric][5,#]&/@Range[5]]]

Transpose[{%,InvToRiemann[%,False]}]//TableForm

From invariants to Riemann expressions.

Given an invariant, it is possible to know the permutation it represents using InvToPerm. The result is returned using the head RPerm, which stands for permutation of Riemann invariant.

This is a typical example of a canonical invariant:

rinv=7RInv[metric][{0,4},100]

dualrinv=3DualRInv[metric][{0,0,2},1]

And this is the permutation it represents. It is given in cyclic form. The first list identifies the case and whether it contains an epsilon ({case, 1}) or not ({case, 0})

rperm=InvToPerm[rinv]

dperm=InvToPerm[dualrinv]

The command also works with polynomials, giving one RPerm for each monomial

InvToPerm[rinv+dualrinv]

Any permutation of N indices can be converted into a Riemann monomial of the appropiate case with the function PermToRiemann. There is a second argument to specify whether we want the contracted Riemann tensors to be automatically transformed into Ricci or not.

The default value of the argument for conversion into Ricci is stored in the global variable

$CurvatureRelations

rinv2 = RInv[metric][{0,0},1]

rperm2=InvToPerm[rinv2]

If we set that variable to True, we get a product of Ricci tensors:

PermToRiemann[rperm2,True]

If we set that argument to False or use the default, no Riccis appear

PermToRiemann[rperm2,False]

PermToRiemann[rperm2]

There is a simple function which combines the action of the previous two. It also has a second argument:

In a single line:

InvToRiemann[RInv[metric][{0,0,0,0,0,0,0},1000]]

It is possible to give a list of invariants:

RInvs[metric][5,{0,0,2}]

Map[InvToRiemann,%]

Transpose[{%%,%}]//TableForm

With contracted Riemanns substituted by Riccis,

RInvs[metric][5,{0,0,2}]

Map[InvToRiemann[#,True]&,%]

Transpose[{%%,%}]//TableForm

Note that we have got a minus sign. This is because the invariants are sorted with respect to their Riemann-only expression:

From Riemann expressions to invariants.

The function RiemannToPerm converts all Riemann scalars of a given metric (or list of metrics) into their canonical permutations:

Suppose we start from this simple expression:

rexpr=RiemannCD[a,b,c,d]RiemannCD[-a,-b,-c,-d]+6RiemannCD[e,f,-c,-d]RiemannCD[-a,-b,-e,-f]epsilonmetric[a,b,c,d]

Then we can transform all terms into their canonical permutations,

rperm=RiemannToPerm[rexpr]

that is, not the permutations which would regenerate the previous objects:

PermToRiemann[rperm]

This function uses the stored tables of results to identify the index corresponding to a given canonical permutation.

Example:

PermToInv[rperm]

This function only works with canonical permutations:

InvToPerm[RInv[metric][{0,2},3]]

PermToInv[%]

We rewrite the cycles in a different form

RPerm[metric][{{0,2},0},xAct`xPerm`Cycles[{3,2},{4,5},{6,7,8,9}]]

but now PermToInv does not work, because the new permutation is not canonical

PermToInv[%]

Combined function:

Simple example:

RiemannToInv[rexpr]

Once we have converted any Riemann expression into invariants with heads RInv and DualRInv, then we can "simplify" the expression by using the multiterm symmetries described above (steps 2, 3 and 4 of the simplification process). We use quotes because in many cases a single monomial is expanded into a large polynomial, its canonical form in the basis we have chosen, and this can be hardly called simplification. However, if an expression is equivalent to zero, the function InvSimplify will find it.

Example:

rinv=RInv[metric][{0,0,0,0,0},100]

At level 1 nothing happens:

InvSimplify[rinv,1]

At level 2 the cyclic identity is used. Note that the degree does not change, but the indexes of the invariants decrease:

InvSimplify[rinv,2]

We skip levels 3 and 4 becasue there are no derivatives in this example. At level 5 we use dimensionally dependent identities for dimension 4:

InvSimplify[rinv,5]//Expand

At level 6 we use signature dependent identities expressing RInv[{0,0,0,0}, 21] in terms of DualRInv[{0,0}, 2] squared:

InvSimplify[rinv,6]//Expand

Another example, with derivatives and involving dual relations

diffrinv=RInv[metric][{0,0,1,1},800]

InvSimplify[diffrinv,2]

InvSimplify[diffrinv,3]

InvSimplify[diffrinv,4]

InvSimplify[diffrinv,5]

InvSimplify[diffrinv,6]

Simplification of a dual invariant

dualrinv=DualRInv[metric][{1,3},3]

InvSimplify[dualrinv,2]

InvSimplify[dualrinv,3]

InvSimplify[dualrinv,4]

By default, InvSimplify applies the first 6 steps. This behaviour can be changed with the following global variable

$InvSimplifyLevel=5

InvSimplify[rinv]

$InvSimplifyLevel=2

InvSimplify[rinv]

We return to the default value

$InvSimplifyLevel=6

Covariant derivatives commute when acting on scalars, which would in principle give an extra permutation symmetry. This symmetry is, however, not applied at step 1, but at step 4, along with the general rules for reordering of derivatives. For example, the following two invariants are obviously equal

InvToRiemann[RInv[metric][{4},2]]

InvToRiemann[RInv[metric][{4},3]]

Nevertheless, they are considered different objects until step 4

InvSimplify[RInv[metric][{4},2]-RInv[metric][{4},3],3]

InvSimplify[RInv[metric][{4},2]-RInv[metric][{4},3],4]

This function combines most of the functionalities of Invar` and it is certainly the most important tool for the user. Essentially RiemannSimplify is equivalent to the process:
	rexpr -> (RiemannToInv) -> rinv -> (InvSimplify) -> canon rinv -> (InvToRiemann) -> canon rexpr
This means that RiemannSimplify requires three additional arguments:
	- a metric for RiemannToInv
	- a simplification level for InvSimplify
	- the curvature-relations switch to Ricci.
All three of them have default values, so that the function can be used with a single argument.

Example:

rexpr=RandomRiemannMonomial[{0,2,2}]

RiemannSimplify[%]

?RiemannSimplify

RiemannSimplify[RandomRiemannMonomial[{6}],4,True,metric]

This is a collection of 54 examples, all of which must return 0.

First we add several indices:

AddIndices[TangentM,{a1,a10,a11,a2,a20,a22,a3,a30,a4,a40,a5,a50,a6,a60,a7,a8,a9,b0,i1,i10,i11,i2,i20,i22,i3,i30,i4,i40,i5,i50,i6,i60,i7,i8,i9}]

Shortcuts:

inv=RInv[metric];
dinv=DualRInv[metric];

Test of RiemannToInv and InvToRiemann:

test[1]=CD[-h]@CD[-a]@RiemannCD[a,b,c,d]RiemannCD[-b,-d,e,f]CD[-g]@CD[-c]@RiemannCD[-e,-f,g,h]+inv[{0,2,2},1157];
test[2]=RiemannCD[-a,e,f,g]RiemannCD[a,b,c,d]RiemannCD[h,i,j,k]CD[-d][RiemannCD[-h,-i,-j,-k]]CD[-e][RiemannCD[-b,-c,-f,-g]]-inv[{0,0,0,1,1},27015];
test[3]=RiemannCD[a,b,c,d]CD[-h]@CD[-g]@CD[-c]@CD[h]@CD[-f]@CD[-e]@CD[-d]@CD[g][RiemannCD[-a,e,-b,f]]+inv[{0,8},20018];
test[4]=epsilonmetric[-b,-d,-g,-h]CD[-c]@CD[-a]@CD[-f][RiemannCD[g,f,-e,h]]CD[e][RiemannCD[a,b,c,d]]-dinv[{1,3},914];

NoScalar/@InvToRiemann/@Array[test,4]//ToCanonical

RiemannToInv/@Array[test,4]

More tests of RiemannToInv, with algebraic invariants:

test[5]:=inv[7,306]-RiemannCD[a2,i1,-a2,i2]*RiemannCD[-i1,i3,-i3,i4]*RiemannCD[-i2,i5,i6,i7]*RiemannCD[-i4,i8,i9,i10]*RiemannCD[-i5,a1,-i8,-a1]*RiemannCD[-i6,a4,-i9,a3]*RiemannCD[-i7,-a4,-i10,-a3];
test[6]:=inv[1,1]*dinv[2,1]-(RiemannCD[i11,i22,-i11,-i22])*(RiemannCD[i1,i2,-i1,i3]*RiemannCD[-i2,i4,i5,i6]*epsilonmetric[-i3,-i4,-i5,-i6]);
test[7]:=inv[3,3]*dinv[5,2]-(RiemannCD[b,i20,-b,i30]*RiemannCD[-i20,i40,i50,i60]*RiemannCD[-i30,-i40,-i50,-i60])*(RiemannCD[a2,i1,-a2,i2]*RiemannCD[-i1,i3,-i3,i4]*RiemannCD[-i2,i5,-i5,i6]*RiemannCD[-i4,i7,i8,i9]*RiemannCD[-i7,i10,-i10,a1]*epsilonmetric[-i6,-i8,-i9,-a1]);
test[8]:=inv[6,137]+2*dinv[5,289]-RiemannCD[a2,i1,-a2,i2]*RiemannCD[-i1,i3,-i3,i4]*RiemannCD[-i2,i5,i6,i7]*RiemannCD[-i4,i8,-i6,i9]*RiemannCD[-i5,-i8,i10,a1]*RiemannCD[-i7,-i10,-i9,-a1]-2*(RiemannCD[a2,i1,-a2,i2]*RiemannCD[-i1,i3,i4,i5]*RiemannCD[-i2,i6,-i4,i7]*RiemannCD[-i3,i8,-i7,i9]*RiemannCD[-i8,i10,-i10,a1]*epsilonmetric[-i5,-i6,-i9,-a1]);

RiemannToInv/@Array[test,4,5]//AbsoluteTiming

In this case we need to guide the computation due to the products of epsilon tensors:

test[9]:=dinv[2,3]^2-(RiemannCD[a1,a2,a4,a3]*RiemannCD[-a1,-a4,a6,a5]*epsilonmetric[-a2,-a3,-a6,-a5])*(RiemannCD[a10,a20,a40,a30]*RiemannCD[-a10,-a40,a60,a50]*epsilonmetric[-a20,-a30,-a60,-a50]);

test[9]//ExpandGdelta//ContractMetric//RiemannToInv//InvSimplify//Simplify

Tests of RiemannSimplify:

test[10]:=epsilonmetric[a,b,c,d]*RiemannCD[-a,-b,e,f]*RiemannCD[-c,-e,-f,g]*RiemannCD[-d,h,i,j]*RicciCD[-g,-i]*RicciCD[-h,-j]+1/8*(epsilonmetric[a,b,c,d]*RiemannCD[-a,-b,e,f]*RiemannCD[-c,-d,-e,-f])*(RiemannCD[g,h,i,j]*RicciCD[-g,-i]*RicciCD[-h,-j]);
test[11]:=RiemannCD[a1,a2,-a1,a3]*RiemannCD[-a2,a4,-a3,a5]*RiemannCD[-a4,a6,a7,a8]*epsilonmetric[-a5,-a6,-a7,-a8];
test[12]:=RiemannCD[a1,a2,a3,-a1]*RiemannCD[-a3,a5,-a2,a4]*RiemannCD[-a4,a6,a8,a7]*epsilonmetric[-a5,-a7,-a8,-a6];
test[13]:=RiemannCD[a1,a2,-a1,a3]*RiemannCD[-a2,a4,a5,a6]*RiemannCD[-a3,-a4,a7,a8]*RiemannCD[-a5,b0,-b0,a9]*epsilonmetric[-a6,-a7,-a8,-a9]+1/2*RiemannCD[a11,a22,-a11,-a22]*RiemannCD[a1,a2,-a1,a3]*RiemannCD[-a2,a4,a5,a6]*RiemannCD[-a4,a7,-a7,a8]*epsilonmetric[-a3,-a5,-a6,-a8]-1/16*RiemannCD[a10,a20,-a10,-a20]*RiemannCD[a11,a22,-a11,-a22]*RiemannCD[a1,a2,a3,a4]*RiemannCD[-a1,-a2,a5,a6]*epsilonmetric[-a3,-a4,-a5,-a6];test[14]:=-RicciCD[-a2,a3]*RicciCD[a5,a2]*RiemannCD[-a3,a6,a7,a8]*RiemannCD[-a5,-a7,-a6,b0]*RicciCD[-a8,-b0]+5/24*RicciScalarCD[]^5+49/24*RicciScalarCD[]^2*RicciCD[a3,-a2]*RicciCD[a2,a5]*RicciCD[-a5,-a3]+RicciCD[a2,a3]*RiemannCD[-a2,a4,-a3,a5]*RiemannCD[-a4,a6,-a5,a7]*RicciCD[-a6,b0]*RicciCD[-a7,-b0]+1/24*RicciScalarCD[]^3*RiemannCD[a1,a2,a3,a4]*RiemannCD[-a1,-a2,-a3,-a4]-5/4*RicciScalarCD[]*RicciCD[a2,a3]*RicciCD[-a2,a5]*RicciCD[-a3,a7]*RicciCD[-a5,-a7]+3/4*RicciScalarCD[]^2*RicciCD[a2,a3]*RiemannCD[-a2,a4,-a3,a5]*RicciCD[-a4,-a5]-13/8*RicciScalarCD[]^3*RicciCD[a2,a3]*RicciCD[-a2,-a3]-1/2*RicciScalarCD[]*RicciCD[a2,-a3]*RiemannCD[-a2,a4,a5,a6]*RiemannCD[a7,a3,-a6,-a5]*RicciCD[-a4,-a7]-1/24*RiemannCD[a3,a4,a1,a2]*RiemannCD[-a1,-a2,-a3,-a4]*RicciCD[a20,a30]*RicciCD[-a20,a50]*RicciCD[-a30,-a50]+5/8*RicciScalarCD[]*RicciCD[a2,a3]*RicciCD[-a2,-a3]*RicciCD[a20,a30]*RicciCD[-a20,-a30];

RiemannSimplify/@Array[test,5,10]//AbsoluteTiming

Tests of the cyclic symmetries:

test[15]:=inv[2,3]-1/2*inv[2,2]-inv[3,6]+1/2*inv[3,5];
test[16]:=-inv[4,38]+1/4*inv[4,23]-inv[4,26]+inv[4,36];
test[17]:=inv[6,31]-inv[5,203]-inv[5,200]+inv[5,201]-1/4*inv[6,27];
test[18]:=-inv[6,1575]+3/4*inv[6,1219]+1/2*inv[6,1223]+inv[6,1572]-3/2*inv[6,1221];
test[19]:=inv[7,15138]-1/2*inv[7,12749]-inv[6,1524]+inv[6,1523]-1/2*inv[6,1161];
test[20]:=-inv[7,16207]-1/4*inv[7,12848]+inv[7,16206];
test[21]:=-inv[7,16467]-inv[7,16383]-4*inv[7,16269]-inv[7,16280]-inv[7,16306]-
3*inv[7,16262]+3*inv[7,16281]+4*inv[7,16263]+inv[7,16265]+inv[7,16268]-3*inv[7,16318]-inv[7,16325]+2*inv[7,16292]-2*inv[7,16341];
test[22]:=dinv[2,1]+dinv[3,1];
test[23]:=-dinv[3,27]-1/4*dinv[3,14]+1/2*dinv[3,23]+dinv[4,1]-dinv[4,3]+1/2*dinv[4,2]-7*dinv[4,9]+dinv[4,11]-1/2*dinv[4,10];
test[24]:=dinv[4,231]+dinv[4,232]+dinv[5,1]+dinv[5,3]-1/2*dinv[5,2]+10*dinv[5,8]+dinv[5,9]-dinv[5,10];
test[25]:=-dinv[5,2560]+2*dinv[5,2505]-dinv[5,2507]-dinv[5,2551];

$InvSimplifyLevel=2;

InvSimplify/@Array[test,11,15]//AbsoluteTiming

test[26]=inv[{1,1,4},15073]+inv[{1,1,4},15063]/4-inv[{1,1,4},15072];
test[27]=dinv[{1,3},914]-dinv[{1,3},908]/4;
test[28]=inv[{0,0,0,1,1},27015]+2inv[{0,0,0,1,1},26365];
test[29]=inv[{8},1116]+inv[{8},1092]-inv[{8},1115];

InvSimplify/@Array[test,4,26]

Tests of the Bianchi relations:

test[30]=inv[{1,1,4},15072]-inv[{1,1,4},1750]+inv[{1,1,4},1751]-2inv[{1,1,4},1753]-inv[{1,1,4},1754];
test[31]=dinv[{1,3},908]+4dinv[{1,3},328]-4dinv[{1,3},332];
test[32]=inv[{0,0,0,1,1},26365]+4inv[{0,0,0,1,1},26327]-4inv[{0,0,0,1,1},26335];
test[33]=inv[{8},1092]+inv[{8},1090]-inv[{8},1091];

$InvSimplifyLevel=3;

InvSimplify/@Array[test,4,30]

Tests of the commutation relations:

test[34]=inv[{0,0,4},70]-inv[{0,0,0,2},50]-inv[{0,0,1,1},100];
test[35]=-inv[{0,0,4},74]+2inv[{0,0,4},18]-2inv[{0,0,4},19]+4inv[{0,0,1,1},71]-4inv[{0,0,1,1},251]-4inv[{0,0,1,1},264]+4inv[{0,0,1,1},267]-2inv[{0,0,0,2},5]+4inv[{0,0,0,2},6]-2inv[{0,0,0,2},8]-2inv[{0,0,0,2},12]-4inv[{0,0,0,2},31]+8inv[{0,0,0,2},32]-4inv[{0,0,0,2},34]+8inv[{0,0,0,2},35]+8inv[{0,0,0,2},37]-4inv[{0,0,0,2},41]-4inv[{0,0,0,2},42]+4inv[{0,0,0,0,0},2]+10inv[{0,0,0,0,0},6]+4inv[{0,0,0,0,0},8]-4inv[{0,0,0,0,0},9]+8inv[{0,0,0,0,0},11]+6inv[{0,0,0,0,0},12]+4inv[{0,0,0,0,0},25]+4inv[{0,0,0,0,0},27]+8inv[{0,0,0,0,0},31]+8inv[{0,0,0,0,0},33]+8inv[{0,0,0,0,0},35]-8inv[{0,0,0,0,0},36]-8inv[{0,0,0,0,0},38]-8inv[{0,0,0,0,0},43]-8inv[{0,0,0,0,0},45];
test[36]=-dinv[{1,3},11]+dinv[{1,3},10]+dinv[{0,1,1},2]-dinv[{0,1,1},4]-2dinv[{0,1,1},6]+dinv[{0,1,1},88]-2dinv[{0,1,1},89];
test[37]=dinv[{1,3},5]-dinv[{0,1,1},1]-dinv[{0,1,1},18]/2;

$InvSimplifyLevel=4;

InvSimplify/@Array[test,4,34]

Tests of the dimension dependent relations:

test[38]:=-inv[3,3]+1/4*inv[1,1]^3-2*inv[3,1]+1/4*inv[1,1]*inv[2,2]+2*inv[3,2]-2*inv[1,1]*inv[2,1];
test[39]:=-inv[4,36]-4/3*inv[1,1]*inv[3,1]-1/4*inv[2,1]*inv[2,2]-3*inv[4,1]+4*inv[4,7]+inv[4,5]-1/4*inv[4,21]+3/4*inv[1,1]^2*inv[2,1]-3*inv[1,1]*inv[3,2]+1/4*inv[1,1]*inv[3,5]-1/12*inv[1,1]^4-1/8*inv[1,1]^2*inv[2,2]+1/8*inv[2,2]^2-inv[5,1]+1/24*inv[1,1]^5-5/6*inv[1,1]^2*inv[3,1]+5/8*inv[1,1]*inv[2,1]^2-5/4*inv[1,1]*inv[4,1]-5/12*inv[1,1]^3*inv[2,1]+5/6*inv[2,1]*inv[3,1];
test[40]:=-inv[6,108]-31/24*inv[1,1]^3*inv[3,1]-11/16*inv[1,1]^4*inv[2,1]+1/12*inv[1,1]^6-7/8*inv[1,1]^2*inv[4,1]+7/16*inv[1,1]^2*inv[2,1]^2+1/8*inv[1,1]^3*inv[3,2]-inv[1,1]*inv[5,2]+1/2*inv[6,47]+inv[6,13]+inv[3,1]^2-inv[3,1]*inv[3,2]+1/8*inv[3,1]*inv[3,5]+1/4*inv[1,1]*inv[2,1]*inv[3,2]+3/2*inv[1,1]*inv[2,1]*inv[3,1]-1/8*inv[1,1]*inv[2,2]*inv[3,1];
test[41]:=-inv[7,7490]+1/64*inv[1,1]*inv[2,2]*inv[4,21]+1/2*inv[7,2190]-3/8*inv[1,1]*inv[2,2]*inv[4,1]+1/12*inv[2,1]*inv[2,2]*inv[3,1]-23/48*inv[1,1]^2*inv[2,2]*inv[3,1]+3/8*inv[1,1]*inv[2,1]^2*inv[2,2]-31/96*inv[1,1]^3*inv[2,1]*inv[2,2]-1/2*inv[1,1]*inv[2,1]*inv[4,1]-11/12*inv[1,1]^2*inv[2,1]*inv[3,1]-1/16*inv[1,1]*inv[2,1]*inv[2,2]^2-2*inv[7,14]+1/192*inv[1,1]^3*inv[2,2]^2+5/12*inv[1,1]^3*inv[4,1]-1/3*inv[3,1]*inv[4,1]-11/288*inv[1,1]^7-25/48*inv[1,1]^3*inv[2,1]^2+35/96*inv[1,1]^5*inv[2,1]+79/144*inv[1,1]^4*inv[3,1]+1/6*inv[2,1]^2*inv[3,1]-4/9*inv[1,1]*inv[3,1]^2+7/192*inv[1,1]^5*inv[2,2]-1/24*inv[2,2]^2*inv[3,1]-2*inv[7,55]-1/192*inv[1,1]^3*inv[4,21]-2*inv[1,1]*inv[6,47]-3/4*inv[1,1]^2*inv[5,33]+1/2*inv[3,2]*inv[4,1]-1/6*inv[1,1]^4*inv[3,2]-1/4*inv[2,1]^2*inv[3,2]+1/4*inv[1,1]^2*inv[5,2]-1/3*inv[3,1]*inv[4,5]+1/6*inv[1,1]^3*inv[4,5]-3/4*inv[1,1]^2*inv[5,8]+1/24*inv[3,1]*inv[4,21]-3/4*inv[2,2]*inv[5,2]-1/2*inv[1,1]*inv[2,1]*inv[4,5]+5/6*inv[1,1]*inv[3,1]*inv[3,2]+1/2*inv[1,1]^2*inv[2,1]*inv[3,2]+1/16*inv[1,1]^2*inv[2,2]*inv[3,2]+1/4*inv[2,2]*inv[5,8]+1/16*inv[2,2]^2*inv[3,2]-2*inv[1,1]*inv[6,13]+inv[2,1]*inv[5,2]+1/4*inv[2,2]*inv[5,33];
test[42]:=-dinv[3,23]+1/2*dinv[3,13]+dinv[3,2]-3/8*inv[1,1]*dinv[2,2]-dinv[4,2]-1/2*inv[1,1]*dinv[3,2];
test[43]:=-dinv[5,1770]+5/32*inv[1,1]^3*dinv[2,2]-9/8*inv[1,1]*inv[2,1]*dinv[2,2]+3/32*inv[1,1]*inv[2,2]*dinv[2,2]-inv[3,1]*dinv[2,2]+3/4*inv[3,2]*dinv[2,2]-1/16*inv[3,5]*dinv[2,2]-dinv[5,1404]-1/8*inv[2,2]*dinv[3,13];

$InvSimplifyLevel=5;

InvSimplify/@Array[test,6,38]//AbsoluteTiming

test[44]=-inv[{1,2,3},5861]+inv[{1,2,3},7]/8+inv[{1,2,3},49]/4+inv[{1,2,3},380]/2-inv[{1,2,3},392]/2-inv[{1,2,3},474]/2+inv[{1,2,3},480]/2-inv[{1,2,3},625]/2+inv[{1,2,3},631]/2+inv[{1,2,3},1356]-2inv[{1,2,3},1362]+inv[{1,2,3},1380]-inv[{1,2,3},1416]+inv[{1,2,3},1422]-inv[{1,2,3},2229]/2+inv[{1,2,3},2626]/2-2inv[{1,2,3},4985]-inv[{1,2,3},5804]+inv[{1,2,3},5816]+inv[{1,2,3},5837];
test[45]=dinv[{0,0,2},95]+dinv[{0,0},2]inv[{2},1]/4;
test[46]=-inv[{0,3,3},3901]+inv[{0},1]inv[{3,3},7]/8-inv[{0},1]inv[{3,3},150]/2+inv[{0},1]inv[{3,3},155]/2-inv[{0,3,3},14]/4-inv[{0,3,3},101]-inv[{0,3,3},111]-2inv[{0,3,3},585]+inv[{0,3,3},590]+2inv[{0,3,3},602]+inv[{0,3,3},718]+inv[{0,3,3},1144]+inv[{0,3,3},3567]-2inv[{0,3,3},3572]+2inv[{0,3,3},3875];
test[47]=dinv[{0,1,1},4]+dinv[{0,1,1},1]/2+dinv[{0,1,1},2]-dinv[{0,1,1},3];

InvSimplify/@Array[test,4,44]

Test of the signature dependent relations:

test[48]:=-inv[5,123]-5*dinv[2,2]*dinv[3,2]/24-5*dinv[2,2]*dinv[3,13]/48-2*inv[1,1]^5/3+25*inv[1,1]^3*inv[2,1]/6+15*inv[1,1]*inv[2,1]^2/2-5*inv[1,1]*inv[2,1]*inv[2,2]/2+15*inv[1,1]^2*inv[3,1]/2+10*inv[2,1]*inv[3,1]/3-5*inv[2,2]*inv[3,1]/6-5*inv[1,1]^2*inv[3,2]/2-10*inv[2,1]*inv[3,2]+5*inv[2,2]*inv[3,2]/2+5*inv[1,1]^2*inv[3,5]/12-5*inv[2,1]*inv[3,5]/6+5*inv[2,2]*inv[3,5]/12+5*inv[1,1]*inv[4,1]+20*inv[5,8]+20*inv[5,33];

$InvSimplifyLevel=6;

test[48]//InvSimplify

test[49]=-inv[{1,1,1,1},53]-dinv[{1,1},1]^2/4-inv[{1,1},1]^2/64+3inv[{1,1},1]inv[{1,1},4]/8-5inv[{1,1},4]^2/4-3inv[{1,1},1]inv[{1,1},5]/8+5inv[{1,1},4]inv[{1,1},5]/2-5inv[{1,1},5]^2/4-inv[{1,1,1,1},3]/4+inv[{1,1,1,1},5]/4+inv[{1,1,1,1},12]-inv[{1,1,1,1},14]-inv[{1,1,1,1},15]-inv[{1,1,1,1},16]+inv[{1,1,1,1},20]-2inv[{1,1,1,1},22]-inv[{1,1,1,1},23]-3inv[{1,1,1,1},38]+2inv[{1,1,1,1},39]+2inv[{1,1,1,1},40]+6inv[{1,1,1,1},41]-4inv[{1,1,1,1},42]-inv[{1,1,1,1},43]-inv[{1,1,1,1},44]+inv[{1,1,1,1},45]/2+3inv[{1,1,1,1},46]/2;
test[50]=inv[{0,0,1,1},1104]-dinv[{0,0},2]dinv[{1,1},25]/4-inv[{0,0,1,1},1098]/2;
test[51]=-inv[{0,0,1,3},25986]+dinv[{0,0},2]dinv[{1,3},294]/8+dinv[{0,0},2]dinv[{0,1,1},1]/8+dinv[{0,0},2]dinv[{0,1,1},2]/4+3dinv[{0,0},2]dinv[{0,1,1},18]/32+dinv[{0,0},2]dinv[{0,1,1},63]/8-dinv[{0,0},2]dinv[{0,1,1},86]/2+5dinv[{0,0},2]dinv[{0,1,1},87]/8+dinv[{0,0},2]dinv[{0,1,1},97]/16+dinv[{0,0},2]dinv[{0,1,1},117]/32+3dinv[{0,0},2]dinv[{0,1,1},271]/16-dinv[{0,0},2]dinv[{1,1},1]inv[{0},1]/16+inv[{0,0,1,3},25974]/2;
test[52]=-inv[{0,0,2,2},5470]-dinv[{0,0},2]dinv[{2,2},19]/8-dinv[{0,0},2]dinv[{0,0,2},2]/4+dinv[{0,0},2]dinv[{0,0,2},5]/16-dinv[{0,0},2]dinv[{0,0,2},14]/16+dinv[{0,0},2]dinv[{0,0,2},32]/4-dinv[{0,0},2]dinv[{0,2},15]inv[{0},1]/16+dinv[{0,0},2]dinv[{0,0,0},2]inv[{0},1]/16-dinv[{0,0},2]^2inv[{0},1]^2/128+dinv[{0,0},2]^2inv[{0,0},1]/32-inv[{0,0,2,2},5461]+inv[{0,0,2,2},5466];

InvSimplify/@Array[test,4,49]

Test of WeylToRiemann:

test[53]:=WeylCD[a,b,c,d]-RiemannCD[a,b,c,d]-1/2*metric[a,d]*RicciCD[b,c]-1/2*metric[b,c]*RicciCD[a,d]+1/2*metric[a,c]*RicciCD[b,d]+1/2*metric[b,d]*RicciCD[a,c]-1/6*RicciScalarCD[]*(metric[a,c]*metric[b,d]-metric[a,d]*metric[b,c]);

test[53]//WeylToRiemann//Simplify//AbsoluteTiming

Test of ContractCurvature:

test[54]:=RiemannCD[c,d,-c,-d]*RiemannCD[a,f,b,-f]*RiemannCD[-a,-b,h,l]*metric[-h,-l]-RicciScalarCD[]*RicciCD[a,b]*RiemannCD[-a,-b,h,l]*metric[-h,-l];

test[54]//ContractCurvature//ContractMetric//AbsoluteTiming

Tidy up:

RemoveIndices[TangentM,{a1,a10,a11,a2,a20,a22,a3,a30,a4,a40,a5,a50,a6,a60,a7,a8,a9,b0,i1,i10,i11,i2,i20,i22,i3,i30,i4,i40,i5,i50,i6,i60,i7,i8,i9}];
Remove[test]

Surprisingly, there are monomials of the Riemann tensor which are zero due to the cyclic symmetry only. This first happens for a single monomial of degree 6:

It does not happen for degrees 1 to 5:

Cases[RInvRules[2,1],HoldPattern[_->0]]

Cases[RInvRules[2,2],HoldPattern[_->0]]

Cases[RInvRules[2,3],HoldPattern[_->0]]

Cases[RInvRules[2,4],HoldPattern[_->0]]

Cases[RInvRules[2,5],HoldPattern[_->0]]

There is a single case in degree 6:

Cases[RInvRules[2,6],HoldPattern[_->0]]

And 19 more cases for degree 7:

Cases[RInvRules[2,7],HoldPattern[_->0]]

There is no obvious reason why this should be zero, and  for all dimensions:

RInv[metric][6,1461]//InvToRiemann//NoScalar

but we can check it in the pure Ricci case:

expr=%/.RiemannCD[a_,b_,c_,d_]->RicciCD[a,c]delta[b,d]+delta[a,c]RicciCD[b,d]-RicciCD[a,d]delta[b,c]-delta[a,d]RicciCD[b,c]

expr[[1]]expr[[2]]//ContractMetric//ToCanonical

%expr[[3]]//ContractMetric//ToCanonical

%expr[[4]]//ContractMetric//ToCanonical

%expr[[5]]//ContractMetric//ToCanonical

%expr[[6]]//ContractMetric//ToCanonical

Fully expanded relations for the fourth step of order 12 invariants take up too much memory to be loaded at the same time in a typical PC. We provide two versions of the database for the hardest cases of this step and order: 
	- Non expanded: these rules have not been fully `simplified' taking into account all the other relations. As a result, they are both somewhat smaller and slower to use. The corresponding files in the database end in the string `NE'.
	- Expanded: these rules have been fully expanded. They are bigger but faster.
We can control which version to use with the global variable $ExpandedCommuteOrder12Q:

The default value is False, meaning that Invar will load the non expanded version.

$ExpandedCommuteOrder12Q

For example, let us take this invariant:

inv=RInv[metric][{0,3,3},100]

which is still independent after steps 2 and 3:

InvSimplify[inv,3]

It can be expanded using the NE-rules for step 4:

InvSimplify[%,4]

but it is still not fully expanded, as this expression changes again under InvSimplify:

InvSimplify[%,4]

The rules take less than 25 Mbytes:

ByteCount[RInvRules[4,{0,3,3}]]/1000./1024

Now remove the rules

RemoveRInvRules[4,{0,3,3}]

and simplify again the invariant, now using the expanded rules. We get the fully expanded result

$ExpandedCommuteOrder12Q=True;
InvSimplify[inv,4]

but now the rules take almost 100 Mbytes:

ByteCount[RInvRules[4,{0,3,3}]]/1000./1024

Tidy up:

Clear[inv]

This section deals only with algebraic invariants. It is well known that there are 14 independent scalars of the Riemann tensor. Narlikar and Karmarkar gave 14 such scalars in 1947. We express them in terms of our basis of invariants.

Definitions taken from [Alex Harvey, Class. Quantum Grav. 7 (1990) 715-716]. First define six intermediate tensors:

IndexSet[Atensor[h_,i_,j_,k_],WeylCD[h,i,-a,-b]WeylCD[a,b,j,k]];
IndexSet[Btensor[h_,i_,j_,k_],WeylCD[h,i,-a,-b]Atensor[a,b,j,k]];
IndexSet[Dtensor[h_,i_,j_,k_],Btensor[h,i,j,k]-1/12J2(metric[h,j]metric[i,k]-metric[h,k]metric[i,j])-1/4J1 WeylCD[h,i,j,k]];
IndexSet[Etensor[h_,i_,j_,k_],WeylCD[h,i,-a,-b]Dtensor[a,b,j,k]];
IndexSet[Ftensor[h_,i_,j_,k_],WeylCD[h,i,-a,-b]Etensor[a,b,j,k]];
IndexSet[Qtensor[a_,b_],RicciCD[-c,a]RicciCD[c,b]];

These are the 14 scalars:

I1:=RicciScalarCD[];
IndexSet[I2,RicciCD[-a,b]RicciCD[-b,a]];
IndexSet[I3,RicciCD[-a,b]RicciCD[-b,c]RicciCD[-c,a]];
IndexSet[I4,RicciCD[-a,b]RicciCD[-b,c]RicciCD[-c,d]RicciCD[-d,a]];
IndexSet[J1,Atensor[-i,-j,i,j]];
IndexSet[J2,Btensor[-i,-j,i,j]];
IndexSet[J3,Etensor[-i,-j,i,j]];
IndexSet[J4,Ftensor[-i,-j,i,j]];
IndexSet[K1,WeylCD[-h,-i,-j,-k]RicciCD[h,j]RicciCD[i,k]];
IndexSet[K2,Atensor[-h,-i,-j,-k]RicciCD[h,j]RicciCD[i,k]];
IndexSet[K3,Dtensor[-h,-i,-j,-k]RicciCD[h,j]RicciCD[i,k]];
IndexSet[K4,WeylCD[-h,-i,-j,-k]Qtensor[h,j]Qtensor[i,k]];
IndexSet[K5,Atensor[-h,-i,-j,-k]Qtensor[h,j]Qtensor[i,k]];
IndexSet[K6,Dtensor[-h,-i,-j,-k]Qtensor[h,j]Qtensor[i,k]];

Pure Ricci:

{I1,I2,I3,I4}

Pure Weyl:

{J1,J2,J3,J4}//ContractMetric

Mixed invariants:

{K1,K2,K3,K4,K5,K6}//ContractMetric

The basis is given in terms of Weyl and Ricci. We need to convert the Weyl tensors into Riemann tensors, what takes quite a long time. The results form appendix B of the first paper.

Show timings over 1 second:

<<xAct`ShowTime1`

The function do1 performs the translation from Weyl to Riemann (do1 has a very strange form in order to make it faster). The function do2 changes to invariants and simplify them:

do1[expr_]:=ToCanonical@ContractMetric[ToCanonical@ContractMetric@WeylToRiemann@ToCanonical[expr]/.CurvatureRelations[CD]];
do2[expr_]:=expr//RiemannToInv//InvSimplify//Simplify;

$InvSimplifyLevel=6

Pure Ricci:

I1//do2

I2//do2

I3//do2

I4//do2

Pure Weyl:

J1//do1//do2

J2//do1//do1

%//do2

J3//do1//do1

%//do2

J4//do1//do1

%//do2

Mixed invariants:

K1//do1//do1

%//do2

K2//do1//do1

%//do2

K3//do1//do1

%//do2

K4//do1//do1

%//do2

K5//do1//do1

%//do2

K6//do1//do1

%//do2

There are many things that Invar` cannot do yet. Here there is a list with some of them:
	- Weyl invariants.
	- Free indices.
	- Dimensionally-dependent identities for dimensions other than 4.

Note: For further information about Invar`, and to be kept informed about new releases, contact jose@xact.es. This is InvarDoc.nb, the docfile of Invar, currently in version 2.0.5.

None yet.

Collection of public symbols in Invar`:

Names["xAct`Invar`*"]

Length[%]

TimeUsed[]

MemoryInUse[]/1000/1024//N

MaxMemoryUsed[]/1000/1024//N