MathGroup Archive 2004

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

Search the Archive

Re: Re: Zero testing

  • To: mathgroup at smc.vnet.net
  • Subject: [mg53211] Re: Re: Zero testing
  • From: Maxim <ab_def at prontomail.com>
  • Date: Thu, 30 Dec 2004 01:38:18 -0500 (EST)
  • Organization: MTU-Intel ISP
  • References: <200412231259.HAA21206@smc.vnet.net> <cqgu81$632$1@smc.vnet.net> <200412250901.EAA18578@smc.vnet.net> <D97FA519-5668-11D9-8E89-000A95B4967A@mimuw.edu.pl> <cqosl0$cf1$1@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

On Mon, 27 Dec 2004 11:45:36 +0000 (UTC), Andrzej Kozlowski  
<akoz at mimuw.edu.pl> wrote:

>
> On 25 Dec 2004, at 18:01, Maxim wrote:
>
>>> On the whole, you pretty much miss the point. Certainly I do not
>>> suggest
>>> that FullSimplify be applied at every step of the evaluation or
>>> anything
>>> of the sort. In any case, FullSimplify won't always be able to verify
>>> a ==
>>> b (take a = Derivative[0, 0, 1, 0][Hypergeometric2F1][1, 1, 1, 1 - E]
>>> and
>>> b = 1/E). When I'm saying that necessary checks aren't performed, in
>>> most
>>> cases that would mean checks based on significance arithmetic. Like I
>>> said, many discontinuous functions such as Floor do that (read the
>>> documentation on Floor and think about what should happen when we
>>> evaluate, say, Floor[Pi/Rationalize[Pi, 10^-100]]). In particular,
>>> Reduce
>>> does just that, generating Reduce::ncomp message when needed:
>>>
>>> In[1]:=
>>> Reduce[Pi*x >
>>>
>>> 754334734322669483655537561140633/
>>> 240112203426728897943499903682238*x]
>>>
>>> Reduce::ncomp: Unable to decide whether
>>> HoldForm[754334734322669483655537561140633/
>>> 240112203426728897943499903682238]
>>> and HoldForm[Pi] are equal. Assuming they are.
>>>
>>> Out[1]=
>>> False
>>>
>>> Even though in this particular example the result is wrong, this is a
>>> reasonable approach, because if two different but close numbers are
>>> incorrectly assumed equal, it should be possible to correct this by
>>> increasing $MaxExtraPrecision, while if a equals b but they're
>>> incorrectly
>>> assumed unequal, there is no way to fix that. That's what happens in
>>> the
>>> Limit and Integrate examples: Reduce performs necessary checks
>>> (numerical
>>> checks!), many other functions don't, that's all. I hope you realize
>>> that
>>> this isn't related to Simplify/FullSimplify in any way.
>>
>> There is a combination of different issues involved here.First, Reduce
>> is a much newer function, if I remember correctly it was completely
>> re-written in version 5. But also, it is not a good example, because
>> it is a function that suffers form exactly the same problem as
>> FullSimplify: it very frequently ends up being aborted since it is
>> unable to return any answer in reasonable time. This is O.K. because
>> it is relatively rarely used. Not so Integrate in which case you might
>> have noticed, if you have been reading this list, complaints about the
>> loss of speed compared with earlier versions are growing more
>> frequent.  Using significance arithmetic to make verifications in all
>> cases is not a reasonable choice (as Daniel Lichtblau pointed out
>> recently in another context).  Mathematica has to be able to identify
>> the situations when a numerical verification is needed and this is of
>> course the difficulty. Such verifications are not performed  when
>> Mathematica "believes" it has returned the correct answer.
>>
>>
>
>
> I forgot about one more thing. The idea of performing numerical
> verifications ("zero checking")  will in any case not work in
> situations where you have a non-numerical identity that identically
> zero. There are just as many examples of this kind as the ones that you
> gave: for example just take
>
>
> a = z;
>
> b = Abs[z]*Cos[Arg[z]] + I*Abs[z]*Sin[Arg[z]];
>
>
> Integrate[1/((x - a)*(x - b)), x] /. z -> I
>
> ComplexInfinity
>
>
> Integrate[FullSimplify[1/((x - a)*(x - b))], x] /. z -> I
>
>
> -(1/(-I + x))
>
>
> This is neither more contrived nor less frequent than your examples.
> How much use would your "zero checking" be in this case? What use is
> $MaxExtraPrecision or significance arithmetic? I daresay exactly zero.
> The basic "problem" would remain, except for the time wasted on a lot
> of extra programming and a lot of extra waiting for answers that would
> still need careful human inspection.  Of course once you decide to use
> FullSimplify (which is what Reduce does and which would deal with this
> example) you can also add high precision numerical verification, it
> won't make much difference. Reduce is intended to give answers that are
> "guaranteed" to be correct no matter how long it takes to reach them.
> If all of Mathematica's functions were written in this way it might
> make a few users happy but it would certainly put off a lot more.
>
>
> Andrzej Kozlowski
> Chiba, Japan
> http://www.akikoz.net/~andrzej/
> http://www.mimuw.edu.pl/~akoz/
>


Just to clarify a few things. First, it wouldn't be desirable if  
expressions such as Sign[Im[Sqrt[-1 - 10^-18*I]]] always remained  
unevaluated (what about Floor[Pi/3] and suchlike then, where numerical  
estimates are also needed). Mathematica numerically evaluates the argument  
of Floor by doing something like N[Pi/3, 17], verifies that 1 < Pi/3 < 2  
and returns 1. If we take Floor[Pi/Rationalize[Pi, 10^-100]] instead, then  
N[#, 17]& will give a result which is equal to 1 to the given precision,  
and Mathematica leaves the expression as it is. Increasing either  
$MinPrecision or $MaxExtraPrecision (value of 110 is sufficient) allows us  
to obtain enough digits to verify that 1 < Pi/Rationalize[Pi, 10^-100] <  
2, and Floor will be automatically evaluated to 1 again.

Reduce deals with such examples in a similar way, which is why setting  
$MaxExtraPrecision to 110 or higher allows us to obtain the correct answer  
for Reduce[Pi*x > Rationalize[Pi, 10^-100]*x]. As a side note, I don't  
quite understand why increasing $MinPrecision doesn't help here -- if we  
know, say, 1000 digits, 100 will cancel but the result is still  
distinguishable from zero.

My point is that other functions may perform similar checks. For example,  
in the case of Limit[k/x, x->0] we need to evaluate k first. If its  
numerical value is equal to 0, then Limit should return 0, not  
ComplexInfinity. The reason for this is that if k is not really zero,  
redoing the computation at a higher precision will allow us to resolve the  
uncertainty (sooner or later we will get to non-zero digits of k). On the  
other hand, if k equals zero and we overlook this possibility, then Limit  
will incorrectly return ComplexInfinity instead of 0 for any setting of  
precision. Similarly for the Integrate examples: for the indefinite  
integral we need to know if the two roots of (x - a)*(x - b) are equal,  
for the definite integral we need to check whether the singularity lies on  
the integration path. This isn't the same as trying to evaluate the limit  
or integral numerically, and FullSimplify isn't involved either. I agree  
that all this won't help if a and b are not numbers.

Returning to the example with Floor, here's another interesting question.  
If we try to force Mathematica to evaluate Floor by doing  
N[Floor[Pi/Rationalize[Pi, 10^-100]], 40], the result will be 0 (and if we  
take a and b which are exactly equal, then N[Floor[a/b], n] may  
incorrectly give 0 for any value of n, however large). Perhaps it would be  
better if the same idea were applied here: if the argument of Floor is  
indistinguishable from an integer, then return this integer -- so that,  
for example, Floor[.999`3] should give 1.

Maxim Rytin
m.r at inbox.ru


  • Prev by Date: Re: shuffling 10^8 numbers
  • Next by Date: Re: including files
  • Previous by thread: Re: Re: Zero testing
  • Next by thread: Re: Zero testing