MathGroup Archive 1998

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

Search the Archive

Re: commutativity


  • To: mathgroup@smc.vnet.net
  • Subject: [mg11726] Re: commutativity
  • From: daiyanh@mindspring.com (Daitaro Hagihara)
  • Date: Thu, 26 Mar 1998 03:08:54 -0500
  • Organization: MindSpring Enterprises
  • References: <6ek4j9$jag@smc.vnet.net>

In article <6ek4j9$jag@smc.vnet.net>, John Albert Horst 
<horst@cme.nist.gov> wrote:

> I would like to be able to define a rule called, say, commutativeOff
> that would work as follows:
> 
> In[1] := a*b == b*a/.commutativeOff
> 
> Out[1] := False
> 
> As it is,
> 
> In[1] := a*b == b*a
> 
> Out[1] := True
> 
> How can I do this?

Working on this topic on and off for a week, I came up with a poor man's
non-commutative package.  It uses ordinay symbols to represent basic
algebra, and it can be turned on and off by a couple of switches in a
considerately unintrusive way.  Just eval all of the following in
brackets ([...]), and it starts out with the usual commutative
behavior; all math is unchanged.  Then by issuing "commutativeOff"
command, things will become completely non-commutative.  To get back to
the usual behavior, issue "commutativeOn" command.  The vector
differentiation is currently nothing more than a hack.  Even with a
future improvement, if any, this is no replacement for full tensor
packages out there.

Examples:

commutativeOff --> False

b x 5 a --> 5 b x a

b x 5 a===x b 5 a --> False

D[b x 5 a,x] -->    T
                 5 b  a

D[Distribute//@((Y-P T)'W(Y-P T)),T]/.W'->W -->     T          T
    -2 P  W Y + 2 P  W P T

 this last example is from least square

The program is short and does more than what you asked for.  So give it
a try.


(*************************************************************************
This is a poor man's non-commutative package.  It uses ordinay symbols
to represent basic algebra, and it can be turned on and off by a couple
of switches in a considerately unintrusive way.  Just evaluate all of
the following, and it starts out with the usual commutative behavior;
all math is unchanged.  Then by issuing "commutativeOff" command,
things will become completely non-commutative.  To get back to the
usual behavior, issue "commutativeOn" command.  The vector
differentiation is currently nothing more than a hack.

Examples:

commutativeOff --> False

b x 5 a --> 5 b x a

b x 5 a===x b 5 a --> False

D[b x 5 a,x] -->    T
                 5 b  a

D[Distribute//@((Y-P T)'W(Y-P T)),T]/.W'->W -->     T          T
    -2 P  W Y + 2 P  W P T

 this last example is from least square
**************************************************************************)


BeginPackage["pmncap`"]


commutativeOff;
commutativeOn;
pmncap`Times;
pmncap`D;


Begin["`private`"]


Module[{privatecommutativity=True},
       commutativeOff:=privatecommutativity=False;
       commutativeOn:=privatecommutativity=True;
       commutativeP:=privatecommutativity;]


Times[x___]:=System`Times[x]/;commutativeP;


Times[x___,n__?NumberQ,y___]:=n Times[x,y]/;!commutativeP;
Times[x___,t_System`Times,y___]:=Times[x,Sequence@@t,y]/;!commutativeP;
Times[x_]:=x/;!commutativeP;
Times[]:=1/;!commutativeP;


Attributes[Times] = {Flat, Listable, OneIdentity}; Default[Times] := 1;


Times[x_^p_.,x_^q_.]:=x^(p+q)/;!commutativeP;


Format[e_Times]:=HoldForm[e]/.Power->power/.Times->System`Times;
Format[e_Times,InputForm]:=ValueList[e]/.Power->power/.Times->System`Times;
Format[power[x__]]:=HoldForm[Power[x]];
Format[power[x__],InputForm]:=ValueList[Power[x]];


Unprotect[Power];
Format[e_Times^p_,InputForm]:=ValueList[e^p]/.Power->power/.Times->System`Times;
Protect[Power];


D[e_,x__]:=System`D[e,x]/;commutativeP;
D[e_,x_?AtomQ]/;!commutativeP:=System`D[e/.(y:(x|tran[x]))^p_Integer?Positive:>Rest[Join@@Table[Times[dummy,y],{p}]]/.Times->(Hold[Times[##]]&)/.tran[x]->Hold[tran[x]],x]//.Hold[y:(Times|tran)[__]]->y/.dummy->1;
D[e_,x_List]:=Fold[D[#1,#2]&,e,Table[#1,#2]&[First@x,Rest@x]]/;!commutativeP;
D[e_,x__]:=Fold[D[#1,#2]&,e,{x}]/;!commutativeP;
System`D[e_Times,x_]^:=Plus@@MapIndexed[tran[MapAt[System`D[#,x]&,##],#2]&,Table[#,{Length@#}]]&@e/;!commutativeP;


tran[e_Times,{n_}]:=Times[tran@Take[e,n-1],Take[e,{n,Length[e]}]];
tran[e_Times]:=Reverse[tran/@e];
tran[e_System`Times,nl___]:=tran[#,nl]&/@e; tran[e_Plus,___]:=tran/@e;
tran[x_Symbol,__]:=tran[x];   (* tran[x_?AtomQ,___]:=x; *)
tran[x_?NumberQ,___]:=x;
tran[x_^p_Integer,___]:=tran[x]^p;
tran[tran[e_],___]:=e;
System`D[tran[x_],x_]^:=1;

Format[tran[x_],OutputForm]:=x^"T";
Format[tran[x_],InputForm]:=OutputForm[x'];


$mypre[e_]:=(If[commutativeP,Identity@#,#/.System`Times->Times//.Derivative[n_][x_]:>Nest[tran,x,n]]&@Hold[e])[[1]];
SetAttributes[$mypre,HoldFirst];
$Pre=$mypre;


End[(*`private`*)]
End[(*pmncap`*)]



  • Prev by Date: Printing from Mathematica 3.0 on NT 4.0
  • Next by Date: Re: Using Mathematica results in publications
  • Prev by thread: RE: commutativity
  • Next by thread: Re: commutativity