[BUGFIX] Fix factor_univariate(poly, x) for constant poly.
authorRichard Kreckel <kreckel@ginac.de>
Mon, 3 Aug 2020 16:09:30 +0000 (18:09 +0200)
committerRichard Kreckel <kreckel@ginac.de>
Mon, 3 Aug 2020 16:16:27 +0000 (18:16 +0200)
The modular factorization fails to find a prime in this case, leading to
an infinite loop. At least one caller (factor_sqrfree) happens to produce
such constant polys in some cases.

check/exam_factor.cpp
ginac/factor.cpp

index c1e98e7072d13a840821085b64ba43de72cda66c..c848fdd4ebc2ca6f9a29cd717366535dad2a1730 100644 (file)
@@ -26,8 +26,6 @@ using namespace GiNaC;
 #include <iostream>
 using namespace std;
 
-static symbol w("w"), x("x"), y("y"), z("z");
-
 static unsigned check_factor(const ex& e)
 {
        ex ee = e.expand();
@@ -44,8 +42,7 @@ static unsigned exam_factor1()
        unsigned result = 0;
        ex e;
        symbol x("x");
-       lst syms;
-       syms.append(x);
+       lst syms = {x};
        
        e = ex("1+x-x^3", syms);
        result += check_factor(e);
@@ -199,7 +196,7 @@ static unsigned exam_factor_wang()
        // "An Improved Multivariate Polynomial Factoring Algorithm"
        unsigned result = 0;
        ex e;
-       symbol x("x"), y("y"), z("z"), u("u");
+       symbol u("u"), w("w"), x("x"), y("y"), z("z");
 
        e = ex("(z+x*y+10)*(x*z+y+30)*(y*z+x+20)", lst{x, y, z});
        result += check_factor_expanded(e);
index bb20589b4b9cf890945107cbf7143b497aa4e920..f53642a2bb7e88504073b14d1bd9e33cecc88f78 100644 (file)
@@ -1491,6 +1491,9 @@ static ex factor_univariate(const ex& poly, const ex& x, unsigned int& prime)
        poly.unitcontprim(x, unit, cont, prim_ex);
        upoly prim;
        upoly_from_ex(prim, prim_ex, x);
+       if (prim_ex.is_equal(1)) {
+               return poly;
+       }
 
        // determine proper prime and minimize number of modular factors
        prime = 3;
@@ -2454,9 +2457,9 @@ static ex factor_sqrfree(const ex& poly)
        if ( findsymbols.syms.size() == 1 ) {
                // univariate case
                const ex& x = *(findsymbols.syms.begin());
-               if ( poly.ldegree(x) > 0 ) {
+               int ld = poly.ldegree(x);
+               if ( ld > 0 ) {
                        // pull out direct factors
-                       int ld = poly.ldegree(x);
                        ex res = factor_univariate(expand(poly/pow(x, ld)), x);
                        return res * pow(x,ld);
                } else {