Fix an infinite loop in factor_multivariate.
authorAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Sun, 18 May 2014 10:24:40 +0000 (13:24 +0300)
committerAlexei Sheplyakov <Alexei.Sheplyakov@gmail.com>
Sun, 18 May 2014 12:59:42 +0000 (15:59 +0300)
Make sure the leading coefficient is really factorized (take care of
the integer content).

check/exam_factor.cpp
ginac/factor.cpp

index 2006a32..9696a2b 100644 (file)
@@ -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;
 }
index 24f828c..4f11e56 100644 (file)
@@ -2118,8 +2118,9 @@ static ex put_factors_into_lst(const ex& e)
                return result;
        }
        if ( is_a<symbol>(e) || is_a<add>(e) ) {
-               result.append(1);
-               result.append(e);
+               ex icont(e.integer_content());
+               result.append(icont);
+               result.append(e/icont);
                return result;
        }
        if ( is_a<mul>(e) ) {