# Normal ordering in Mathematica

I want to create a function which normally orders a string of field operators. Consider the following:

$$\langle0\vert\hat{a}(k_n) \cdots \hat{a}(k_2)\hat{a}(k_1)\hat{a}^\dagger(k_1)\hat{a}^\dagger(k_2) \cdots \hat{a}^\dagger(k_n)\vert 0\rangle.$$

I would like to write the expression in the brackets with all daggered operators on the left, with the field operators satisfying

$$\left[\hat{a}(k_i), \hat{a}^\dagger(k_j)\right] = \delta(k_i - k_j),$$ $$\left[\hat{a}(k_i), \hat{a}(k_j)\right] = \left[\hat{a}^\dagger(k_i), \hat{a}^\dagger(k_j)\right] = 0.$$

This will generate many terms and I would like Mathematica to generate the terms for any specified $n$.

The required non-commutativity of the operators has been addressed in this post; Boson commutation relations, but I am stuck in using it to achieve a normally ordered expression.

• You might be interested in SNEG library (nrgljubljana.ijs.si/sneg). It is a mathematica package for second quantization. I think it does what you are looking for. – Sumit Mar 17 '16 at 12:11
• SNEG library does not work well at all for $n$ larger than 3. I need to take $n$ to much larger values – Sid Mar 17 '16 at 18:13
• I was going to link to my answer of that other question, but it seems you already knew about it! Magic! – evanb Dec 28 '17 at 16:25

Represent a string of field operators a[k]$\equiv\hat{a}(k)$ and ad[k]$\equiv\hat{a}^\dagger(k)$sandwiched between the ground state as correlate.

Then the definitions that will automate the manipulations is as follows:

ClearAll[correlate];

(*  Normalization <0|0> = 1  *)
correlate[] = 1;

(*  Commutation relation: [a(k1), a†(k2)] = δ(k1-k2)  *)
correlate[left, ad[k2], a[k1], right] + δ[k1 - k2] correlate[left, right];

(*  Commutation relations: [a(k1), a(k2)] = [a†(k1), a†(k2)] = 0  *)
correlate[left___, a[k1_], a[k2_], right___] /; !OrderedQ[{k2, k1}] :=
correlate[left, a[k2], a[k1], right];

(*  Annihilation of vacuum state: <0|a† and a|0> = 0  *)
correlate[___, a[_]] := 0;

correlate[a[k10], a[k9], ad[k8], a[k7], ad[k6], a[k5], ad[k4], ad[k3]]

• Actually there is a bug in my code. Instead of OrderedQ, I should have !OrderedQ. I'm fixing it now. Try the new version, and let me know if it works. – QuantumDot Dec 28 '17 at 15:15
• I'll just chime in and say you might want to use δ[k1,k2] rather than δ[k1-k2] depending on whether your momentum space is continuous or not. I suppose you can always make replacements. – evanb Dec 28 '17 at 16:36
• @Sid Be sure to clear definitions with ClearAll[correlate] after making the change to !OrderedQ to eliminate the old (buggy) definition from memory. (Or rerun from a fresh kernel). Your example works on my machine. – QuantumDot Dec 28 '17 at 17:36