3 #include "../Evaluation.h"
8 #include <CoCoA/library.H>
12 namespace detail_field_extensions {
15 struct CoCoAConverter {
17 std::map<Variable, CoCoA::RingElem> mSymbolThere;
18 std::map<std::pair<long,std::size_t>,
Variable> mSymbolBack;
20 auto buildPolyRing(CoCoA::ring coeff_ring,
Variable v) {
21 CoCoA::SparsePolyRing ring = CoCoA::NewPolyRing(coeff_ring, {CoCoA::NewSymbol()});
22 mSymbolThere.emplace(v, CoCoA::indets(ring)[0]);
23 mSymbolBack.emplace(std::make_pair(CoCoA::RingID(ring), 0), v);
27 CoCoA::BigRat
convert(
const mpq_class& n)
const {
28 return CoCoA::BigRatFromMPQ(n.get_mpq_t());
31 T
convert(
const CoCoA::BigRat& n)
const {
32 if constexpr(std::is_same<T,mpq_class>::value) {
33 return mpq_class(CoCoA::mpqref(n));
35 #ifdef USE_CLN_NUMBERS
36 else if constexpr(std::is_same<T,cln::cl_RA>::value) {
39 return T(ss.str().c_str());
46 #ifdef USE_CLN_NUMBERS
47 CoCoA::BigRat
convert(
const cln::cl_RA& n)
const {
50 return CoCoA::BigRatFromString(ss.str());
54 template<
typename Poly>
55 Poly convertMV(
const CoCoA::RingElem& p)
const {
57 for (CoCoA::SparsePolyIter i = CoCoA::BeginIter(p); !CoCoA::IsEnded(i); ++i) {
59 CoCoA::BigRat numcoeff;
60 if (CoCoA::IsRational(numcoeff, CoCoA::coeff(i))) {
61 coeff = Poly(convert<typename Poly::CoeffType>(numcoeff));
63 coeff = convertMV<Poly>(CoCoA::CanonicalRepr(CoCoA::coeff(i)));
65 if (CoCoA::IsOne(CoCoA::PP(i))) {
68 std::vector<long> exponents;
69 CoCoA::exponents(exponents, CoCoA::PP(i));
72 for (std::size_t i = 0; i < exponents.size(); ++i) {
73 if (exponents[i] == 0)
continue;
74 const auto& ring = CoCoA::owner(p);
75 monContent.emplace_back(mSymbolBack.at(std::make_pair(CoCoA::RingID(ring),i)), exponents[i]);
76 tdeg += std::size_t(exponents[i]);
84 template<
typename Poly>
85 CoCoA::RingElem convertMV(
const Poly& p,
const CoCoA::ring& ring)
const {
86 CoCoA::RingElem res(ring);
87 for (
const auto& t: p) {
92 std::vector<long> exponents(mSymbolBack.size());
93 for (
const auto& p: *t.monomial()) {
94 auto it = mSymbolThere.find(p.first);
95 assert(it != mSymbolThere.end());
97 if (CoCoA::IsIndet(indetIndex, it->second)) {
98 exponents[std::size_t(indetIndex)] = long(p.second);
100 assert(
false &&
"The symbol is not an inderminant.");
103 res += CoCoA::monomial(ring,
convert(t.coeff()), exponents);
108 template<
typename Poly>
109 CoCoA::RingElem convertUV(
const Poly& p,
const CoCoA::SparsePolyRing& ring)
const {
110 CoCoA::RingElem res(ring);
111 CoCoA::RingElem
exp(ring, 1);
112 CoCoA::RingElem var = mSymbolThere.at(p.main_var());
113 for (std::size_t deg = 0; deg <= p.degree(); ++deg) {
127 template<
typename Rational,
typename Poly>
130 std::map<Variable,IntRepRealAlgebraicNumber<Rational>>
mModel;
133 CoCoA::ring mQ = CoCoA::RingQQ();
134 detail_field_extensions::CoCoAConverter cc;
137 return cc.buildPolyRing(mQ, v);
140 bool evaluatesToZero(
const CoCoA::RingElem& p)
const {
141 auto mp = cc.convertMV<Poly>(p);
143 CARL_LOG_DEBUG(
"carl.ran.interval",
"Evaluated " << p <<
" -> " << mp <<
" == 0 -> " << res);
144 assert(!indeterminate(res));
148 void extendRing(
const CoCoA::ring& ring,
const CoCoA::RingElem& p) {
149 mQ = CoCoA::NewQuotientRing(ring, CoCoA::ideal(p));
171 CARL_LOG_DEBUG(
"carl.ran.interval",
"Is numeric: " << v <<
" -> " << r);
172 return std::make_pair(
true, Poly(r.
value()));
174 auto ci = buildPolyRing(v);
176 CARL_LOG_DEBUG(
"carl.ran.interval",
"Factorization of " << p <<
" on " << ci);
180 if (evaluatesToZero(f)) {
181 CARL_LOG_DEBUG(
"carl.ran.interval",
"Factor " << f <<
" is zero in assignment.");
182 if (CoCoA::deg(f) == 1) {
183 auto cf =-(f -CoCoA::LF(f)) / CoCoA::CoeffEmbeddingHom(CoCoA::owner(f))(CoCoA::LC(f));
184 return std::make_pair(
true, cc.convertMV<Poly>(cf));
187 return std::make_pair(
false, cc.convertMV<Poly>(f));
191 CARL_LOG_ERROR(
"carl.ran.interval",
"No factor is zero in assignment.");
193 return std::make_pair(
false, Poly());
197 return std::make_pair(
false, Poly());
203 CARL_LOG_DEBUG(
"carl.ran.interval",
"Embed " << poly <<
" into " << mQ);
204 auto f = cc.convertMV(poly, mQ);
206 return cc.convertMV<Poly>(f);
#define CARL_LOG_ERROR(channel, msg)
#define CARL_LOG_DEBUG(channel, msg)
Monomial::Arg createMonomial(T &&... t)
Interval< Number > exp(const Interval< Number > &i)
bool evaluate(const BasicConstraint< Poly > &c, const Assignment< Number > &m)
UnivariatePolynomial< Coeff > replace_main_variable(const UnivariatePolynomial< Coeff > &p, Variable newVar)
Replaces the main variable in a polynomial.
BasicConstraint< ToPoly > convert(const typename ToPoly::ContextType &context, const BasicConstraint< FromPoly > &c)
Factors< MultivariatePolynomial< C, O, P > > factorization(const MultivariatePolynomial< C, O, P > &p, bool includeConstants=true)
Try to factorize a multivariate polynomial.
Represent a polynomial (in)equality against zero.
A Variable represents an algebraic variable that can be used throughout carl.
std::vector< std::pair< Variable, std::size_t > > Content
const auto & value() const
const auto & polynomial() const
This class can be used to construct iterated field extensions from a sequence of real algebraic numbe...
std::map< Variable, IntRepRealAlgebraicNumber< Rational > > mModel
std::pair< bool, Poly > extend(Variable v, const IntRepRealAlgebraicNumber< Rational > &r)
Extend the current number field with the field extension defined by r.
Poly embed(const Poly &poly)