11 #include <poly/polynomial.h>
29 lp_polynomial_t* m_internal;
36 using CoeffType = mpq_class ;
37 using RootType = LPRealAlgebraicNumber;
38 using ContextType = LPContext;
41 using NumberType = mpq_class;
46 LPPolynomial() =
delete;
50 LPPolynomial(
const LPPolynomial& p);
54 LPPolynomial(LPPolynomial&& p);
58 LPPolynomial& operator=(
const LPPolynomial& p);
62 LPPolynomial& operator=(LPPolynomial&& p);
68 explicit LPPolynomial(
const LPContext& context);
73 LPPolynomial(lp_polynomial_t* p,
const LPContext& context);
79 LPPolynomial(
const LPContext& context,
long val);
86 LPPolynomial(
const LPContext& context,
const mpq_class& val);
92 LPPolynomial(
const LPContext& context,
const mpz_class& val);
99 LPPolynomial(
const LPContext& context,
const Variable& var);
108 LPPolynomial(
const LPContext& context,
const Variable& var,
const mpz_class& coeff,
unsigned int degree = 0);
116 LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::initializer_list<mpz_class>& coefficients);
124 LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::vector<mpz_class>& coefficients);
131 LPPolynomial(
const LPContext& context,
const Variable& mainVar, std::vector<mpz_class>&& coefficients);
138 LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::map<unsigned int, mpz_class>& coefficients);
143 ~LPPolynomial() =
default;
151 LPPolynomial one()
const {
152 return LPPolynomial(m_context, 1);
159 Variable single_variable()
const {
160 assert(lp_polynomial_is_univariate(get_internal()));
161 auto carl_var = context().carl_variable(lp_polynomial_top_variable(get_internal()));
162 assert(carl_var.has_value());
166 LPPolynomial coeff(std::size_t k)
const {
167 lp_polynomial_t* res = lp_polynomial_alloc();
168 lp_polynomial_construct(res, m_context.lp_context());
169 lp_polynomial_get_coefficient(res, get_internal(), k);
170 return LPPolynomial(res, m_context);
179 size_t degree()
const {
180 return lp_polynomial_degree(get_internal());
187 LPPolynomial lcoeff()
const {
188 return coeff(degree());
192 std::vector<LPPolynomial> coefficients()
const {
193 std::vector<LPPolynomial> res;
194 for (std::size_t deg = 0; deg <= degree(); ++deg) {
195 auto cf = coeff(deg);
196 if (lp_polynomial_is_zero(cf.get_internal()))
continue;
197 res.emplace_back(std::move(cf));
206 mpz_class constant_part()
const {
207 struct LPPolynomial_constantPart_visitor {
211 auto getConstantPart = [](
const lp_polynomial_context_t* ,
214 auto& v = *
static_cast<LPPolynomial_constantPart_visitor*
>(d);
216 v.part += *
reinterpret_cast<mpz_class*
>(&m->a);
220 LPPolynomial_constantPart_visitor visitor;
221 lp_polynomial_traverse(get_internal(), getConstantPart, &visitor);
229 lp_polynomial_t* lcoeff = lp_polynomial_alloc();
230 lp_polynomial_construct(lcoeff, m_context.lp_context());
231 lp_polynomial_get_coefficient(lcoeff, get_internal(), lp_polynomial_degree(get_internal()));
232 lp_polynomial_sub(get_internal(), get_internal(), lcoeff);
233 lp_polynomial_delete(lcoeff);
241 Variable main_var()
const {
243 else return *(context().carl_variable(lp_polynomial_top_variable(get_internal())));
251 lp_polynomial_t* get_internal() {
259 const lp_polynomial_t* get_internal()
const {
268 const LPContext& context()
const {
277 LPContext& context() {
281 void set_context(
const LPContext& c);
288 bool has(
const Variable& v)
const;
297 mpz_class coprime_factor()
const;
306 LPPolynomial coprime_coefficients()
const;
314 bool is_normal()
const;
322 LPPolynomial normalized()
const;
332 mpz_class unit_part()
const;
338 LPPolynomial negate_variable()
const {
340 return LPPolynomial(m_context);
348 bool divides(
const LPPolynomial& divisor)
const;
355 LPPolynomial&
mod(
const mpz_class& modulus);
361 LPPolynomial
mod(
const mpz_class& modulus)
const;
368 mpz_class main_denom()
const {
377 std::vector<std::size_t> monomial_total_degrees()
const;
378 std::vector<std::size_t> monomial_degrees(
Variable::Arg var)
const;
389 friend std::ostream&
operator<<(std::ostream& os,
const LPPolynomial& rhs);
392 bool operator==(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
393 bool operator==(
const LPPolynomial& lhs,
const mpz_class& rhs);
394 bool operator==(
const mpz_class& lhs,
const LPPolynomial& rhs);
396 bool operator!=(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
397 bool operator!=(
const LPPolynomial& lhs,
const mpz_class& rhs);
398 bool operator!=(
const mpz_class& lhs,
const LPPolynomial& rhs);
400 bool operator<(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
401 bool operator<(
const LPPolynomial& lhs,
const mpz_class& rhs);
402 bool operator<(
const mpz_class& lhs,
const LPPolynomial& rhs);
404 bool operator<=(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
405 bool operator<=(
const LPPolynomial& lhs,
const mpz_class& rhs);
406 bool operator<=(
const mpz_class& lhs,
const LPPolynomial& rhs);
408 bool operator>(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
409 bool operator>(
const LPPolynomial& lhs,
const mpz_class& rhs);
410 bool operator>(
const mpz_class& lhs,
const LPPolynomial& rhs);
412 bool operator>=(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
413 bool operator>=(
const LPPolynomial& lhs,
const mpz_class& rhs);
414 bool operator>=(
const mpz_class& lhs,
const LPPolynomial& rhs);
416 LPPolynomial
operator+(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
417 LPPolynomial
operator+(
const LPPolynomial& lhs,
const mpz_class& rhs);
418 LPPolynomial
operator+(
const mpz_class& lhs,
const LPPolynomial& rhs);
420 LPPolynomial
operator-(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
421 LPPolynomial
operator-(
const LPPolynomial& lhs,
const mpz_class& rhs);
422 LPPolynomial
operator-(
const mpz_class& lhs,
const LPPolynomial& rhs);
424 LPPolynomial
operator*(
const LPPolynomial& lhs,
const LPPolynomial& rhs);
425 LPPolynomial
operator*(
const LPPolynomial& lhs,
const mpz_class& rhs);
426 LPPolynomial
operator*(
const mpz_class& lhs,
const LPPolynomial& rhs);
428 LPPolynomial&
operator+=(LPPolynomial& lhs,
const LPPolynomial& rhs);
429 LPPolynomial&
operator+=(LPPolynomial& lhs,
const mpz_class& rhs);
431 LPPolynomial&
operator-=(LPPolynomial& lhs,
const LPPolynomial& rhs);
432 LPPolynomial&
operator-=(LPPolynomial& lhs,
const mpz_class& rhs);
434 LPPolynomial&
operator*=(LPPolynomial& lhs,
const LPPolynomial& rhs);
435 LPPolynomial&
operator*=(LPPolynomial& lhs,
const mpz_class& rhs);
441 inline bool is_zero(
const LPPolynomial& p) {
442 return lp_polynomial_is_zero(p.get_internal());
450 return lp_polynomial_is_constant(p.get_internal());
457 inline bool is_one(
const LPPolynomial& p) {
462 lp_polynomial_t* one = lp_polynomial_alloc();
463 mpz_class one_int(1);
464 lp_polynomial_construct_simple(one, p.context().lp_context(), one_int.get_mpz_t(), lp_variable_null, 0);
465 bool res = lp_polynomial_eq(p.get_internal(), one);
466 lp_polynomial_delete(one);
474 inline bool is_number(
const LPPolynomial& p) {
481 inline bool is_linear(
const LPPolynomial& p) {
482 return lp_polynomial_is_linear(p.get_internal());
488 inline bool is_univariate(
const LPPolynomial& p) {
489 return lp_polynomial_is_univariate(p.get_internal());
492 inline std::size_t
level_of(
const LPPolynomial& p) {
494 auto it = std::find(p.context().variable_ordering().begin(), p.context().variable_ordering().end(), p.main_var());
495 assert(it != p.context().variable_ordering().end());
496 return (std::size_t)std::distance(p.context().variable_ordering().begin(), it)+1;
500 inline void variables(
const LPPolynomial& p, carlVariables& vars) {
501 struct TraverseData {
503 const LPContext& context;
504 TraverseData(carlVariables& v,
const LPContext& c) : vars(v), context(c) {}
507 auto collectVars = [](
const lp_polynomial_context_t* ,
510 TraverseData* data =
static_cast<TraverseData*
>(d);
511 for (
size_t i = 0; i < m->n; i++) {
512 auto var = data->context.carl_variable(m->p[i].x);
513 assert(var.has_value());
514 data->vars.add(*var);
518 TraverseData d(vars, p.context());
519 lp_polynomial_traverse(p.get_internal(), collectVars, &d);
524 struct needs_context_type<LPPolynomial> : std::true_type {};
527 struct is_polynomial_type<LPPolynomial> : std::true_type {};
536 struct hash<
carl::LPPolynomial> {
542 std::size_t operator()(
const carl::LPPolynomial& p)
const {
543 return lp_polynomial_hash(p.get_internal());
A small wrapper that configures logging for carl.
#define CARL_LOG_NOTIMPLEMENTED()
carl is the main namespace for the library.
bool operator>(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
Interval< Number > operator+(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the addition of two intervals.
bool operator<(const BasicConstraint< P > &lhs, const BasicConstraint< P > &rhs)
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
cln::cl_I mod(const cln::cl_I &a, const cln::cl_I &b)
Calculate the remainder of the integer division.
Interval< Number > exp(const Interval< Number > &i)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Interval< Number > operator*(const Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of two intervals.
Interval< Number > & operator*=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the multiplication of an interval and a number with assignment.
Interval< Number > & operator+=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the addition of an interval and a number with assignment.
Interval< Number > operator-(const Interval< Number > &rhs)
Unary minus.
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)
Interval< Number > & operator-=(Interval< Number > &lhs, const Interval< Number > &rhs)
Operator for the subtraction of two intervals with assignment.
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
std::size_t level_of(const ContextPolynomial< Coeff, Ordering, Policies > &p)
bool is_linear(const ContextPolynomial< Coeff, Ordering, Policies > &p)
auto total_degree(const Monomial &m)
Gives the total degree, i.e.
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
const Variable & Arg
Argument type for variables being function arguments.
static const Variable NO_VARIABLE
Instance of an invalid variable.