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.
CHECKS = check_numeric \
check_inifcns \
check_matrices \
- check_lsolve
+ check_lsolve \
+ check_is_polynomial
EXAMS = exam_paranoia \
exam_heur_gcd \
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
--- /dev/null
+/*
+ * 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;
+}
+
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))