a field-theory motivated approach to computer algebra

# Implicit versus explicit indices

When writing expressions which involves vectors, spinors and matrices, one often employs an implicit notation in which some or all of the indices are suppressed. Examples are $$a = M b\,, \quad \bar{\psi}\gamma^{m}\chi\,,$$ where $a$ and $b$ are vectors, $\psi$ and $\chi$ are spinors and $M$ and $\gamma^{m}$ are matrices. Clearly, the computer cannot know this without some further information. In Cadabra objects can carry implicit indices, through the ImplicitIndex property. There are derived forms of this, e.g. Matrix and Spinor. The following example shows how implicit indices ensure that objects do not get moved through each other when sorting expressions.
{a,b}::ImplicitIndex; M::Matrix; ex:= a = M b; sort_product(_);
$$\displaystyle{}\text{Attached property ImplicitIndex to }\left[a, b\right].$$
$$\displaystyle{}\text{Attached property Matrix to }M.$$
$$\displaystyle{}a = M b$$
a = M b
$$\displaystyle{}a = M b$$
a = M b
If you had not made the property assignment in the first two lines, the sort_product would have incorrectly swapped the matrix and vector, leading to a meaningless expression. If you have more than one set of implicit indices, it is best to use a form of ImplicitIndex which makes explicit which indices are suppressed. In the following example, we write consider the expression $M c b$ in which $M$ is a matrix acting on the vector $b$, while $c$ is a different matrix which does not act on the same vector space. In other words, we consider $M^{i}{}_{j} c^{m}{}_{n} b^{j}$. Clearly we can also write this as $M b c$, which is indeed what sort_product converts it to.
{i,j}::Indices(vector); {m,n}::Indices(spinor); M::ImplicitIndex(M^{i}_{j}); b::ImplicitIndex(b^{i}); c::ImplicitIndex(c^{m}_{n});
$$\displaystyle{}\text{Attached property Indices(position=free) to }\left[i, j\right].$$
$$\displaystyle{}\text{Attached property Indices(position=free) to }\left[m, n\right].$$
$$\displaystyle{}\text{Attached property ImplicitIndex to }M.$$
$$\displaystyle{}\text{Attached property ImplicitIndex to }b.$$
$$\displaystyle{}\text{Attached property ImplicitIndex to }c.$$
ex:= M c b;
$$\displaystyle{}M c b$$
M c b
sort_product(_);
$$\displaystyle{}M b c$$
M b c
Such explicit property information is also respected by operators like Trace. The following example shows how to remove objects from traces when they do not carry any indices on which the trace acts.
Tr{#}::Trace(indices=vector); ex:= Tr( M c M ); untrace(_);
$$\displaystyle{}\text{Attached property Trace to }Tr\left(\#\right).$$
$$\displaystyle{}Tr\left(M c M\right)$$
Tr(M c M)
$$\displaystyle{}c Tr\left(M M\right)$$
c Tr(M M)

## Converting between implicit and explicit

It is possible to convert from implicit indices to explicit indices, that is, make Cadabra write out all implicit indices explicitly. For this to work you need to have declared an ImplicitIndex property which lists the explicit indices of the object. Cadabra will then take care of creating index lines.
{i,j,k}::Indices; a::ImplicitIndex(a^{i}); M::ImplicitIndex(M^{i}_{j}); ex:= M a;
$$\displaystyle{}\text{Attached property Indices(position=free) to }\left[i, j, k\right].$$
$$\displaystyle{}\text{Attached property ImplicitIndex to }a.$$
$$\displaystyle{}\text{Attached property ImplicitIndex to }M.$$
$$\displaystyle{}M a$$
M a
explicit_indices(ex);
$$\displaystyle{}M^{i}\,_{j} a^{j}$$
M^{i}_{j} a^{j}
Note how dummy indices were introduced automatically.