3 #include <poly/variable_list.h>
10 LPPolynomial::LPPolynomial(
const LPPolynomial& rhs)
11 : m_internal(lp_polynomial_new_copy(rhs.m_internal)), m_context(rhs.m_context) {
12 assert(lp_polynomial_check_order(get_internal()));
15 LPPolynomial::LPPolynomial(LPPolynomial&& rhs)
16 : m_internal(rhs.m_internal), m_context(std::move(rhs.m_context)) {
18 assert(lp_polynomial_check_order(get_internal()));
21 LPPolynomial& LPPolynomial::operator=(
const LPPolynomial& rhs) {
22 m_internal = lp_polynomial_new_copy(rhs.m_internal);
23 m_context = rhs.m_context;
24 assert(lp_polynomial_check_order(get_internal()));
28 LPPolynomial& LPPolynomial::operator=(LPPolynomial&& rhs) {
29 if (m_internal) lp_polynomial_delete(m_internal);
30 m_internal = rhs.m_internal;
31 m_context = std::move(rhs.m_context);
33 assert(lp_polynomial_check_order(get_internal()));
37 LPPolynomial::LPPolynomial(
const LPContext& context)
38 : m_internal(lp_polynomial_new(context.lp_context())), m_context(context) {
40 assert(lp_polynomial_check_order(get_internal()));
43 LPPolynomial::LPPolynomial(lp_polynomial_t* p,
const LPContext& context)
44 : m_internal(p), m_context(context) {
46 assert(lp_polynomial_check_order(get_internal()));
47 assert(context.lp_context() == lp_polynomial_get_context(get_internal()));
50 LPPolynomial::LPPolynomial(
const LPContext& context,
long val)
51 : m_internal(lp_polynomial_alloc()), m_context(context) {
52 lp_polynomial_construct_simple(get_internal(), context.lp_context(), mpz_class(val).get_mpz_t(), 0, 0);
54 assert(lp_polynomial_check_order(get_internal()));
57 LPPolynomial::LPPolynomial(
const LPContext& context,
const mpz_class& val)
58 : m_internal(lp_polynomial_alloc()), m_context(context) {
59 lp_polynomial_construct_simple(get_internal(), context.lp_context(), val.get_mpz_t(), lp_variable_null, 0) ;
61 assert(lp_polynomial_check_order(get_internal()));
64 LPPolynomial::LPPolynomial(
const LPContext& context,
const mpq_class& val) : LPPolynomial(context,
carl::
get_num(val)) {}
66 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& var,
const mpz_class& coeff,
unsigned int degree)
67 : m_internal(lp_polynomial_alloc()), m_context(context) {
68 lp_polynomial_construct_simple(get_internal(), context.lp_context(), mpz_class(coeff).get_mpz_t(), context.lp_variable(var), degree);
70 assert(lp_polynomial_check_order(get_internal()));
73 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& var)
74 : m_internal(lp_polynomial_alloc()), m_context(context) {
75 lp_polynomial_construct_simple(get_internal(), context.lp_context(), mpz_class(1).get_mpz_t(), context.lp_variable(var), 1);
77 assert(lp_polynomial_check_order(get_internal()));
80 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::initializer_list<mpz_class>& coefficients)
81 : LPPolynomial(context) {
83 auto var = context.lp_variable(mainVar);
84 auto pow = coefficients.size();
86 for (
const mpz_class& coeff : coefficients) {
90 lp_monomial_construct(context.lp_context(), &t);
91 lp_monomial_set_coefficient(context.lp_context(), &t, mpz_class(coeff).get_mpz_t());
93 lp_monomial_push(&t, var, (
unsigned int)
pow);
94 lp_polynomial_add_monomial(get_internal(), &t);
95 lp_monomial_destruct(&t);
100 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::vector<mpz_class>& coefficients)
101 : LPPolynomial(context) {
103 auto var = context.lp_variable(mainVar);
104 auto pow = coefficients.size();
106 for (
const mpz_class& coeff : coefficients) {
110 lp_monomial_construct(context.lp_context(), &t);
111 lp_monomial_set_coefficient(context.lp_context(), &t, mpz_class(coeff).get_mpz_t());
113 lp_monomial_push(&t, var, (
unsigned int)
pow);
114 lp_polynomial_add_monomial(get_internal(), &t);
115 lp_monomial_destruct(&t);
120 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& mainVar, std::vector<mpz_class>&& coefficients)
121 : LPPolynomial(context) {
123 auto var = context.lp_variable(mainVar);
124 auto pow = coefficients.size();
126 for (
const mpz_class& coeff : coefficients) {
130 lp_monomial_construct(context.lp_context(), &t);
131 lp_monomial_set_coefficient(context.lp_context(), &t, mpz_class(coeff).get_mpz_t());
133 lp_monomial_push(&t, var, (
unsigned int)
pow);
134 lp_polynomial_add_monomial(get_internal(), &t);
135 lp_monomial_destruct(&t);
140 LPPolynomial::LPPolynomial(
const LPContext& context,
const Variable& mainVar,
const std::map<unsigned int, mpz_class>& coefficients)
141 : LPPolynomial(context) {
143 auto var = context.lp_variable(mainVar);
145 for (
const auto& coeff : coefficients) {
146 if (
is_zero(coeff.second))
continue;
148 lp_monomial_construct(context.lp_context(), &t);
149 lp_monomial_set_coefficient(context.lp_context(), &t, mpz_class(coeff.second).get_mpz_t());
151 lp_monomial_push(&t, var, (
unsigned int)coeff.first);
152 lp_polynomial_add_monomial(get_internal(), &t);
153 lp_monomial_destruct(&t);
158 LPPolynomial::~LPPolynomial() {
160 if (m_internal) lp_polynomial_delete(m_internal);
163 bool LPPolynomial::has(
const Variable& var)
const {
164 lp_variable_list_t varList;
165 lp_variable_list_construct(&varList);
166 lp_polynomial_get_variables(get_internal(), &varList);
167 auto lp_variable = context().lp_variable_opt(var);
168 if (!lp_variable)
return false;
169 bool contains = lp_variable_list_contains(&varList, *lp_variable);
170 lp_variable_list_destruct(&varList);
174 bool operator==(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
175 return lp_polynomial_eq(lhs.get_internal(), rhs.get_internal());
177 bool operator==(
const LPPolynomial& lhs,
const mpz_class& rhs) {
181 return lhs.constant_part() == rhs;
183 bool operator==(
const mpz_class& lhs,
const LPPolynomial& rhs) {
187 bool operator!=(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
188 return !(lhs == rhs);
190 bool operator!=(
const LPPolynomial& lhs,
const mpz_class& rhs) {
191 return !(lhs == rhs);
193 bool operator!=(
const mpz_class& lhs,
const LPPolynomial& rhs) {
194 return !(lhs == rhs);
197 inline auto cmp_util(
const LPPolynomial& lhs,
const mpz_class& rhs) {
199 auto res = lp_polynomial_cmp(lhs.get_internal(), tmp);
200 lp_polynomial_delete(tmp);
204 bool operator<(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
205 return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) < 0;
207 bool operator<(
const LPPolynomial& lhs,
const mpz_class& rhs) {
208 return cmp_util(lhs,rhs) < 0;
210 bool operator<(
const mpz_class& lhs,
const LPPolynomial& rhs) {
211 return cmp_util(rhs,lhs) > 0;
214 bool operator<=(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
215 return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) <= 0;
217 bool operator<=(
const LPPolynomial& lhs,
const mpz_class& rhs) {
218 return cmp_util(lhs,rhs) <= 0;
220 bool operator<=(
const mpz_class& lhs,
const LPPolynomial& rhs) {
221 return cmp_util(rhs,lhs) >= 0;
224 bool operator>(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
225 return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) > 0;
227 bool operator>(
const LPPolynomial& lhs,
const mpz_class& rhs) {
228 return cmp_util(lhs,rhs) > 0;
230 bool operator>(
const mpz_class& lhs,
const LPPolynomial& rhs) {
231 return cmp_util(rhs,lhs) < 0;
234 bool operator>=(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
235 return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) >= 0;
237 bool operator>=(
const LPPolynomial& lhs,
const mpz_class& rhs) {
238 return cmp_util(lhs,rhs) >= 0;
240 bool operator>=(
const mpz_class& lhs,
const LPPolynomial& rhs) {
241 return cmp_util(rhs,lhs) <= 0;
244 LPPolynomial
operator+(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
245 assert(rhs.context() == lhs.context());
246 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
247 LPPolynomial result(lhs.context());
248 lp_polynomial_add(result.get_internal(), lhs.get_internal(), rhs.get_internal());
251 LPPolynomial
operator+(
const LPPolynomial& lhs,
const mpz_class& rhs) {
252 return lhs + LPPolynomial(lhs.context(), rhs);
254 LPPolynomial
operator+(
const mpz_class& lhs,
const LPPolynomial& rhs) {
258 LPPolynomial
operator-(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
259 assert(rhs.context() == lhs.context());
260 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
261 LPPolynomial result(lhs.context());
262 lp_polynomial_sub(result.get_internal(), lhs.get_internal(), rhs.get_internal());
265 LPPolynomial
operator-(
const LPPolynomial& lhs,
const mpz_class& rhs) {
266 return lhs - LPPolynomial(lhs.context(), rhs);
268 LPPolynomial
operator-(
const mpz_class& lhs,
const LPPolynomial& rhs) {
269 return LPPolynomial(rhs.context(), lhs) - rhs;
272 LPPolynomial
operator*(
const LPPolynomial& lhs,
const LPPolynomial& rhs) {
273 assert(lhs.context() == rhs.context());
274 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
275 LPPolynomial result(lhs.context());
276 lp_polynomial_mul(result.get_internal(), lhs.get_internal(), rhs.get_internal());
279 LPPolynomial
operator*(
const LPPolynomial& lhs,
const mpz_class& rhs) {
280 return lhs * LPPolynomial(lhs.context(), rhs);
282 LPPolynomial
operator*(
const mpz_class& lhs,
const LPPolynomial& rhs) {
286 LPPolynomial&
operator+=(LPPolynomial& lhs,
const LPPolynomial& rhs) {
287 assert(rhs.context() == lhs.context());
288 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
289 lp_polynomial_add(lhs.get_internal(), lhs.get_internal(), rhs.get_internal());
292 LPPolynomial&
operator+=(LPPolynomial& lhs,
const mpz_class& rhs) {
294 lp_polynomial_add(lhs.get_internal(), lhs.get_internal(), tmp);
295 lp_polynomial_delete(tmp);
299 LPPolynomial&
operator-=(LPPolynomial& lhs,
const LPPolynomial& rhs) {
300 assert(rhs.context() == lhs.context());
301 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
302 lp_polynomial_sub(lhs.get_internal(), lhs.get_internal(), rhs.get_internal());
305 LPPolynomial&
operator-=(LPPolynomial& lhs,
const mpz_class& rhs) {
307 lp_polynomial_sub(lhs.get_internal(), lhs.get_internal(), tmp);
308 lp_polynomial_delete(tmp);
312 LPPolynomial&
operator*=(LPPolynomial& lhs,
const LPPolynomial& rhs) {
313 assert(rhs.context() == lhs.context());
314 assert(lp_polynomial_context_equal(lp_polynomial_get_context(lhs.get_internal()), lp_polynomial_get_context(rhs.get_internal())));
315 lp_polynomial_mul(lhs.get_internal(), lhs.get_internal(), rhs.get_internal());
318 LPPolynomial&
operator*=(LPPolynomial& lhs,
const mpz_class& rhs) {
320 lp_polynomial_mul(lhs.get_internal(), lhs.get_internal(), tmp);
321 lp_polynomial_delete(tmp);
325 mpz_class LPPolynomial::coprime_factor()
const {
327 struct coprime_factor_travers {
328 std::vector<mpz_class> coefficients;
331 auto getCoeffs = [](
const lp_polynomial_context_t* ,
334 coprime_factor_travers& v = *
static_cast<coprime_factor_travers*
>(d);
335 v.coefficients.push_back(*
reinterpret_cast<mpz_class*
>(&m->a));
339 coprime_factor_travers travers;
340 lp_polynomial_traverse(get_internal(), getCoeffs, &travers);
342 if (travers.coefficients.size() == 0) {
345 mpz_class res = travers.coefficients[0];
346 for (
size_t i = 1; i < travers.coefficients.size(); i++) {
347 res =
gcd(res, travers.coefficients[i]);
353 LPPolynomial LPPolynomial::coprime_coefficients()
const {
354 mpz_class g = coprime_factor();
355 if (g == 1)
return *
this;
357 lp_polynomial_t* res = lp_polynomial_new(context().lp_context());
358 lp_polynomial_div(res, get_internal(), temp);
359 lp_polynomial_delete(temp);
360 return LPPolynomial(res, context());
365 struct degree_travers {
366 std::size_t degree = 0;
369 auto getDegree = [](
const lp_polynomial_context_t* ,
372 degree_travers& v = *
static_cast<degree_travers*
>(d);
374 size_t current_degree = 0;
376 for (
size_t i = 0; i < m->n; i++) {
377 current_degree += m->p[i].d;
379 v.degree = std::max(v.degree, current_degree);
382 degree_travers travers;
383 lp_polynomial_traverse(get_internal(), getDegree, &travers);
385 return travers.degree;
388 std::size_t LPPolynomial::degree(Variable::Arg var)
const {
389 struct degree_travers {
390 std::size_t degree = 0;
394 auto getDegree = [](
const lp_polynomial_context_t* ,
397 degree_travers& v = *
static_cast<degree_travers*
>(d);
399 size_t current_degree = 0;
401 for (
size_t i = 0; i < m->n; i++) {
402 if (m->p[i].x == v.var) {
403 current_degree = m->p[i].d;
407 v.degree = std::max(v.degree, current_degree);
410 degree_travers travers;
411 travers.var = context().lp_variable(var);
412 lp_polynomial_traverse(get_internal(), getDegree, &travers);
414 return travers.degree;
417 std::vector<std::size_t> LPPolynomial::monomial_total_degrees()
const {
418 struct degree_travers {
419 std::vector<std::size_t> degree;
422 auto getDegree = [](
const lp_polynomial_context_t* ,
425 degree_travers& v = *
static_cast<degree_travers*
>(d);
427 size_t current_degree = 0;
429 for (
size_t i = 0; i < m->n; i++) {
430 current_degree += m->p[i].d;
432 v.degree.push_back(current_degree);
435 degree_travers travers;
436 lp_polynomial_traverse(get_internal(), getDegree, &travers);
438 return travers.degree;
441 std::vector<std::size_t> LPPolynomial::monomial_degrees(Variable::Arg var)
const {
442 struct degree_travers {
443 std::vector<std::size_t> degree;
447 auto getDegree = [](
const lp_polynomial_context_t* ,
450 degree_travers& v = *
static_cast<degree_travers*
>(d);
452 size_t current_degree = 0;
454 for (
size_t i = 0; i < m->n; i++) {
455 if (m->p[i].x == v.var) {
456 current_degree = m->p[i].d;
460 v.degree.push_back(current_degree);
463 degree_travers travers;
464 travers.var = context().lp_variable(var);
465 lp_polynomial_traverse(get_internal(), getDegree, &travers);
467 return travers.degree;
470 mpz_class LPPolynomial::unit_part()
const {
477 return lp_polynomial_lc_sgn(get_internal()) ;
480 LPPolynomial LPPolynomial::normalized()
const {
481 auto res = coprime_coefficients();
482 auto unit = res.unit_part() ;
493 LPPolynomial LPPolynomial::coeff(Variable::Arg var, std::size_t
exp)
const {
494 struct coeff_travers {
495 std::vector<lp_monomial_t> coeff;
496 const lp_polynomial_context_t* ctx;
502 auto getCoeff = [](
const lp_polynomial_context_t* ,
505 coeff_travers& v = *
static_cast<coeff_travers*
>(d);
509 for (
size_t i = 0; i < m->n; i++) {
510 if (m->p[i].x == v.var && m->p[i].d == v.exp) {
521 lp_monomial_t new_monomial;
522 lp_monomial_construct(v.ctx, &new_monomial);
523 new_monomial.n = m->n -1 ;
524 new_monomial.capacity = m->capacity ;
525 lp_integer_assign(v.ctx->K, &new_monomial.a ,&m->a);
526 new_monomial.p = (power_t*)realloc(new_monomial.p,
sizeof(power_t) * new_monomial.capacity);
528 size_t current_counter = 0 ;
529 for(
size_t i = 0; i < m->n; i++){
530 if(m->p[i].x == v.var && m->p[i].d == v.exp){
533 new_monomial.p[current_counter].x = m->p[i].x;
534 new_monomial.p[current_counter].d = m->p[i].d;
537 assert(current_counter == new_monomial.n);
538 v.coeff.push_back(std::move(new_monomial));
541 coeff_travers travers;
542 travers.var = context().lp_variable(var);
544 travers.ctx = lp_polynomial_get_context(get_internal());
545 lp_polynomial_traverse(get_internal(), getCoeff, &travers);
547 LPPolynomial res(context());
548 for (
auto m : travers.coeff) {
549 lp_polynomial_add_monomial(res.get_internal(), &m);
553 for(
auto& m : travers.coeff){
554 lp_monomial_destruct(&m);
560 bool LPPolynomial::is_normal()
const {
565 std::ostream&
operator<<(std::ostream& os,
const LPPolynomial& p) {
566 os << lp_polynomial_to_string(p.get_internal());
570 void LPPolynomial::set_context(
const LPContext& c) {
571 for (
auto& v :
variables(*
this)) assert(c.has(v));
572 if (context() == c)
return;
574 bool reorder = !(c.is_extension_of(context()) || context().is_extension_of(c));
576 lp_polynomial_set_context(get_internal(), m_context.lp_context());
578 lp_polynomial_ensure_order(get_internal());
580 assert(lp_polynomial_check_order(get_internal()));
std::ostream & operator<<(std::ostream &os, const GbBenchmark< C, O, P > &b)
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)
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
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.
cln::cl_I get_num(const cln::cl_RA &n)
Extract the numerator from a fraction.
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)
Interval< Number > pow(const Interval< Number > &i, Integer exp)
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.
lp_polynomial_t * construct_lp_poly(const lp_polynomial_context_t *c, lp_variable_t v)