MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Simplify and Noncommutativity

  • To: mathgroup at
  • Subject: [mg60372] Re: Simplify and Noncommutativity
  • From: "Carl K. Woll" <carlw at>
  • Date: Wed, 14 Sep 2005 03:27:44 -0400 (EDT)
  • Organization: University of Washington
  • References: <dfrhi4$g4l$>
  • Sender: owner-wri-mathgroup at

"Robert Schoefbeck" wrote:
>I have a rather lengthy expression of abstract products of matrices
> of the form
> myDot[M1,M2,...]
> If Inv[M] denotes the inverse matrix
> i have told mathematica that
> myDot[P1___,P2_,Inv[P2_],P3___]:=myDot[P1,P3];
> myDot[P1___,Inv[P2_],P2_,P3___]:=myDot[P1,P3];
> myDot[]=Unity;
> and that
> myDot[P1___,P2_+P3_,P4___]:=myDot[P1,P2,P4]+myDot[P1,P3,P4];
> and a lot more things.
> My Problem is:
> In big expressions i have huge cancellations of the form
> myDot[M1,Inv[M1+M2+M3+....]] + myDot[M2,Inv[M1+M2+M3+....]]
>  + myDot[M3 ,Inv[M1+M2+M3+....]]+...
> such that the summands M1,M2.... should be summed and then cancel
> against the Inv[...] part.
> I have a very slow workaround,
>     myDotSimp[HoldPattern[Plus[P6___, myDot[P5___, P1_, P3___],
>   myDot[P5___,P2_, P3___]]]] := P6 + myDot[P5, P1 + P2, P3];
>     SetOptions[Simplify, TransformationFunctions ->
>     {Automatic,myDotSimp}];
> this thing, however, is immensly time consuming.
> On the other hand, cancellations of the type
> Simplify[b/(b+c)+c/(b+c)]
> are extremly fast.
> Is there a way to combine the power of Simplify on Rational functions
> with a noncommutative multiplication?
> kind regards
> robert schoefbeck

One approach is to use regular multiplication, but to change your variables 
by adding ordering information. Here are the definitions:

Format[ov[ord_, var_]] := var

ov /: ov[i_, x_] + ov[i_, y_] := ov[i, x + y]
ov /: ov[i_, x_] ov[j_, Inv[x_]] := ov[Max[i, j], 1] /; Abs[i - j] == 1
ov /: a_. ov[i_, 1] := a /. ov[j_ /; j > i, x_] -> ov[j - 2, x]

Since it is cumbersome to type in ov for each variable, I create a rule that 
converts noncommutative multiplication using CenterDot into regular 
multiplication with ov variables. However, since CenterDot can't be 
displayed in plain text, for the purposes of this post I use 
NonCommutativeMultiply instead:

NonCommutativeMultiply[a__] := Times @@ MapIndexed[ov[First[#2], #1] &, {a}]

If you try it out, use CenterDot (or something else that looks nice) and you 
won't need the Unprotect/Protect statements.

Now, let's try out your problem:

p2 p1 Inv[p1+p3+p4] p5+p2 p3 Inv[p1+p3+p4] p5+p2 p4 Inv[p1+p3+p4] p5

Notice that the proper order of the factors is maintained. The displayed 
form of ov[1,p2] is p2, but the ordering is based on the first argument of 

Now, let's factor:

p2 p5

Just what you wanted. Now, for a few comments on the ov definitions. It is 
possible that the ov definitions can by very slow due to combinatorial 
explosion associated with the pattern matcher. If this happens, I have more 
complicated definitions which will avoid the combinatorial explosion and 
will hence be much quicker. Second, the rule with a_. ov[i_,1] is there to 
reindex all of the ov variables, so that stuff like

x y Inv[y] Inv[x]

will simplify. If you like this approach, and decided to experiment, I would 
be happy to have a dialog about your results.

Carl Woll
Wolfram Research 

  • Prev by Date: Re: Timed Notebooks for Student Take-home examinations
  • Next by Date: Re: Draw3D ColorFunction->Hue
  • Previous by thread: Simplify and Noncommutativity
  • Next by thread: Re: Simplify and Noncommutativity