From 704fe31c78553ffe2058c72bc4d17e6a1ae31350 Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Thu, 25 Mar 2010 23:08:54 +0100 Subject: [PATCH] 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. --- ginac/inifcns_trans.cpp | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) 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); } -- 2.44.0