23 template<
typename Coeff>
24 class UnivariatePolynomial;
26 template<
typename Coeff>
28 template<
typename Coeff>
30 template<
typename Coeff>
32 template<
typename Coeff>
36 #include "../UnivariatePolynomial.h"
47 template<
typename Coeff>
65 CARL_LOG_TRACE(
"carl.core.resultant",
"subresultants(" << pol1 <<
", " << pol2 <<
")");
75 if (p.degree() < q.
degree()) {
95 assert(p.degree() >= q.
degree());
102 CARL_LOG_TRACE(
"carl.core.resultant",
"subresLcoeff = " << subresLcoeff);
107 CARL_LOG_TRACE(
"carl.core.resultant",
"q = pseudo_remainder(p,-q) = " << q);
121 uint pDeg = p.degree();
126 assert(pDeg >= qDeg);
127 uint delta = pDeg - qDeg;
143 CARL_LOG_TRACE(
"carl.core.resultant",
"Part 2: Generic strategy");
158 CARL_LOG_TRACE(
"carl.core.resultant",
"Part 2: Ducos/Lazard strategy");
160 uint deltaReduced = delta - 1;
161 CARL_LOG_TRACE(
"carl.core.resultant",
"deltaReduced = " << deltaReduced);
163 assert(deltaReduced > 0);
169 CARL_LOG_TRACE(
"carl.core.resultant",
"reductionCoeff = " << reductionCoeff);
174 CARL_LOG_TRACE(
"carl.core.resultant",
"deltaReduced = " << deltaReduced);
179 bool res =
carl::try_divide(reductionCoeff * reductionCoeff, subresLcoeff, reductionCoeff);
180 if (res && deltaReduced >=
exponent) {
185 CARL_LOG_TRACE(
"carl.core.resultant",
"reductionCoeff = " << reductionCoeff);
187 CARL_LOG_TRACE(
"carl.core.resultant",
"reductionCoeff = " << reductionCoeff);
215 CARL_LOG_TRACE(
"carl.core.resultant",
"Part 3: Generic/Lazard strategy");
232 std::vector<Coeff> h(pDeg);
234 for (
uint d = 0; d < qDeg; d++) {
240 for (
uint d = qDeg + 1; d < pDeg; d++) {
241 Coeff t = h[d - 1] * variable;
245 h[d] =
Coeff(t - reducedNewB);
249 for (
uint d = 1; d < pDeg; d++) {
259 if (delta % 2 == 0) {
268 subresLcoeff = p.
lcoeff();
272 template<
typename Coeff>
280 std::vector<UnivariatePolynomial<Coeff>> subresCoeffs;
281 for (
const auto& s : subres) {
283 subresCoeffs.emplace_back(s.main_var(), s.lcoeff());
288 template<
typename Coeff>
298 CARL_LOG_TRACE(
"carl.core.resultant",
"resultant(" << p <<
", " << q <<
") = " << res);
306 template<
typename Coeff>
317 CARL_LOG_TRACE(
"carl.core.discriminant",
"discriminant(" << p <<
") = " << res);
321 namespace resultant_debug {
326 template<
typename Coeff>
364 std::size_t degA =
A.degree(q.
main_var());
365 std::size_t degB = B.degree(q.
main_var());
368 if (degA % 2 == 1 && degB % 2 == 1) s = -1;
375 bool div_res =
false;
383 assert(degA >= degB);
384 std::size_t delta = degA - degB;
386 if (degA % 2 == 1 && degB % 2 == 1) s = -s;
393 for (std::size_t i = 0; i < delta; i++) {
404 for (std::size_t i = 0; i < delta - 1; i++) {
411 std::size_t degA =
A.degree(q.
main_var());
415 for (std::size_t i = 0; i < degA - 1; i++) {
430 template<
typename Coeff>
447 template<
typename Coeff>
511 for (std::size_t i = 0; i < g.
degree() - f.
degree() + 1; i++) {
518 for (std::size_t i = 0; i < g.
degree(); i++) {
523 std::vector<UnivariatePolynomial<Coeff>> m;
526 m[f.
degree() - 1] = gRest;
527 for (std::size_t i = 1; i < f.
degree(); i++) {
530 m[f.
degree() - 1 - i] = gRest;
533 for (std::size_t i = 0; i < m.size() - 1; i++) {
534 for (std::size_t j = i + 1; j < m.size(); j++) {
542 for (std::size_t i = 0; i < m.size(); i++) {
544 if (m[i].degree() >= m.size() - 1 - i) {
545 determinant *= m[i].coefficients()[m.size() - 1 - i];
547 determinant =
Coeff(0);
551 determinant = determinant.coprime_coefficients();
Implements utility functions concerning the (total) degree of monomials, terms and polynomials.
#define CARL_LOG_TRACE(channel, msg)
#define CARL_LOG_DEBUG(channel, msg)
carl is the main namespace for the library.
Coeff content(const UnivariatePolynomial< Coeff > &p)
The content of a polynomial is the gcd of the coefficients of the normal part of a polynomial.
UnivariatePolynomial< C > to_univariate_polynomial(const MultivariatePolynomial< C, O, P > &p)
Convert a univariate polynomial that is currently (mis)represented by a 'MultivariatePolynomial' into...
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.
bool try_divide(const Term< Coeff > &t, const Coeff &c, Term< Coeff > &res)
std::vector< UnivariatePolynomial< Coeff > > principalSubresultantsCoefficients(const UnivariatePolynomial< Coeff > &, const UnivariatePolynomial< Coeff > &, SubresultantStrategy=SubresultantStrategy::Default)
void swap(Variable &lhs, Variable &rhs)
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
auto discriminant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
std::list< UnivariatePolynomial< Coeff > > subresultants(const UnivariatePolynomial< Coeff > &, const UnivariatePolynomial< Coeff > &, SubresultantStrategy=SubresultantStrategy::Default)
Implements a subresultants algorithm with optimizations described in .
std::size_t exponent
Type of an exponent.
Number highestPower(const Number &n)
Returns the highest power of two below n.
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
typename UnderlyingNumberType< P >::type Coeff
UnivariatePolynomial< Coeff > primitive_part(const UnivariatePolynomial< Coeff > &p)
The primitive part of p is the normal part of p divided by the content of p.
UnivariatePolynomial< Coeff > pseudo_remainder(const UnivariatePolynomial< Coeff > ÷nd, const UnivariatePolynomial< Coeff > &divisor)
Calculates the pseudo-remainder.
auto resultant(const ContextPolynomial< Coeff, Ordering, Policies > &p, const ContextPolynomial< Coeff, Ordering, Policies > &q)
Interval< Number > pow(const Interval< Number > &i, Integer exp)
UnivariatePolynomial< Coeff > resultant_z3(const UnivariatePolynomial< Coeff > &p, const UnivariatePolynomial< Coeff > &q)
A reimplementation of the resultant algorithm from z3.
UnivariatePolynomial< Coeff > eliminate(const UnivariatePolynomial< Coeff > &p, const UnivariatePolynomial< Coeff > &q)
Eliminates the leading factor of p with q.
UnivariatePolynomial< Coeff > resultant_det(const UnivariatePolynomial< Coeff > &p, const UnivariatePolynomial< Coeff > &q)
An implementation of the naive resultant algorithm based on the silvester matrix.
A Variable represents an algebraic variable that can be used throughout carl.
This class represents a univariate polynomial with coefficients of an arbitrary type.
bool is_number() const
Checks whether the polynomial is only a number.
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.
uint degree() const
Get the maximal exponent of the main variable.
UnivariatePolynomial normalized() const
The normal part of a polynomial is the polynomial divided by the unit part.