X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Ffactor.cpp;h=2c0ab8a5c07b04ab37aea5a78e4e22996fab9821;hp=945b25e653a4c56ba59b1ec3abeac50f34a065f8;hb=131d527194c15034422a0caf740bdf5a68689aea;hpb=4077d8b144e2e5f3db75cf95fbb590981b2eb8d4 diff --git a/ginac/factor.cpp b/ginac/factor.cpp index 945b25e6..2c0ab8a5 100644 --- a/ginac/factor.cpp +++ b/ginac/factor.cpp @@ -33,7 +33,7 @@ */ /* - * GiNaC Copyright (C) 1999-2011 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2017 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -70,6 +70,7 @@ #include #include #include +#include #ifdef DEBUGFACTOR #include #endif @@ -86,15 +87,16 @@ namespace GiNaC { #define DCOUT2(str,var) cout << #str << ": " << var << endl ostream& operator<<(ostream& o, const vector& v) { - vector::const_iterator i = v.begin(), end = v.end(); + auto i = v.begin(), end = v.end(); while ( i != end ) { - o << *i++ << " "; + o << *i << " "; + ++i; } return o; } static ostream& operator<<(ostream& o, const vector& v) { - vector::const_iterator i = v.begin(), end = v.end(); + auto i = v.begin(), end = v.end(); while ( i != end ) { o << *i << "[" << i-v.begin() << "]" << " "; ++i; @@ -103,7 +105,7 @@ static ostream& operator<<(ostream& o, const vector& v) } static ostream& operator<<(ostream& o, const vector& v) { - vector::const_iterator i = v.begin(), end = v.end(); + auto i = v.begin(), end = v.end(); while ( i != end ) { o << *i << "[" << i-v.begin() << "]" << " "; ++i; @@ -117,9 +119,9 @@ ostream& operator<<(ostream& o, const vector& v) } return o; } -ostream& operator<<(ostream& o, const vector< vector >& v) +ostream& operator<<(ostream& o, const vector>& v) { - vector< vector >::const_iterator i = v.begin(), end = v.end(); + auto i = v.begin(), end = v.end(); while ( i != end ) { o << i-v.begin() << ": " << *i << endl; ++i; @@ -498,11 +500,10 @@ static void reduce_coeff(umodpoly& a, const cl_I& x) if ( a.empty() ) return; cl_modint_ring R = a[0].ring(); - umodpoly::iterator i = a.begin(), end = a.end(); - for ( ; i!=end; ++i ) { + for (auto & i : a) { // cln cannot perform this division in the modular field - cl_I c = R->retract(*i); - *i = cl_MI(R, the(c / x)); + cl_I c = R->retract(i); + i = cl_MI(R, the(c / x)); } } @@ -679,7 +680,9 @@ typedef vector mvec; class modular_matrix { +#ifdef DEBUGFACTOR friend ostream& operator<<(ostream& o, const modular_matrix& m); +#endif public: modular_matrix(size_t r_, size_t c_, const cl_MI& init) : r(r_), c(c_) { @@ -913,8 +916,7 @@ static void berlekamp(const umodpoly& a, upvec& upv) return; } - list factors; - factors.push_back(a); + list factors = {a}; unsigned int size = 1; unsigned int r = 1; unsigned int q = cl_I_to_uint(R->modulus); @@ -934,21 +936,18 @@ static void berlekamp(const umodpoly& a, upvec& upv) div(*u, g, uo); if ( equal_one(uo) ) { throw logic_error("berlekamp: unexpected divisor."); - } - else { + } else { *u = uo; } factors.push_back(g); size = 0; - list::const_iterator i = factors.begin(), end = factors.end(); - while ( i != end ) { - if ( degree(*i) ) ++size; - ++i; + for (auto & i : factors) { + if (degree(i)) + ++size; } if ( size == k ) { - list::const_iterator i = factors.begin(), end = factors.end(); - while ( i != end ) { - upv.push_back(*i++); + for (auto & i : factors) { + upv.push_back(i); } return; } @@ -1020,8 +1019,7 @@ static void modsqrfree(const umodpoly& a, upvec& factors, vector& mult) mult[i] *= prime; } } - } - else { + } else { umodpoly ap; expt_1_over_p(a, prime, ap); size_t previ = mult.size(); @@ -1106,8 +1104,7 @@ static void same_degree_factor(const umodpoly& a, upvec& upv) for ( size_t i=0; i primes; - if ( primes.size() == 0 ) { - primes.push_back(3); primes.push_back(5); primes.push_back(7); + if (primes.empty()) { + primes = {3, 5, 7}; } - vector::const_iterator it = primes.begin(); if ( p >= primes.back() ) { unsigned int candidate = primes.back() + 2; while ( true ) { size_t n = primes.size()/2; for ( size_t i=0; i p ) break; + if (candidate > p) + break; } return candidate; } - vector::const_iterator end = primes.end(); - for ( ; it!=end; ++it ) { - if ( *it > p ) { - return *it; + for (auto & it : primes) { + if ( it > p ) { + return it; } } throw logic_error("next_prime: should not reach this point!"); @@ -1408,8 +1402,7 @@ public: if ( len > n/2 ) return false; fill(k.begin(), k.begin()+len, 1); fill(k.begin()+len+1, k.end(), 0); - } - else { + } else { k[last++] = 0; k[last] = 1; } @@ -1432,8 +1425,7 @@ private: if ( d ) { if ( cache[pos].size() >= d ) { lr[group] = lr[group] * cache[pos][d-1]; - } - else { + } else { if ( cache[pos].size() == 0 ) { cache[pos].push_back(factors[pos] * factors[pos+1]); } @@ -1447,8 +1439,7 @@ private: } lr[group] = lr[group] * cache[pos].back(); } - } - else { + } else { lr[group] = lr[group] * factors[pos]; } } while ( i < n ); @@ -1459,8 +1450,7 @@ private: lr[1] = one; if ( n > 6 ) { split_cached(); - } - else { + } else { for ( size_t i=0; i > cache; + vector> cache; upvec factors; umodpoly one; size_t n; @@ -1509,7 +1499,17 @@ static ex factor_univariate(const ex& poly, const ex& x, unsigned int& prime) cl_modint_ring R; unsigned int trials = 0; unsigned int minfactors = 0; - cl_I lc = lcoeff(prim) * the(ex_to(cont).to_cl_N()); + + const numeric& cont_n = ex_to(cont); + cl_I i_cont; + if (cont_n.is_integer()) { + i_cont = the(cont_n.to_cl_N()); + } else { + // poly \in Q[x] => poly = q ipoly, ipoly \in Z[x], q \in Q + // factor(poly) \equiv q factor(ipoly) + i_cont = cl_I(1); + } + cl_I lc = lcoeff(prim)*i_cont; upvec factors; while ( trials < 2 ) { umodpoly modpoly; @@ -1535,8 +1535,7 @@ static ex factor_univariate(const ex& poly, const ex& x, unsigned int& prime) minfactors = trialfactors.size(); lastp = prime; trials = 1; - } - else { + } else { ++trials; } } @@ -1590,15 +1589,13 @@ static ex factor_univariate(const ex& poly, const ex& x, unsigned int& prime) } } break; - } - else { + } else { upvec newfactors1(part.size_left()), newfactors2(part.size_right()); - upvec::iterator i1 = newfactors1.begin(), i2 = newfactors2.begin(); + auto i1 = newfactors1.begin(), i2 = newfactors2.begin(); for ( size_t i=0; icanonhom(oldR->retract(*i)); + for (auto & i : a) { + i = R->canonhom(oldR->retract(i)); } canonicalize(a); } @@ -1802,8 +1797,7 @@ static upvec univar_diophant(const upvec& a, const ex& x, unsigned int m, unsign rem(bmod, a[j], buf); result.push_back(buf); } - } - else { + } else { umodpoly s, t; eea_lift(a[1], a[0], x, p, k, s, t); umodpoly bmod = umodpoly_to_umodpoly(s, R, m); @@ -1825,7 +1819,7 @@ static upvec univar_diophant(const upvec& a, const ex& x, unsigned int m, unsign struct make_modular_map : public map_function { cl_modint_ring R; make_modular_map(const cl_modint_ring& R_) : R(R_) { } - ex operator()(const ex& e) + ex operator()(const ex& e) override { if ( is_a(e) || is_a(e) ) { return e.map(*this); @@ -1837,8 +1831,7 @@ struct make_modular_map : public map_function { numeric n(R->retract(emod)); if ( n > halfmod ) { return n-mod; - } - else { + } else { return n; } } @@ -1931,8 +1924,7 @@ static vector multivar_diophant(const vector& a_, const ex& x, const ex& e = make_modular(buf, R); } } - } - else { + } else { upvec amod; for ( size_t i=0; i multivar_diophant(const vector& a_, const ex& x, const ex& if ( is_a(c) ) { nterms = c.nops(); z = c.op(0); - } - else { + } else { nterms = 1; z = c; } @@ -2079,15 +2070,9 @@ static ex hensel_multivar(const ex& a, const ex& x, const vector& I, acand *= U[i]; } if ( expand(a-acand).is_zero() ) { - lst res; - for ( size_t i=0; i(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) ) { @@ -2260,7 +2246,7 @@ static ex factor_multivariate(const ex& poly, const exset& syms) ex vn = pp.collect(x).lcoeff(x); ex vnlst; if ( is_a(vn) ) { - vnlst = lst(vn); + vnlst = lst{vn}; } else { ex vnfactors = factor(vn); @@ -2318,8 +2304,7 @@ static ex factor_multivariate(const ex& poly, const exset& syms) for ( size_t i=1; i(ufaclst.op(i+1).lcoeff(x)); for ( int j=ftilde.size()-1; j>=0; --j ) { @@ -2434,7 +2418,7 @@ static ex factor_multivariate(const ex& poly, const exset& syms) // try Hensel lifting ex res = hensel_multivar(pp, x, epv, prime, l, modfactors, C); - if ( res != lst() ) { + if ( res != lst{} ) { ex result = cont * unit; for ( size_t i=0; i(e) ) { syms.insert(e); @@ -2479,8 +2463,7 @@ static ex factor_sqrfree(const ex& poly) int ld = poly.ldegree(x); ex res = factor_univariate(expand(poly/pow(x, ld)), x); return res * pow(x,ld); - } - else { + } else { ex res = factor_univariate(poly, x); return res; } @@ -2497,7 +2480,7 @@ static ex factor_sqrfree(const ex& poly) struct apply_factor_map : public map_function { unsigned options; apply_factor_map(unsigned options_) : options(options_) { } - ex operator()(const ex& e) + ex operator()(const ex& e) override { if ( e.info(info_flags::polynomial) ) { return factor(e, options); @@ -2507,13 +2490,10 @@ struct apply_factor_map : public map_function { for ( size_t i=0; i(base) ) { res *= t; - } - else { + } else { ex f = factor_sqrfree(base); res *= pow(f, t.op(1)); } - } - else if ( is_a(t) ) { + } else if ( is_a(t) ) { ex f = factor_sqrfree(t); res *= f; - } - else { + } else { res *= t; } }