GCC Code Coverage Report
Directory: . Exec Total Coverage
File: build-coverage/deps/include/poly/polyxx/upolynomial.h Lines: 1 1 100.0 %
Date: 2021-05-22 Branches: 0 0 0.0 %

Line Exec Source
1
#pragma once
2
3
#include <iosfwd>
4
#include <utility>
5
#include <vector>
6
7
#include "../integer.h"
8
#include "../upolynomial.h"
9
#include "dyadic_rational.h"
10
#include "integer.h"
11
#include "integer_ring.h"
12
#include "rational.h"
13
#include "variable.h"
14
15
namespace poly {
16
17
  /**
18
   * Implements a wrapper for lp_upolynomial_t.
19
   */
20
25
  class UPolynomial {
21
    /** The actual univariate polynomial. */
22
    deleting_unique_ptr<lp_upolynomial_t> mPoly;
23
24
   public:
25
    /** Create from a lp_upolynomial_t pointer, claiming it's ownership. */
26
    explicit UPolynomial(lp_upolynomial_t* poly);
27
    /** Copy from an internal lp_upolynomial_t pointer. */
28
    explicit UPolynomial(const lp_upolynomial_t* poly);
29
30
    /** Create the zero polynomial. */
31
    explicit UPolynomial();
32
    /** Create a constant polynomial. */
33
    explicit UPolynomial(const Integer& i);
34
    /** Create a constant polynomial. */
35
    explicit UPolynomial(long i);
36
37
    /** Create from integer coefficients. */
38
    explicit UPolynomial(const std::vector<Integer>& coefficients);
39
    /** Create from integer coefficients into the given integer ring. */
40
    UPolynomial(const IntegerRing& ir,
41
                const std::vector<Integer>& coefficients);
42
    /** Create from integer coefficients. */
43
    explicit UPolynomial(const std::vector<long>& coefficients);
44
    /** Create from integer coefficients into the given integer ring. */
45
    UPolynomial(const IntegerRing& ir, const std::vector<long>& coefficients);
46
47
    /** Create from integer coefficients. */
48
    explicit UPolynomial(std::initializer_list<long> coefficients);
49
    /** Create from integer coefficients into the given integer ring. */
50
    UPolynomial(const IntegerRing& ir,
51
                std::initializer_list<long> coefficients);
52
53
    /** Construct c * x^degree. */
54
    UPolynomial(std::size_t degree, long c);
55
    /** Construct c * x^degree into the given integer ring. */
56
    UPolynomial(const IntegerRing& ir, std::size_t degree, long c);
57
58
    /** Copy from a polynomial. */
59
    UPolynomial(const UPolynomial& poly);
60
    /** Move from a polynomial. */
61
    UPolynomial(UPolynomial&& poly);
62
    /** Copy from a polynomial into the given integer ring. */
63
    UPolynomial(const IntegerRing& ir, const UPolynomial& poly);
64
65
    /** Copy from a polynomial. */
66
    UPolynomial& operator=(const UPolynomial& poly);
67
    /** Move from a polynomial. */
68
    UPolynomial& operator=(UPolynomial&& poly);
69
    /** Assign from and take ownership of an internal lp_upolynomial_t pointer.
70
     */
71
    UPolynomial& operator=(lp_upolynomial_t* poly);
72
73
    /** Get a non-const pointer to the internal lp_upolynomial_t. Handle with
74
     * care! */
75
    lp_upolynomial_t* get_internal();
76
    /** Get a const pointer to the internal lp_upolynomial_t. */
77
    const lp_upolynomial_t* get_internal() const;
78
    /** Release the lp_upolynomial_t pointer. This yields ownership of the
79
     * returned pointer. */
80
    lp_upolynomial_t* release();
81
  };
82
83
  /** Return the degree of a polynomial. */
84
  std::size_t degree(const UPolynomial& p);
85
86
  /** Get the leading coefficient. */
87
  const Integer& leading_coefficient(const UPolynomial& p);
88
  /** Get the constant coefficient. */
89
  const Integer& constant_coefficient(const UPolynomial& p);
90
91
  /** Get all coefficients. */
92
  std::vector<Integer> coefficients(const UPolynomial& p);
93
94
  /** Stream the given UPolynomial to an output stream. */
95
  std::ostream& operator<<(std::ostream& os, const UPolynomial& p);
96
97
  /** Check if the polynomial is zero. */
98
  bool is_zero(const UPolynomial& p);
99
  /** Check if the polynomial is one. */
100
  bool is_one(const UPolynomial& p);
101
  /** Check if the polynomial is monic.
102
   * A polynomial is monic if its leading coefficient is one.
103
   */
104
  bool is_monic(const UPolynomial& p);
105
  /** Check if the polynomial is primitive.
106
   * A polynomial is primitive if the gcd of all coefficients is one and the
107
   * leading coefficient is positive.
108
   */
109
  bool is_primitive(const UPolynomial& p);
110
111
  /** Evaluate a polynomial at an integer. */
112
  Integer evaluate_at(const UPolynomial& p, const Integer& i);
113
  /** Evaluate a polynomial at a rational. */
114
  Rational evaluate_at(const UPolynomial& p, const Rational& r);
115
  /** Evaluate a polynomial at a dyadic rational. */
116
  DyadicRational evaluate_at(const UPolynomial& p, const DyadicRational& dr);
117
118
  /** Determine the sign of a polynomial at an integer. */
119
  int sign_at(const UPolynomial& p, const Integer& i);
120
  /** Determine the sign of a polynomial at a rational. */
121
  int sign_at(const UPolynomial& p, const Rational& r);
122
  /** Determine the sign of a polynomial at a dyadic rational. */
123
  int sign_at(const UPolynomial& p, const DyadicRational& dr);
124
125
  /** Compares two polynomials (using a lexicographic order on the
126
   * coefficients). */
127
  bool operator==(const UPolynomial& lhs, const UPolynomial& rhs);
128
  /** Compares two polynomials (using a lexicographic order on the
129
   * coefficients). */
130
  bool operator!=(const UPolynomial& lhs, const UPolynomial& rhs);
131
  /** Compares two polynomials (using a lexicographic order on the
132
   * coefficients). */
133
  bool operator<(const UPolynomial& lhs, const UPolynomial& rhs);
134
  /** Compares two polynomials (using a lexicographic order on the
135
   * coefficients). */
136
  bool operator<=(const UPolynomial& lhs, const UPolynomial& rhs);
137
  /** Compares two polynomials (using a lexicographic order on the
138
   * coefficients). */
139
  bool operator>(const UPolynomial& lhs, const UPolynomial& rhs);
140
  /** Compares two polynomials (using a lexicographic order on the
141
   * coefficients). */
142
  bool operator>=(const UPolynomial& lhs, const UPolynomial& rhs);
143
144
  /** Compute p(-x). */
145
  UPolynomial subst_x_neg(const UPolynomial& p);
146
  /** Compute -p. */
147
  UPolynomial operator-(const UPolynomial& p);
148
  /** Negate a polynomial in place. */
149
  void neg(UPolynomial& p);
150
151
  /** Add two polynomials. */
152
  UPolynomial operator+(const UPolynomial& lhs, const UPolynomial& rhs);
153
  /** Subtract two polynomials. */
154
  UPolynomial operator-(const UPolynomial& lhs, const UPolynomial& rhs);
155
  /** Multiply two polynomials. */
156
  UPolynomial operator*(const UPolynomial& lhs, const UPolynomial& rhs);
157
  /** Multiply a polynomial and an integer. */
158
  UPolynomial operator*(const UPolynomial& lhs, const Integer& rhs);
159
  /** Multiply an integer and a polynomial. */
160
  UPolynomial operator*(const Integer& lhs, const UPolynomial& rhs);
161
162
  /** Compute lhs^rhs. */
163
  UPolynomial pow(const UPolynomial& lhs, long rhs);
164
165
  /** Compute the first derivative. */
166
  UPolynomial derivative(const UPolynomial& p);
167
168
  /** Check whether lhs divides rhs. */
169
  bool divides(const UPolynomial& lhs, const UPolynomial& rhs);
170
171
  /** Divide all degrees within lhs by rhs. All degrees (with non-zero
172
   * coefficients) must be divisible by rhs. */
173
  UPolynomial div_degrees(const UPolynomial& lhs, long rhs);
174
175
  /** Divides two polynomials, assuming all necessary inverses can be computed.
176
   */
177
  UPolynomial div_exact(const UPolynomial& lhs, const UPolynomial& rhs);
178
  /** Divides a polynomial by an integer, assuming that all coefficients are
179
   * divisible by rhs. */
180
  UPolynomial div_exact(const UPolynomial& lhs, const Integer& rhs);
181
  /** Computes the remainder of two polynomials, assuming all necessary inverses
182
   * can be computed. */
183
  UPolynomial rem_exact(const UPolynomial& lhs, const UPolynomial& rhs);
184
  /** Computes the quotient and the remainder of two polynomials, assuming all
185
   * necessary inverses can be computed. */
186
  std::pair<UPolynomial, UPolynomial> div_rem_exact(const UPolynomial& lhs,
187
                                                    const UPolynomial& rhs);
188
  /** Performs pseudo-division such that
189
   *  lc(rhs)^(lhs_deg - rhs_deg + 1) * lhs = div * rhs + rem
190
   * and returns (div, rem).
191
   */
192
  std::pair<UPolynomial, UPolynomial> div_rem_pseudo(const UPolynomial& lhs,
193
                                                     const UPolynomial& rhs);
194
195
  /** Computes the content of a polynomial.
196
   * The content is the gcd of all coefficients with the sign of the leading
197
   * coefficient.
198
   */
199
  Integer content(const UPolynomial& p);
200
  /** Makes a polynomial primitive in place.
201
   * A polynomial is primitive if its content is one.
202
   */
203
  void make_primitive(UPolynomial& p);
204
  /** Computes the primitive part, that is p / content(p). */
205
  UPolynomial primitive_part(const UPolynomial& p);
206
207
  /** Compute the greatest common divisor. */
208
  UPolynomial gcd(const UPolynomial& lhs, const UPolynomial& rhs);
209
  /** Compute the extended greatest common divisor. */
210
  UPolynomial extended_gcd(const UPolynomial& lhs, const UPolynomial& rhs,
211
                           UPolynomial& u, UPolynomial& v);
212
  /** Solves the equations
213
   *  u * p + v * q = r
214
   * assuming that gcd(p,q) divides r.
215
   */
216
  void solve_bezout(const UPolynomial& p, const UPolynomial& q,
217
                    const UPolynomial& r, UPolynomial& u, UPolynomial& v);
218
219
  /** Compute a square-free factorization of a polynomial. */
220
  std::vector<UPolynomial> square_free_factors(const UPolynomial& p,
221
                                               bool with_constant = false);
222
223
  /** Compute the sturm sequence of a polynomial. */
224
  std::vector<UPolynomial> sturm_sequence(const UPolynomial& p);
225
226
  class AlgebraicNumber;
227
  class RationalInterval;
228
229
  /** Count the real roots of a polynomial within a rational interval.*/
230
  std::size_t count_real_roots(const UPolynomial& p,
231
                               const RationalInterval& ri);
232
233
  /** Isolate the real roots of a UPolynomial, returning them as algebraic
234
   * numbers. The roots are sorted in increasing numerical order.
235
   */
236
  std::vector<AlgebraicNumber> isolate_real_roots(const UPolynomial& p);
237
238
}  // namespace poly