atan2 throws divide by zero
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.
Hi GeeBee, 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 ... :-) Regards, Jens
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/>
Thanks, All. I'll look forward to the changes percolating through. Cheers-- Greg On Thu, Mar 25, 2010 at 2:41 PM, Richard B. Kreckel <kreckel@ginac.de>wrote:
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/>
_______________________________________________ GiNaC-devel mailing list GiNaC-devel@ginac.de https://www.cebix.net/mailman/listinfo/ginac-devel
participants (3)
-
G B
-
Jens Vollinga
-
Richard B. Kreckel