MathGroup Archive 2010

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

Search the Archive

Re: Re: Define an antisymmetric function

  • To: mathgroup at smc.vnet.net
  • Subject: [mg107467] Re: [mg107449] Re: Define an antisymmetric function
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Sat, 13 Feb 2010 05:24:24 -0500 (EST)
  • References: <hl0r36$uu$1@smc.vnet.net> <201002111307.IAA03558@smc.vnet.net>

Hi Szabolcs & Torsten,

Szabolcs, thanks for this clarification  - I should have been more clear.

I believe that what Leonid referred to when he said that it might not
> work if you add pattern based definitions later on was that this
> approach assumed that the "antisymmetry definition" is the very last
> one in the DownValue list.


Yes, that's exactly what I meant.  As soon as we attach some condition of
almost any complexity to the rule, it becomes specific (less specific than only
explicit definitions which do not involve patterns at all and are kept internally
in a hash table), even if it's "host" pattern is very general. Therefore, even
patterns that appear less general than the bare "host" pattern, have a pretty
good chance to be interpreted as more general by Mathematica, and therefore
become the last.

Precisely this happens if for example you add the following definition:

In[75]:=G[x_, a] := (x + a)^2;

In[76]:= DownValues[G]

Out[76]= {HoldPattern[G[a, b]] :> f[a, b],
 HoldPattern[G[a, c]] :> g[a, c], HoldPattern[G[b, c]] :> h[b, c],
 HoldPattern[G[x_, y_]] :> -G[y, x] /;
   Hold[G[y, x]] =!= (Hold[G[y, x]] /. Most[DownValues[G]]),
 HoldPattern[G[x_, a]] :> (x + a)^2}

In[77]:= G[d, a]

During evaluation of In[77]:= $RecursionLimit::reclim: Recursion depth of
256 exceeded. >>

During evaluation of In[77]:= $RecursionLimit::reclim: Recursion depth of
256 exceeded. >>


The following version will be somewhat more robust:

ClearAll[G];
G[a, b] := f[a, b]
G[a, c] := g[a, c]
G[b, c] := h[b, c]

Module[{this},
  G[x_, y_] :=
   -G[y, x] /; (this; True) &&
     Hold[G[y, x]] =!= (Hold[G[y, x]] /.
        DeleteCases[DownValues[G], _?(! FreeQ[#, this] &)])];

But it resorts to DeleteCases and this will result in some performance hit.
This version can take this extra definition added later:

In[86]:= G[x_, a] := (x + a)^2;

In[87]:= G[b, a]

Out[87]= -f[a, b]

In[88]:= G[d, a]

Out[88]= (a + d)^2

In[89]:= G[a, d]

Out[89]= -(a + d)^2



> Mathematica tries to automatically order
> definitions from most specific to most general, but this is not always
> possible.  When it can't do this, it just adds rules to the DownValue
> list in the order they were defined.  So a general pattern based
> definition *may* displace the antisymmetry rule from the very last
> position, especially if it is added later.  Just be careful with the
> order in which definitions are made.
>

Yes, this is exactly the point. (which I think is well -illustrated by the
examples above).

Best,
Leonid



  • Prev by Date: Re: How to scope PopupMenu values in a DynamicModule?
  • Next by Date: Re: Random number with custom distribution
  • Previous by thread: Re: Define an antisymmetric function
  • Next by thread: Re: Define an antisymmetric function