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 theImplicitIndex
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 anImplicitIndex
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.