MathGroup Archive 2003

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

Search the Archive

Re: Redefine[Plus] - problem

  • To: mathgroup at smc.vnet.net
  • Subject: [mg41171] Re: Redefine[Plus] - problem
  • From: "Carl K. Woll" <carlw at u.washington.edu>
  • Date: Tue, 6 May 2003 06:02:14 -0400 (EDT)
  • Organization: University of Washington
  • References: <b92ha1$li0$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Petr,

As mentioned by others, in general it is not a good idea to write rules for
Plus. Since Plus is an extremely common operation, writing rules for Plus
will slow it down. Moreover, Plus is a Flat, Orderless function, and writing
rules for Flat, Orderless functions needs to be done very carefully.

You might ask why one should be careful when writing rules for Flat,
Orderless functions. In particular, consider the following case of a binary
rule for a Flat, Orderless function f:

SetAttributes[f, {Flat, Orderless}]
f[a_,a_]:= a

Admittedly this definition is silly, since it would be much simpler to
simply use Union. At any rate, when f is applied to a list of random
integers, what will happen? If f were simply flat, then f would compare all
adjacent elements to see if they are the same, and then basically delete one
of them, an O(n) operation, where n is the length of the list. Now consider
the case where f is both flat and orderless. At the minimum, f would need to
compare each element to every other element for an O(n^2) operation.
However, it might be worse than this, since the orderless function means
that all n! permutations of the list are equivalent, and so Mathematica
could basically permute the list, compare adjacent elements and repeat up to
n! times for a complexity of O(n*n!). Since the complexity of the Union
function is O(n log n), the above approach is a horrifyingly awful
possibility.

Consider the following test of the function f:

In[10]:=
Table[f@@Range[i];//Timing,{i,15}]
Out[10]=
{{0. Second, Null}, {0. Second, Null}, {0. Second, Null}, {0. Second,
    Null}, {0. Second, Null}, {0. Second, Null}, {0. Second,
    Null}, {0. Second, Null}, {0.031 Second, Null}, {0.094 Second,
    Null}, {0.234 Second, Null}, {0.734 Second, Null}, {2.266 Second,
    Null}, {6.781 Second, Null}, {20.547 Second, Null}}

When f is applied to Range[i], nothing happens other than substituting List
with f, since the input is already sorted and contains no duplicates. Yet
the complexity of this operation appears to be O(3^n), incredibly worse than
O(n log n).

The message you should get is never define a binary rule for a flat,
orderless function! Actually, that statement is too strong, a better message
would be: never define a binary rule for a flat, orderless function if you
plan to use that function with more than several arguments.

Now, as to your particular question, the difference in timing appears to be
a bug. It appears to be related to the rule

Plus[k : _?NumericQ, b : fc[y_]] := fc[k + y]

You may want to post a description of what you are trying to accomplish with
your code to the newsgroup, as I am sure you will get many useful responses.

Carl Woll
Physics Dept
U of Washington

"Petr Kujan" <kujanp at fel.cvut.cz> wrote in message
news:b92ha1$li0$1 at smc.vnet.net...
> Hello all,
>
> I would be grateful if someone could explain the difference in
> time consummation.
>
> I need redefine standard function Plus[] for function fc[]:
>
> Unprotect[Plus];
> Plus[a : fc[x_], b : fc[y_]] := fc[x + y]
> Plus[k : _?NumericQ, b : fc[y_]] := fc[k + y]
> Protect[Plus];
>
>
> Now easy computation is very slow (time consummation is exponential!):
>
> dat = Table[s, {20}];
> Plus @@ dat // Timing
>
> {20.019 Second, 20 s}
>
>
> But if the symbol s replace by x only:
>
> dat = Table[x, {20}];
> Plus @@ dat // Timing
>
> {0. Second, 20 x}
>
>
> Thank you,
> Petr Kujan
> --
> kujanp at fel.cvut.cz
>
>




  • Prev by Date: Re: Re: How change $AddOnsDirectory
  • Next by Date: Re: Using InterpolateRoot Function in Mathematica
  • Previous by thread: Re: Redefine[Plus] - problem
  • Next by thread: RE: Re: Redefine[Plus] - problem