5
$\begingroup$

I have been trying to do some oscillator algebra in Mathematica and having troubles with sorting and simplifying expressions. I am using the NCAlgebra package which helps to improve the properties of NonCommutativeMultiply in Mathematica. However I have to create a huge list of rules to replace terms using the algebra. This quickly becomes impractical since I get these enormous expressions and I have to sift through the terms to see what simplifies and add more rules.

I have been wondering if there is a way to write a sorting function that would take an elementary expression and change it to a list and then permute the elements of list to sort the expression. I am fairly new to Mathematica but I would eventually like to write a small package which would allow me to these kind of manipulations.

For example, I have terms like $a**b**c**a^\dagger$ where $a$, $b$, $c$, etc. commute with each other but $a**a^\dagger-a^\dagger**a =1$. So I would like to sort things such that all dagger operators are to the left and have Mathematica use the fact that $a$, $b$, $c$ commute to rewrite the expressions. Right now I am assigning rules for every type of term that appears in my calculation but the number of terms has become unmanageable.

$\endgroup$
4
  • $\begingroup$ Hello Karan, welcome to Mathematica.SE? Did you mean a**a(dagger)-a(dagger)**a =1? Note that you can also write $\LaTeX$, just surround your expression with dollar signs. $\endgroup$ Commented Dec 11, 2012 at 0:53
  • $\begingroup$ I was just going to point out what Szabolcs said... I've changed it to $\LaTeX$, but do review the dagger term. $\endgroup$ Commented Dec 11, 2012 at 0:56
  • $\begingroup$ Thanks for the edit guys. I have corrected it and will remember to format things correctly in future. $\endgroup$ Commented Dec 11, 2012 at 1:12
  • $\begingroup$ Check section "Some noncommutative algebraic manipulation" from nb available here $\endgroup$ Commented Dec 11, 2012 at 16:27

3 Answers 3

6
$\begingroup$

The trick here is to take control of the non-commuting operators, and to define your own set of rules. Use prod as the head of each operator product, where prod[x,y] represents x ** y, and you can then define rules for manipulating prod.

Define rules that move $a^\dagger$ to the left in an operator product.

prod[u___, a, ad, v___] := prod[u, ad, a, v] + prod[u, v];
prod[u___, x : b | c, ad, v___] := prod[u, ad, x, v];

then you can evaluate

prod[a, b, c, ad]

(* prod[b, c] + prod[ad, a, b, c] *)

Generalisations of this sort of trick should solve your problem.

$\endgroup$
9
  • $\begingroup$ @Karan Stephen's suggestion is good. Does $a^\dagger$, indeed commute with $b$ and $c$, though? $\endgroup$ Commented Dec 11, 2012 at 2:22
  • $\begingroup$ @Mark Yes $a^\dagger$ does commute with $b$ and $c$. However there is $b^\dagger$ and $c^\dagger$ which doesn't commute with b and c respectively. $\endgroup$ Commented Dec 11, 2012 at 2:38
  • $\begingroup$ @Stephen That sounds like a good idea. I will try this. $\endgroup$ Commented Dec 11, 2012 at 2:38
  • $\begingroup$ A more general approach would be to define prod[u___, a[i_], ad[j_], v___] := prod[u, ad[j], a[i], v] + prod[u, comm[a[i], ad[j]], v]; and then to define particular rules for c-number commutators such as prod[u___, comm[a[2], ad[1]], v___] := comm[a[2], ad[1]] prod[u, v]; $\endgroup$ Commented Dec 11, 2012 at 3:27
  • $\begingroup$ @Stephen I tried what you suggested but I ran into troubles. Here is what I did: Prod[x___, y___] := x ** y; Prod[a___, b_, c_, d___] := Prod[a, c, b, d] + Comm[b, c] Prod[a, d];Comm[a, $a^\dagger$] = 1; Comm[b, $b^\dagger$] = 1; Comm[a, b] = 0; Comm[$a^\dagger$, b] = 0; Comm[a, $b^\dagger$] = 0; Comm[$a^\dagger$, $b^\dagger$] = 0; Prod[a, b, $a^\dagger$]. However this gives some errors. Where am I making a mistake? $\endgroup$ Commented Dec 11, 2012 at 7:13
3
$\begingroup$

One possibility is to use FeynCalc:

[rolfm@localhost ~]$ math
Mathematica 9.0 for Linux x86 (64-bit)
Copyright 1988-2012 Wolfram Research, Inc.

In[1]:= FilePrint@"karan"                                                                                                                                                                                                                                                                    
(*
If FeynCalc is not already installed, do:
Import["http://www.feyncalc.org/install.m"]
*)
$LoadFeynArts=False;
Quiet@Get["HighEnergyPhysics`FeynCalc`"]
FI;
DeclareNonCommutative[a,b,ad,bd];
Commutator[a, ad] = 1;
Commutator[b, bd] = 1;
Commutator[b, ad] = 0;
Commutator[a, bd] = 0;
Commutator[ad,bd] = 0;
Commutator[a,  b] = 0;
DotSimplify[ a.b.ad ] 

In[2]:= <<karan                                                                                                                                                                                                                                                                              
Loading FeynCalc from /home/rolfm/.Mathematica/Applications/HighEnergyPhysics
FeynCalc 8.2.0 Type ?FeynCalc for help or visit http://www.feyncalc.org/
$PrePrint is set to FeynCalcForm. Use FI and FC to change the display format.

Out[2]= b + ad . b . a
$\endgroup$
2
  • $\begingroup$ Thanks for directing me to the package. It does do the job pretty neatly but somehow it is taking a very long time to do the calculations. I have a lot of expressions and using the DotSimplify on them is taking too long. Is there any way I can speed things up. $\endgroup$ Commented Dec 11, 2012 at 18:51
  • $\begingroup$ Maybe. Can you send me a notebook with some large expressions? $\endgroup$ Commented Dec 11, 2012 at 21:48
1
$\begingroup$

It would have helped if you have gives a simple example of what you want.

But you could always do something like

expr = a x^3 + b x^2 + c x + d
Apply[List, expr]
(*  {d, c*x, b*x^2, a*x^3}  *)

Now to sort it, use Sort and you can apply your sorting function, as described in help:

"Sort[list,p] applies the function p to pairs of elements in list to 
determine whether they are in order. The default function p is 
OrderedQ[{#1,#2}]&."

You can also use Permute using some permutation group.

If you give a small example of an input, and what you like to get as output it will help.

$\endgroup$
1
  • $\begingroup$ Thanks for the help. I have edited the question to include an example. I will try what you suggested. $\endgroup$ Commented Dec 11, 2012 at 0:41

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.