MathGroup Archive 2011

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

Search the Archive

Re: Solve never calls Equal?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg120306] Re: Solve never calls Equal?
  • From: Richard Fateman <fateman at cs.berkeley.edu>
  • Date: Mon, 18 Jul 2011 06:13:34 -0400 (EDT)
  • References: <201107150118.VAA23606@smc.vnet.net> <ivovvt$qpa$1@smc.vnet.net> <201107160941.FAA08237@smc.vnet.net> <7BBB2BCC-0234-4BDA-A129-3270EBA623CE@mimuw.edu.pl> <ivuc93$gth$1@smc.vnet.net>

On 7/17/2011 3:07 AM, Andrzej Kozlowski wrote:

>>>
>>> (RJF wrote) When does Solve call Equal on 2 numbers?   I poked around a little and
>>> found -- never.   I tried Integrate, Factor, Do, Product, Plot..  --never.
>>>
>>>
>>> note that f[x_] := If [x == 0, 1, f[x - 1]*x]; f[5] computes 5! and
>>> calls Equal 6 times... but Factorial[5] does not.
>>>
>>>
>>> Perhaps the internal support routines do not call Equal?
>>> or calls to it are compiled away and not in reach of redefinition by the
>>> user?  Or do they call SameQ?   (no, they don't. I tried it).
>>>
>>> Cheers
>>>
>>>
>>> RJF
>>>
>>>
>>
>> This may indeed "work", though one would have to check functions such as NSolve,

  NSum, Reduce, etc, which I haven't tried (and don't want to). But it 
certainly will produce effects like this:
>>
>> In[1]:= Unprotect[Equal];
>>
>> In[2]:= Equal[a_?NumberQ, b_?NumberQ] := SameQ[a, b]
>>
>> In[3]:= Protect[Equal];
>>
>> In[4]:= eqn = 2 x + 1 == 0;
>>
>> In[5]:= Solve[eqn, x][[1]] // N
>>
>> Out[5]= {x->-0.5}
>>
>> In[6]:= eqn /. %
>>
>> Out[6]= False
>>
>> I am not at all convinced that the "naive user" will find this behaviour much of an improvement,

in fact, quite the opposite.
>>
>> Andrzej Kozlowski
>
>
> Well, I decided to test it, and, as I suspected, the results are not "great". Let's solve a nice equation:
>
> Reduce[Exp[x] - x == 1/2&&  Abs[x]<  1, x]//N
> x==0.162909 -0.972479 I\[Or]x==0.162909 +0.972479 I
>
> Great, now let's try Richard's "improved" Mathematica:
>
> Unprotect[Equal];
>
> Equal[a_?NumberQ, b_?NumberQ] := SameQ[a, b]
>
> Protect[Equal];
>
> Reduce[Exp[x]-x==1/2&&Abs[x]<1,x]
> Reduce::nsmet: This system cannot be solved with the methods available to Reduce.>>


To be specific, let's change the definition of Equal to the one that I 
suggested, but augmented to keep count of how many times it was called 
with at least one Real argument.  Unprotect[Equal] and then

  Equal[a_Real, b_] := (count++;
   Equal[Rationalize[SetAccuracy[a, Infinity]], b])

  Equal[a_, b_Real] := (count++;
   Equal[a, Rationalize[SetAccuracy[b, Infinity]]])

Initialize count to 0.

What is count, after these numerical operations:

NIntegrate[Sin[1/x], {x, 0.1, 10.0}]
   count is 0.

Reduce[Sin[1/x] == 0, x]
   count is 0.

f[x_] := If[x == 0.0, 1.0, x*f[x - 1]]; f[5]
   count is 5.

Reduce[Exp[x] - x == 1/2 && Abs[x] < 1, x]     (andrzej's example)
   count is 4.

NSolve[Sin[1.0/x] == 0.0, x]

   count is 3.
NSolve[Sin[1/x] == 0, x]
   count is 2.

These numbers are small enough that we might as well print out WHAT is 
being compared.
The Reduce example tests the following numbers for equality to exactly 0:
-0.972478922705943081742383427880
0.51462253970
0.972478922705943081742383427880
0.51462253970  (again).

The NSolve example compares some complicated expression to 1.0.

I think it is hard to claim that these test could be done only with 
Significance arithmetic.  However, DanL has indicated that tracing Equal 
may not be effective if the system programs utilize some internal call 
to a system entry into PossibleZeroQ.  The point remains that
redefining Equal as done here does not seem to adversely affect NSolve, 
Reduce, NIntegrate. Nor does it seem to take much time.

RJF


  • Prev by Date: Re: Compile and Total
  • Next by Date: Find position of nonzero elements
  • Previous by thread: Re: Solve never calls Equal?
  • Next by thread: Re: Solve never calls Equal?