Re: Conversion of Orderless functions to non Orderless one

• To: mathgroup at smc.vnet.net
• Subject: [mg24152] Re: [mg24046] Conversion of Orderless functions to non Orderless one
• From: Carl Woll <carlw at u.washington.edu>
• Date: Wed, 28 Jun 2000 02:12:04 -0400 (EDT)
• Organization: Physics Department, U of Washington
• References: <200006210620.CAA10924@smc.vnet.net>
• Sender: owner-wri-mathgroup at wolfram.com

```Here is one idea which may be useful.

Instead of messing with Times, create rules for NonCommutativeMultiply and
following presents suitable rules:

operators = a | b | c;

Unprotect[NonCommutativeMultiply];
ClearAll[NonCommutativeMultiply]
SetAttributes[NonCommutativeMultiply, {Flat, OneIdentity}]

x_ ** y_ := x y /; (FreeQ[Unevaluated[y], operators])
y_ ** z_ := y z /; (FreeQ[Unevaluated[y], operators])
x___ ** (y_ a_) ** z___ /; FreeQ[Unevaluated[y], operators] := y x ** a **
z

Protect[NonCommutativeMultiply];

In the above, it isn't necessary to set the attributes Flat and
OneIdentity for NonCommutativeMultiply,
as they are set by default. However, if you choose to use a different
operator, like CircleTimes, then you would need to set these attributes,
and this is why I chose to explicitly set these attributes. An important
point to note in the above code is the use of Unevaluated. Since we are
checking whether the operators a, b or c are present in y, there is no
need to evaluate y. If we didn't use Unevaluated, then the code would be
orders of magnitude slower.

For example, using Daniel Lichtblau's test case, we have

In[9]:=
NonCommutativeMultiply @@ {q, r, s, b, t, y, a, x, w, q, c, d, f} //
Timing

Out[9]=
2
{0.07 Second, d f q  r s t w x y b ** a ** c}

which looks like what we want. To illustrate what would happen if we
didn't use Unevaluated, I removed it from the definition of **, with the
following timing result.

In[18]:=
NonCommutativeMultiply @@ {q, r, s, b, t, y, a, x, w, q, c, d, f} //
Timing

Out[18]=
2
{23.06 Second, d f q  r s t w x y b ** a ** c}

The same result, but over 30 times slower.

I hope the above ideas are useful for you.

Carl

zhl67 at hotmail.com wrote:

> Hi, there
>
> My question might be silly to somebody out there but it really bothers
> me: Is there any way to convert an orderless function into non
> orderless ones for a certain range of arguments?
>
> For instance, let's say have a set Operators:
>
> Operators={a,b,c}
>
> What I wanted to do is that whenever expressions like Times[b,a,c] is
> entered, the outcome should look like b**a**c (i.e. Times turned into
> NonCommutativeMultiply). The special requirement is that this change
> happens only for members of the set Operators (otherwise I can just
> ClearAttributes[Times,Orderless] ), and that the output keeps the order
> of the input argument, i.e. it should be b**a**c, NOT a**b**c. Could
> anyone help the case?
>
> Liu Zhao
> Univ. York, UK
>
> Sent via Deja.com http://www.deja.com/