8 #include "../UnivariatePolynomial.h"
14 template<
typename Coeff>
17 std::map<uint,UnivariatePolynomial<Coeff>> result;
18 CLANG_WARNING_DISABLE(
"-Wtautological-compare")
24 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivSSF: degree greater than characteristic!");
26 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivSSF: add the factor (" << p <<
")^1");
46 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivSSF: add the factor (" << p <<
")^1");
67 assert(result.find(i) == result.end());
69 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivSSF: add the factor (" << g <<
")^" << i);
79 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivSSF: add the factor (" << w <<
")^" << i);
87 template<
typename Coeff,
typename Integer>
96 while(*cf ==
Coeff(0))
104 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: add the factor (" << retVal.first->first <<
")^" << k );
107 retVal.first->second += k;
110 std::vector<Coeff> cfs;
112 cfs = std::vector<Coeff>(cf, poly.
coefficients().end());
114 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: remainder is " << result );
128 if( maxInt != 0 && (tc > mi || lc > mi) )
132 Integer lcAsInt = to_int<Integer>(lc);
133 Integer tcAsInt = to_int<Integer>(tc);
134 Integer halfOfLcAsInt = lcAsInt == 1 ? 1 : lcAsInt/2;
135 Integer halfOfTcAsInt = tcAsInt == 1 ? 1 : tcAsInt/2;
136 std::vector<std::pair<Integer, Integer>> shiftedTcs;
137 bool positive =
true;
138 bool tcFactorsFound =
false;
139 std::vector<Integer> tcFactors(1, 1);
140 auto tcFactor = tcFactors.begin();
141 bool lcFactorsFound =
false;
142 std::vector<Integer> lcFactors(1, 1);
143 auto lcFactor = lcFactors.begin();
146 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: try rational " << (positive ?
"-" :
"") << *tcFactor <<
"/" << *lcFactor);
149 auto shiftedTc = shiftedTcs.begin();
150 for(; shiftedTc != shiftedTcs.end(); ++shiftedTc)
153 if(maxInt/(*lcFactor) >= shiftedTc->first)
155 Integer divisor = (*lcFactor) * shiftedTc->first;
156 if( divisor != *tcFactor )
158 if( !(divisor < 0 && *tcFactor < 0 && maxInt + divisor >= -(*tcFactor)) && !(divisor > 0 && *tcFactor > 0 && maxInt - divisor >= *tcFactor ) )
160 if( divisor > *tcFactor )
162 divisor = divisor - *tcFactor;
166 divisor = *tcFactor - divisor;
168 if(
carl::mod(shiftedTc->second, divisor) != 0)
176 if(shiftedTc == shiftedTcs.end())
178 Coeff posRatZero = carl::from_int<typename IntegralType<Coeff>::type>(*tcFactor) / carl::from_int<typename IntegralType<Coeff>::type>(*lcFactor);
179 if (!positive) posRatZero = -posRatZero;
180 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: consider possible non zero rational factor " << posRatZero);
186 auto retVal = linearFactors.emplace(linearFactor, 1);
187 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: add the factor (" << linearFactor <<
")^" << 1 );
190 ++retVal.first->second;
195 goto LinearFactorRemains;
206 if( imageInt <= carl::from_int<IntNumberType>(maxInt) )
209 shiftedTcs.push_back(std::pair<Integer, Integer>(to_int<Integer>(
get_num(posRatZero)), to_int<Integer>(
carl::abs(
get_num(image)))));
214 if(shiftedTc == shiftedTcs.end() && positive)
227 lcFactors.push_back(lcFactors.back());
228 while(lcFactors.back() <= halfOfLcAsInt)
231 if(
carl::mod(lcAsInt, lcFactors.back()) == 0)
236 if(lcFactors.back() > halfOfLcAsInt)
238 lcFactors.pop_back();
239 lcFactorsFound =
true;
240 lcFactor = lcFactors.end();
244 lcFactor = --(lcFactors.end());
247 if(lcFactor == lcFactors.end())
255 tcFactors.push_back(tcFactors.back());
256 while(tcFactors.back() <= halfOfTcAsInt)
258 ++(tcFactors.back());
259 if(
carl::mod(tcAsInt, tcFactors.back()) == 0)
264 if(tcFactors.back() > halfOfTcAsInt)
266 tcFactors.pop_back();
267 tcFactor = tcFactors.end();
271 tcFactor = --(tcFactors.end());
274 if(tcFactor == tcFactors.end())
283 factor =
Coeff(1) / factor;
284 factor *= linearFactors.begin()->first.lcoeff();
285 linearFactors.erase(linearFactors.begin());
291 lcFactor = lcFactors.begin();
303 if( !linearFactors.empty() &&
is_constant(linearFactors.begin()->first) )
308 factor *= linearFactors.begin()->first.lcoeff();
309 linearFactors.erase(linearFactors.begin());
313 auto retVal = linearFactors.emplace(result, 1);
314 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivELF: add the factor (" << result <<
")^" << 1 );
317 ++retVal.first->second;
324 template<
typename Coeff>
330 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivFactor: add the factor (" << p <<
")^" << 1 );
331 result.emplace(p, 1);
346 std::vector<Coeff> remaining;
350 remaining.push_back(coeff * factor);
360 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivFactor: Calculating square-free factorization of " << remainingPoly);
364 for(
auto expFactorPair = sff.begin(); expFactorPair != sff.end(); ++expFactorPair)
374 auto retVal = result.emplace(expFactorPair->second, expFactorPair->first);
375 CARL_LOG_TRACE(
"carl.core.upoly",
"UnivFactor: add the factor (" << expFactorPair->second <<
")^" << expFactorPair->first );
378 retVal.first->second += expFactorPair->first;
A small wrapper that configures logging for carl.
#define CARL_LOG_TRACE(channel, msg)
carl is the main namespace for the library.
UnivariatePolynomial< Coeff > extended_gcd(const UnivariatePolynomial< Coeff > &a, const UnivariatePolynomial< Coeff > &b, UnivariatePolynomial< Coeff > &s, UnivariatePolynomial< Coeff > &t)
Calculates the extended greatest common divisor g of two polynomials.
const T & derivative(const T &t, Variable, std::size_t n=1)
Computes the n'th derivative of a number, which is either the number itself (for n = 0) or zero.
Interval< Number > abs(const Interval< Number > &_in)
Method which returns the absolute value of the passed number.
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
cln::cl_I mod(const cln::cl_I &a, const cln::cl_I &b)
Calculate the remainder of the integer division.
std::map< uint, UnivariatePolynomial< Coeff > > squareFreeFactorization(const UnivariatePolynomial< Coeff > &p)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
cln::cl_I get_num(const cln::cl_RA &n)
Extract the numerator from a fraction.
std::map< UnivariatePolynomial< Coefficient >, uint > FactorMap
void divide(const cln::cl_I ÷nd, const cln::cl_I &divisor, cln::cl_I "ient, cln::cl_I &remainder)
typename UnderlyingNumberType< P >::type Coeff
bool is_integer(const Interval< Number > &n)
Factors< MultivariatePolynomial< C, O, P > > factorization(const MultivariatePolynomial< C, O, P > &p, bool includeConstants=true)
Try to factorize a multivariate polynomial.
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
UnivariatePolynomial< Coeff > exclude_linear_factors(const UnivariatePolynomial< Coeff > &poly, FactorMap< Coeff > &linearFactors, const Integer &maxInt)
This class represents a univariate polynomial with coefficients of an arbitrary type.
bool is_linear_in_main_var() const
Coefficient coprime_factor() const
Calculates a factor that would make the coefficients of this polynomial coprime integers.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
Variable main_var() const
Retrieves the main variable of this polynomial.
const Coefficient & lcoeff() const
Returns the leading coefficient.
Coefficient synthetic_division(const Coefficient &zeroOfDivisor)
uint degree() const
Get the maximal exponent of the main variable.
Type trait for the characteristic of the given field (template argument).
Gives the corresponding integral type.