Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
    
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. –  Szabolcs Dec 11 '12 at 0:53
    
I was just going to point out what Szabolcs said... I've changed it to $\LaTeX$, but do review the dagger term. –  rm -rf Dec 11 '12 at 0:56
    
Thanks for the edit guys. I have corrected it and will remember to format things correctly in future. –  Karan Dec 11 '12 at 1:12
    
Check section "Some noncommutative algebraic manipulation" from nb available here –  Daniel Lichtblau Dec 11 '12 at 16:27
add comment

migrated from stackoverflow.com Dec 11 '12 at 0:22

This question came from our site for professional and enthusiast programmers.

3 Answers

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.

share|improve this answer
    
@Karan Stephen's suggestion is good. Does $a^\dagger$, indeed commute with $b$ and $c$, though? –  Mark McClure Dec 11 '12 at 2:22
    
@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. –  Karan Dec 11 '12 at 2:38
    
@Stephen That sounds like a good idea. I will try this. –  Karan Dec 11 '12 at 2:38
    
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]; –  Stephen Luttrell Dec 11 '12 at 3:27
    
@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? –  Karan Dec 11 '12 at 7:13
show 3 more comments

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.

share|improve this answer
    
Thanks for the help. I have edited the question to include an example. I will try what you suggested. –  Karan Dec 11 '12 at 0:41
add comment

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
share|improve this answer
    
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. –  Karan Dec 11 '12 at 18:51
    
Maybe. Can you send me a notebook with some large expressions? –  Rolf Mertig Dec 11 '12 at 21:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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