I would advise against using the Metric
property for \epsilon
, because Metric
implies Symmetric
and that will almost certainly cause trouble later (given that you also declare epsilon
to be an antisymmetric EpsilonTensor
). Cadabra does not attempt to detect contradictory properties (a relatively simple task in this case, but practically impossible in general), so it didn't warn you.
Instead, I would stick to the approach of using epsilon_to_delta
, since that's really meant for this kind of thing. Start from
{a,b,c,d,e,f}::Indices(position=fixed).
{a,b,c,d,e,f}::Integer(1..2).
\delta{#}::KroneckerDelta;
\epsilon_{a b}::EpsilonTensor(delta=\delta);
\epsilon^{a b}::EpsilonTensor(delta=\delta);
Note the {#}
on \delta{#}
in the 3rd line. Also note the last line: since your indices are position=fixed
, a declaration of a property for \epsilon_{a b}
does not automatically attach that property to \epsilon^{a b}
as well; you need to do that explicitly.
Now you can do
ex:=\epsilon_{a b} \epsilon^{a c};
epsilon_to_delta(_);
which gives $\delta_{b}{}^{c}$ as expected.
The next question you will now probably ask is how to convert
$$ A^{a} \epsilon_{a b} \rightarrow A_{b},$$
(which is, as you noted, easy if you have a symmetric lowering/raising object, as you can then use eliminate_metric
). I was about to suggest that you can abuse eliminate_vielbein
for this, but alas, that one didn't make it into 2.x yet... Will put thison the todo list for a future version.
Until that future version is out, one thing that may help you a bit is that you can use rewrite_indices
to write the indices of all objects either upstairs or downstairs, using a given 'conversion' tensor. An example:
ex2:= A^{a b} \epsilon_{b c};
rewrite_indices(_, $A_{a b}$, $\epsilon^{a b}$);
This gives $A_{d e} \epsilon_{b c} \epsilon^{a d} \epsilon^{b e}$, which you can then simplify using the epsilon_to_delta
.
I'll keep you posted about 2.1.5. Are you building from source or installing from a binary package?