From: Alexei Sheplyakov Date: Thu, 6 Nov 2008 14:51:28 +0000 (+0300) Subject: Fix is_polynomial() so it works as advertised in the manual. X-Git-Tag: release_1-4-4~3 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=commitdiff_plain;h=398f4eb2273a8a6adfe54361aa98cce12fe70174;p=ginac.git Fix is_polynomial() so it works as advertised in the manual. 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. --- diff --git a/check/Makefile.am b/check/Makefile.am index a96dcfe7..549532fc 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -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 index 00000000..a62f0c26 --- /dev/null +++ b/check/check_is_polynomial.cpp @@ -0,0 +1,30 @@ +/* + * Check for inconsistency in power::is_polynomial + */ +#include "ginac.h" +#include +#include +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; +} + diff --git a/ginac/power.cpp b/ginac/power.cpp index f92233c3..ca549300 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -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))