13#ifndef INCLUDE_STURM_POLY_HH
14#define INCLUDE_STURM_POLY_HH
27 template <
typename Real>
28 class Poly :
public Eigen::Vector<Real, Eigen::Dynamic> {
31 Eigen::Vector<Real, Eigen::Dynamic>;
33 std::numeric_limits<Real>::epsilon()};
43 return *
static_cast<Vector *
>(
this);
72 this->resize(c.size());
73 this->Vector::operator=(c);
74 this->m_order =
Integer(c.size());
82 return *
static_cast<const Vector *
>(
this);
90 this->m_order =
order;
100 this->m_order =
degree + 1;
101 this->resize(this->m_order);
112 this->coeffRef(0) = s;
124 this->coeffRef(0) = a;
125 this->coeffRef(1) = 1;
143 return this->m_order - 1;
151 return this->m_order;
159 if (this->
order() <= 0) {
160 return "(empty polynomial)";
162 if (this->
order() == 1) {
163 return std::to_string(this->coeff(0));
165 if ((*this).cwiseAbs().maxCoeff() == 0) {
176 if (this->coeff(0) != 0) {
177 res = std::to_string(this->coeff(0));
183 if (this->coeff(i) < 0) {
194 }
else if (this->coeff(i) > 0) {
214 e =
"x^" + std::to_string(i);
222 res += s + std::to_string(c) + e;
235 Real res{this->coeff(n)};
237 res = res * x + this->coeff(n);
249 Real Dp{this->coeff(n) * n};
251 Dp = Dp * x + this->coeff(n) * n;
265 Dp = this->coeff(n) * n;
267 p = p * x + this->coeff(n);
268 Dp = Dp * x + this->coeff(n) * n;
270 p = p * x + this->coeff(0);
278 return this->coeff(
m_order - 1);
286 res.resize(this->m_order - 1);
287 for (
Integer i{1}; i < this->m_order; ++i) {
288 res.coeffRef(i - 1) = i * this->coeff(i);
290 res.
m_order = this->m_order - 1;
298 res.resize(this->m_order + 1);
300 for (
Integer i{1}; i <= this->m_order; ++i) {
301 res.coeffRef(i) = this->coeff(i - 1) / i;
303 res.
m_order = this->m_order + 1;
312 res.resize(this->m_order + 1);
314 for (
Integer i{1}; i <= this->m_order; ++i) {
315 res.coeffRef(i) = this->coeff(i - 1) / i;
317 res.
m_order = this->m_order + 1;
327 Real scale{this->cwiseAbs().maxCoeff()};
328 if (scale >
static_cast<Real
>(0.0)) {
342 if (this->m_order > 0) {
343 Real max{this->cwiseAbs().maxCoeff()};
347 Real eps_tmp{eps * max};
348 for (
Integer i{0}; i < this->m_order; ++i) {
349 Real &c_i{this->coeffRef(i)};
350 if (std::abs(c_i) <= eps_tmp) {
365 while (this->m_order > 0 && this->coeff(this->m_order - 1) == 0) {
368 this->conservativeResize(this->m_order);
380 for (
Integer i{0}; i < this->m_order; ++i) {
381 Real v = this->coeff(i);
383 if (last_sign == -1) {
388 if (last_sign == 1) {
408 this->
to_eigen() /= this->coeff(this->m_order - 1);
409 this->coeffRef(this->m_order - 1) = 1;
440 this->conservativeResize(
442 this->head(min_order).noalias() += p.head(min_order);
445 this->tail(n_tail).noalias() = p.tail(n_tail);
447 this->m_order = max_order;
459 this->conservativeResize(
461 this->head(min_order).noalias() -= p.head(min_order);
464 this->tail(n_tail).noalias() = -p.tail(n_tail);
466 this->m_order = max_order;
478 this->resize(new_order);
480 for (
Integer i{0}; i < this->m_order; ++i) {
482 this->coeffRef(i + j) += a.coeff(i) * p.coeff(j);
485 this->m_order = new_order;
495 if (this->m_order > 0)
496 this->coeffRef(0) += s;
499 this->coeffRef(0) = s;
511 if (this->m_order > 0) {
512 this->coeffRef(0) -= s;
515 this->coeffRef(0) = -s;
540 template <
typename Real>
545 res.head(min_order).noalias() = p_1.head(min_order) + p_2.head(min_order);
546 Integer n_tail{max_order - min_order};
549 res.tail(n_tail).noalias() = p_1.tail(n_tail);
551 res.tail(n_tail).noalias() = p_2.tail(n_tail);
564 template <
typename Real>
569 res.coeffRef(0) = p.coeff(0) + s;
571 res.tail(p.
order() - 1).noalias() = p.tail(p.
order() - 1);
585 template <
typename Real>
590 res.coeffRef(0) = s + p.coeff(0);
592 res.tail(p.
order() - 1).noalias() = p.tail(p.
order() - 1);
606 template <
typename Real>
611 res.head(min_order).noalias() = p_1.head(min_order) - p_2.head(min_order);
612 Integer n_tail{max_order - min_order};
615 res.tail(n_tail).noalias() = p_1.tail(n_tail);
617 res.tail(n_tail).noalias() = -p_2.tail(n_tail);
630 template <
typename Real>
635 res.coeffRef(0) = p.coeff(0) - s;
637 res.tail(p.
order() - 1).noalias() = p.tail(p.
order() - 1);
639 res.coeffRef(0) = -s;
651 template <
typename Real>
656 res.coeffRef(0) = s - p.coeff(0);
658 res.tail(p.
order() - 1).noalias() = -p.tail(p.
order() - 1);
673 template <
typename Real>
678 res.coeffRef(i + j) += p_1.coeff(i) * p_2.coeff(j);
691 template <
typename Real>
705 template <
typename Real>
723 template <
typename Real>
731 Real scale_p_1{p_1_norm.normalize()};
741 r = p_1_norm - p_2_norm;
748 "Sturm::Poly::divide(...): leading coefficient of p_2(x) is 0.");
750 while (d >= 0 && r_degree >= 0) {
751 Real leading_r = {r(r_degree)};
752 Real ratio{leading_r / leading_b_norm};
753 q.coeffRef(d) = ratio;
754 r.segment(d, p_2_norm.
degree()).noalias() -=
755 ratio * p_2_norm.head(p_2_norm.
degree());
756 r.coeffRef(r_degree) = 0;
769 q *= scale_p_1 / scale_p_2;
781 template <
typename Real>
786 if (p_2.
order() > 0) {
804 template <
typename Real>
#define STURM_ASSERT(COND, MSG)
Definition Sturm.hh:38
Polynomial class.
Definition Poly.hh:28
Poly & operator-=(const Poly &p)
Define the subtraction with another polynomial.
Definition Poly.hh:456
void set_degree(Integer degree)
Set the degree of the polynomial.
Definition Poly.hh:99
Poly & operator-=(Real s)
Define the subtraction with a scalar.
Definition Poly.hh:510
Poly(const Vector &c)
Class constructor from a vector.
Definition Poly.hh:71
Poly(const Poly &c)
Class constructor from a vector.
Definition Poly.hh:65
void derivative(Poly &res) const
Compute the derivative of the polynomial.
Definition Poly.hh:285
void make_monic()
Normalize the polynomial to monic form.
Definition Poly.hh:407
static constexpr const Real EPSILON
Definition Poly.hh:32
Integer m_order
Definition Poly.hh:36
Poly & operator=(const Poly &p)
Define the assignment with another polynomial.
Definition Poly.hh:417
Poly & operator+=(Real s)
Define the addition with a scalar.
Definition Poly.hh:494
Poly operator-()
Define the negation of the polynomial.
Definition Poly.hh:428
void purge(const Real eps)
Purge small coefficients.
Definition Poly.hh:341
void adjust_degree()
Adjust the degree of the polynomial and remove leading zeros.
Definition Poly.hh:364
Vector coeffs() const
Get the coefficients of the polynomial.
Definition Poly.hh:134
void integral(Poly &res) const
Compute the integral of the polynomial.
Definition Poly.hh:297
Poly & set_monomial(Real a)
Set the polynomial to a monomial with a given coefficient.
Definition Poly.hh:122
void evaluate(Real x, Real &p, Real &Dp) const
Evaluate the polynomial and its derivative at a given point.
Definition Poly.hh:262
Poly & set_scalar(Real s)
Set the polynomial to a scalar value.
Definition Poly.hh:110
Real leading_coeff() const
Get the leading coefficient of the polynomial.
Definition Poly.hh:277
Poly(Integer order)
Class constructor from a vector.
Definition Poly.hh:56
Vector & to_eigen()
Access to the Eigen class.
Definition Poly.hh:42
Poly & operator*=(Real s)
Define the multiplication with a scalar.
Definition Poly.hh:526
Real evaluate_derivative(Real x) const
Evaluate the derivative of the polynomial at a given point.
Definition Poly.hh:247
Poly & operator*=(const Poly &p)
Define the multiplication with another polynomial.
Definition Poly.hh:475
Poly()
Class constructor from a vector.
Definition Poly.hh:50
std::string to_string() const
Convert the polynomial to a string representation.
Definition Poly.hh:158
Integer degree() const
Get the degree of the polynomial.
Definition Poly.hh:142
Real evaluate(Real x) const
Evaluate the polynomial at a given point.
Definition Poly.hh:233
Real normalize()
Normalize the polynomial.
Definition Poly.hh:326
Integer order() const
Get the order of the polynomial.
Definition Poly.hh:150
void set_order(Integer order)
Set the order of the polynomial.
Definition Poly.hh:89
Poly & operator+=(const Poly &p)
Define the addition with another polynomial.
Definition Poly.hh:437
const Vector & to_eigen() const
Access to the Eigen const class.
Definition Poly.hh:81
Eigen::Vector< Real, Eigen::Dynamic > Vector
Definition Poly.hh:30
void integral(Poly &res, Real c) const
Compute the integral of the polynomial with a given constant.
Definition Poly.hh:311
Integer sign_variations() const
Count the number of sign variations.
Definition Poly.hh:377
Namespace for the Sturm library.
Definition Sturm.hh:71
Poly< Real > operator+(const Poly< Real > &p_1, const Poly< Real > &p_2)
Define the sum between two polynomials.
Definition Poly.hh:541
void GCD(const Poly< Real > &p_1, const Poly< Real > &p_2, Poly< Real > &gcd, Real eps=Poly< Real >::EPSILON)
Compute the greatest common divisor of two polynomials.
Definition Poly.hh:782
Poly< Real > operator-(const Poly< Real > &p_1, const Poly< Real > &p_2)
Define the difference between two polynomials.
Definition Poly.hh:607
void divide(const Poly< Real > &p_1, const Poly< Real > &p_2, Poly< Real > &q, Poly< Real > &r)
Divide the polynomial.
Definition Poly.hh:724
std::ostream & operator<<(std::ostream &os, const Poly< Real > &p)
Print the polynomial on an output stream.
Definition Poly.hh:805
Poly< Real > operator*(const Poly< Real > &p_1, const Poly< Real > &p_2)
Define the multiplication between two polynomials.
Definition Poly.hh:674
STURM_DEFAULT_INTEGER_TYPE Integer
The Integer type as used for the API.
Definition Sturm.hh:79