0
$\begingroup$

I'm actually new to Mathematica I have been using sympy and sometimes cadabra to do calculations for a while though, I was wondering if there is an easy way to compute arbitrary expressions simplified by commutators, by defining commutations

For example, let's say I have

H=w_{1}bbd+w2aad+g bd a +conjugate(g)adb

And I wanted to get

H=w_{1}bbd+w2aad+g bd a +conjugate(g)adb

How would I get a simplified answer using the fact that

H=w_{1}bbd+w2aad+g bd a +conjugate(g)adb

Here's how it would be done in Cadabra for reference https://stackoverflow.com/questions/62254012/sympy-how-to-get-simplified-commutators-using-the-second-quantization-module

Can this be done simply in Mathematica? Sorry if it's a silly question could not find any info about it

$\endgroup$
2
0
$\begingroup$

As already discussed in the comments under OPs question: computations of this kind can be facilitated by some packages. Regarding the specific problem posed by OP a minimal semi-automatic solution would be

(* Check if a symbol is non-commutative under NCM: defaults False *)
ClearAll[NCQ]
NCQ[a__]:=NCQ@List[a];
NCQ[a_List]:=NCQ[#]&/@a
NCQ[Subscript[a_,i_]]:=NCQ[a]
NCQ[a_]:=False;

(* Non-commutative multiply *)
ClearAll[NCM];
NCM[]:=1;
NCM[a_]:=a
NCM[x___,NCM[y1_,y2__],z___]:=NCM[x,y1,y2,z]
NCM[x___,f_[y1_,y2___],z___]/;MemberQ[{Plus,List,Equal,Rule,RuleDelayed},f]:=f@@Map[NCM[x,#,z]&,{y1,y2}]
NCM[x___,Times[y1_,y2__],z___]:=NCM[x,y1,y2,z]
NCM[x__/;MemberQ[NCQ[x],False](*contains commuting factors*)]:=Module[{s,nc},
    s=1;
    nc=If[NCQ[#],#,s=Times[s,#];Nothing]&/@{x};
    Return[Times[s,NCM@@nc]]
]
NCM/:MakeBoxes[NCM[a_,b__],StandardForm]/;BoxForm`UseIcons:=ToBoxes@Row[{a,b},"**"]

(* Dagger symbol *)
ClearAll[dagger];
dagger/:MakeBoxes[dagger[a_],StandardForm]/;BoxForm`UseIcons:=ToBoxes@Superscript[a,"\[Dagger]"]
dagger/:NCQ[dagger[a_]]:=NCQ[a]

(* Commutator symbol *)
ClearAll[NCC];
NCQ[NCC[a_,b_]]:=True;
NCC[a_,a_]:=0
NCC/:MakeBoxes[NCC[a_,b_],StandardForm]/;BoxForm`UseIcons:=ToBoxes@Row[{"[",a,",",b,"]"}]

followed by the explicit computation based by "normal" ordering non-commutative products (the method order) of as assuming $\omega_1$, $\omega_2$, $g$ and $\bar{g}$ are commutative constants:

(* Establish a as a non-commuting symbol in NCM *)
NCQ[a]=True;

(* Setup normal-ordered commutators *)
NCC[Subscript[a, k_],dagger[Subscript[a, l_]]]:=KroneckerDelta[k,l]
NCC[dagger[Subscript[a, l_]],Subscript[a, k_]]:=-NCC[Subscript[a, k],dagger[Subscript[a, l]]]
NCC[Subscript[a, k_],Subscript[a, l_]]:=-NCC[Subscript[a, l],Subscript[a, k]]/;(!OrderedQ[{k,l}])
NCC[dagger[Subscript[a, k_]],dagger[Subscript[a, l_]]]:=-NCC[dagger[Subscript[a, l]],dagger[Subscript[a, k]]]/;(!OrderedQ[{k,l}])

(* Implement a "normal order" for products of a_i and dagger[a_i]*)
ClearAll[order]; 
order[exp_]:=Fold[ReplaceRepeated,exp,{
HoldPattern[NCM[x___,dagger[Subscript[a, k_]],Subscript[a, l_],y___]]:>NCM[x,Subscript[a, l],dagger[Subscript[a, k]],y]+NCM[x,NCC[dagger[Subscript[a, k]],Subscript[a, l]],y],
HoldPattern[NCM[x___,Subscript[a, k_],Subscript[a, l_],y___]]:>NCM[x,Subscript[a, l],Subscript[a, k],y]+NCM[x,NCC[Subscript[a, k],Subscript[a, l]],y]/;(!OrderedQ[{k,l}]),
HoldPattern[NCM[x___,dagger[Subscript[a, k_]],dagger[Subscript[a, l_]],y___]]:>NCM[x,dagger[Subscript[a, l]],dagger[Subscript[a, k]],y]+NCM[x,NCC[dagger[Subscript[a, k]],dagger[Subscript[a, l]]],y]/;(!OrderedQ[{k,l}])
}];

(** Computation **)
Subscript[\[Omega],1]* NCM[Subscript[a,1],dagger[Subscript[a,1]]]+Subscript[\[Omega],2]*NCM[Subscript[a,2],dagger[Subscript[a,2]]]+g*NCM[dagger[Subscript[a,1]],Subscript[a,2]]+gb*NCM[dagger[Subscript[a,1]],Subscript[a,2]]
NCM[%,Subscript[a, 1]]-NCM[Subscript[a, 1],%]
%//order//Expand//Simplify
%/.HoldPattern[NCC[Subscript[a, k_],Subscript[a, l_]]]:>0

Result

which I simplified further in the last step assuming $[a_i,a_j]=0$, which if I recall Second quantization correctly should be the case. I have neither checked the code thoroughly nor did I do the computation by hand carefully, so I can not really guarantee it to be correct but it seems plausible to me apart from the strange definition of the last two terms in $H$ (I would have expected by looking at for something like $a_2^\dagger a_1$ in the last term instead of being identical to the second to last apart from the prefactor).

This code works by first implementing the rudimentary method NCM for non-commutative products with the auxiliary function NCQ checking symbols for potentially non-commutative character. dagger and NCC are symbols for Hermitian conjugate (just a wrapper here) and symbolic commutators respectively. To perform the actual computation $[H,a_1]$ I implemented the explicit commutators for $a_i$ and $a_i^\dagger$ and established a "normal ordering" with the rules in order. order commutes all daggers to the right and then orders all daggered and non-daggered appearances of $a$ according to Mathematicas canonical ordering.

This code is meant to given an impression on how one could implement such computations in an in principle straight-forward manner: which means that the code is probably terribly inefficient BUT most likely faster than a human. Implementing $[a_i,a_j]=0$ together with the other commutators would reduce the intermediate terms significantly.

$\endgroup$
3
  • $\begingroup$ This is pretty much was I was looking for , It is quite the work to have this simple calculations in mathematica, I'll give it a try but most likely I'll end up still using cadabra, Thanks for the answer it was pretty detailed and understandable $\endgroup$ Nov 26 '20 at 4:26
  • $\begingroup$ @GerardoSuarez The problem is that Mathematica has (at least to my knowledge) no inbuilt functionalities for symbolic computations involving non-commutative products. Implementing such methods is quite tricky if one wants a flexible solution on the one hand and a potent one on the other. I had most of the code for this answer NCM and NCQ lying around since I have been working on large symbolic expressions involving non-commutative products. $\endgroup$
    – N0va
    Nov 26 '20 at 5:10
  • $\begingroup$ Yes, I get it, in this case I think the open source route seems way more user friendly to me, It will probably be a pain to implement things like partial traces in mathematica, but I will have to take a look and try for myself $\endgroup$ Nov 26 '20 at 5:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.