Welcome to Cadabra Q&A, where you can ask questions and receive answers from other members of the community.
+1 vote

Hi,

I am dealing with fields which have SU(2) spin indices, and so would like to use the EpsilonTensor $\epsilon_{a b}$ as the metric to raise/lower/contract indices. I define the spin indices like this

{a,b,c}::Indices(position=fixed).
{a,b,c}::Integer(1..2).

Then I define the EpsilonTensor as a metric

\delta::KroneckerDelta;
\epsilon_{a b}::EpsilonTensor(delta=\delta);
\epsilon_{a b}::Metric; 

Now, I am able to contract the spin indices such that $\epsilon_{a b} \epsilon^{a c} = \epsilon^{b}{}_{c}$ by using eliminate_metric, but I can't seem to reduce this further to a kronecker delta, like $\epsilon^{b}{}_{c} = \delta^{b}{}_{c}$. For example,

ex:=\epsilon_{a b} \epsilon^{a c};
eliminate_metric(_);

gives me $\epsilon_{b}{}^{c}$ correctly. But how can I reduce this to $\delta_{b}{}^{c}$?

I tried using the algorithm epsilon_to_delta, but I can only make it work when all indices are lower, or when all indices are upper, but not with mixed indices. Maybe I am missing something.

One solution to this problem is to just define a substitution that does this epsilon to delta conversion, but I was wondering if there is a more canonical way to do this?

Thank you for the help, and thanks for the excellent work on Cadabra!

in General questions by
edited by

1 Answer

+2 votes

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?

by (83.1k points)

Thank you very much! This does work. I did not realize the fact about having to separately define upper and lower epsilon tensors, but it makes sense. I'll try to use you suggestion about using rewrite_indices as well.

I am using version 2.1.4 built from source. Looking forward to version 2.1.5! I discovered Cadabra a few days ago, and that got me pretty excited about it's possibilities. I appreciate the fact that this is open-source. Thanks again :)

...