Ordering in noncommutative multiply

I have an expression like

s ** p1 ** p1 ** p2 - s ** p1 ** p2 ** p1


Which should be zero because the commutator between p1 and p2 is zero (this example is from quantum mechanics)

So I tried ReplaceRepeated on my expressions to order them, and a Simplify should then give 0

For instance this rule works:

p2 ** p1 //. {a_ ** b_ /; ! OrderedQ[{a, b}] -> Com[a, b] + b ** a}


but this one never stops :

p2 ** p1 ** p1 //. {a_ ** b_ /; ! OrderedQ[{a, b}] -> Com[a, b] + b ** a}


Thus I tried

p2 ** p1 //. {a_ ** b_ /; Except[a neq b, ! OrderedQ[{a, b}]] -> Com[a, b] + b ** a}


but it doesn't work. Do you have any suggestions ?

The issue in your rule is that a_ and b_ don't necessarily need to be symbols. What if your a matches a larger portion of the expression?

OrderedQ[{(Com[p2, p1] + p1 ** p2), p1}]
(* False *)


Then the rule would be applied and I'm not sure this your intention. Please try this set of rules. I have added some print commands so that you see which rule was applied:

r = {
a_Symbol ** b_Symbol /; ! OrderedQ[{a, b}] :> (Print["R1"];
Com[a, b] + b ** a),
(e1_ + e2_) ** e3_ :> (Print["R2"]; e1 ** e3 + e2 ** e3),
e3_ ** (e1_ + e2_) :> (Print["R3"]; e3 ** e1 + e3 ** e2)
}

s ** p1 ** p1 ** p2 - s ** p1 ** p2 ** p1 //. r

(* -Com[s, p1] ** Com[p2, p1] - p1 ** s ** Com[p2, p1] *)


If Com[p2,p1] is zero, then the above expression vanishes.

mathematica can't reduce mostly the same expression: f[x1] ** p2 + g[x1] ** p1 ** p1 ** p2 - g[x1] ** p1 ** p2 ** p1 //. r

Yes, that's because I only allowed the rule to apply if the a_ and b_ are symbols. f[x1] is not a symbol. It is an expression with the head f.

The big catch here is the following: An expression like x+y is basically of the same type as f[x1]. It is Plus[x,y] and now let's assume you have to following:

z ** (x + y)


As you can check easily, OrderedQ[{z, (x + y)}] is False and therefore, your rule would apply which would result in

z ** (x + y) /. a_ ** b_ :> Com[a, b] + b ** a
(* Com[z, x + y] + (x + y) ** z *)


I thought that this is not what you want. Therefore, I explicitly forced the a and b in the replacement rule to be symbols. But this will lead to exactly the situation you have found, where f[x1] is not simplified.

• Thanks! this looks great. But can you explain me why: g[x1] ** p1 ** p1 ** p2 - g[x1] ** p1 ** p2 ** p1 //. r gives now zero as I wanted, but mathematica can't reduce mostly the same expression : f[x1] ** p2 + g[x1] ** p1 ** p1 ** p2 - g[x1] ** p1 ** p2 ** p1 //. r Then he doesn't simplify the last term! – Jip Jun 2 '15 at 9:14
• @Jip I tried to give some further explanation in the end of my answer. Please see the edit. – halirutan Jun 2 '15 at 10:14

Try NCAlgebra. You can do what you want with

<< NC
<< NCAlgebra
SetNonCommutative[p1, p2];
expr = s ** p1 ** p1 ** p2 - s ** p1 ** p2 ** p1
NCReplaceRepeated[expr, p2 ** p1 -> p1 ** p2]


which will evaluate to 0. Single lower case letters, e.g. s, are noncommutative by default.