carl  24.04
Computer ARithmetic Library
MultivariatePolynomial.h
Go to the documentation of this file.
1 /**
2  * @file MultivariatePolynomial.h
3  * @ingroup multirp
4  * @author Sebastian Junges
5  * @author Florian Corzilius
6  */
7 
8 #pragma once
9 
10 #include <algorithm>
11 #include <numeric>
12 #include <memory>
13 #include <type_traits>
14 #include <vector>
15 
17 #include "Term.h"
19 #include "TermAdditionManager.h"
20 #include "../typetraits.h"
21 
22 
23 namespace carl
24 {
25 // forward declaration of UnivariatePolynomials
26 template<typename Coeff>
27 class UnivariatePolynomial;
28 
29 /**
30  * The general-purpose multivariate polynomial class.
31  *
32  * It is represented as a sum of terms, being a coefficient and a monomial.
33  *
34  * A polynomial is always *minimally ordered*.
35  * By that, we mean that the leading term and the constant term (if there is any) are at the correct positions.
36  * For some operations, the terms may be *fully ordered*.
37  * `isOrdered()` checks if the polynomial is *fully ordered* while `makeOrdered()` makes the polynomial *fully ordered*.
38  *
39  * @ingroup multirp
40  */
41 template<typename Coeff, typename Ordering = GrLexOrdering, typename Policies = StdMultivariatePolynomialPolicies<>>
42 class MultivariatePolynomial : public Policies
43 {
44  template<typename Polynomial, typename Order>
45  friend class TermAdditionManager;
46 public:
47  /// The ordering of the terms.
48  using OrderedBy = Ordering;
49  /// Type of the terms.
51  /// Type of the monomials within the terms.
53  /// Type of the coefficients.
54  using CoeffType = Coeff;
55  /// Policies for this monomial.
56  using Policy = Policies;
57  /// Number type within the coefficients.
59  /// Integer type associated with the number type.
61  ///
63  /// The type of the cache. Multivariate polynomials do not need a cache, we set it to something.
64  using CACHE = void;
65  /// Type our terms vector.f
66  using TermsType = std::vector<Term<Coeff>>;
67  // RAN type
69 
70  template<typename C, typename T>
71  using EnableIfNotSame = typename std::enable_if<!std::is_same<C,T>::value,T>::type;
72 
73 private:
74  /// A vector of all terms.
75  mutable TermsType mTerms;
76  /// Flag that indicates if the terms are ordered.
77  mutable bool mOrdered;
78 public:
79  ///
81 
82  enum class ConstructorOperation { ADD, SUB, MUL, DIV };
83  friend std::ostream& operator<<(std::ostream& os, ConstructorOperation op) {
84  switch (op) {
85  case ConstructorOperation::ADD: return os << "+";
86  case ConstructorOperation::SUB: return os << "-";
87  case ConstructorOperation::MUL: return os << "*";
88  case ConstructorOperation::DIV: return os << "/";
89  }
90  return os << "?";
91  }
92 
93  /// @name Constructors
94  /// @{
101  template<typename C = Coeff>
103  template<typename C = Coeff>
105  explicit MultivariatePolynomial(const Coeff& c);
108  explicit MultivariatePolynomial(const std::shared_ptr<const Monomial>& m);
111  template<class OtherPolicies, DisableIf<std::is_same<Policies,OtherPolicies>> = dummy>
113  explicit MultivariatePolynomial(TermsType&& terms, bool duplicates = true, bool ordered = false);
114  explicit MultivariatePolynomial(const TermsType& terms, bool duplicates = true, bool ordered = false);
115  MultivariatePolynomial(const std::initializer_list<Term<Coeff>>& terms);
116  MultivariatePolynomial(const std::initializer_list<Variable>& terms);
117  explicit MultivariatePolynomial(const std::pair<ConstructorOperation, std::vector<MultivariatePolynomial>>& p);
118  explicit MultivariatePolynomial(ConstructorOperation op, const std::vector<MultivariatePolynomial>& operands);
119  /// @}
120 
121  ~MultivariatePolynomial() noexcept = default;
122 
123  /**
124  * Check if the terms are ordered.
125  * @return If terms are ordered.
126  */
127  bool isOrdered() const {
128  return mOrdered;
129  }
130  void reset_ordered() const {
131  mOrdered = false;
132  }
133  /**
134  * Ensure that the terms are ordered.
135  */
136  void makeOrdered() const {
137  if (isOrdered()) return;
138  std::sort(begin(), end(),
139  [](const auto& lhs, const auto& rhs){ return Ordering::less(lhs, rhs); }
140  );
141  mOrdered = true;
142  assert(this->is_consistent());
143  }
144  /**
145  * The leading term
146  * @return leading term.
147  */
148  const Term<Coeff>& lterm() const {
149  CARL_LOG_ASSERT("carl.core", nr_terms() > 0, "Leading term undefined on zero polynomials.");
150  return mTerms.back();
151  }
153  CARL_LOG_ASSERT("carl.core", nr_terms() > 0, "Leading term undefined on zero polynomials.");
154  return mTerms.back();
155  }
156  /**
157  * Returns the coefficient of the leading term.
158  * Notice that this is not defined for zero polynomials.
159  * @return Leading coefficient.
160  */
161  const Coeff& lcoeff() const {
162  return lterm().coeff();
163  }
164  /**
165  * The leading monomial
166  * @return monomial of leading term.
167  */
168  const Monomial::Arg& lmon() const {
169  return lterm().monomial();
170  }
171  /**
172  * Returns the leading coefficient with respect to the given variable.
173  * @param var Variable.
174  * @return Leading coefficient.
175  */
177  return coeff(var, degree(var));
178  }
179 
180  /**
181  * Give the last term according to Ordering. Notice that if there is a constant part, it is always trailing.
182  */
183  const Term<Coeff>& trailingTerm() const {
184  CARL_LOG_ASSERT("carl.core", nr_terms() > 0, "Trailing term undefined on zero polynomials.");
185  return mTerms.front();
186  }
188  CARL_LOG_ASSERT("carl.core", nr_terms() > 0, "Trailing term undefined on zero polynomials.");
189  return mTerms.front();
190  }
191 
192  /**
193  * Calculates the max. degree over all monomials occurring in the polynomial.
194  * As the degree of the zero polynomial is \f$-\infty\f$, we assert that this polynomial is not zero. This must be checked by the caller before calling this method.
195  * @see @cite GCL92, page 48
196  * @return Total degree.
197  */
198  std::size_t total_degree() const;
199 
200  /**
201  * Calculates the degree of this polynomial with respect to the given variable.
202  * @param var Variable.
203  * @return Degree w.r.t. var.
204  */
205  std::size_t degree(Variable::Arg var) const {
206  std::size_t max = 0;
207  for (const auto& t: mTerms) {
208  if (t.monomial() == nullptr) continue;
209  std::size_t c = t.monomial()->exponent_of_variable(var);
210  if (c > max) max = c;
211  }
212  return max;
213  }
214 
215  /**
216  * Calculates the coefficient of var^exp.
217  * @param var Variable.
218  * @param exp Exponent.
219  * @return Coefficient of var^exp.
220  */
221  MultivariatePolynomial coeff(Variable::Arg var, std::size_t exp) const {
223  for (const auto& t: mTerms) {
224  if (t.monomial() == nullptr) {
225  if (exp == 0) res.mTerms.push_back(t);
226  } else if (t.monomial()->exponent_of_variable(var) == exp) {
227  Monomial::Arg newMon = t.monomial()->drop_variable(var);
228  res.mTerms.push_back(TermType(t.coeff(), newMon));
229  }
230  }
231  res.mOrdered = false;
232  res.makeMinimallyOrdered<true,true>();
233  return res;
234  }
235 
236  /**
237  * Check if the polynomial is zero.
238  */
239  [[deprecated("use carl::is_zero(p) instead.")]]
240  bool is_zero() const {
241  return mTerms.empty();
242  }
243  /**
244  *
245  * @return
246  */
247  [[deprecated("use carl::is_one(p) instead.")]]
248  bool is_one() const {
249  return (nr_terms() == 1) && carl::is_one(lterm());
250  }
251  /**
252  * Check if the polynomial is constant.
253  */
254  bool is_constant() const {
255  return (nr_terms() == 0) || ((nr_terms() == 1) && lterm().is_constant());
256  }
257  /**
258  * Check if the polynomial is a number, i.e., a constant.
259  */
260  bool is_number() const {
261  return is_constant();
262  }
263  /**
264  * @return true, if this polynomial consists just of one variable (with coefficient 1).
265  */
266  bool is_variable() const {
267  return (nr_terms() == 1) && carl::is_one(lcoeff()) && lterm().is_single_variable();
268  }
269  /**
270  * Check if the polynomial is linear.
271  */
272  bool is_linear() const;
273 
274  /**
275  * Calculate the number of terms.
276  */
277  std::size_t nr_terms() const {
278  return mTerms.size();
279  }
280 
281  /**
282  * @return A rough estimation of the size of this polynomial being the number of its terms.
283  * (Note, that this method is required, as it is provided of other polynomials not necessarily being straightforward.)
284  */
285  std::size_t size() const {
286  return mTerms.size();
287  }
288 
289  /**
290  * Check if the polynomial has a constant term that is not zero.
291  */
292  bool has_constant_term() const {
293  return (nr_terms() > 0) && trailingTerm().is_constant();
294  }
295 
296  /**
297  * @return true, if the image of this polynomial is integer-valued.
298  */
299  bool integer_valued() const {
300  return std::all_of(begin(), end(),
301  [](const auto& t){ return t.integer_valued(); }
302  );
303  }
304 
305  /**
306  * Retrieve the constant term of this polynomial or zero, if there is no constant term.
307  */
308  const Coeff& constant_part() const;
309 
310  auto begin() const {
311  return mTerms.begin();
312  }
313  auto end() const {
314  return mTerms.end();
315  }
316  auto rbegin() const {
317  return mTerms.rbegin();
318  }
319  auto rend() const {
320  return mTerms.rend();
321  }
322 
323  auto erase_term(typename TermsType::iterator pos) {
324  ///@todo find new lterm or constant term
325  assert(false);
326  return mTerms.erase(pos);
327  }
328 
329  const TermsType& terms() const {
330  return mTerms;
331  }
333  return mTerms;
334  }
335 
336  /**
337  * For the polynomial p, the function calculates a polynomial p - lt(p).
338  * The function assumes the polynomial to be nonzero, otherwise, lt(p) is not defined.
339  * @return A new polynomial p - lt(p).
340  */
341  MultivariatePolynomial tail(bool makeFullyOrdered = false) const;
342  /**
343  * Drops the leading term.
344  * The function assumes the polynomial to be nonzero, otherwise the leading term is not defined.
345  * @return A reference to this.
346  */
347  ///@todo find new lterm
349 
350  bool has_single_variable() const {
351  return lterm().is_single_variable() && nr_terms() == 1;
352  }
353 
354  /**
355  * For terms with exactly one variable, get this variable.
356  * @return The only variable occuring in the term.
357  */
359  return lterm().single_variable();
360  }
361 
362  /**
363  * @return Coefficient of the polynomial (this makes only sense for polynomials storing the gcd of all coefficients separately)
364  */
365  const CoeffType& coefficient() const {
367  }
368 
369  /**
370  * @return The coprimeCoefficients of this polyomial, if this is stored internally, otherwise this polynomial.
371  */
372  const PolyType& polynomial() const {
373  return *this;
374  }
375 
376  /**
377  * Checks whether only one variable occurs.
378  * @return
379  * Notice that it might be better to use the variable information if several pieces of information are requested.
380  */
381  bool is_univariate() const;
382 
383  /**
384  * Checks whether the polynomial is a trivial sum of squares.
385  * @return true if polynomial is of the form \\sum a_im_i^2 with a_i > 0 for all i.
386  */
387  bool is_tsos() const {
388  return std::all_of(begin(), end(),
389  [](const auto& t){ return t.is_square(); }
390  );
391  }
392 
393  /**
394  * @param v The variable to check for its occurrence.
395  * @return true, if the variable occurs in this term.
396  */
397  bool has(Variable v) const {
398  return std::any_of(begin(), end(),
399  [v](const auto& t){ return t.has(v); }
400  );
401  }
402 
403  bool is_reducible_identity() const;
404 
405  /**
406  * Subtract a term times a polynomial from this polynomial.
407  * @param factor Term.
408  * @param p Polynomial.
409  */
410  void subtractProduct(const Term<Coeff>& factor, const MultivariatePolynomial& p);
411 
412  /**
413  * Adds a single term without using a TermAdditionManager or changing the ordering status.
414  * @param term Term.
415  */
416  void addTerm(const Term<Coeff>& term);
417 
418  /**
419  * Calculates the square of this multivariate polynomial if it is a square.
420  * @param res Used to store the result in.
421  * @return true, if this multivariate polynomial is a square; false, otherwise.
422  */
423  bool sqrt(MultivariatePolynomial& res) const;
424 
425  /**
426  * @return The lcm of the denominators of the coefficients in p divided by the gcd of numerators
427  * of the coefficients in p.
428  */
430 
431  /**
432  * @return The lcm of the denominators of the coefficients (without the constant one) in p divided by the gcd of numerators
433  * of the coefficients in p.
434  */
435  template<typename C = Coeff, EnableIf<is_subset_of_rationals_type<C>> = dummy>
437 
438  /**
439  * @return p * p.coprime_factor()
440  * @see coprime_factor()
441  */
443 
444  /**
445  * @return p * |p.coprime_factor()|
446  * @see coprime_coefficients()
447  */
449 
450  /**
451  * For a polynomial p, returns p/lc(p)
452  * @return
453  */
455 
456  bool divides(const MultivariatePolynomial& b) const;
457 
459 
460  const Term<Coeff>& operator[](std::size_t index) const {
461  assert(index < mTerms.size());
462  return mTerms[index];
463  }
464 
465  MultivariatePolynomial mod(const typename IntegralType<Coeff>::type& modulo) const;
466 
467  template<typename C=Coeff, EnableIf<is_number_type<C>> = dummy>
469  template<typename C=Coeff, DisableIf<is_number_type<C>> = dummy>
471 
472  template<typename C=Coeff, EnableIf<is_number_type<C>> = dummy>
474 
475  /// @name In-place addition operators
476  /// @{
477  /**
478  * Add something to this polynomial and return the changed polynomial.
479  * @param rhs Right hand side.
480  * @return Changed polynomial.
481  */
484  MultivariatePolynomial& operator+=(const std::shared_ptr<const TermType>& rhs);
488  /// @}
489 
490  /// @name In-place subtraction operators
491  /// @{
492  /**
493  * Subtract something from this polynomial and return the changed polynomial.
494  * @param rhs Right hand side.
495  * @return Changed polynomial.
496  */
502  /// @}
503 
504 
506 
507  /// @name In-place multiplication operators
508  /// @{
509  /**
510  * Multiply this polynomial with something and return the changed polynomial.
511  * @param rhs Right hand side.
512  * @return Changed polynomial.
513  */
519  /// @}
520 
521  /// @name In-place division operators
522  /// @{
523  /**
524  * Divide this polynomial by something and return the changed polynomial.
525  * @param rhs Right hand side.
526  * @return Changed polynomial.
527  */
533  /// @}
534 
535  /// @name Division operators
536  /// @{
537  /**
538  * Perform a division involving a polynomial.
539  * @param lhs Left hand side.
540  * @param rhs Right hand side.
541  * @return `lhs / rhs`
542  */
543  template<typename C, typename O, typename P>
545 
546  template<typename C, typename O, typename P>
548  /// @}
549 
550 
552  {
553  return Ordering::less(p1.lterm(), p2.lterm());
554  }
555 
557  {
558  return (p1.nr_terms() < p2.nr_terms());
559  }
560 
561 
562  /**
563  * Make sure that the terms are at least minimally ordered.
564  */
565  template<bool findConstantTerm=true, bool findLeadingTerm=true>
566  void makeMinimallyOrdered() const;
567 private:
568  /**
569  * Make sure that the terms are at least minimally ordered.
570  * Iterators to the important terms are given as arguments, so that we don't need to scan the whole vector.
571  * @param lterm Iterator to leading term.
572  * @param cterm Iterator to constant term.
573  */
574  void makeMinimallyOrdered(typename TermsType::iterator& lterm, typename TermsType::iterator& cterm) const;
575 
576 public:
577  /**
578  * Asserts that this polynomial complies with the requirements and assumptions for MultivariatePolynomial objects.
579  *
580  * <ul>
581  * <li>All terms are actually valid and not nullptr or alike</li>
582  * <li>Only the trailing term may be constant.</li>
583  * </ul>
584  */
585  bool is_consistent() const;
586 };
587 
588  template<typename C, typename O, typename P>
590  return (p.nr_terms() == 1) && carl::is_one(p.lterm());
591  }
592  template<typename C, typename O, typename P>
594  return p.nr_terms() == 0;
595  }
596 
597  //template<typename C, typename O, typename P>
598  //MultivariatePolynomial<C,O,P> pow(const MultivariatePolynomial<C,O,P>& p, std::size_t exp)
599  //{
600  // return p.pow(exp);
601  //}
602 
603  /// @name Division operators
604  /// @{
605  /**
606  * Perform a division involving a polynomial.
607  * @param lhs Left hand side.
608  * @param rhs Right hand side.
609  * @return `lhs / rhs`
610  */
611  template<typename C, typename O, typename P, EnableIf<carl::is_number_type<C>> = dummy>
613  return MultivariatePolynomial<C,O,P>(lhs) /= rhs;
614  }
615  /// @}
616  template<typename C, typename O, typename P>
617  std::pair<MultivariatePolynomial<C,O,P>,MultivariatePolynomial<C,O,P>> lazyDiv( const MultivariatePolynomial<C,O,P>& _polyA, const MultivariatePolynomial<C,O,P>& _polyB )
618  {
619  MultivariatePolynomial<C,O,P> g = gcd( _polyA, _polyB );
620  return std::make_pair( _polyA/g, _polyB/g );
621  }
622 
623  /**
624  * Streaming operator for multivariate polynomials.
625  * @param os Output stream.
626  * @param rhs Polynomial.
627  * @return `os`.
628  */
629  template<typename C, typename O, typename P>
630  inline std::ostream& operator<<(std::ostream& os, const MultivariatePolynomial<C,O,P>& rhs) {
631  if (is_zero(rhs)) return os << "0";
632  return os << carl::stream_joined(" + ", rhs);
633  }
634 
635  /// Add the variables of the given polynomial to the variables.
636  template<typename Coeff, typename Ordering, typename Policies>
638  for (const auto& t : p) {
639  variables(t, vars);
640  }
641  }
642 
643 template<typename T, typename O, typename P>
644 struct is_polynomial_type<carl::MultivariatePolynomial<T, O, P>>: std::true_type {};
645 /**
646  * States that UnderlyingNumberType of MultivariatePolynomial<C,O,P> is UnderlyingNumberType<C>::type.
647  * @ingroup typetraits_UnderlyingNumberType
648  */
649 template<typename C, typename O, typename P>
650 struct UnderlyingNumberType<MultivariatePolynomial<C, O, P>>: has_subtype<typename UnderlyingNumberType<C>::type> {};
651 
652 
653 } // namespace carl
654 
655 /**
656  * @ingroup multirp
657  */
658 namespace std {
659  /**
660  * Specialization of `std::hash` for MultivariatePolynomial.
661  */
662  template<typename C, typename O, typename P>
663  struct hash<carl::MultivariatePolynomial<C,O,P>> {
664  /**
665  * Calculates the hash of a MultivariatePolynomial.
666  * @param mpoly MultivariatePolynomial.
667  * @return Hash of mpoly.
668  */
669 
670  std::size_t operator()(const carl::MultivariatePolynomial<C,O,P>& mpoly) const {
671  assert(mpoly.is_consistent());
672 #if false
673  if (mpoly.nr_terms() == 0) return 0;
674  if (mpoly.nr_terms() == 1) return carl::hash_all(mpoly[0]);
675  std::size_t seed = 0;
676  carl::hash_add(seed, mpoly[0]);
677  for (std::size_t i = 1; i < mpoly.nr_terms() - 1; ++i) {
678  seed = seed ^ carl::hash_all(mpoly[i]);
679  }
680  carl::hash_add(seed, mpoly[mpoly.nr_terms()-1]);
681  return seed;
682 #else
683  mpoly.makeOrdered();
684  return std::accumulate(mpoly.begin(), mpoly.end(), static_cast<std::size_t>(0),
685  [](std::size_t seed, const auto& t){ carl::hash_add(seed, t); return seed; }
686  );
687 #endif
688  }
689  };
690 } // namespace std
691 
#define CARL_LOG_ASSERT(channel, condition, msg)
Definition: carl-logging.h:47
Gives the underlying number type of a complex object.
Definition: typetraits.h:336
carl is the main namespace for the library.
Interval< Number > operator/(const Interval< Number > &lhs, const Number &rhs)
Operator for the division of an interval and a number.
Definition: operators.h:453
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
Definition: operations.h:310
Interval< Number > exp(const Interval< Number > &i)
Definition: Exponential.h:10
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
std::pair< MultivariatePolynomial< C, O, P >, MultivariatePolynomial< C, O, P > > lazyDiv(const MultivariatePolynomial< C, O, P > &_polyA, const MultivariatePolynomial< C, O, P > &_polyB)
typename UnderlyingNumberType< P >::type Coeff
std::int64_t sint
Definition: numbers.h:17
auto stream_joined(const std::string &glue, const T &v)
Allows to easily output some container with all elements separated by some string.
std::size_t hash_all(Args &&... args)
Hashes an arbitrary number of values.
Definition: hash.h:71
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
void hash_add(std::size_t &seed, const T &value)
Add hash of the given value to the hash seed.
Definition: hash.h:23
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
Definition: Interval.h:1462
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
static const T & get()
Definition: constants.h:51
This template is designed to provide types that are related to other types.
Definition: typetraits.h:75
T type
A type associated with the type.
Definition: typetraits.h:77
This class represents a univariate polynomial with coefficients of an arbitrary type.
The general-purpose multivariate polynomial class.
MultivariatePolynomial(const std::shared_ptr< const Monomial > &m)
MultivariatePolynomial & operator/=(const MultivariatePolynomial &rhs)
Divide this polynomial by something and return the changed polynomial.
IntNumberType main_denom() const
MultivariatePolynomial & operator=(MultivariatePolynomial &&p) noexcept
MultivariatePolynomial & operator+=(const std::shared_ptr< const TermType > &rhs)
Add something to this polynomial and return the changed polynomial.
MultivariatePolynomial & operator*=(const MultivariatePolynomial &rhs)
Multiply this polynomial with something and return the changed polynomial.
typename UnivariatePolynomial< NumberType >::RootType RootType
UnderlyingNumberType< C >::type numeric_content() const
void makeOrdered() const
Ensure that the terms are ordered.
MultivariatePolynomial(const TermsType &terms, bool duplicates=true, bool ordered=false)
const CoeffType & coefficient() const
friend MultivariatePolynomial< C, O, P > operator/(const MultivariatePolynomial< C, O, P > &lhs, const MultivariatePolynomial< C, O, P > &rhs)
Perform a division involving a polynomial.
Definition: Division.h:242
const TermsType & terms() const
bool is_consistent() const
Asserts that this polynomial complies with the requirements and assumptions for MultivariatePolynomia...
MultivariatePolynomial(const UnivariatePolynomial< Coeff > &p)
MultivariatePolynomial(const MultivariatePolynomial< Coeff, Ordering, OtherPolicies > &p)
const Term< Coeff > & trailingTerm() const
Give the last term according to Ordering.
void makeMinimallyOrdered() const
Make sure that the terms are at least minimally ordered.
bool divides(const MultivariatePolynomial &b) const
typename std::enable_if<!std::is_same< C, T >::value, T >::type EnableIfNotSame
auto erase_term(typename TermsType::iterator pos)
bool is_constant() const
Check if the polynomial is constant.
MultivariatePolynomial coprime_coefficients() const
void CACHE
The type of the cache. Multivariate polynomials do not need a cache, we set it to something.
MultivariatePolynomial(const std::pair< ConstructorOperation, std::vector< MultivariatePolynomial >> &p)
MultivariatePolynomial & strip_lterm()
Drops the leading term.
std::size_t degree(Variable::Arg var) const
Calculates the degree of this polynomial with respect to the given variable.
MultivariatePolynomial(const std::initializer_list< Term< Coeff >> &terms)
MultivariatePolynomial(MultivariatePolynomial< Coeff, Ordering, Policies > &&p)
MultivariatePolynomial & operator+=(const Coeff &rhs)
Add something to this polynomial and return the changed polynomial.
MultivariatePolynomial tail(bool makeFullyOrdered=false) const
For the polynomial p, the function calculates a polynomial p - lt(p).
MultivariatePolynomial & operator-=(Variable::Arg rhs)
Subtract something from this polynomial and return the changed polynomial.
bool is_zero() const
Check if the polynomial is zero.
MultivariatePolynomial lcoeff(Variable::Arg var) const
Returns the leading coefficient with respect to the given variable.
const Term< Coeff > & lterm() const
The leading term.
~MultivariatePolynomial() noexcept=default
MultivariatePolynomial(ConstructorOperation op, const std::vector< MultivariatePolynomial > &operands)
const Coeff & constant_part() const
Retrieve the constant term of this polynomial or zero, if there is no constant term.
MultivariatePolynomial(const Coeff &c)
bool is_univariate() const
Checks whether only one variable occurs.
typename UnderlyingNumberType< Coeff >::type NumberType
Number type within the coefficients.
Coeff coprime_factor_without_constant() const
void subtractProduct(const Term< Coeff > &factor, const MultivariatePolynomial &p)
Subtract a term times a polynomial from this polynomial.
bool is_number() const
Check if the polynomial is a number, i.e., a constant.
MultivariatePolynomial< typename IntegralType< Coeff >::type, Ordering, Policies > to_integer_domain() const
bool is_reducible_identity() const
typename IntegralType< NumberType >::type IntNumberType
Integer type associated with the number type.
MultivariatePolynomial & operator+=(const MultivariatePolynomial &rhs)
Add something to this polynomial and return the changed polynomial.
bool sqrt(MultivariatePolynomial &res) const
Calculates the square of this multivariate polynomial if it is a square.
MultivariatePolynomial & operator+=(const Monomial::Arg &rhs)
Add something to this polynomial and return the changed polynomial.
const Coeff & lcoeff() const
Returns the coefficient of the leading term.
TermsType mTerms
A vector of all terms.
MultivariatePolynomial & operator*=(Variable::Arg rhs)
Multiply this polynomial with something and return the changed polynomial.
bool has_constant_term() const
Check if the polynomial has a constant term that is not zero.
const Monomial::Arg & lmon() const
The leading monomial.
MultivariatePolynomial normalize() const
For a polynomial p, returns p/lc(p)
Policies Policy
Policies for this monomial.
bool is_tsos() const
Checks whether the polynomial is a trivial sum of squares.
MultivariatePolynomial & operator=(const MultivariatePolynomial &p)
const Term< Coeff > & operator[](std::size_t index) const
MultivariatePolynomial & operator/=(const Coeff &rhs)
Divide this polynomial by something and return the changed polynomial.
MultivariatePolynomial(Variable::Arg v)
MultivariatePolynomial & operator*=(const Term< Coeff > &rhs)
Multiply this polynomial with something and return the changed polynomial.
MultivariatePolynomial & operator/=(const Term< Coeff > &rhs)
Divide this polynomial by something and return the changed polynomial.
bool mOrdered
Flag that indicates if the terms are ordered.
std::vector< Term< Coeff > > TermsType
Type our terms vector.f.
MultivariatePolynomial mod(const typename IntegralType< Coeff >::type &modulo) const
MultivariatePolynomial(const MultivariatePolynomial< Coeff, Ordering, Policies > &p)
MultivariatePolynomial & operator*=(const Monomial::Arg &rhs)
Multiply this polynomial with something and return the changed polynomial.
MultivariatePolynomial & operator/=(Variable::Arg rhs)
Divide this polynomial by something and return the changed polynomial.
MultivariatePolynomial & operator-=(const Coeff &rhs)
Subtract something from this polynomial and return the changed polynomial.
Ordering OrderedBy
The ordering of the terms.
MultivariatePolynomial coprime_coefficients_sign_preserving() const
friend std::ostream & operator<<(std::ostream &os, ConstructorOperation op)
MultivariatePolynomial(const std::initializer_list< Variable > &terms)
bool is_linear() const
Check if the polynomial is linear.
static bool compareByLeadingTerm(const MultivariatePolynomial &p1, const MultivariatePolynomial &p2)
MultivariatePolynomial operator-() const
MultivariatePolynomial(const UnivariatePolynomial< MultivariatePolynomial< Coeff, Ordering, Policy >> &pol)
MultivariatePolynomial & operator-=(const Term< Coeff > &rhs)
Subtract something from this polynomial and return the changed polynomial.
Variable single_variable() const
For terms with exactly one variable, get this variable.
std::size_t nr_terms() const
Calculate the number of terms.
MultivariatePolynomial & operator+=(Variable rhs)
Add something to this polynomial and return the changed polynomial.
friend MultivariatePolynomial< C, O, P > operator/(const MultivariatePolynomial< C, O, P > &lhs, unsigned long rhs)
Perform a division involving a polynomial.
static bool compareByNrTerms(const MultivariatePolynomial &p1, const MultivariatePolynomial &p2)
bool isOrdered() const
Check if the terms are ordered.
MultivariatePolynomial coeff(Variable::Arg var, std::size_t exp) const
Calculates the coefficient of var^exp.
MultivariatePolynomial & operator+=(const TermType &rhs)
Add something to this polynomial and return the changed polynomial.
MultivariatePolynomial(EnableIfNotSame< C, sint > c)
void addTerm(const Term< Coeff > &term)
Adds a single term without using a TermAdditionManager or changing the ordering status.
MultivariatePolynomial & operator-=(const Monomial::Arg &rhs)
Subtract something from this polynomial and return the changed polynomial.
static TermAdditionManager< MultivariatePolynomial, Ordering > mTermAdditionManager
MultivariatePolynomial & operator*=(const Coeff &rhs)
Multiply this polynomial with something and return the changed polynomial.
MultivariatePolynomial(EnableIfNotSame< C, uint > c)
Term< Coeff > TermType
Type of the terms.
MultivariatePolynomial(TermsType &&terms, bool duplicates=true, bool ordered=false)
void makeMinimallyOrdered(typename TermsType::iterator &lterm, typename TermsType::iterator &cterm) const
Make sure that the terms are at least minimally ordered.
const PolyType & polynomial() const
std::size_t total_degree() const
Calculates the max.
MultivariatePolynomial(const Term< Coeff > &t)
Coeff CoeffType
Type of the coefficients.
MultivariatePolynomial & operator/=(const Monomial::Arg &rhs)
Divide this polynomial by something and return the changed polynomial.
MultivariatePolynomial & operator-=(const MultivariatePolynomial &rhs)
Subtract something from this polynomial and return the changed polynomial.
The general-purpose monomials.
Definition: Monomial.h:59
std::shared_ptr< const Monomial > Arg
Definition: Monomial.h:62
std::size_t operator()(const carl::MultivariatePolynomial< C, O, P > &mpoly) const
Calculates the hash of a MultivariatePolynomial.
Coefficient & coeff()
Get the coefficient.
Definition: Term.h:80
bool is_single_variable() const
Definition: Term.h:182
Variable single_variable() const
For terms with exactly one variable, get this variable.
Definition: Term.h:190
bool is_constant() const
Checks whether the monomial is a constant.
Definition: Term.h:127
Monomial::Arg & monomial()
Get the monomial.
Definition: Term.h:91