# How can I implement cyclicity of trace?

I want to compute ${\rm trace}(\phi\psi- \psi\phi)^2$. The answer is $2\phi\psi\phi\psi-2\phi^2\psi^2$.

So how can I do this in Cadabra?

I have declared $\phi,\psi$ to be matrices. I am not giving them ImplicitIndices.

I tried using complete(), by defining a rule, to give the trace cyclic symmetries but that does not work. It is not using the condition. So probably I am using the wrong function.

I thought of using the young tableau symmetries to define the indices of $\phi\psi$ but that gives symmetries to a specific tensor rather than the indices themselves. So cant be used in a product.

Is there a quick way to implement the trace in Cadabra. I have a very long expression I want to take the trace of?

edited

A time ago I was trying something related to your question. After a while of looking on the web (and asking... just like you!) I came out with the following: define a circular function.

Let $a$ and $b$ be noncommuting, but distributable

{a,b}::NonCommuting.
{a,b}::Distributable.
def post_process(ex):
expand_power(ex)
distribute(ex)


I define the function

def isCircular(arr1, arr2):
return arr1 in arr2+' '+arr2


and a expression to test

expr := (a + b)**2;


The trick is now to convert this to a string, split it, and compare term by term if they are circular. NOTE: blank spaces before and after the plus sign inside the split method.

list = str(expr)
list = str(expr).split(' + ')
list;

for i in range(len(list)):
for j in range(i+1,len(list)):
if isCircular( list[i], list[j]):
list[j] = list[i]
list;


Then, convert it back to a cadabra expression to finally simplify. NOTE: the newexpr is initalised as an empty expression, it is not a single double quote, but double single quotes.

newexpr = '';
for word in list:
newexpr = newexpr + ' + ' + word
;
cab_expr = Ex(newexpr)
collect_terms(cab_expr);


I tried something like expr := (a b + b a)**2; and the result is almost there! It could be a starting point!!!

Cheers.

+1 vote

The current version on github handles this:

{\phi,\psi}::ImplicitIndex;
tr{#}::Trace;
ex:= tr( (\phi\psi - \psi\phi)**2 );
expand_power(_)
distribute(_)
sort_product(_);


produces your answer. Thanks to Connor Behan for providing the patch that makes this work.