[bugfix] ex::is_polynomial(x): fix miscomputations
authorRichard Kreckel <kreckel@ginac.de>
Fri, 25 Jul 2014 23:11:11 +0000 (23:11 +0000)
committerRichard Kreckel <kreckel@ginac.de>
Fri, 25 Jul 2014 23:11:11 +0000 (23:11 +0000)
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.)

check/exam_paranoia.cpp
ginac/mul.cpp
ginac/power.cpp

index 52d261c..2817d18 100644 (file)
@@ -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;
 }
 
index 64660a2..73d7b24 100644 (file)
@@ -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;
                }
        }
index 87792b9..1bd122b 100644 (file)
@@ -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