carl  24.04
Computer ARithmetic Library
Degree.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../MultivariatePolynomial.h"
4 #include "../UnivariatePolynomial.h"
5 
6 /**
7  * @file Degree.h
8  * Implements utility functions concerning the (total) degree of monomials, terms and polynomials.
9  * - total_degree()
10  * - is_zero()
11  * - is_one()
12  * - is_constant()
13  * - is_linear()
14  * - is_at_most_linear()
15  *
16  */
17 
18 namespace carl {
19 
20 /**
21  * Gives the total degree, i.e. the sum of all exponents.
22  * @return Total degree.
23  */
24 inline auto total_degree(const Monomial& m) {
25  return m.tdeg();
26 }
27 
28 /**
29  * Checks whether the monomial is a constant.
30  * @return If monomial is constant.
31  */
32 inline bool is_constant(const Monomial& m) {
33  return total_degree(m) == 0;
34 }
35 
36 /**
37  * Checks whether the monomial has exactly degree one.
38  * @return If monomial is linear.
39  */
40 inline bool is_linear(const Monomial& m) {
41  return total_degree(m) == 1;
42 }
43 
44 /**
45  * Checks whether the monomial has at most degree one.
46  * @return If monomial is linear or constant.
47  */
48 inline bool is_at_most_linear(const Monomial& m) {
49  return total_degree(m) <= 1;
50 }
51 
52 /**
53  * Gives the total degree, i.e. the sum of all exponents.
54  * @return Total degree.
55  */
56 template<typename Coeff>
57 std::size_t total_degree(const Term<Coeff>& t) {
58  if (!t.monomial()) return 0;
59  return total_degree(*t.monomial());
60 }
61 
62 // /**
63 // * Checks whether a term is zero.
64 // */
65 // template<typename Coeff>
66 // bool is_zero(const Term<Coeff>& term) {
67 // return carl::is_zero(term.coeff());
68 // }
69 //
70 // /**
71 // * Checks whether a term is one.
72 // */
73 // template<typename Coeff>
74 // bool is_one(const Term<Coeff>& term) {
75 // return is_constant(term) && carl::is_one(term.coeff());
76 // }
77 
78 /**
79  * Checks whether the monomial is a constant.
80  * @return
81  */
82 template<typename Coeff>
83 bool is_constant(const Term<Coeff>& t) {
84  return !t.monomial();
85 }
86 
87 /**
88  * Checks whether the monomial has exactly the degree one.
89  * @return
90  */
91 template<typename Coeff>
92 bool is_linear(const Term<Coeff>& t) {
93  if (!t.monomial()) return false;
94  return is_linear(*t.monomial());
95 }
96 
97 /**
98  * Checks whether the monomial has at most degree one.
99  * @return If monomial is linear or constant.
100  */
101 template<typename Coeff>
103  if (!t.monomial()) return true;
104  return is_at_most_linear(*t.monomial());
105 }
106 
107 /**
108  * Calculates the max. degree over all monomials occurring in the polynomial.
109  * 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.
110  * @see @cite GCL92, page 48
111  * @return Total degree.
112  */
113 template<typename Coeff, typename Ordering, typename Policies>
115  if (carl::is_zero(p)) return 0;
116  assert(p.size() != 0);
117  if (Ordering::degreeOrder) {
118  return total_degree(p.lterm());
119  } else {
121  }
122 }
123 
124 // template<typename C, typename O, typename P>
125 // bool is_one(const MultivariatePolynomial<C,O,P>& p) {
126 // return (p.nr_terms() == 1) && is_one(p.lterm());
127 // }
128 //
129 // template<typename C, typename O, typename P>
130 // bool is_zero(const MultivariatePolynomial<C,O,P>& p) {
131 // return p.nr_terms() == 0;
132 // }
133 
134 /**
135  * Check if the polynomial is linear.
136  */
137 template<typename Coeff, typename Ordering, typename Policies>
139  return (p.nr_terms() == 0) || ((p.nr_terms() == 1) && is_constant(p.lterm()));
140 }
141 
142 /**
143  * Check if the polynomial is linear.
144  */
145 template<typename Coeff, typename Ordering, typename Policies>
147  if (carl::is_zero(p)) return true;
148  if (Ordering::degreeOrder) {
149  return is_linear(p.lterm());
150  } else {
151  return std::all_of(p.begin(), p.end(),
152  [](const auto& t){ return is_linear(t); }
153  );
154  }
155 }
156 
157 /**
158  * Returns the total degree of the polynomial, that is the maximum degree of any monomial.
159  * 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.
160  * @see @cite GCL92, page 38
161  * @return Total degree.
162  */
163 template<typename Coeff>
165  if constexpr (carl::is_number_type<Coeff>::value) {
166  return p.degree();
167  } else {
168  if (carl::is_zero(p)) return 0;
169  uint max = 0;
170  for (std::size_t deg = 0; deg < p.coefficients().size(); deg++) {
171  if (!carl::is_zero(p.coefficients()[deg])) {
172  uint tdeg = deg + total_degree(p.coefficients()[deg]);
173  if (tdeg > max) max = tdeg;
174  }
175  }
176  return max;
177  }
178 }
179 
180 // /**
181 // * Checks if the polynomial is equal to zero.
182 // * @return If polynomial is zero.
183 // */
184 // template<typename Coeff>
185 // bool is_zero(const UnivariatePolynomial<Coeff>& p) {
186 // return p.coefficients().size() == 0;
187 // }
188 //
189 // /**
190 // * Checks if the polynomial is equal to one.
191 // * @return If polynomial is one.
192 // */
193 // template<typename Coeff>
194 // bool is_one(const UnivariatePolynomial<Coeff>& p) {
195 // return p.coefficients().size() == 1 && carl::is_one(p.coefficients().front());
196 // }
197 
198 /**
199  * Checks whether the polynomial is constant with respect to the main variable.
200  * @return If polynomial is constant.
201  */
202 template<typename Coeff>
204  return p.coefficients().size() <= 1;
205 }
206 
207 template<typename Coeff>
209  if (!p.is_linear_in_main_var()) return false;
210  if (!is_linear(p.coefficients().front())) return false;
211  bool front = true;
212  for (const auto& c : p.coefficients()) {
213  if (front) {
214  front = false;
215  continue;
216  }
217  if (!is_constant(c)) return false;
218  }
219  return true;
220 }
221 
222 }
#define CARL_LOG_NOTIMPLEMENTED()
Definition: carl-logging.h:48
carl is the main namespace for the library.
std::uint64_t uint
Definition: numbers.h:16
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
bool is_at_most_linear(const Monomial &m)
Checks whether the monomial has at most degree one.
Definition: Degree.h:48
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
bool is_linear(const ContextPolynomial< Coeff, Ordering, Policies > &p)
auto total_degree(const Monomial &m)
Gives the total degree, i.e.
Definition: Degree.h:24
This class represents a univariate polynomial with coefficients of an arbitrary type.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
uint degree() const
Get the maximal exponent of the main variable.
The general-purpose multivariate polynomial class.
const Term< Coeff > & lterm() const
The leading term.
std::size_t nr_terms() const
Calculate the number of terms.
States if a type is a number type.
Definition: typetraits.h:237
The general-purpose monomials.
Definition: Monomial.h:59
exponent tdeg() const
Gives the total degree, i.e.
Definition: Monomial.h:185
Monomial::Arg & monomial()
Get the monomial.
Definition: Term.h:91