# Elegant List Reordering under specific conditions

I use the fantastic Package DiracQ in order to work with fermionic creation and annihilation operators. My problem is quite general, for all of you interested in the physical background I will describe the problem in detail. For all of you being interested in the general problem I will paraphrase my problem in a less physically driven way.

Physics: Assume we want to calculate a trace in real space for a product of fermionic creation (f+[i,s]) and annihilation (f[i,s]) operators that operate on site i with spin s each. A trace of a product of tensor product hilbert spaces can be calculated as a product of the traces at different sites. I now want to keep the former order regarding one quantum number but separate the product regarding different quantum numbers.

General problem: I have a list of operators (the same letter, e.g. A, means the same set of quantum numbers (i,s))

{A+,B+,C,B,B+,A}

and want to sort them according to the rule to never change place of operators of the same letter but to group according to the family of letters with the condition {A,B} = -{B,A}. {…} denotes the list, not the fermionic anticommutator. My above list should become:

{A+,A,B+,C,B,B+}

in the first step (A goes to the left as far as possible, but isn't allowed to go further left because there is a member of the same family with A+; as A went 4 steps to the left, we have a factor of (-1)^4 = 1). Next step:

-{A+,A,B+,B,C,B+}

(note the minus because we changed B by exactly one position). Final result:

{A+,A,B+,B,B+,C}.

Now we are done and not allowed to change any operator further because we would now only be able to change members of the same family (same letter) and this should not be allowed.

I am not sure how to model this problem elegantly in Mathematica. Hints are appreciated.

Allow me to replace your 'A' and 'A+' by 'a' and 'a1'; Build a test case:

it = {a,a,a,a1,b,b,b1,b1,c,c1,c1,c1}[[RandomPermutation[12]]]
{b1, b, a, c1, c1, a, c1, c, b1, a1, b, a}


now find the positions of the families:

{Position[it, a | a1], Position[it, b | b1], Position[it, c | c1]}
Flatten[%]


gives:

{{{3}, {6}, {10}, {12}}, {{1}, {2}, {9}, {11}}, {{4}, {5}, {7}, {8}}}
{3, 6, 10, 12, 1, 2, 9, 11, 4, 5, 7, 8}


and now do:

f[it[[%]]] Signature[%]
-f[{a, a, a1, a, b1, b, b1, b, c1, c1, c1, c}]


where I wrapped the result in a dummy function 'f' to prevent the sign from threading over all elements of the list.

• That's definitely elegant. My current solution (for loop and lots of clutter) will be replaced by your suggestion. Didn't know how useful "Signature" might be. Thanks!
– pbx
Commented Nov 2, 2016 at 13:08