carl  24.04
Computer ARithmetic Library
Monomial.h
Go to the documentation of this file.
1 /**
2  * @file Monomial.h
3  * @ingroup multirp
4  * @author Sebastian Junges
5  * @author Florian Corzilius
6  */
7 
8 #pragma once
9 
10 #include <carl-common/util/hash.h>
16 
17 #include <algorithm>
18 #include <list>
19 #include <numeric>
20 #include <set>
21 #include <sstream>
22 
23 #include <boost/intrusive/unordered_set.hpp>
24 
25 
26 namespace carl
27 {
28  /// Type of an exponent.
29  using exponent = std::size_t;
30 
31  /**
32  * Compare a pair of variable and exponent with a variable.
33  * Returns true, if both variables are the same.
34  * @param p Pair of variable and exponent.
35  * @param v Variable.
36  * @return `p.first == v`
37  */
38  inline bool operator==(const std::pair<Variable, std::size_t>& p, Variable v) {
39  return p.first == v;
40  }
41 
42  /**
43  * The general-purpose monomials. Notice that we aim to keep this object as small as possbible,
44  * while also limiting the use of expensive language features such as RTTI, exceptions and even
45  * polymorphism.
46  *
47  * Although a Monomial can conceptually be seen as a map from variables to exponents,
48  * this implementation uses a vector of pairs of variables and exponents.
49  * Due to the fact that monomials usually contain only a small number of variables,
50  * the overhead introduced by `std::map` makes up for the asymptotically slower `std::find` on
51  * the `std::vector` that is used.
52  *
53  * Besides, many operations like multiplication, division or substitution do not rely
54  * on finding some variable, but must iterate over all entries anyway.
55  *
56  * @ingroup multirp
57  */
58  class Monomial final : public boost::intrusive::unordered_set_base_hook<>
59  {
60  friend class MonomialPool;
61  public:
62  using Arg = std::shared_ptr<const Monomial>;
63  using Content = std::vector<std::pair<Variable, std::size_t>>;
64  ~Monomial();
65 
66  /**
67  * Default constructor.
68  */
69  Monomial() = delete;
70  Monomial(const Monomial& rhs) = delete;
71  Monomial(Monomial&& rhs) = delete;
72  private:
73  /// A vector of variable exponent pairs (v_i^e_i) with nonzero exponents.
75  /// Some applications performance depends on getting the degree of monomials very fast
76  std::size_t mTotalDegree = 0;
77  /// Monomial id.
78  mutable std::size_t mId = 0;
79  /// Cached hash.
80  mutable std::size_t mHash = 0;
81 
82  using exponents_it = Content::iterator ;
83  using exponents_cIt = Content::const_iterator;
84 
85  mutable std::weak_ptr<const Monomial> mWeakPtr;
86 
87  /**
88  * Calculates the hash and stores it to mHash.
89  */
90  void calc_hash() {
92  }
93  /**
94  * Calculates the total degree and stores it to mTotalDegree.
95  */
97  mTotalDegree = std::accumulate(
98  mExponents.begin(), mExponents.end(), std::size_t(0),
99  [](std::size_t d, const auto& p) { return d + p.second; }
100  );
101  }
102 
103  /**
104  * Generate a monomial from a vector of variable-exponent pairs and a total degree.
105  * If the totalDegree is zero, it is recalculated.
106  * The content is not expected to be sorted.
107  * @param content The variables and their exponents.
108  * @param totalDegree The total degree of the monomial to generate, or zero.
109  */
110  Monomial(Content&& content, std::size_t totalDegree = 0) :
111  mExponents(std::move(content)),
112  mTotalDegree(totalDegree)
113  {
114  std::sort(mExponents.begin(), mExponents.end(),
115  [](const auto& p1, const auto& p2){ return p1.first < p2.first; }
116  );
117  if (mTotalDegree == 0) {
119  }
120  calc_hash();
121  assert(is_consistent());
122  }
123 
124  /**
125  * Generate a monomial from a vector of variable-exponent pairs and a total degree.
126  * If the totalDegree is zero, it is recalculated.
127  * The content is not expected to be sorted.
128  * @param content The variables and their exponents
129  * @param totalDegree The total degree of the monomial to generate, or zero.
130  */
131  Monomial(const Content& content, std::size_t totalDegree = 0) :
132  Monomial(Content(content), totalDegree)
133  {}
134 
135  public:
136  /**
137  * Returns iterator on first pair of variable and exponent.
138  * @return Iterator on begin.
139  */
141  return mExponents.begin();
142  }
143  /**
144  * Returns constant iterator on first pair of variable and exponent.
145  * @return Iterator on begin.
146  */
148  return mExponents.begin();
149  }
150  /**
151  * Returns past-the-end iterator.
152  * @return Iterator on end.
153  */
155  return mExponents.end();
156  }
157  /**
158  * Returns past-the-end iterator.
159  * @return Iterator on end.
160  */
161  exponents_cIt end() const {
162  return mExponents.end();
163  }
164 
165  /**
166  * Returns the hash of this monomial
167  * @return Hash.
168  */
169  std::size_t hash() const {
170  return mHash;
171  }
172 
173  /**
174  * Return the id of this monomial.
175  * @return Id.
176  */
177  std::size_t id() const {
178  return mId;
179  }
180 
181  /**
182  * Gives the total degree, i.e. the sum of all exponents.
183  * @return Total degree.
184  */
185  exponent tdeg() const {
186  return mTotalDegree;
187  }
188 
189  const Content& exponents() const {
190  return mExponents;
191  }
192 
193  /**
194  * Checks whether the monomial is a constant.
195  * @return If monomial is constant.
196  */
197  bool is_constant() const {
198  return mTotalDegree == 0;
199  }
200 
201  /**
202  * @return true, if the image of this monomial is integer-valued.
203  */
204  bool integer_valued() const {
205  auto res = std::find_if(
206  mExponents.begin(), mExponents.end(),
207  [](const auto& e){ return e.first.type() != VariableType::VT_INT; }
208  );
209  return res == mExponents.end();
210  }
211 
212  /**
213  * Checks whether the monomial has exactly degree one.
214  * @return If monomial is linear.
215  */
216  bool is_linear() const {
217  return mTotalDegree == 1;
218  }
219 
220  /**
221  * Checks whether the monomial has at most degree one.
222  * @return If monomial is linear or constant.
223  */
224  bool isAtMostLinear() const {
225  return mTotalDegree <= 1;
226  }
227 
228  /**
229  * Checks whether the monomial is a square, i.e. whether all exponents are even.
230  * @return If monomial is a square.
231  */
232  bool is_square() const {
233  if (mTotalDegree % 2 == 1) return false;
234  auto res = std::find_if(
235  mExponents.begin(), mExponents.end(),
236  [](const auto& e){ return e.second % 2 == 1; }
237  );
238  return res == mExponents.end();
239  }
240 
241  /**
242  * Returns the number of variables that occur in the monomial.
243  * @return Number of variables.
244  */
245  std::size_t num_variables() const {
246  return mExponents.size();
247  }
248 
249  /**
250  * Retrieves the single variable of the monomial.
251  * Asserts that there is in fact only a single variable.
252  * @return Variable.
253  */
255  assert(mExponents.size() == 1);
256  return mExponents.front().first;
257  }
258 
259  /**
260  * Checks that there is no other variable than the given one.
261  * @param v Variable.
262  * @return If there is only v.
263  */
265  if(mExponents.size() == 1) {
266  return mExponents.front().first == v;
267  }
268  return mExponents.empty();
269  }
270 
271  /**
272  * Retrieves the given VarExpPair.
273  * @param index Index.
274  * @return VarExpPair.
275  */
276  const std::pair<Variable, std::size_t>& operator[](std::size_t index) const {
277  assert(index < mExponents.size());
278  return mExponents[index];
279  }
280  /**
281  * Retrieves the exponent of the given variable.
282  * @param v Variable.
283  * @return Exponent of v.
284  */
286  auto it = std::find(mExponents.cbegin(), mExponents.cend(), v);
287  if(it == mExponents.cend()) {
288  return 0;
289  } else {
290  return it->second;
291  }
292  }
293 
294  /**
295  * TODO: write code if binary search is preferred.
296  * @param v The variable to check for its occurrence.
297  * @return true, if the variable occurs in this term.
298  */
299  bool has(Variable v) const {
300  return (std::find(mExponents.cbegin(), mExponents.cend(), v) != mExponents.cend());
301  }
302 
303  /**
304  * For a monomial m = Prod( x_i^{e_i} ) * v^e, divides m by v^e
305  * @return nullptr if result is 1, otherwise m/v^e.
306  */
308 
309  /**
310  * Divides the monomial by a variable v.
311  * If the division is impossible (because v does not occur in the monomial), nullptr is returned.
312  * @param v Variable
313  * @param res Resulting monomial
314  * @return This divided by v.
315  */
316  bool divide(Variable v, Monomial::Arg& res) const;
317 
318 
319  /**
320  * Checks if this monomial is divisible by the given monomial m.
321  * @param m Monomial.
322  * @return If this is divisible by m.
323  */
324  bool divisible(const Monomial::Arg& m) const
325  {
326  if(!m) return true;
327  assert(is_consistent());
328  if(m->mTotalDegree > mTotalDegree) return false;
329  if(m->num_variables() > num_variables()) return false;
330  // Linear, as we expect small monomials.
331  auto itright = m->mExponents.begin();
332  for (const auto& itleft: mExponents) {
333  // Done with division
334  if(itright == m->mExponents.end())
335  {
336  return true;
337  }
338  // Variable is present in both monomials.
339  if(itleft.first == itright->first)
340  {
341  if(itright->second > itleft.second)
342  {
343  // Underflow, itright->exp was larger than itleft->exp.
344  return false;
345  }
346  itright++;
347  }
348  // Variable is not present in lhs, division fails.
349  else if(itleft.first > itright->first)
350  {
351  return false;
352  }
353  else
354  {
355  assert(itright->first > itleft.first);
356  }
357  }
358  // If there remain variables in the m, it fails.
359  return itright == m->mExponents.end();
360  }
361  /**
362  * Returns a new monomial that is this monomial divided by m.
363  * Returns a pair of a monomial pointer and a bool.
364  * The bool indicates if the division was possible.
365  * The monomial pointer holds the result of the division.
366  * If the division resulted in an empty monomial (i.e. the two monomials were equal), the pointer is nullptr.
367  * @param m Monomial.
368  * @param res Resulting monomial.
369  * @return this divided by m.
370  */
371  bool divide(const Monomial::Arg& m, Monomial::Arg& res) const;
372 
373  /**
374  * Calculates and returns the square root of this monomial, iff the monomial is a square as checked by is_square().
375  * Otherwise, nullptr is returned.
376  * @return The square root of this monomial, iff the monomial is a square as checked by is_square().
377  */
378  Monomial::Arg sqrt() const;
379 
380 
381  ///////////////////////////
382  // Orderings
383  ///////////////////////////
384 
386  {
387  if( !lhs && !rhs )
388  return CompareResult::EQUAL;
389  if( !lhs )
390  return CompareResult::LESS;
391  if( !rhs )
392  return CompareResult::GREATER;
393  return lexicalCompare(*lhs, *rhs);
394  }
395 
397  {
398  if(!lhs) return CompareResult::LESS;
399  if(lhs->mExponents.front().first < rhs) return CompareResult::GREATER;
400  if(lhs->mExponents.front().first > rhs) return CompareResult::LESS;
401  if(lhs->mExponents.front().second > 1) return CompareResult::GREATER;
402  return CompareResult::EQUAL;
403  }
404 
405 
407  {
408  if( !lhs && !rhs )
409  return CompareResult::EQUAL;
410  if( !lhs )
411  return CompareResult::LESS;
412  if( !rhs )
413  return CompareResult::GREATER;
414  if(lhs->mTotalDegree < rhs->mTotalDegree) return CompareResult::LESS;
415  if(lhs->mTotalDegree > rhs->mTotalDegree) return CompareResult::GREATER;
416  return lexicalCompare(*lhs, *rhs);
417  }
418 
420  {
421  if(!lhs) return CompareResult::LESS;
422  if(lhs->mTotalDegree > 1) return CompareResult::GREATER;
423  if(lhs->mExponents.front().first < rhs) return CompareResult::GREATER;
424  if(lhs->mExponents.front().first > rhs) return CompareResult::LESS;
425  if(lhs->mExponents.front().second > 1) return CompareResult::GREATER;
426  return CompareResult::EQUAL;
427  }
428 
429  /**
430  * Calculates the least common multiple of two monomial pointers.
431  * If both are valid objects, the lcm of both is calculated.
432  * If only one is a valid object, this one is returned.
433  * If both are invalid objects, an empty monomial is returned.
434  * @param lhs First monomial.
435  * @param rhs Second monomial.
436  * @return lcm of lhs and rhs.
437  */
438  static Monomial::Arg lcm(const Monomial::Arg& lhs, const Monomial::Arg& rhs);
439 
440 
441  /**
442  * Returns lcm(lhs, rhs) / rhs
443  */
445  Monomial::Arg res;
446  bool works = lcm(lhs, rhs)->divide(rhs, res);
447  assert(works);
448  return res;
449  }
450 
451  /**
452  * This method performs a lexical comparison as defined in @cite GCL92, page 47.
453  * We define the exponent vectors to be in decreasing order, i.e. the exponents of the larger variables first.
454  * @param lhs First monomial.
455  * @param rhs Second monomial.
456  * @return Comparison result.
457  * @see @cite GCL92, page 47.
458  */
459  static CompareResult lexicalCompare(const Monomial& lhs, const Monomial& rhs);
460 
461  /**
462  * Calculate the hash of a monomial based on its content.
463  * @param c Content of a monomial.
464  * @return Hash of the monomial.
465  */
466  static std::size_t hashContent(const Monomial::Content& c) {
467  return carl::hash_all(c);
468  }
469 
470  public:
471 
472  /**
473  * Checks if the monomial is consistent.
474  * @return If this is consistent.
475  */
476  bool is_consistent() const;
477 
478  /*
479  * TODO: cannot link Monomial::evaluate
480  template<typename SubstitutionType>
481  SubstitutionType evaluate(const std::map<Variable, SubstitutionType>& map) const;
482  */
483  };
484 
485  /// @name Comparison operators
486  /// @{
487 
488 
489  inline bool operator==(const Monomial& lhs, const Monomial& rhs) {
490  if (&lhs == &rhs) return true;
491  if ((lhs.id() != 0) && (rhs.id() != 0)) return lhs.id() == rhs.id();
492  if (lhs.hash() != rhs.hash()) return false;
493  if (lhs.tdeg() != rhs.tdeg()) return false;
494  return lhs.exponents() == rhs.exponents();
495  }
496 
497  /**
498  * Compares two arguments where one is a Monomial and the other is either a monomial or a variable.
499  * @param lhs First argument.
500  * @param rhs Second argument.
501  * @return `lhs ~ rhs`, `~` being the relation that is checked.
502  */
503  inline bool operator==(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
504  if (lhs.get() == rhs.get()) return true;
505  if (lhs == nullptr || rhs == nullptr) return false;
506  if ((lhs->id() != 0) && (rhs->id() != 0)) return lhs->id() == rhs->id();
507  if (lhs->hash() != rhs->hash()) return false;
508  if (lhs->tdeg() != rhs->tdeg()) return false;
509  return lhs->exponents() == rhs->exponents();
510  }
511 
512  inline bool operator==(const Monomial::Arg& lhs, Variable rhs) {
513  if (lhs == nullptr) return false;
514  if (lhs->tdeg() != 1) return false;
515  return lhs->begin()->first == rhs;
516  }
517 
518  inline bool operator==(Variable lhs, const Monomial::Arg& rhs) {
519  return rhs == lhs;
520  }
521 
522  inline bool operator!=(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
523  return !(lhs == rhs);
524  }
525 
526  inline bool operator!=(const Monomial::Arg& lhs, Variable rhs) {
527  return !(lhs == rhs);
528  }
529 
530  inline bool operator!=(Variable lhs, const Monomial::Arg& rhs) {
531  return !(rhs == lhs);
532  }
533 
534  inline bool operator<(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
535  if (lhs.get() == rhs.get()) return false;
536  if (lhs == nullptr) return true;
537  if (rhs == nullptr) return false;
538  if ((lhs->id() != 0) && (rhs->id() != 0)) {
539  if (lhs->id() == rhs->id()) return false;
540  // TODO sort by id?
541  //return (lhs->id() < rhs->id());
542  }
543  if(lhs->tdeg() < rhs->tdeg()) return true;
544  if(lhs->tdeg() > rhs->tdeg()) return false;
545  CompareResult cr = Monomial::lexicalCompare(*lhs, *rhs);
546  return cr == CompareResult::LESS;
547  }
548 
549  inline bool operator<(const Monomial::Arg& lhs, Variable rhs) {
550  if (lhs == nullptr) return true;
551  if (lhs->tdeg() > 1) return false;
552  return lhs->begin()->first < rhs;
553  }
554 
555  inline bool operator<(Variable lhs, const Monomial::Arg& rhs) {
556  if (rhs == nullptr) return false;
557  if (rhs->tdeg() > 1) return true;
558  return lhs < rhs->begin()->first;
559  }
560 
561  inline bool operator<=(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
562  return !(rhs < lhs);
563  }
564 
565  inline bool operator<=(const Monomial::Arg& lhs, Variable rhs) {
566  return !(rhs < lhs);
567  }
568 
569  inline bool operator<=(Variable lhs, const Monomial::Arg& rhs) {
570  return !(rhs < lhs);
571  }
572 
573  inline bool operator>(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
574  return rhs < lhs;
575  }
576 
577  inline bool operator>(const Monomial::Arg& lhs, Variable rhs) {
578  return rhs < lhs;
579  }
580 
581  inline bool operator>(Variable lhs, const Monomial::Arg& rhs) {
582  return rhs < lhs;
583  }
584 
585  inline bool operator>=(const Monomial::Arg& lhs, const Monomial::Arg& rhs) {
586  return rhs <= lhs;
587  }
588 
589  inline bool operator>=(const Monomial::Arg& lhs, Variable rhs) {
590  return rhs <= lhs;
591  }
592 
593  inline bool operator>=(Variable lhs, const Monomial::Arg& rhs) {
594  return rhs <= lhs;
595  }
596 
597  /// @}
598 
599  /// @name Multiplication operators
600  /// @{
601  /**
602  * Perform a multiplication involving a monomial.
603  * @param lhs Left hand side.
604  * @param rhs Right hand side.
605  * @return `lhs * rhs`
606  */
607  Monomial::Arg operator*(const Monomial::Arg& lhs, const Monomial::Arg& rhs);
608 
609  Monomial::Arg operator*(const Monomial::Arg& lhs, Variable rhs);
610 
611  Monomial::Arg operator*(Variable lhs, const Monomial::Arg& rhs);
612 
613  Monomial::Arg operator*(Variable lhs, Variable rhs);
614  /// @}
615 
616 
617  /**
618  * Streaming operator for Monomial.
619  * @param os Output stream.
620  * @param rhs Monomial.
621  * @return `os`
622  */
623  inline std::ostream& operator<<(std::ostream& os, const Monomial& rhs) {
624  if (rhs.exponents().empty()) return os << "1";
625  bool first = true;
626  for (const auto& vp: rhs) {
627  if (first) first = false;
628  else os << "*";
629  os << vp.first;
630  if (vp.second > 1) os << "^" << vp.second;
631  }
632  return os;
633  }
634  /**
635  * Streaming operator for std::shared_ptr<Monomial>.
636  * @param os Output stream.
637  * @param rhs Monomial.
638  * @return `os`
639  */
640  inline std::ostream& operator<<(std::ostream& os, const Monomial::Arg& rhs) {
641  if (rhs) return os << *rhs;
642  return os << "1";
643  }
644 
645  Monomial::Arg pow(Variable v, std::size_t exp);
646 
647  /// Add the variables of the given monomial to the variables.
648  inline void variables(const Monomial& m, carlVariables& vars) {
649  for (const auto& e : m) {
650  vars.add(e.first);
651  }
652  }
653 
654  struct hashLess {
655  bool operator()(const Monomial& lhs, const Monomial& rhs) const {
656  return lhs.hash() < rhs.hash();
657  }
658  bool operator()(const Monomial::Arg& lhs, const Monomial::Arg& rhs) const {
659  if (lhs == rhs) return false;
660  if (lhs && rhs) return (*this)(*lhs, *rhs);
661  return bool(rhs);
662  }
663  };
664 
665  struct hashEqual {
666  bool operator()(const Monomial& lhs, const Monomial& rhs) const {
667  return lhs.hash() == rhs.hash();
668  }
669  bool operator()(const Monomial::Arg& lhs, const Monomial::Arg& rhs) const {
670  if (lhs == rhs) return true;
671  if (lhs && rhs) return (*this)(*lhs, *rhs);
672  return false;
673  }
674  };
675 
676 } // namespace carl
677 
678 namespace std
679 {
680  template<>
681  struct equal_to<carl::Monomial::Arg> {
682  bool operator()(const carl::Monomial::Arg& lhs, const carl::Monomial::Arg& rhs) const {
683  return lhs == rhs;
684  }
685  };
686  template<>
687  struct less<carl::Monomial::Arg> {
688  bool operator()(const carl::Monomial::Arg& lhs, const carl::Monomial::Arg& rhs) const {
689  if (lhs && rhs) return lhs < rhs;
690  return !lhs;
691  }
692  };
693 
694  /**
695  * The template specialization of `std::hash` for `carl::Monomial`.
696  * @param monomial Monomial.
697  * @return Hash of monomial.
698  */
699  template<>
700  struct hash<carl::Monomial> {
701  std::size_t operator()(const carl::Monomial& monomial) const {
702  return monomial.hash();
703  }
704  };
705 
706  /**
707  * The template specialization of `std::hash` for a shared pointer of a `carl::Monomial`.
708  * @param monomial The shared pointer to a monomial.
709  * @return Hash of monomial.
710  */
711  template<>
712  struct hash<carl::Monomial::Arg>
713  {
714  size_t operator()(const carl::Monomial::Arg& monomial) const
715  {
716  if (!monomial) return 0;
717  return monomial->hash();
718  }
719  };
720 } // namespace std
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.
Definition: Content.h:22
bool operator>(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
std::size_t exponent
Type of an exponent.
Definition: Monomial.h:29
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
Interval< Number > exp(const Interval< Number > &i)
Definition: Exponential.h:10
Interval< Number > operator*(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of two intervals.
Definition: operators.h:386
CompareResult
Definition: CompareResult.h:12
bool operator!=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator<=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator==(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool operator>=(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
@ GREATER
Definition: SignCondition.h:15
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)
Interval< Number > pow(const Interval< Number > &i, Integer exp)
Definition: Power.h:11
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
void add(Variable v)
Definition: Variables.h:141
The general-purpose monomials.
Definition: Monomial.h:59
static CompareResult compareLexical(const Monomial::Arg &lhs, const Monomial::Arg &rhs)
Definition: Monomial.h:385
Monomial()=delete
Default constructor.
static CompareResult compareGradedLexical(const Monomial::Arg &lhs, const Monomial::Arg &rhs)
Definition: Monomial.h:406
std::size_t mTotalDegree
Some applications performance depends on getting the degree of monomials very fast.
Definition: Monomial.h:76
const std::pair< Variable, std::size_t > & operator[](std::size_t index) const
Retrieves the given VarExpPair.
Definition: Monomial.h:276
exponents_cIt end() const
Returns past-the-end iterator.
Definition: Monomial.h:161
exponent tdeg() const
Gives the total degree, i.e.
Definition: Monomial.h:185
std::shared_ptr< const Monomial > Arg
Definition: Monomial.h:62
bool is_linear() const
Checks whether the monomial has exactly degree one.
Definition: Monomial.h:216
exponent exponent_of_variable(Variable v) const
Retrieves the exponent of the given variable.
Definition: Monomial.h:285
exponents_cIt begin() const
Returns constant iterator on first pair of variable and exponent.
Definition: Monomial.h:147
bool isAtMostLinear() const
Checks whether the monomial has at most degree one.
Definition: Monomial.h:224
static Monomial::Arg lcm(const Monomial::Arg &lhs, const Monomial::Arg &rhs)
Calculates the least common multiple of two monomial pointers.
Definition: Monomial.cpp:151
bool is_square() const
Checks whether the monomial is a square, i.e.
Definition: Monomial.h:232
exponents_it end()
Returns past-the-end iterator.
Definition: Monomial.h:154
bool is_consistent() const
Checks if the monomial is consistent.
Definition: Monomial.cpp:207
std::weak_ptr< const Monomial > mWeakPtr
Definition: Monomial.h:85
Monomial(Content &&content, std::size_t totalDegree=0)
Generate a monomial from a vector of variable-exponent pairs and a total degree.
Definition: Monomial.h:110
Content mExponents
A vector of variable exponent pairs (v_i^e_i) with nonzero exponents.
Definition: Monomial.h:74
bool integer_valued() const
Definition: Monomial.h:204
Content::const_iterator exponents_cIt
Definition: Monomial.h:83
std::size_t hash() const
Returns the hash of this monomial.
Definition: Monomial.h:169
std::vector< std::pair< Variable, std::size_t > > Content
Definition: Monomial.h:63
void calc_total_degree()
Calculates the total degree and stores it to mTotalDegree.
Definition: Monomial.h:96
bool has_no_other_variable(Variable v) const
Checks that there is no other variable than the given one.
Definition: Monomial.h:264
std::size_t id() const
Return the id of this monomial.
Definition: Monomial.h:177
void calc_hash()
Calculates the hash and stores it to mHash.
Definition: Monomial.h:90
exponents_it begin()
Returns iterator on first pair of variable and exponent.
Definition: Monomial.h:140
static CompareResult compareLexical(const Monomial::Arg &lhs, Variable rhs)
Definition: Monomial.h:396
Variable single_variable() const
Retrieves the single variable of the monomial.
Definition: Monomial.h:254
static std::size_t hashContent(const Monomial::Content &c)
Calculate the hash of a monomial based on its content.
Definition: Monomial.h:466
static Monomial::Arg calcLcmAndDivideBy(const Monomial::Arg &lhs, const Monomial::Arg &rhs)
Returns lcm(lhs, rhs) / rhs.
Definition: Monomial.h:444
static CompareResult lexicalCompare(const Monomial &lhs, const Monomial &rhs)
This method performs a lexical comparison as defined in , page 47.
Definition: Monomial.cpp:231
std::size_t mHash
Cached hash.
Definition: Monomial.h:80
Content::iterator exponents_it
Definition: Monomial.h:82
std::size_t num_variables() const
Returns the number of variables that occur in the monomial.
Definition: Monomial.h:245
bool divide(Variable v, Monomial::Arg &res) const
Divides the monomial by a variable v.
Definition: Monomial.cpp:37
Monomial(const Content &content, std::size_t totalDegree=0)
Generate a monomial from a vector of variable-exponent pairs and a total degree.
Definition: Monomial.h:131
bool is_constant() const
Checks whether the monomial is a constant.
Definition: Monomial.h:197
static CompareResult compareGradedLexical(const Monomial::Arg &lhs, Variable rhs)
Definition: Monomial.h:419
const Content & exponents() const
Definition: Monomial.h:189
Monomial(Monomial &&rhs)=delete
bool has(Variable v) const
TODO: write code if binary search is preferred.
Definition: Monomial.h:299
bool divisible(const Monomial::Arg &m) const
Checks if this monomial is divisible by the given monomial m.
Definition: Monomial.h:324
std::size_t mId
Monomial id.
Definition: Monomial.h:78
Monomial(const Monomial &rhs)=delete
Monomial::Arg sqrt() const
Calculates and returns the square root of this monomial, iff the monomial is a square as checked by i...
Definition: Monomial.cpp:141
Monomial::Arg drop_variable(Variable v) const
For a monomial m = Prod( x_i^{e_i} ) * v^e, divides m by v^e.
Definition: Monomial.cpp:17
bool operator()(const Monomial &lhs, const Monomial &rhs) const
Definition: Monomial.h:655
bool operator()(const Monomial::Arg &lhs, const Monomial::Arg &rhs) const
Definition: Monomial.h:658
bool operator()(const Monomial &lhs, const Monomial &rhs) const
Definition: Monomial.h:666
bool operator()(const Monomial::Arg &lhs, const Monomial::Arg &rhs) const
Definition: Monomial.h:669
bool operator()(const carl::Monomial::Arg &lhs, const carl::Monomial::Arg &rhs) const
Definition: Monomial.h:682
bool operator()(const carl::Monomial::Arg &lhs, const carl::Monomial::Arg &rhs) const
Definition: Monomial.h:688
std::size_t operator()(const carl::Monomial &monomial) const
Definition: Monomial.h:701
size_t operator()(const carl::Monomial::Arg &monomial) const
Definition: Monomial.h:714