From cdddbc6dcdabef73aeb20bb9b81e08dba92a235c Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Mon, 3 Aug 2020 18:09:30 +0200 Subject: [PATCH] [BUGFIX] Fix factor_univariate(poly, x) for constant poly. 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 | 7 ++----- ginac/factor.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/check/exam_factor.cpp b/check/exam_factor.cpp index c1e98e70..c848fdd4 100644 --- a/check/exam_factor.cpp +++ b/check/exam_factor.cpp @@ -26,8 +26,6 @@ using namespace GiNaC; #include 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); diff --git a/ginac/factor.cpp b/ginac/factor.cpp index bb20589b..f53642a2 100644 --- a/ginac/factor.cpp +++ b/ginac/factor.cpp @@ -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 { -- 2.44.0