Say I have an expression such as

(a + X)**(b-Y)

where the variables above possess the following commutation relations [a, b] = [a, X] = [a, Y] = [b, X] = [b, Y] = 0 and [X, Y] is nonzero.

I want to use mathematica to expand out these terms. This can be done using the "Distribute" command. The input is

Distribute[(a + X)**(b-Y)]

and the output is

a ** b + a ** (-Y) + X ** b + X ** (-Y).

I now want to simplify this expression using the commutation relations given above. I'm not sure how to go about uploading these commutation relations into mathematica such that this expression can be simplified.

  • $\begingroup$ How about using replacement rules? $\endgroup$
    – J. M.'s torpor
    Jun 29 '15 at 5:53
  • $\begingroup$ In general, these expression get much more ugly. Such as (a+bY+cX)^3(b-Y)^2 or typically much worse expression. As far as I know, although I am new to mathematica, applying replacement rules would involve applying a rule for all possible permutations of the terms. Which would not be fun. $\endgroup$
    – T-Ray
    Jun 29 '15 at 6:02
  • 1
    $\begingroup$ what are the rules for processing of powers for example [a,b^n] and [a^n, b] ? $\endgroup$
    – k_v
    Jun 29 '15 at 6:30
  • $\begingroup$ @k_v If $[a,b]=0$, it follows that $[a,b^n]=[a^n,b]=0$, so this is not an issue. $\endgroup$
    – Jens
    Jun 29 '15 at 17:28

One way to achieve what is asked in the question, is to introduce an identity id which commutes with all quantities but can be used together with X and Y to efficiently tell NonCommutativeMultiply how to treat scalars a, b, and c:

id /: NonCommutativeMultiply[id, y_] := y
id /: NonCommutativeMultiply[x_, id] := x

NonCommutativeMultiply[x___, HoldPattern[Times[id, a_]], 
  y___] := a NonCommutativeMultiply[x, id, y]
NonCommutativeMultiply[x___, HoldPattern[Times[X, a_]], 
  y___] := a NonCommutativeMultiply[x, X, y]
NonCommutativeMultiply[x___, HoldPattern[Times[Y, a_]], 
  y___] := a NonCommutativeMultiply[x, Y, y]

In defining the properties of NonCommutativeMultiply, I had to temporarily use UnProtect. The purpose of id is seen in the three last lines: I can now define the linearity of ** under regular multiplication by a scalar a in the same way for the elements id, X and Y. But by specifying that id commutes with X and Y, I designate it as the element that accompanies all scalars a: instead of writing a for a commuting element, you therefore have to write a id.

The benefit of this additional convention is that I don't need to add specific definitions for each individual variable name that is intended to be a scalar. Anything that appears in the form a id or id c etc. is a scalar by definition.

Here is what the example looks like:

Distribute[(a id + X) ** (b id - Y)]

(* ==> a b id + b X - a Y - X ** Y *)

In the result, id again appears in the one term that has only scalars in it.

To make the definitions even shorter, you could replace all three lines between Unprotect and Protect by this:

 a NonCommutativeMultiply[x,p,y]
  • $\begingroup$ It works great. Thank you! $\endgroup$
    – T-Ray
    Jul 1 '15 at 4:06

Here's a method using replacement rules. This function takes a list of the noncommuting variables and returns the simplification rules:

commuteRules[noncom_] := {
  NonCommutativeMultiply[x___, 1, z___] -> NonCommutativeMultiply[x, z], 
  NonCommutativeMultiply[x___, a_ y_. /; FreeQ[a, Alternatives @@ noncom], z___] -> 
   a NonCommutativeMultiply[x, y, z], 
  NonCommutativeMultiply[x_] -> x,
  NonCommutativeMultiply[] -> 1

Now simplify an expression:

expr = Distribute[(a + X) ** (2 b - Y) ** (b - Y)]
a ** (2 b) ** b + a ** (2 b) ** (-Y) + a ** (-Y) ** b + 
a ** (-Y) ** (-Y) + X ** (2 b) ** b + X ** (2 b) ** (-Y) + 
X ** (-Y) ** b + X ** (-Y) ** (-Y)
expr //. commuteRules[{X, Y}]
2 a b^2 + 2 b^2 X - 3 a b Y - 3 b X ** Y + a Y ** Y + X ** Y ** Y

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.