Hello, I'm using GiNaC 1.4.3 built on Mac OS X. I think I've found a problem with is_polynomial when powers are involved. When there is an expression involving a non-integer power---even when the expression is independent of the dummy variable of the polynomial--- then the expression is not considered a polynomial by GiNaC. The following code illustrates the problem: (or perhaps I don't fully understand "is_polynomial"?) ------------------------- #include <iostream> #include <ginac/ginac.h> using namespace std; int main() { GiNaC::symbol x("x"); GiNaC::symbol s("s"); // here are two expressions that are both polynomials with respect to s. GiNaC::ex expr1 = sin(x) + 2*s; GiNaC::ex expr2 = pow(2,x) + 2*s; // works as expected if (expr1.is_polynomial(s)) cout << expr1 << " is a polynomial with respect to " << s << endl; else cout << expr1 << " is NOT a polynomial with respect to " << s << endl; // reports 2^x + 2s is not a polynomial in s? if (expr2.is_polynomial(s)) cout << expr2 << " is a polynomial with respect to " << s << endl; else cout << expr2 << " is NOT a polynomial with respect to " << s << endl; return 0; } ------------------------ I'm not familiar enough with the internal workings of GiNaC to make a patch, but this seems like the changes required would be fairly small. Thanks!
Hello! On Tue, Aug 05, 2008 at 01:58:59PM -0700, Jonathan Cross wrote:
When there is an expression involving a non-integer power---even when the expression is independent of the dummy variable of the polynomial--- then the expression is not considered a polynomial by GiNaC.
Mathematically such an expression is not a polynomial (over field of rational numbers). See you favourite book on the (commutative) ring theory for more details.
// here are two expressions that are both polynomials with respect to s. GiNaC::ex expr1 = sin(x) + 2*s; GiNaC::ex expr2 = pow(2,x) + 2*s;
I don't quite understand why these expressions are polynomials. Could you elaborate, please? Best regards, Alexei -- All science is either physics or stamp collecting.
Alexei, I agree these are not polynomials over the field of rational numbers. I thought that if R is any ring, then you could define the polynomial ring R[s], where the elements are "polynomials" in the variable s with coefficients in the ring R. Within this framework, the examples in my code are in the ring R[s], where R = the ring of continuous functions in the real variable x s = the polynomial variable. If you need to be more restrictive than arbitrary rings for GiNaC, that's understandable. In which case, there's an inconsistency, as GiNaC reports sin(x) + 2*s is a polynomial in s, but pow(2,x) + 2*s is not a polynomial in s. I would think that (for GiNaC) these should either both be or neither be polynomials in s. Clearly neither is a polynomial in x. IMHO, calling such expressions polynomials in s makes more sense mathematically, and seems consistent with the examples in the GiNaC tutorial, section 5.7.1. Hope this clarifies things. Thanks for taking the time to maintain GiNaC (or at least the time to respond to email)! -Jonathan On Aug 5, 2008, at 11:58 PM, Alexei Sheplyakov wrote:
Hello!
On Tue, Aug 05, 2008 at 01:58:59PM -0700, Jonathan Cross wrote:
When there is an expression involving a non-integer power---even when the expression is independent of the dummy variable of the polynomial--- then the expression is not considered a polynomial by GiNaC.
Mathematically such an expression is not a polynomial (over field of rational numbers). See you favourite book on the (commutative) ring theory for more details.
// here are two expressions that are both polynomials with respect to s. GiNaC::ex expr1 = sin(x) + 2*s; GiNaC::ex expr2 = pow(2,x) + 2*s;
I don't quite understand why these expressions are polynomials. Could you elaborate, please?
Best regards, Alexei
-- All science is either physics or stamp collecting.
_______________________________________________ GiNaC-list mailing list GiNaC-list@ginac.de https://www.cebix.net/mailman/listinfo/ginac-list
Hi! On Wed, Aug 06, 2008 at 01:42:19AM -0700, Jonathan Cross wrote:
I thought that if R is any ring,
As of now GiNaC can operate only on polynomials over (real) rational numbers. Extending GiNaC to handle polynomials over (reasonably) arbitrary ring would be nice, but this requires a lot of effort. On the over hand, there are a number of good (free) polynomial-oriented libraries/programs (Pari/GP, Singular, CoCoA, you name it), so it sounds like re-inventing the wheel.
then you could define the polynomial ring R[s], where the elements are "polynomials" in the variable s with coefficients in the ring R. Within this framework, the examples in my code are in the ring R[s], where R = the ring of continuous functions in the real variable x s = the polynomial variable.
This makes perfect sense, so here is the patch which gives the semantics you want: diff --git a/ginac/power.cpp b/ginac/power.cpp index f92233c..ed2d2c0 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; if (exponent.has(var)) return false; if (!exponent.info(info_flags::nonnegint)) It leads to a small problem, though. AFAIR several GiNaC functions (i.e. gcd(), normal()) use is_polynomial() to check if the argument is a polynomial over rationals. So these functions might be confused and give incorrect results. On the other hand, current implementation is broken anyway, so (hopefully) making it a little bit more broken won't hurt.
In which case, there's an inconsistency, as GiNaC reports sin(x) + 2*s is a polynomial in s, but pow(2,x) + 2*s is not a polynomial in s.
Sure, this is a bug.
I would think that (for GiNaC) these should either both be or neither be polynomials in s. Clearly neither is a polynomial in x.
I intend to fix it (the patch above is merely a work around), but I'm not quite sure how to proceed. I'd like to support the semantics you ask for. On the other hand, gcd() and friends need more strict variant. There are (at least) two ways to solve this collision: 1. Add the method is_real_polynomial(). 2. Add and optional argument to is_polynomial(), which tells if the coefficients are allowed to be arbitrary expressions (which don't depend on the main variable, of course) and defaults to off (so gcd() and friends need no modifications). N.B. Unfortunately, both variants break binary compatibility.
IMHO, calling such expressions polynomials in s makes more sense mathematically, and seems consistent with the examples in the GiNaC tutorial, section 5.7.1.
I haven't noticed any polynomial with non-rational coefficients in that section. Could you please be more specific? (Maybe you've found some bug in the tutorial itself?) Best regards, Alexei -- All science is either physics or stamp collecting.
Alexi, Thanks for the patch! It does sound like the correct fix requires two types of "is_polynomial". Since any such fix breaks binary compatibility, I'm happy if you have to delay the fix until the next major version. (Especially if you are working on more important things like polynomial factorization and Groebner bases!)
I haven't noticed any polynomial with non-rational coefficients in that section. Could you please be more specific? (Maybe you've found some bug in the tutorial itself?)
The documentation has the following text, found on section 5.7.1 of the pdf and online at http://www.ginac.de/tutorial/Polynomial-arithmetic.html#Polynomial%20arithme... 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. The first example is a polynomial in x where the coefficient of x is a function of y, not just a rational number. -Jonathan
participants (2)
-
Alexei Sheplyakov
-
Jonathan Cross