MathGroup Archive 1997

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

Search the Archive

Re: possible bug in Cases/pattern matching??

  • To: mathgroup at smc.vnet.net
  • Subject: [mg6909] Re: [mg6859] possible bug in Cases/pattern matching??
  • From: David Withoff <withoff>
  • Date: Fri, 25 Apr 1997 14:00:39 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

> I am getting some very strange behavior when using Cases and
> replacement rules on a moderately long, but not horribly long
> expression.  When I use the expression bound to "tester" (below) in a
> variety of ways (also shown below), Mathematica just goes off into
> hyperspace and cannot even be properly interrupted, only aborted.  
> 
> I can make the expression just a little bit simpler and the correct
> answer is quickly returned, so I don't think it is a matter of
> insufficient memory or anything like that.  I have the same problem
> under both mma2 and mma3 under solaris and linux, and under at least
> mma2 on a PC.  Does this return the right answer for anyone?  Anyone
> have any idea what is happening??  Would appreciate direct answers to
> kant at scicomp.com for speed as well as to the mailing list if desired.
> 
>   Much thanks.  
>  - Elaine Kant
> 
> (*************************************************************)
> 
> (* Give the expression tester, defined below, *)
> 
>     Cases[tester[[2]], xx_ + num_Real, Infinity]
> 
> (* returns {}, correctly and virtually instantly (as does tester[[1]] etc),
> BUT
> *)
> 
>     Cases[tester, xx_ + num_Real, Infinity]
> 
> (* goes off into hyperspace.
> In addition, the following works fine:    *)
> 
>     Scan[Print[# /. (xx_ + num_Real :> xx+mcDouble[num])]&, tester[[2]]];
>     Print[done];
> 
> (* But this also seems to hang: *)
> 
>      tester[[2]] /. (xx_ + num_Real :> xx+mcDouble[num]) 
> 
> (* here's the expression used *)
> 
> tester = set[part[r1, i21, j1, k1], part[r1, i21, j1, k1] + 
>     part[U, -1 + i21, -1 + j1, -1 + k1]*part[SA1, 1, 0, 0, 0] + 
>     part[U, -1 + i21, -1 + j1, k1]*part[SA1, 1, 0, 0, 1] + 
>     part[U, -1 + i21, -1 + j1, 1 + k1]*part[SA1, 1, 0, 0, 2] + 
>     part[U, -1 + i21, j1, -1 + k1]*part[SA1, 1, 0, 1, 0] + 
>     part[U, -1 + i21, j1, k1]*part[SA1, 1, 0, 1, 1] + 
>     part[U, -1 + i21, j1, 1 + k1]*part[SA1, 1, 0, 1, 2] + 
>     part[U, -1 + i21, 1 + j1, -1 + k1]*part[SA1, 1, 0, 2, 0] + 
>     part[U, -1 + i21, 1 + j1, k1]*part[SA1, 1, 0, 2, 1] + 
>     part[U, -1 + i21, 1 + j1, 1 + k1]*part[SA1, 1, 0, 2, 2] + 
>     part[U, i21, -1 + j1, -1 + k1]*part[SA1, 1, 1, 0, 0] + 
>     part[U, i21, -1 + j1, k1]*part[SA1, 1, 1, 0, 1] + 
>     part[U, i21, -1 + j1, 1 + k1]*part[SA1, 1, 1, 0, 2] + 
>     part[U, i21, j1, -1 + k1]*part[SA1, 1, 1, 1, 0] + 
>     part[U, i21, j1, k1]*part[SA1, 1, 1, 1, 1] + 
>     part[U, i21, j1, 1 + k1]*part[SA1, 1, 1, 1, 2] + 
>     part[U, i21, 1 + j1, -1 + k1]*part[SA1, 1, 1, 2, 0] + 
>     part[U, i21, 1 + j1, k1]*part[SA1, 1, 1, 2, 1] + 
>     part[U, i21, 1 + j1, 1 + k1]*part[SA1, 1, 1, 2, 2] + 
>     part[U, 1 + i21, -1 + j1, -1 + k1]*part[SA1, 1, 2, 0, 0] + 
>     part[U, 1 + i21, -1 + j1, k1]*part[SA1, 1, 2, 0, 1] + 
>     part[U, 1 + i21, -1 + j1, 1 + k1]*part[SA1, 1, 2, 0, 2] + 
>     part[U, 1 + i21, j1, -1 + k1]*part[SA1, 1, 2, 1, 0] + 
>     part[U, 1 + i21, j1, k1]*part[SA1, 1, 2, 1, 1] + 
>     part[U, 1 + i21, j1, 1 + k1]*part[SA1, 1, 2, 1, 2] + 
>     part[U, 1 + i21, 1 + j1, -1 + k1]*part[SA1, 1, 2, 2, 0] + 
>     part[U, 1 + i21, 1 + j1, k1]*part[SA1, 1, 2, 2, 1] + 
>     part[U, 1 + i21, 1 + j1, 1 + k1]*part[SA1, 1, 2, 2, 2]];
> 
> Print[Cases[tester[[2]], xx_ + num_Real, Infinity]];
> Scan[Print[# /. (xx_ + num_Real :> xx+mcDouble[num])]&, tester[[2]]];
> Print[done];
> 
> (* trouble ahead *)
> Cases[tester, xx_ + num_Real, Infinity]
> 
> (* tester[[2]] /. (xx_ + num_Real :> xx+mcDouble[num])  *)
> 
> ====================================
> 
> Elaine Kant
> SciComp Inc.
> 5806 Mesa Drive, Suite 250
> Austin, TX 78731
> 
> email:  kant at scicomp.com
> voice:  512-451-1430
> fax:    512-451-1622
> www:    http://www.sig.net/~scicomp/
> 
=====================================================================

This example will (in principle) finish, but the time required will
be rather large.  You can get an estimate of the time by extrapolating
from shorter examples.  Here are a few examples which show the trend.

In[2]:= Timing[
          Take[tester[[2]], 10] /. xx_ + num_Real :> xx+mcDouble[num]][[1]]

Out[2]= 4.79619 Second

In[3]:= Timing[
          Take[tester[[2]], 11] /. xx_ + num_Real :> xx+mcDouble[num]][[1]]

Out[3]= 14.6702 Second

In[4]:= Timing[
          Take[tester[[2]], 12] /. xx_ + num_Real :> xx+mcDouble[num]][[1]]

Out[4]= 44.7598 Second

These examples show that the time increases by roughly a factor of 3
with each additional element taken from tester[[2]].  Since tester[[2]]
has 28 elements, a simple extrapolation suggests that the complete
calculation will finish in about 60 years.

I didn't have any trouble aborting this particular example, though.
If weren't able to abort this calculation, that's a separate problem.

If you don't want to wait 60 years, you can change the calculation so
that the pattern matcher doesn't have to try so many cases.  The basic
idea is to do some simple tests, or to check some simple patterns, before
trying the pattern that you really want to use.

Here is one way to do that in your example.  This rule is set up so that
the pattern matcher doesn't attempt to match xx_ + num_Real until it
has already checked that the expression has a head of Plus and that at
least one element in the expression has a head of Real.

In[6]:= Timing[Take[tester[[2]], 12] /.
               p_Plus :> result /;
                  (MemberQ[Head /@ List @@ p, Real] &&
                     ((result = p /. xx_ + num_Real ->
                             xx + mcDouble[num]) =!= p)) ][[1]]

Out[6]= 0.046868 Second

It could be argued (and I would certainly agree with this) that the
pattern matcher ought to do this automatically.  It is unavoidable
that the pattern matcher will sometimes look through a large number
of cases, such as all possible element orderings in patterns that are
affected by the Orderless attribute, but in this example, the pattern
matcher is checking far more cases than it needs to check.  I will
report this example to our development group so that it can be
investigated to see if something can be done about it.

In the meantime, I hope that the suggestion above is useful.  The
basic idea of doing some simple tests before checking more complicated
patterns is useful in many examples involving pattern matching.

Dave Withoff
Wolfram Research


  • Prev by Date: Re: Fingerpainting Linear Inequalities
  • Next by Date: [Q] Prblems with characters
  • Previous by thread: possible bug in Cases/pattern matching??
  • Next by thread: Hurst Exponent