Re: Simplify and Noncommutativity

• To: mathgroup at smc.vnet.net
• Subject: [mg60589] Re: Simplify and Noncommutativity
• From: "Carl K. Woll" <carl at woll2woll.com>
• Date: Wed, 21 Sep 2005 03:20:25 -0400 (EDT)
• Sender: owner-wri-mathgroup at wolfram.com

```Nilton wrote:
> Carl,
>
> I also would like a simple way to use Factor and Simplify with
> Noncommutative multiplication, but this seems not to work. Considers
> this case:
>
> In[1]:=  Factor[p0**p1**p0+p1**p1**p1]
>
> Out[1]=  p1 (p0 p0+p1 p1)
>
> The middle p1 should not "go out" of the product. Any workaround?
>
> Thanks,
> -- Nilton
>

I did consider this problem when I came up with my proposal. One thought was
to write my own factor function. This factor function would use Factor, and
then expand out any terms that contained out of order terms. In your
example, the full form of

p0 p0 + p1 p1

would be

ov[1,p0]ov[3,p0]+ov[1,p1]ov[3,p1]

and so this term would need to be expanded. For example:

factor[a_]:=Module[{},
tmp=Factor[a];
tmp //. t1 t2_Plus /; outoforderQ[t2] :> ((t1 # &) /@ t2
]

A suitable outoforderQ function would need to be written.

I didn't pursue this idea any further because I wasn't sure it was needed.
Other than appearance, what harm is there in having the out of order p1
term? The real problem is if applying Factor changed the expression so that
applying Expand to it yields something unequal to the original. I wouldn't
be surprised if there was an expression where Expand[Factor[expr]]!=expr but
I didn't think of one.

To summarize, if an out of order term bothers you, simply create your own
factor or simplify function as above. On the other hand, if there is a
situation where an out of order term causes other errors my whole approach
to this problem will need to be reworked or discarded.

Carl Woll
Wolfram Research

> Carl K. Woll wrote:
>> "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:
>>
>> Clear[ov]
>> 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
>>
>> Unprotect[NonCommutativeMultiply];
>> NonCommutativeMultiply[a__] := Times @@ MapIndexed[ov[First[#2], #1] &,
>> {a}]
>> Protect[NonCommutativeMultiply];
>>
>> 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:
>>
>> In[50]:=
>> p2**p1**Inv[p1+p3+p4]**p5+p2**p3**Inv[p1+p3+p4]**p5+p2**p4**Inv[p1+p3+p4]**p5
>> Out[50]=
>> 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
>> ov.
>>
>> Now, let's factor:
>>
>> In[51]:=
>> Factor[%]
>> Out[51]=
>> 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
>>
>> Carl Woll
>> Wolfram Research
>
>

```

• Prev by Date: Re: sporadic failure of SingularValueDecomposition[] in Mathematica 5.2
• Next by Date: Replacement Rule
• Previous by thread: Re: Bug in Reduce?
• Next by thread: Looking for n for which all 2-partitions are prime partitions.