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.
if (x.is_zero())
return _ex0;
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;
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()) {
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;
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)) {
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;
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)) {
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;
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;
}
if (y.info(info_flags::negative))
return _ex_1_4*Pi;
}
- // atan(float, float) -> float
+ // atan2(float, float) -> float
if (is_a<numeric>(y) && !y.info(info_flags::crational) &&
is_a<numeric>(x) && !x.info(info_flags::crational))
return atan(ex_to<numeric>(y), ex_to<numeric>(x));
if (is_a<numeric>(y) && !y.info(info_flags::crational) &&
is_a<numeric>(x) && !x.info(info_flags::crational))
return atan(ex_to<numeric>(y), ex_to<numeric>(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);
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();
}
return atan2(y, x).hold();
GINAC_ASSERT(deriv_param<2);
if (deriv_param==0) {
GINAC_ASSERT(deriv_param<2);
if (deriv_param==0) {
return x*power(power(x,_ex2)+power(y,_ex2),_ex_1);
}
return x*power(power(x,_ex2)+power(y,_ex2),_ex_1);
}
return -y*power(power(x,_ex2)+power(y,_ex2),_ex_1);
}
return -y*power(power(x,_ex2)+power(y,_ex2),_ex_1);
}