# Simplification of quantum ladder operators (ideally using Using NCAlgebra)

I want to do math that involves a series of ladder operators. In the past I've tried to get it working with a 20 year old Mathematica package. But my feeling is that this is a very unused package and that it may be better to just work with NCAlgebra package instead.

Ultimately, I often have expressions that I need to work with and simplify. I have a series of ladder operators $$a_i$$. They have the commutation relationship:

$$[a_i, a_j^\dagger] = \delta_{ij},$$

For example, if I have a messier non-commuting polynomial of this, such as: $$a_4**(k a_1**a_2**a_1^\dagger+c*a_2**a_1**a_3),$$ I want a general way that I can define my operators, their commutation relations, and provide a simplification such that it organizes the operators in increasing ordering and uses the commutator to flip them so that it is in the expanded form:

$$ka_2 + ka_1^\dagger a_1 a_2+ c*a_1**a_2**a_3$$

With all of the daggers in the leftmost side.

Similar to this question, I am looking for something like a "commutator expand," but with the daggers being placed on the left (instead of the right which is done with this commutator expand.). What is the most straightforward way of doing this, and can the NCAlgebra tools be useful in this case?

Also, in a more general question I asked, it was mentioned in the comments that a solution is provided 12 years ago here:

prod[u___, x_ + y_, v___] :=
prod[u, x, v] + prod[u, y, v];(*expand sums*)
prod[u___, x_?NumericQ, v___] := x prod[u, v];(*pull out c-numbers*)
prod[u___, prod[x___], v___] := prod[u, x, v];


This seems like a simple solution which doesnt need NCAlgebra, but it doesnt seem to work in some cases. For example with the code:

H = \[Omega]a prod[ad, a] + \[Omega]b prod[bd, b];
prod[H, a] - prod[a, H] // Simplify


This does not actually simplify it out, and instead returns:

-prod[a, \[Omega]a prod[ad, a]] - prod[a, \[Omega]b prod[bd, b]] +
prod[\[Omega]a prod[ad, a], a] + prod[\[Omega]b prod[bd, b], a]


So I either need a solution to this problem via NCAlgebra, or at least a fix for this issue in the solution that doesnt use NCAlgebra.

• I gave the solution that you referenced at mathematica.stackexchange.com/questions/16063/… (12 years ago), which ended with the comment "Generalisations of this sort of trick should solve your problem.". You would need prod[u___, x_?(FreeQ[#, prod] &) w_, v___] := x prod[u, w, v] to expand out nested prod expressions such as yours that contain non-numeric coefficients. Actually, to control expression evaluation better, I prefer to use <rule> <pattern> :> <replacement> rather than <pattern> := <replacement>. Commented Apr 22 at 20:01

This is a variation on code I put together over 25 years ago. It can be redone (as it originally was) to use a new symbol instead of NonCommutativeMultiply. Since I do use that symbol I need to first remove its attributes, as they will interfere impolitely with the definitions I'll give it. I will use aOp and aOpDagger to denote the two types of operator under consideration.

(* define scalars *)

ScalarQ[n_?NumberQ] := True
ScalarQ[_aOp] := False
ScalarQ[_aOpDagger] := False
SetScalar[k_] := (ScalarQ[k] = True);

(* Define transformations required to canonicalize operator expressions *)

NonCommutativeMultiply[] := 1
NonCommutativeMultiply[aa_] := aa
NonCommutativeMultiply[aa___, xx_ + yy_, bb___] :=
NonCommutativeMultiply[aa, xx, bb] +
NonCommutativeMultiply[aa, yy, bb]
NonCommutativeMultiply[aa___, NonCommutativeMultiply[bb_, cc__],
dd___] := NonCommutativeMultiply[aa, bb, cc, dd]
NonCommutativeMultiply[aa___, i_?ScalarQ, bb___] :=
i*NonCommutativeMultiply[aa, bb]
NonCommutativeMultiply[aa___, i_?ScalarQ*cc_, bb___] :=
i*NonCommutativeMultiply[aa, cc, bb]
NonCommutativeMultiply[aa___, aOp[i_Integer], aOp[j_Integer], bb___] /;
j < i := NonCommutativeMultiply[aa, aOp[j], aOp[i], bb]
NonCommutativeMultiply[aa___, aOpDagger[i_Integer],
aOpDagger[j_Integer], bb___] /; j < i :=
NonCommutativeMultiply[aa, aOpDagger[j], aOpDagger[i], bb]
NonCommutativeMultiply[aa___, aOp[i_Integer], aOpDagger[j_Integer],
bb___] /; j =!= i :=
NonCommutativeMultiply[aa, aOpDagger[j], aOp[i], bb]
NonCommutativeMultiply[aa___, aOp[i_Integer], aOpDagger[i_],
bb___] := -NonCommutativeMultiply[aa, aOpDagger[i], aOp[i], bb]


Now for the example.

SetScalar[c];
SetScalar[k];

NonCommutativeMultiply[aOp[4],
NonCommutativeMultiply[k*aOp[1], aOp[2], aOpDagger[1]] +
c*NonCommutativeMultiply[aOp[2], aOp[1], aOp[3]]]

(* Out[19]=
c aOp[1] ** aOp[2] ** aOp[3] ** aOp[4] -
k aOpDagger[1] ** aOp[1] ** aOp[2] ** aOp[4] *)

• Thank you for your answer, it's almost there -- but it's not quite at the state where it's useful to me. If I use it with functions, such as NC[e^it A, B] it does not identify that I can pull out the function as a noncommuting scalar. Is there a way to fix this? Commented Apr 10 at 6:07
• Maybe try this. Clear[ScalarQ]; ScalarQ[a_] := FreeQ[a, aOp | aOpDagger]. Commented Apr 10 at 17:16

If I understand what you want, here how you can do it in NCAlgebra:

SNC[a1, a2, a3]
exp = (K a1 ** a2 ** aj[a1] + C a2 ** a1 ** a3)


defines a1 through a3 to be noncommutative and the expression you would like to manipulate. aj is the adjoint operator. From here, there are many ways to perform the substitutions you want. Using the core NCAlgebra functionality you can create the rules:

CommutatorRule[a_, b_] := a ** aj[b] -> aj[b] ** a + 1
rules = Apply[CommutatorRule, Tuples[{a1, a2, a3}, {2}], 1];


and then apply them with

NCExpandReplaceRepeated[exp, rules]


This will return

a1 K + a2 K + C a2 ** a1 ** a3 + K aj[a1] ** a1 ** a2

For more complex substitution and sorting scenarios check out our NCGroebnerBasis algo.