5 #if defined(USE_COCOA) && defined(USE_LIBPOLY)
19 #include <CoCoA/BigInt.H>
20 #include <CoCoA/BigRat.H>
21 #include <CoCoA/RingQQ.H>
22 #include <CoCoA/SparsePolyIter.H>
23 #include <CoCoA/SparsePolyOps-RingElem.H>
24 #include <CoCoA/SparsePolyRing.H>
25 #include <CoCoA/factorization.H>
26 #include <CoCoA/ring.H>
34 namespace cocoawrapper {
36 CoCoA::RingElem
gcd(
const CoCoA::RingElem& p,
const CoCoA::RingElem& q);
38 CoCoA::factorization<CoCoA::RingElem> factor(
const CoCoA::RingElem& p);
40 std::vector<CoCoA::RingElem> ReducedGBasis(
const std::vector<CoCoA::RingElem>& p);
42 CoCoA::factorization<CoCoA::RingElem> SqFreeFactor(
const CoCoA::RingElem& p);
45 class CoCoAAdaptorLP {
47 std::map<Variable, CoCoA::RingElem> mSymbolThere;
48 std::vector<Variable> mSymbolBack;
49 CoCoA::ring mQ = CoCoA::RingQQ();
50 CoCoA::SparsePolyRing mRing;
52 const LPContext& mContext ;
55 static CoCoA::BigInt
convert(
const mpz_class& n) {
56 return CoCoA::BigIntFromMPZ(n.get_mpz_t());
58 static CoCoA::BigInt
convert(
const mpz_t n) {
59 return CoCoA::BigIntFromMPZ(n);
61 mpz_class
convert(
const CoCoA::BigInt& n)
const {
62 return mpz_class(CoCoA::mpzref(n));
64 static CoCoA::BigRat
convert(
const mpq_class& n) {
65 return CoCoA::BigRatFromMPQ(n.get_mpq_t());
67 mpq_class
convert(
const CoCoA::BigRat& n)
const {
68 return mpq_class(CoCoA::mpqref(n));
71 void convert(mpz_class& res,
const CoCoA::RingElem& n)
const {
73 CoCoA::IsInteger(i, n);
76 void convert(mpq_class& res,
const CoCoA::RingElem& n)
const {
78 CoCoA::IsRational(r, n);
82 CoCoA::RingElem
convert(
const LPPolynomial& p)
const {
83 assert(p.context() == mContext);
85 CoCoA::RingElem res(mRing);
88 CoCoA::RingElem* resPoly;
89 std::map<Variable, CoCoA::RingElem> mSymbolThere;
90 std::vector<Variable> mSymbolBack;
92 CoCoA::SparsePolyRing mRing;
93 const LPContext& context;
96 auto collectTerms = [](
const lp_polynomial_context_t* , lp_monomial_t* m,
void* d) {
97 DataLP* data =
static_cast<DataLP*
>(d);
99 std::vector<long> exponents(data->mSymbolBack.size());
101 for (
size_t i = 0; i < m->n; i++) {
102 auto var = data->context.carl_variable(m->p[i].x);
103 assert(var.has_value());
104 auto it = data->mSymbolThere.find(*var);
105 assert(it != data->mSymbolThere.end());
107 if (CoCoA::IsIndet(indetIndex, it->second)) {
108 exponents[std::size_t(indetIndex)] = long(m->p[i].d);
110 assert(
false &&
"The symbol is not an inderminant.");
114 *data->resPoly += CoCoA::monomial(data->mRing,
convert(&(m->a)), exponents);
117 DataLP data{&res, mSymbolThere, mSymbolBack, mQ, mRing, mContext};
118 lp_polynomial_traverse(p.get_internal(), collectTerms, &data);
122 LPPolynomial
convert(
const CoCoA::RingElem& p)
const {
123 lp_polynomial_t* res = lp_polynomial_new(mContext.lp_context());
125 for (CoCoA::SparsePolyIter i = CoCoA::BeginIter(p); !CoCoA::IsEnded(i); ++i) {
127 convert(coeff, CoCoA::coeff(i));
128 std::vector<long> exponents;
129 CoCoA::exponents(exponents, CoCoA::PP(i));
135 lp_monomial_construct(mContext.lp_context(), &t);
136 lp_monomial_set_coefficient(mContext.lp_context(), &t,
carl::get_num(coeff).get_mpz_t());
138 for (std::size_t i = 0; i < exponents.size(); ++i) {
139 if (exponents[i] == 0)
continue;
140 lp_variable_t var = mContext.lp_variable(mSymbolBack[i]);
141 lp_monomial_push(&t, var, (
unsigned int)exponents[i]);
143 lp_polynomial_add_monomial(res, &t);
144 lp_monomial_destruct(&t);
147 return LPPolynomial(res, mContext);;
150 std::vector<CoCoA::RingElem>
convert(
const std::vector<LPPolynomial>& p)
const {
151 std::vector<CoCoA::RingElem> res;
152 for (
const auto& poly : p)
153 res.emplace_back(
convert(poly));
156 std::vector<LPPolynomial>
convert(
const std::vector<CoCoA::RingElem>& p)
const {
157 std::vector<LPPolynomial> res;
158 for (
const CoCoA::RingElem& poly : p)
159 res.emplace_back(
convert(poly));
168 auto construct_ring(
const std::vector<Variable>& vars)
const {
169 std::vector<CoCoA::symbol> indets;
170 for (
auto s : vars) {
171 indets.emplace_back(s.safe_name());
173 return CoCoA::NewPolyRing(mQ, indets) ;
178 CoCoAAdaptorLP() = delete ;
180 CoCoAAdaptorLP(
const LPContext& ctx) : mSymbolBack(ctx.variable_ordering()), mRing(construct_ring(mSymbolBack)), mContext(ctx) {
181 std::vector<Variable> vars = ctx.variable_ordering() ;
183 auto indets = CoCoA::indets(mRing);
184 for (std::size_t i = 0; i < mSymbolBack.size(); ++i) {
185 mSymbolThere.emplace(mSymbolBack[i], indets[i]);
215 Factors<LPPolynomial> factorize(
const LPPolynomial& p,
bool includeConstant =
true)
const {
216 auto finfo = cocoawrapper::factor(
convert(p));
217 Factors<LPPolynomial> res;
218 if (includeConstant && !CoCoA::IsOne(finfo.myRemainingFactor())) {
219 res.emplace(
convert(finfo.myRemainingFactor()), 1);
221 for (std::size_t i = 0; i < finfo.myFactors().size(); i++) {
222 res[
convert(finfo.myFactors()[i])] = finfo.myMultiplicities()[i];
233 std::vector<LPPolynomial>
irreducible_factors(
const LPPolynomial& p,
bool includeConstant =
true)
const {
234 std::vector<LPPolynomial> res;
235 for (
auto& f : factorize(p, includeConstant)) {
236 res.emplace_back(std::move(f.first));
250 auto GBasis(
const std::vector<LPPolynomial>& p)
const {
carl is the main namespace for the library.
auto irreducible_factors(const ContextPolynomial< Coeff, Ordering, Policies > &p, bool constants=true)
cln::cl_I gcd(const cln::cl_I &a, const cln::cl_I &b)
Calculate the greatest common divisor of two integers.
cln::cl_I get_num(const cln::cl_RA &n)
Extract the numerator from a fraction.
BasicConstraint< ToPoly > convert(const typename ToPoly::ContextType &context, const BasicConstraint< FromPoly > &c)
cln::cl_I get_denom(const cln::cl_RA &n)
Extract the denominator from a fraction.
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)