1

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

1 Answers1

0

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]]]+gNCM[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.

N0va
  • 3,370
  • 11
  • 16
  • 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 – Gerardo Suarez Nov 26 '20 at 04:26
  • @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. – N0va Nov 26 '20 at 05:10
  • 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 – Gerardo Suarez Nov 26 '20 at 05:20