From: Richard Kreckel Date: Fri, 25 Jul 2014 23:11:11 +0000 (+0000) Subject: [bugfix] ex::is_polynomial(x): fix miscomputations X-Git-Tag: release_1-6-3~9 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=92da4c16f5d6edf276be011a08ce04b352945a83 [bugfix] ex::is_polynomial(x): fix miscomputations The function power::is_polynomial(x) sometimes returned false, even if x did not occur in the power object. Thanks to Rubel Zilibowitz for reporting this bug. Similarly, mul::is_polynomial(x) sometimes returned true, even if x occurred only in the denominator of a rational function. The function mul::is_polynomial(x) does a simpler version of power::is_polynomial(x) on its factors. (It's simpler because the exponents cannot be functions of x.) --- diff --git a/check/exam_paranoia.cpp b/check/exam_paranoia.cpp index 52d261c8..2817d18e 100644 --- a/check/exam_paranoia.cpp +++ b/check/exam_paranoia.cpp @@ -494,11 +494,11 @@ static unsigned exam_paranoia19() return 0; } -// Bug in expairseq::is_polynomial (fixed 2011-05-20). +// Bugs in is_polynomial (fixed 2011-05-20 and 2014-07-26). static unsigned exam_paranoia20() { unsigned result = 0; - symbol x("x"); + symbol x("x"), y("y"); ex e1 = sqrt(x*x+1)*sqrt(x+1); if (e1.is_polynomial(x)) { clog << "sqrt(x*x+1)*sqrt(x+1) is wrongly reported to be a polynomial in x\n"; @@ -509,6 +509,16 @@ static unsigned exam_paranoia20() clog << "sqrt(Pi)*x is wrongly reported to be no polynomial in x\n"; ++result; } + ex e3 = sqrt(x); + if (!e3.is_polynomial(y)) { + clog << "sqrt(x) is wrongly reported to be no polynomial in y\n"; + ++result; + } + ex e4 = (1+y)/(2+x); + if (e4.is_polynomial(x)) { + clog << "(1+y)/(2+x) is wrongly reported to be a polynomial in x\n"; + ++result; + } return result; } diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 64660a28..73d7b240 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -406,7 +406,7 @@ bool mul::is_polynomial(const ex & var) const { for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) { if (!i->rest.is_polynomial(var) || - (i->rest.has(var) && !i->coeff.info(info_flags::integer))) { + (i->rest.has(var) && !i->coeff.info(info_flags::nonnegint))) { return false; } } diff --git a/ginac/power.cpp b/ginac/power.cpp index 87792b92..1bd122b8 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -289,11 +289,16 @@ ex power::map(map_function & f) const bool power::is_polynomial(const ex & var) const { - if (exponent.has(var)) - return false; - if (!exponent.info(info_flags::nonnegint)) - return false; - return basis.is_polynomial(var); + if (basis.is_polynomial(var)) { + if (basis.has(var)) + // basis is non-constant polynomial in var + return exponent.info(info_flags::nonnegint); + else + // basis is constant in var + return !exponent.has(var); + } + // basis is a non-polynomial function of var + return false; } int power::degree(const ex & s) const