From: Richard Kreckel Date: Thu, 25 Mar 2010 22:08:54 +0000 (+0100) Subject: Really fixed the atan2(-Pi, 0) bug. X-Git-Tag: release_1-6-0~61 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=704fe31c78553ffe2058c72bc4d17e6a1ae31350;ds=inline Really fixed the atan2(-Pi, 0) bug. The problem was that atan2_eval assumed that if y is real and not positive, it must be negative. But this neglects the fact that in symbolic compution it may just not be possible to determine the sign. Now, the expression is returned as it is. Ugly, but correct. --- diff --git a/ginac/inifcns_trans.cpp b/ginac/inifcns_trans.cpp index 3f161d21..c8a0a821 100644 --- a/ginac/inifcns_trans.cpp +++ b/ginac/inifcns_trans.cpp @@ -822,65 +822,68 @@ static ex atan2_eval(const ex & y, const ex & x) { if (y.is_zero()) { - // atan(0, 0) -> 0 + // atan2(0, 0) -> 0 if (x.is_zero()) return _ex0; - // atan(0, x), x real and positive -> 0 + // atan2(0, x), x real and positive -> 0 if (x.info(info_flags::positive)) return _ex0; - // atan(0, x), x real and negative -> Pi + // atan2(0, x), x real and negative -> Pi if (x.info(info_flags::negative)) return Pi; } if (x.is_zero()) { - // atan(y, 0), y real and positive -> Pi/2 + // atan2(y, 0), y real and positive -> Pi/2 if (y.info(info_flags::positive)) return _ex1_2*Pi; - // atan(y, 0), y real and negative -> -Pi/2 - if (y.info(info_flags::real) && !y.is_zero()) + // atan2(y, 0), y real and negative -> -Pi/2 + if (y.info(info_flags::negative)) return _ex_1_2*Pi; } if (y.is_equal(x)) { - // atan(y, y), y real and positive -> Pi/4 + // atan2(y, y), y real and positive -> Pi/4 if (y.info(info_flags::positive)) return _ex1_4*Pi; - // atan(y, y), y real and negative -> -3/4*Pi + // atan2(y, y), y real and negative -> -3/4*Pi if (y.info(info_flags::negative)) return numeric(-3, 4)*Pi; } if (y.is_equal(-x)) { - // atan(y, -y), y real and positive -> 3*Pi/4 + // atan2(y, -y), y real and positive -> 3*Pi/4 if (y.info(info_flags::positive)) return numeric(3, 4)*Pi; - // atan(y, -y), y real and negative -> -Pi/4 + // atan2(y, -y), y real and negative -> -Pi/4 if (y.info(info_flags::negative)) return _ex_1_4*Pi; } - // atan(float, float) -> float + // atan2(float, float) -> float if (is_a(y) && !y.info(info_flags::crational) && is_a(x) && !x.info(info_flags::crational)) return atan(ex_to(y), ex_to(x)); - // atan(real, real) -> atan(y/x) +/- Pi + // atan2(real, real) -> atan(y/x) +/- Pi 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(); @@ -891,10 +894,10 @@ static ex atan2_deriv(const ex & y, const ex & x, unsigned deriv_param) GINAC_ASSERT(deriv_param<2); if (deriv_param==0) { - // d/dy atan(y,x) + // d/dy atan2(y,x) return x*power(power(x,_ex2)+power(y,_ex2),_ex_1); } - // d/dx atan(y,x) + // d/dx atan2(y,x) return -y*power(power(x,_ex2)+power(y,_ex2),_ex_1); }