carl  24.04
Computer ARithmetic Library
helper.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <carl-common/config.h>
4 #ifdef USE_LIBPOLY
5 
6 #include <algorithm>
7 #include <map>
8 
16 #include <carl-arith/core/Common.h>
18 
19 #include <poly/upolynomial.h>
20 
21 namespace carl {
22 
23 inline mpz_class to_integer(const lp_integer_t* m) {
24  return *reinterpret_cast<const mpz_class*>(m);
25 }
26 
27 inline mpq_class to_rational(const lp_integer_t* m) {
28  return mpq_class(to_integer(m));
29 }
30 
31 inline mpq_class to_rational(const lp_rational_t* m) {
32  return *reinterpret_cast<const mpq_class*>(m);
33 }
34 
35 inline mpq_class to_rational(const lp_dyadic_rational_t* m) {
36  lp_integer_t num;
37  lp_integer_construct(&num);
38  lp_dyadic_rational_get_num(m, &num);
39 
40  lp_integer_t den;
41  lp_integer_construct(&den);
42  lp_dyadic_rational_get_den(m, &den);
43 
44  auto res = mpq_class(to_integer(&num), to_integer(&den));
45 
46  lp_integer_destruct(&num);
47  lp_integer_destruct(&den);
48 
49  return res;
50 }
51 
52 inline mpq_class to_rational(const lp_value_t* m){
53  switch(m->type){
54  case lp_value_type_t::LP_VALUE_INTEGER:
55  return to_rational(&m->value.z);
56  case lp_value_type_t::LP_VALUE_RATIONAL:
57  return to_rational(&m->value.q);
58  case lp_value_type_t::LP_VALUE_DYADIC_RATIONAL:
59  return to_rational(&m->value.dy_q);
60  default:
61  CARL_LOG_ERROR("carl.converter", "Cannot convert libpoly value: " << m << " to rational.");
62  assert(false);
63  return mpq_class(0);
64  }
65 }
66 
67 inline carl::UnivariatePolynomial<mpq_class> to_carl_univariate_polynomial(const lp_upolynomial_t* p, const carl::Variable& main_var){
68  CARL_LOG_FUNC("carl.converter", p << ", " << main_var);
69 
70  lp_integer_t coeffs[lp_upolynomial_degree(p) + 1];
71  for (std::size_t i = 0; i < lp_upolynomial_degree(p) + 1; ++i) {
72  lp_integer_construct(&coeffs[i]);
73  }
74  lp_upolynomial_unpack(p, coeffs);
75 
76  std::vector<mpq_class> carl_coeffs;
77  for (std::size_t i = 0; i < lp_upolynomial_degree(p) + 1; ++i) {
78  carl_coeffs.emplace_back(to_rational(&coeffs[i]));
79  lp_integer_destruct(&coeffs[i]);
80  }
81 
82  CARL_LOG_TRACE("carl.converter", "-> coefficients: " << carl_coeffs);
83  return carl::UnivariatePolynomial<mpq_class>(main_var, carl_coeffs);
84 }
85 
86 
87 template<typename Coeff, EnableIf<is_subset_of_rationals_type<Coeff>> = dummy>
88 inline lp_upolynomial_t* to_libpoly_upolynomial(const carl::UnivariatePolynomial<Coeff>& p) {
89  CARL_LOG_FUNC("carl.converter", p);
90 
91  if (carl::is_constant(p)) {
92  CARL_LOG_TRACE("carl.converter", "Poly is constant");
93  assert(carl::get_denom(p.lcoeff())>0);
94  lp_upolynomial_t* res = lp_upolynomial_construct(lp_Z, 0, mpz_class(carl::get_num(p.lcoeff())).get_mpz_t());
95  return res;
96  }
97 
98  Coeff coprimeFactor = p.coprime_factor();
99  CARL_LOG_TRACE("carl.converter", "Coprime Factor: " << coprimeFactor);
100  mpz_class denominator;
101  if (carl::get_denom(coprimeFactor) != 1) {
102  // if coprime factor is not an integer
103  denominator = coprimeFactor > 0 ? mpz_class(carl::get_num(coprimeFactor)) : mpz_class(-carl::get_num(coprimeFactor));
104  } else if (coprimeFactor == 0) {
105  // Wie kann das überhaupt sein? TODO
106  denominator = mpz_class(1);
107  } else {
108  denominator = mpz_class(coprimeFactor);
109  }
110  CARL_LOG_TRACE("carl.converter", "Coprime factor/ denominator: " << denominator);
111 
112  std::vector<mpz_class> coefficients;
113  std::vector<lp_integer_t> coefficients_ptr;
114  for (const auto& c : p.coefficients()) {
115  coefficients.emplace_back(c * denominator);
116  coefficients_ptr.emplace_back(*coefficients.back().get_mpz_t());
117  }
118  CARL_LOG_TRACE("carl.converter", "coefficients: " << coefficients);
119  lp_upolynomial_t* res = lp_upolynomial_construct(lp_Z, p.coefficients().size()-1, reinterpret_cast<const lp_integer_t*>(coefficients_ptr.data()));
120  return res;
121 }
122 
123 /**
124  * Convert a carl interval to a libpoly interval
125  * This keeps the bound types
126  */
127 inline lp_interval_t* to_libpoly_interval(const carl::Interval<mpq_class>& inter) {
128  lp_value_t low;
129  bool low_open;
130  switch (inter.lower_bound_type()) {
131  case BoundType::STRICT:
132  lp_value_construct(&low, LP_VALUE_RATIONAL, &inter.lower());
133  low_open = true;
134  break;
135  case BoundType::WEAK:
136  lp_value_construct(&low, LP_VALUE_RATIONAL, &inter.lower());
137  low_open = false;
138  break;
139  case BoundType::INFTY:
140  default:
141  low = *lp_value_minus_infinity();
142  low_open = true;
143  break;
144  }
145  lp_value_t up;
146  bool up_open;
147  switch (inter.upper_bound_type()) {
148  case BoundType::STRICT:
149  lp_value_construct(&up, LP_VALUE_RATIONAL, &inter.upper());
150  up_open = true;
151  break;
152  case BoundType::WEAK:
153  lp_value_construct(&up, LP_VALUE_RATIONAL, &inter.upper());
154  up_open = false;
155  break;
156  case BoundType::INFTY:
157  default:
158  up = *lp_value_plus_infinity();
159  up_open = false;
160  break;
161  }
162 
163  lp_interval_t* res = new lp_interval_t;
164  lp_interval_construct(res, &low, low_open, &up, up_open);
165  lp_value_destruct(&low);
166  lp_value_destruct(&up);
167  return res;
168 }
169 
170 } // namespace carl
171 
172 #endif
Implements utility functions concerning the (total) degree of monomials, terms and polynomials.
#define CARL_LOG_FUNC(channel, args)
Definition: carl-logging.h:46
#define CARL_LOG_ERROR(channel, msg)
Definition: carl-logging.h:40
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
carl is the main namespace for the library.
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
cln::cl_I get_num(const cln::cl_RA &n)
Extract the numerator from a fraction.
Definition: operations.h:60
typename UnderlyingNumberType< P >::type Coeff
cln::cl_I get_denom(const cln::cl_RA &n)
Extract the denominator from a fraction.
Definition: operations.h:69
@ WEAK
the given bound is compared by a weak ordering relation
@ STRICT
the given bound is compared by a strict ordering relation
@ INFTY
the given bound is interpreted as minus or plus infinity depending on whether it is the left or the r...
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
The class which contains the interval arithmetic including trigonometric functions.
Definition: Interval.h:134
BoundType lower_bound_type() const
The getter for the lower bound type of the interval.
Definition: Interval.h:883
const Number & upper() const
The getter for the upper boundary of the interval.
Definition: Interval.h:849
const Number & lower() const
The getter for the lower boundary of the interval.
Definition: Interval.h:840
BoundType upper_bound_type() const
The getter for the upper bound type of the interval.
Definition: Interval.h:892
This class represents a univariate polynomial with coefficients of an arbitrary type.
Coefficient coprime_factor() const
Calculates a factor that would make the coefficients of this polynomial coprime integers.
const std::vector< Coefficient > & coefficients() const &
Retrieves the coefficients defining this polynomial.
const Coefficient & lcoeff() const
Returns the leading coefficient.