# Simplifying quantum operators (ladder operators with multiple modes)

Similar to this question, I am interested in working with an implementation of quantum ladder operators.

I've been trying to use this "Quantum Mathematica Package" to solve some lengthy algebra with a lot of ladder-operators in different modes, but have been having trouble.

I want to be able to evaluate and manipulate some of the quantum operators that are inside of a sum.

For example, I might be working with a term involing the multiplication of multiple ladder operators such as:

$$\frac{1}{4} a_1\cdot a_2^2\cdot a_7{}^{\dagger }\cdot a_2\cdot a_7\cdot a_7{}^{\dagger }$$

One thing I would like to do is get it to simplify this knowing the commutation relation between operators to:

$$\frac{1}{4} a_1\cdot a_2^3\cdot a_7{}^{\dagger }\cdot a_7\cdot a_7{}^{\dagger }$$

(so I want Mathematica to identify that because $$a_7$$ and $$a_2$$ commute, that I can sort these operators in an "alphabetical ordering")

Theoretically I can do this with the following code:

Needs["QuantumNotation"];
Clear[a];
SetQuantumObject[a];


Now if I specify the commutation relationship between these operators using the code:

(I'm using pictures here because the code looks hideous if I copy+paste it)

Now I can apply a function called "CommutatorExpand[]" to try to simplify this to the desired form:

And here I see that it can successfully organize my operators!

But unfortunately I haven't been able to figure out how to do this consistently. For example, this case doesn't work:

Any idea what the issue is or how to fix this?

Here's a copy+paste version of the code:

Needs["QuantumNotation"];
Clear[a];
SetQuantumObject[a];

\!$$\* TagBox[ SubscriptBox[ RowBox[{"[[", TagBox[ RowBox[{ SubscriptBox["a", RowBox[{"b", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ",", SuperscriptBox[ RowBox[{"(", SubscriptBox["a", RowBox[{"a", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ")"}], "\[Dagger]"]}], QuantumNotationzz080KetArgs, Editable->True, Selectable->True], "]]"}], "-"], QuantumNotationzz050Commutator, Editable->False, Selectable->False]$$ := KroneckerDelta[a, b];
\!$$\* TagBox[ SubscriptBox[ RowBox[{"[[", TagBox[ RowBox[{ SubscriptBox["a", RowBox[{"b", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ",", RowBox[{"(", SubscriptBox["a", RowBox[{"a", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ")"}]}], QuantumNotationzz080KetArgs, Editable->True, Selectable->True], "]]"}], "-"], QuantumNotationzz050Commutator, Editable->False, Selectable->False]$$ := 0;
\!$$\* TagBox[ SubscriptBox[ RowBox[{"[[", TagBox[ RowBox[{ SuperscriptBox[ RowBox[{"(", SubscriptBox["a", RowBox[{"b", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ")"}], "\[Dagger]"], ",", SuperscriptBox[ RowBox[{"(", SubscriptBox["a", RowBox[{"a", ":", RowBox[{"1", "|", "2", "|", "3", "|", "4", "|", "5", "|", "6", "|", "7", "|", "8", "|", "9"}]}]], ")"}], "\[Dagger]"]}], QuantumNotationzz080KetArgs, Editable->True, Selectable->True], "]]"}], "-"], QuantumNotationzz050Commutator, Editable->False, Selectable->False]$$ := 0;

CommutatorExpand[ Subscript[a, 1]\[CenterDot]
\!$$\*SubsuperscriptBox[\(a$$, $$2$$, $$2$$]\)\[CenterDot]SuperDagger[
Subscript[a, 7]]\[CenterDot]Subscript[a, 2]\[CenterDot]Subscript[a,
7]\[CenterDot]SuperDagger[Subscript[a, 7]]]
CommutatorExpand[Subscript[a, 1]\[CenterDot]Subscript[a, 2]\[CenterDot]
\!$$\*SubsuperscriptBox[\(a$$, $$7$$, $$2$$]\)\[CenterDot]SuperDagger[
Subscript[a, 1]]\[CenterDot]SuperDagger[Subscript[a,
7]]\[CenterDot]SuperDagger[Subscript[a, 2]]]

• Can you please specify what is the expected result for the second expression ($a_1 \cdot a_2 \cdot a_7^2 \cdot a_1^\dagger \cdot a_7^\dagger \cdot a_2^\dagger$)? Also, this expression in the code is different than the one in the picture ($a_1$ vs $a_1^\dagger$). Commented Aug 14, 2021 at 13:17
• @Domen, thanks for pointing that out. I fixed it in the question. My desired output is of the form $a_1 \cdot a_1^\dagger \cdot a_2 \cdot a_2^\dagger \cdot a_7^2 \cdot a_7^\dagger$. Additionally quantum expand also is supposed to reduce it to a "unique form" by using the commutator to put it in a specific ordering. (which is what is done in the first example). Ideally I would also like it to have this feature. Commented Aug 14, 2021 at 13:44
• If what I described is still to confusing, please let me know and I'll expand on it in the question. Commented Aug 14, 2021 at 13:45
• Have you tried the NCAlgebra package? Commented Aug 15, 2021 at 4:29
• Perhaps dated but see section on noncommutative algebra in these notes. At least one example was specific to working with commutators. Commented Sep 19, 2021 at 16:27

Here is a modalForm function that may help. The function applies a replacement rule, modalRule, at all levels of an expression. The rule sorts the operators according to their subscripts. This is valid since operators with different subscripts commute. The order of operators with the same subscripts is not changed. In should be emphasized that modalRule has commutation relations hard-wired into it.

modalRule = product_zz075NonCommutativeTimes :>
Sort[product,
If[Length[Cases[#1, _Subscript, {0, ∞}]] == 1 &&
Length[Cases[#2, _Subscript, {0, ∞}]] == 1,
Order[
FirstCase[#2, z_Subscript :> Last@z, ∞, {0, ∞}],
FirstCase[#1, z_Subscript :> Last@z, ∞, {0, ∞}]], 0, 0] &
];

ClearAll[modalForm]
modalForm[expr_] := Replace[expr, modalRule, {0, ∞}]


The function has been tested on several test cases, which are defined below. To run the test cases, we must first load the Quantum Notation package and define the commutation relations, as in the question.

The replacement rule only acts on objects with the head zz075NonCommutativeTimes, which is part of the Quantum Notation package.

### First test case

The first test case is take from the question. This test shows the modalRule applied to the test (defined below) and modalForm applied to the expression. In both cases the result is $$a_2$$ moves to left and $$a_7^\dagger$$ moves to the right.

{test1,
test1 /. modalRule,
test1 // modalForm} // ColumnForm


$$\begin{array}{c} \frac{1}{4} a_1a_2^2a_7{}^{\dagger }a_2a_7a_7{}^{\dagger } \\ \frac{1}{4} a_1a_2^3a_7{}^{\dagger }a_7a_7{}^{\dagger } \\ \frac{1}{4} a_1a_2^3a_7{}^{\dagger }a_7a_7{}^{\dagger } \\ \end{array}$$

### Second test case

The second test is similar to the first. In the first two lines of this test, operators $$a_2$$ and $$a_3^\dagger$$ move to the left and $$a_7^\dagger$$ moves to the right. It gets more interesting when CommutatorExpand is applied before modalForm. CommutatorExpand uses the commutator relations, defined in the question, to arrange the operators in cannonical form, with all of the daggers to the right, as in the third line below. Then, in the fourth line, modalForm sorts the operators according to their modes (subscripts).

{test2,
test2 // modalForm,
"",
test2 // CommutatorExpand,
test2 // CommutatorExpand // modalForm} // ColumnForm


$$\begin{array}{c} a_1a_2^2a_2{}^{\dagger }a_2a_7a_2{}^{\dagger }a_3{}^{\dagger } \\ a_1a_2^2a_2{}^{\dagger }a_2a_2{}^{\dagger }a_3{}^{\dagger }a_7 \\ \text{} \\ a_1a_2^3a_7\left(a_2{}^{\dagger }\right){}^2a_3{}^{\dagger }-a_1a_2^2a_7a_2{}^{\dagger }a_3{}^{\dagger } \\ a_1a_2^3\left(a_2{}^{\dagger }\right){}^2a_3{}^{\dagger }a_7-a_1a_2^2a_2{}^{\dagger }a_3{}^{\dagger }a_7 \\ \end{array}$$

### Third test case

CommutatorExpand will sometimes return a factored form, as this test case shows. Here, modalForm is applied to baseline case, test3. Then test3 is expanded. This introduces a term in parentheses (see the third line). modalForm is applied to shift the position of $$a_7$$ inside the parentheses. In a third variation, modalForm is applied before and after CommuatorExpand to show an alternate form of the operator expression.

{test3,
test3 // modalForm,
"",
test3 // CommutatorExpand,
test3 // CommutatorExpand // modalForm,
"",
test3 // modalForm // CommutatorExpand,
test3 // modalForm // CommutatorExpand // modalForm} // ColumnForm


$$\begin{array}{c} a_1a_2^2a_7{}^{\dagger }a_2a_7a_7{}^{\dagger }a_3{}^{\dagger } \\ a_1a_2^3a_3{}^{\dagger }a_7{}^{\dagger }a_7a_7{}^{\dagger } \\ \text{} \\ a_1a_2^3\left(a_7a_3{}^{\dagger }a_7{}^{\dagger }-a_3{}^{\dagger }\right)a_7{}^{\dagger } \\ a_1a_2^3\left(a_3{}^{\dagger }a_7a_7{}^{\dagger }-a_3{}^{\dagger }\right)a_7{}^{\dagger } \\ \text{} \\ a_1a_2^3a_7a_3{}^{\dagger }\left(a_7{}^{\dagger }\right){}^2-a_1a_2^3a_3{}^{\dagger }a_7{}^{\dagger } \\ a_1a_2^3a_3{}^{\dagger }a_7\left(a_7{}^{\dagger }\right){}^2-a_1a_2^3a_3{}^{\dagger }a_7{}^{\dagger } \\ \end{array}$$

### Defintions for test1, test2 and test3

test1 =  zz075NonCommutativeTimes @@ Reverse@{
Subscript[a, 1], Subscript[a, 2]^2,
zz080HermitianConjugate[Subscript[a, 7]],
Subscript[a, 2], Subscript[a, 7],
zz080HermitianConjugate[Subscript[a, 7]]}/4;

test2 =  zz075NonCommutativeTimes @@ Reverse@{
Subscript[a, 1], Subscript[a, 2]^2,
zz080HermitianConjugate[Subscript[a, 2]],
Subscript[a, 2], Subscript[a, 7],
zz080HermitianConjugate[Subscript[a, 2]],
zz080HermitianConjugate[Subscript[a, 3]]};

test3 =  zz075NonCommutativeTimes @@ Reverse@{
Subscript[a, 1], Subscript[a, 2]^2,
zz080HermitianConjugate[Subscript[a, 7]],
Subscript[a, 2], Subscript[a, 7],
zz080HermitianConjugate[Subscript[a, 7]],
zz080HermitianConjugate[Subscript[a, 3]]};