carl  24.04
Computer ARithmetic Library
Conversion.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <carl-common/config.h>
4 
8 
9 namespace carl {
10 
11 namespace convert_poly {
12 template<typename T, typename S>
13 struct ConvertHelper {};
14 
15 template<typename A, typename B, typename C>
18  return ContextPolynomial<A, B, C>(context, p);
19  }
20 };
21 
22 template<typename A, typename B, typename C>
25  return p.as_multivariate();
26  }
27 };
28 
29 #ifdef USE_LIBPOLY
30 template<typename A, typename B, typename C>
31 struct ConvertHelper<LPPolynomial, MultivariatePolynomial<A, B, C>> {
32  static LPPolynomial convert(const LPContext& context, const MultivariatePolynomial<A, B, C>& p) {
33  CARL_LOG_DEBUG("carl.converter", "Converting Carl Multivariate Poly " << p << " with LPContext " << context);
34 
35  // Problem: LPPolynomials must have mpz_class as coefficient type -> might loose information when converting mpq_class to mpz_class
36 
37  if (carl::is_constant(p)) {
38  CARL_LOG_DEBUG("carl.converter", "Poly is constant");
39  return LPPolynomial(context, carl::get_num(p.constant_part()));
40  }
41 
42  auto denominator = p.coprime_factor();
43  if (denominator < 0) {
44  denominator *= -1;
45  }
46 
47  CARL_LOG_DEBUG("carl.converter", "Coprime Factor/ Denominator: " << denominator);
48  lp_polynomial_t* res = lp_polynomial_new(context.lp_context());
49  for (const auto& term : p) {
50  assert(carl::get_denom(term.coeff() * denominator) == 1);
51  lp_monomial_t t;
52  lp_monomial_construct(context.lp_context(), &t);
53  lp_monomial_set_coefficient(context.lp_context(), &t, (lp_integer_t*)mpz_class(term.coeff() * denominator).get_mpz_t());
54  if (term.monomial()) {
55  // A monomial is a vector of pairs <variable, power>
56  for (const std::pair<carl::Variable, std::size_t>& var_pow : (*term.monomial()).exponents()) {
57  lp_monomial_push(&t, context.lp_variable(var_pow.first), var_pow.second);
58  }
59  }
60  lp_polynomial_add_monomial(res, &t);
61  lp_monomial_destruct(&t);
62  }
63  return LPPolynomial(res, context);
64  }
65 };
66 
67 namespace conversion_private {
68 template<typename T>
69 struct CollectTermData {
70  std::vector<carl::Term<T>> terms;
71  const LPContext& context;
72  CollectTermData(const LPContext& c) : context(c) {}
73 };
74 
75 template<typename T>
76 void collectTermDataFunction(const lp_polynomial_context_t* /*ctx*/, lp_monomial_t* m, void* d) {
77  CollectTermData<T>* data = static_cast<CollectTermData<T>*>(d);
78  carl::Term<T> term(mpz_class(&m->a)); // m->a is the integer coefficient
79  for (size_t i = 0; i < m->n; i++) { // m->n is the capacity of the power array
80  auto carl_var = data->context.carl_variable(m->p[i].x);
81  assert(carl_var.has_value());
82  term *= carl::Term<T>(1, *carl_var, m->p[i].d); // p[i].x is the variable, p[i].d is the power
83  }
84  data->terms.emplace_back(term);
85 }
86 } // namespace conversion_private
87 
88 template<typename A, typename B, typename C>
89 struct ConvertHelper<MultivariatePolynomial<A, B, C>, LPPolynomial> {
90  static MultivariatePolynomial<A, B, C> convert(const LPPolynomial& p) {
91  conversion_private::CollectTermData<A> termdata(p.context());
92  CARL_LOG_DEBUG("carl.converter", "Converting LPPolynomial " << p);
93  lp_polynomial_traverse(p.get_internal(), conversion_private::collectTermDataFunction<A>, &termdata);
94 
95  if (termdata.terms.empty()) {
96  return MultivariatePolynomial<A, B, C>();
97  }
98  return MultivariatePolynomial<A, B, C>(termdata.terms);
99  }
100 };
101 #endif
102 
103 }
104 
105 template<typename T, typename S, std::enable_if_t<is_polynomial_type<T>::value && is_polynomial_type<S>::value && !needs_context_type<T>::value, int> = 0>
106 inline T convert(const S& r) {
108 }
109 
110 template<typename T, typename S, std::enable_if_t<is_polynomial_type<T>::value && is_polynomial_type<S>::value && needs_context_type<T>::value, int> = 0>
111 inline T convert(const typename T::ContextType& c, const S& r) {
113 }
114 
115 } // namespace carl
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
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
BasicConstraint< ToPoly > convert(const typename ToPoly::ContextType &context, const BasicConstraint< FromPoly > &c)
Definition: Conversion.h:9
T convert(const T &r)
Definition: Conversion.h:10
cln::cl_I get_denom(const cln::cl_RA &n)
Extract the denominator from a fraction.
Definition: operations.h:69
The general-purpose multivariate polynomial class.
const Coeff & constant_part() const
Retrieve the constant term of this polynomial or zero, if there is no constant term.
static ContextPolynomial< A, B, C > convert(const Context &context, const MultivariatePolynomial< A, B, C > &p)
Definition: Conversion.h:17
static MultivariatePolynomial< A, B, C > convert(const ContextPolynomial< A, B, C > &p)
Definition: Conversion.h:24
MultivariatePolynomial< Coeff, Ordering, Policies > as_multivariate() const
Represents a single term, that is a numeric coefficient and a monomial.
Definition: Term.h:23