From edfa67d26bac695b5ef9911f3cda3ff50232e35a Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Sun, 18 May 2014 13:24:40 +0300 Subject: [PATCH] Fix an infinite loop in factor_multivariate. Make sure the leading coefficient is really factorized (take care of the integer content). --- check/exam_factor.cpp | 29 +++++++++++++++++++++++++++++ ginac/factor.cpp | 5 +++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/check/exam_factor.cpp b/check/exam_factor.cpp index 2006a325..9696a2b5 100644 --- a/check/exam_factor.cpp +++ b/check/exam_factor.cpp @@ -184,6 +184,33 @@ static unsigned exam_factor3() return result; } +static unsigned check_factorization(const exvector& factors) +{ + ex e = (new mul(factors))->setflag(status_flags::dynallocated); + ex ef = factor(e.expand()); + if (ef.nops() != factors.size()) { + clog << "wrong number of factors, expected " << factors.size() << + ", got " << ef.nops(); + return 1; + } + for (size_t i = 0; i < ef.nops(); ++i) { + if (find(factors.begin(), factors.end(), ef.op(i)) == factors.end()) { + clog << "wrong factorization: term not found: " << ef.op(i); + return 1; + } + } + return 0; +} + +static unsigned factor_integer_content_bug() +{ + parser reader; + exvector factors; + factors.push_back(reader("x+y+x*y")); + factors.push_back(reader("3*x+2*y")); + return check_factorization(factors); +} + unsigned exam_factor() { unsigned result = 0; @@ -193,6 +220,8 @@ unsigned exam_factor() result += exam_factor1(); cout << '.' << flush; result += exam_factor2(); cout << '.' << flush; result += exam_factor3(); cout << '.' << flush; + result += factor_integer_content_bug(); + cout << '.' << flush; return result; } diff --git a/ginac/factor.cpp b/ginac/factor.cpp index 24f828cb..4f11e562 100644 --- a/ginac/factor.cpp +++ b/ginac/factor.cpp @@ -2118,8 +2118,9 @@ static ex put_factors_into_lst(const ex& e) return result; } if ( is_a(e) || is_a(e) ) { - result.append(1); - result.append(e); + ex icont(e.integer_content()); + result.append(icont); + result.append(e/icont); return result; } if ( is_a(e) ) { -- 2.47.0