[GiNaC-devel] atan2 throws divide by zero

Richard B. Kreckel kreckel at ginac.de
Thu Mar 25 22:41:06 CET 2010


Hi!

Jens Vollinga wrote:
> Am 25.03.2010 00:17, schrieb G B:
>> I stumbled upon this using Sage, but developers there have traced it to
>> a problem in GiNaC by running the following in ginsh:
>>
>>  > atan2(-Pi,0);
>>
>> The response is:
>> power::eval(): division by zero
>>
>> atan2 appears to work for other values, including (positive) (Pi,0), but
>> (-Pi,0) fails.
> 
> thanks for the bug report. I fixed that bug in the repository.
> Finally it is time to make a new release ... :-)

Wait a minute, I think your fix is wrong. It assumes that if 
y.info(info_flags::real) and not y.info(info_flags::positive) and not 
y.is_zero(), then y must be negative. But that's not correct, because 
info returns true if the predicate is known to be true and false if it 
os known to be false or if it is unknown. Consider, for instance, 
positive symbols a and b and ex x = a-b. So, the patch introduces 
actually a new bug.

What's really wrong is the last part in atan2_eval, where atan(real, 
real) -> atan(y/x) +/- Pi. Ironically, it is suffering from the same 
mistake as your patch. This ought to fix it:

@@ -877,10 +877,13 @@ static ex atan2_eval(const ex & y, const ex & x)
         if (y.info(info_flags::real) && x.info(info_flags::real)) {
                 if (x.info(info_flags::positive))
                         return atan(y/x);
-               else if (y.info(info_flags::positive))
-                       return atan(y/x)+Pi;
-               else
-                       return atan(y/x)-Pi;
+
+               if (x.info(info_flags::negative)) {
+                       if (y.info(info_flags::positive))
+                               return atan(y/x)+Pi;
+                       if (y.info(info_flags::negative))
+                               return atan(y/x)-Pi;
+               }
         }

         return atan2(y, x).hold();

It appears that this bug has been latent until Vladimir's patch 
c7299e51d5ecf6. The bad news is that with my patch atan2(-Pi,0) isn't 
simplified at all any more. One could argue that GiNaC should evaluate 
ex(-Pi).info(info_flags::negative) -> true. This would make atan2(-Pi,0) 
evaluate to -Pi/2 again.

   -richy.
-- 
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>


More information about the GiNaC-devel mailing list