# 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;


Here's a test:

correlate[a[k10], a[k9], ad[k8], a[k7], ad[k6], a[k5], ad[k4], ad[k3]] • this works great for the string asked in the question. Can an extension of correlate handle cases where some field operators in the string appear multiple times? At the moment, the above doesn't handle repeats. – Sid Dec 28 '17 at 15:11
• @Sid I'm sure I can. But to help me out, would you give me a couple examples and their expected results? – QuantumDot Dec 28 '17 at 15:14
• 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