Re: question
- To: mathgroup at christensen.cybernetics.net
- Subject: [mg1499] Re: question
- From: villegas (Robert Villegas)
- Date: Mon, 19 Jun 1995 02:26:14 -0400
- Newsgroups: comp.soft-sys.math.mathematica
- Organization: Wolfram Research, Inc.
> Here's the question: result= a b c d
>
> a,b,c,d are long algebraic expressions, but one of them, d, often is zero.
Even
> then, Mathematica grinds away wasting time calculating a,b, and c, quite
> uselessly. If I switch to result= d a b c will that fix it? Or how?
>
> (I don't just try it because its buried in complex code and involving large
> numbers of such cases; I don't want to change the code unless I am assurred
it
> is going to shorten calculations substantially.)
When you know it's the fourth factor that is often 0, you can extract
the fourth element without evaluating it or the expression, and see if
it's 0. HeldPart combined with Unevaluated will do this. I'll use
variables that print so we can verify that things aren't evaluating when
we don't want them to.
In[7]:= {a, b, c, d} := {Print["a"], Print["b"], Print["c"], Print["d"]};
In[10]:= HeldPart[Unevaluated[a b c 0], 4] === Hold[0]
Out[10]= True
In[13]:= HeldPart[Unevaluated[a b c d], 4] === Hold[0]
Out[13]= False
Possibly it's most convenient for you if you have a separate function
to do this checking in your program:
In[14]:= Attributes[test] = HoldFirst
Out[14]= HoldFirst
In[15]:= test[expr_] :=
If[HeldPart[Unevaluated[expr], 4] === Hold[0], 0, expr]
In[16]:= test[a b c 0]
Out[16]= 0
In[17]:= test[a b c d]
a
b
c
d
4
Out[17]= Null
This should handle the stated problem.
It's no more difficult to handle this even if you have one or more
terms and at least one of them might be 0, but you don't know which
one(s). MemberQ is ideal for this:
In[22]:= MemberQ[Unevaluated[a 0 b c], 0]
Out[22]= True
If a degenerate case with 0 being the only factor is a possibility, tell
MemberQ to look at level 0 of the expression (the whole thing) in addition
to the default level 1:
In[23]:= MemberQ[Unevaluated[0], 0, {0, 1}]
Out[23]= True
Another approach to the general case is Replace:
In[25]:= Replace[Unevaluated[a 0 b c], Literal[_. 0] -> 0]
Out[25]= 0
In[26]:= Replace[Unevaluated[0], Literal[_. 0] -> 0]
Out[26]= 0
In[27]:= Replace[Unevaluated[a b c d], Literal[_. 0] -> 0]
a
b
c
d
4
Out[27]= Null
If you're going to call this lots and lots of times, the Replace method
might use up some extra time, since as Allan Hayes has demonstrated,
the Flat and Orderless attributes have a measurable effect.
Robby Villegas