]> www.ginac.de Git - ginac.git/commitdiff
Fix is_polynomial() so it works as advertised in the manual.
authorAlexei Sheplyakov <varg@theor.jinr.ru>
Thu, 6 Nov 2008 14:51:28 +0000 (17:51 +0300)
committerAlexei Sheplyakov <varg@theor.jinr.ru>
Thu, 6 Nov 2008 14:51:28 +0000 (17:51 +0300)
GiNaC manual says:
"Testing whether an expression is a polynomial in one or more variables
can be done with the method

 bool ex::is_polynomial(const ex & vars) const;
In the case of more than one variable, the variables are given as a list.

(x*y*sin(y)).is_polynomial(x)        // Returns true.
(x*y*sin(y)).is_polynomial(lst(x,y)) // Returns false."

However, the implementation is a bit inconsistent, as GiNaC reports
sin(x) + 2*s     is a polynomial in s, but
pow(2,x) + 2*s   is not a polynomial in s.

This patch fixes the inconsistency. Thanks to Jonathan Cross for reporting
this bug.

check/Makefile.am
check/check_is_polynomial.cpp [new file with mode: 0644]
ginac/power.cpp

index a96dcfe7e798fa7950d9d8e1cd856031d236329d..549532fca1271d0ab07889ce91776f13170b405e 100644 (file)
@@ -3,7 +3,8 @@
 CHECKS = check_numeric \
         check_inifcns \
         check_matrices \
-        check_lsolve 
+        check_lsolve \
+        check_is_polynomial
 
 EXAMS = exam_paranoia \
        exam_heur_gcd \
@@ -66,6 +67,9 @@ check_matrices_LDADD = ../ginac/libginac.la
 check_lsolve_SOURCES = check_lsolve.cpp genex.cpp
 check_lsolve_LDADD = ../ginac/libginac.la
 
+check_is_polynomial_SOURCES = check_is_polynomial.cpp
+check_is_polynomial_LDADD = ../ginac/libginac.la
+
 exam_paranoia_SOURCES = exam_paranoia.cpp
 exam_paranoia_LDADD = ../ginac/libginac.la
 
diff --git a/check/check_is_polynomial.cpp b/check/check_is_polynomial.cpp
new file mode 100644 (file)
index 0000000..a62f0c2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Check for inconsistency in power::is_polynomial
+ */
+#include "ginac.h"
+#include <iostream>
+#include <stdexcept>
+using namespace std;
+using namespace GiNaC;
+
+static void do_test(const ex& e, const ex& s)
+{
+       if (e.is_polynomial(s))
+               return;
+       cerr << "*** Error: is_polynomial() says \"" << e << "\""
+               << "is not a polynomial in \"" << s << "\"" << endl;
+       throw std::logic_error("bug in is_polynomial()");
+}
+
+int main(int argc, char** argv)
+{
+       cout << "checking for bugs in is_polynomial()... " << flush;
+       symbol x("x"), s("s");
+       ex e = sin(x) + 2*s;
+       ex g = pow(2, x) + 2*s;
+       do_test(e, s);
+       do_test(g, s);
+       cout << " OK, not found." << endl;
+       return 0;
+}
+       
index f92233c39ea8cc8a32d0b4df728eded18fcc549c..ca549300f9249deb184e02d048ff78bc05cccd48 100644 (file)
@@ -285,6 +285,8 @@ ex power::map(map_function & f) const
 
 bool power::is_polynomial(const ex & var) const
 {
+       if (!(basis.has(var) || exponent.has(var)))
+               return true; // i.e. 2^x is polynomial in s
        if (exponent.has(var))
                return false;
        if (!exponent.info(info_flags::nonnegint))