Non Commutative sorting in Mathematica

I have been trying to do some oscillator algebra in Mathematica and having troubles with sorting and simplifying expressions. I am using the NCAlgebra package which helps to improve the properties of NonCommutativeMultiply in Mathematica. However I have to create a huge list of rules to replace terms using the algebra. This quickly becomes impractical since I get these enormous expressions and I have to sift through the terms to see what simplifies and add more rules.

I have been wondering if there is a way to write a sorting function that would take an elementary expression and change it to a list and then permute the elements of list to sort the expression. I am fairly new to Mathematica but I would eventually like to write a small package which would allow me to these kind of manipulations.

For example, I have terms like $a**b**c**a^\dagger$ where $a$, $b$, $c$, etc. commute with each other but $a**a^\dagger-a^\dagger**a =1$. So I would like to sort things such that all dagger operators are to the left and have Mathematica use the fact that $a$, $b$, $c$ commute to rewrite the expressions. Right now I am assigning rules for every type of term that appears in my calculation but the number of terms has become unmanageable.

-

migrated from stackoverflow.comDec 11 '12 at 0:22

This question came from our site for professional and enthusiast programmers.

Hello Karan, welcome to Mathematica.SE? Did you mean a**a(dagger)-a(dagger)**a =1? Note that you can also write $\LaTeX$, just surround your expression with dollar signs. –  Szabolcs Dec 11 '12 at 0:53
I was just going to point out what Szabolcs said... I've changed it to $\LaTeX$, but do review the dagger term. –  The Toad Dec 11 '12 at 0:56
Thanks for the edit guys. I have corrected it and will remember to format things correctly in future. –  Karan Dec 11 '12 at 1:12
Check section "Some noncommutative algebraic manipulation" from nb available here –  Daniel Lichtblau Dec 11 '12 at 16:27

The trick here is to take control of the non-commuting operators, and to define your own set of rules. Use prod as the head of each operator product, where prod[x,y] represents x ** y, and you can then define rules for manipulating prod.

Define rules that move $a^\dagger$ to the left in an operator product.

prod[u___, a, ad, v___] := prod[u, ad, a, v] + prod[u, v];
prod[u___, x : b | c, ad, v___] := prod[u, ad, x, v];


then you can evaluate

prod[a, b, c, ad]

(* prod[b, c] + prod[ad, a, b, c] *)


Generalisations of this sort of trick should solve your problem.

-
@Karan Stephen's suggestion is good. Does $a^\dagger$, indeed commute with $b$ and $c$, though? –  Mark McClure Dec 11 '12 at 2:22
@Mark Yes $a^\dagger$ does commute with $b$ and $c$. However there is $b^\dagger$ and $c^\dagger$ which doesn't commute with b and c respectively. –  Karan Dec 11 '12 at 2:38
@Stephen That sounds like a good idea. I will try this. –  Karan Dec 11 '12 at 2:38
A more general approach would be to define prod[u___, a[i_], ad[j_], v___] := prod[u, ad[j], a[i], v] + prod[u, comm[a[i], ad[j]], v]; and then to define particular rules for c-number commutators such as prod[u___, comm[a[2], ad[1]], v___] := comm[a[2], ad[1]] prod[u, v]; –  Stephen Luttrell Dec 11 '12 at 3:27
@Stephen I tried what you suggested but I ran into troubles. Here is what I did: Prod[x___, y___] := x ** y; Prod[a___, b_, c_, d___] := Prod[a, c, b, d] + Comm[b, c] Prod[a, d];Comm[a, $a^\dagger$] = 1; Comm[b, $b^\dagger$] = 1; Comm[a, b] = 0; Comm[$a^\dagger$, b] = 0; Comm[a, $b^\dagger$] = 0; Comm[$a^\dagger$, $b^\dagger$] = 0; Prod[a, b, $a^\dagger$]. However this gives some errors. Where am I making a mistake? –  Karan Dec 11 '12 at 7:13

It would have helped if you have gives a simple example of what you want.

But you could always do something like

expr = a x^3 + b x^2 + c x + d
Apply[List, expr]
(*  {d, c*x, b*x^2, a*x^3}  *)


Now to sort it, use Sort and you can apply your sorting function, as described in help:

"Sort[list,p] applies the function p to pairs of elements in list to
determine whether they are in order. The default function p is
OrderedQ[{#1,#2}]&."


You can also use Permute using some permutation group.

If you give a small example of an input, and what you like to get as output it will help.

-
Thanks for the help. I have edited the question to include an example. I will try what you suggested. –  Karan Dec 11 '12 at 0:41

One possibility is to use FeynCalc:

[rolfm@localhost ~]$math Mathematica 9.0 for Linux x86 (64-bit) Copyright 1988-2012 Wolfram Research, Inc. In[1]:= FilePrint@"karan" (* If FeynCalc is not already installed, do: Import["http://www.feyncalc.org/install.m"] *)$LoadFeynArts=False;
Quiet@Get["HighEnergyPhysicsFeynCalc"]
FI;
Commutator[b, bd] = 1;
Commutator[a, bd] = 0;
Commutator[a,  b] = 0;