22 #include <CoCoA/BigInt.H>
23 #include <CoCoA/BigRat.H>
24 #include <CoCoA/factorization.H>
25 #include <CoCoA/ring.H>
26 #include <CoCoA/RingQQ.H>
27 #include <CoCoA/SparsePolyIter.H>
28 #include <CoCoA/SparsePolyOps-RingElem.H>
29 #include <CoCoA/SparsePolyRing.H>
37 namespace cocoawrapper {
39 CoCoA::RingElem
gcd(
const CoCoA::RingElem& p,
const CoCoA::RingElem& q);
41 CoCoA::factorization<CoCoA::RingElem> factor(
const CoCoA::RingElem& p);
43 std::vector<CoCoA::RingElem> ReducedGBasis(
const std::vector<CoCoA::RingElem>& p);
45 CoCoA::factorization<CoCoA::RingElem> SqFreeFactor(
const CoCoA::RingElem& p);
48 template<
typename Poly>
51 std::map<Variable, CoCoA::RingElem> mSymbolThere;
52 std::vector<Variable> mSymbolBack;
53 CoCoA::ring mQ = CoCoA::RingQQ();
54 CoCoA::SparsePolyRing mRing;
56 CoCoA::BigInt
convert(
const mpz_class& n)
const {
57 return CoCoA::BigIntFromMPZ(n.get_mpz_t());
59 mpz_class
convert(
const CoCoA::BigInt& n)
const {
60 return mpz_class(CoCoA::mpzref(n));
62 CoCoA::BigRat
convert(
const mpq_class& n)
const {
63 return CoCoA::BigRatFromMPQ(n.get_mpq_t());
65 mpq_class
convert(
const CoCoA::BigRat& n)
const {
66 return mpq_class(CoCoA::mpqref(n));
69 void convert(mpz_class& res,
const CoCoA::RingElem& n)
const {
71 CoCoA::IsInteger(i, n);
74 void convert(mpq_class& res,
const CoCoA::RingElem& n)
const {
76 CoCoA::IsRational(r, n);
80 #ifdef USE_CLN_NUMBERS
81 CoCoA::BigInt
convert(
const cln::cl_I& n)
const {
82 return convert(carl::convert<cln::cl_I, mpz_class>(n));
84 CoCoA::BigRat
convert(
const cln::cl_RA& n)
const {
85 return convert(carl::convert<cln::cl_RA, mpq_class>(n));
87 void convert(cln::cl_I& res,
const CoCoA::RingElem& n)
const {
89 CoCoA::IsInteger(i, n);
90 res = carl::convert<mpz_class, cln::cl_I>(
convert(i));
92 void convert(cln::cl_RA& res,
const CoCoA::RingElem& n)
const {
94 CoCoA::IsRational(r, n);
95 res = carl::convert<mpq_class, cln::cl_RA>(
convert(r));
99 static carlVariables
variables(
const std::vector<Poly>& polys) {
105 CoCoA::RingElem
convert(
const Poly& p)
const {
106 CoCoA::RingElem res(mRing);
107 for (
const auto& t: p) {
112 std::vector<long> exponents(mSymbolBack.size());
113 for (
const auto& p: *t.monomial()) {
114 auto it = mSymbolThere.find(p.first);
115 assert(it != mSymbolThere.end());
117 if (CoCoA::IsIndet(indetIndex, it->second)) {
118 exponents[std::size_t(indetIndex)] = long(p.second);
120 assert(
false &&
"The symbol is not an inderminant.");
123 res += CoCoA::monomial(mRing,
convert(t.coeff()), exponents);
128 Poly
convert(
const CoCoA::RingElem& p)
const {
130 for (CoCoA::SparsePolyIter i = CoCoA::BeginIter(p); !CoCoA::IsEnded(i); ++i) {
131 typename Poly::CoeffType coeff;
132 convert(coeff, CoCoA::coeff(i));
133 if (CoCoA::IsOne(CoCoA::PP(i))) {
136 std::vector<long> exponents;
137 CoCoA::exponents(exponents, CoCoA::PP(i));
139 std::size_t tdeg = 0;
140 for (std::size_t i = 0; i < exponents.size(); ++i) {
141 if (exponents[i] == 0)
continue;
142 monContent.emplace_back(mSymbolBack[i], exponents[i]);
143 tdeg += std::size_t(exponents[i]);
145 std::sort(monContent.begin(), monContent.end(), [](
const std::pair<Variable, exponent>& p1,
const std::pair<Variable, exponent>& p2){ return p1.first < p2.first; });
152 std::vector<CoCoA::RingElem>
convert(
const std::vector<Poly>& p)
const {
153 std::vector<CoCoA::RingElem> res;
154 for (
const auto& poly: p) res.emplace_back(
convert(poly));
157 std::vector<Poly>
convert(
const std::vector<CoCoA::RingElem>& p)
const {
158 std::vector<Poly> res;
159 for (
const auto& poly: p) res.emplace_back(
convert(poly));
167 auto construct_symbol_back(std::vector<Variable> vars,
bool lex_order =
false)
const {
169 std::sort(vars.begin(), vars.end());
174 auto construct_ring(
const std::vector<Variable>& vars,
bool lex_order =
false)
const {
175 std::vector<CoCoA::symbol> indets;
177 indets.emplace_back(s.safe_name());
180 return CoCoA::NewPolyRing(mQ, indets, CoCoA::lex);
182 return CoCoA::NewPolyRing(mQ, indets);
187 explicit CoCoAAdaptor(
const std::vector<Variable>& vars,
bool lex_order =
false):
188 mSymbolBack(construct_symbol_back(vars)), mRing(construct_ring(mSymbolBack, lex_order))
190 auto indets = CoCoA::indets(mRing);
191 for (std::size_t i = 0; i < mSymbolBack.size(); ++i) {
192 mSymbolThere.emplace(mSymbolBack[i], indets[i]);
195 CoCoAAdaptor(
const std::vector<Poly>& polys):
196 CoCoAAdaptor(
variables(polys).as_vector())
198 CoCoAAdaptor(
const std::initializer_list<Poly>& polys):
199 CoCoAAdaptor(std::vector<Poly>(polys))
202 void resetVariableOrdering(
const std::vector<Variable>& ordering) {
203 assert(ordering.size() == mSymbolBack.size());
204 assert(ordering.size() == mSymbolThere.size());
205 mSymbolBack = ordering;
206 std::sort(mSymbolBack.begin(), mSymbolBack.end());
208 auto indets = CoCoA::indets(mRing);
209 for (std::size_t i = 0; i < mSymbolBack.size(); ++i) {
210 mSymbolThere[mSymbolBack[i]] = indets[i];
214 Poly
gcd(
const Poly& p1,
const Poly& p2)
const {
221 Poly makeCoprimeWith(
const Poly& p1,
const Poly& p2)
const {
222 CoCoA::RingElem res =
convert(p1);
240 Factors<Poly> factorize(
const Poly& p,
bool includeConstant =
true)
const {
242 auto finfo = cocoawrapper::factor(
convert(p));
244 if (includeConstant && !CoCoA::IsOne(finfo.myRemainingFactor())) {
245 res.emplace(
convert(finfo.myRemainingFactor()), 1);
247 for (std::size_t i = 0; i < finfo.myFactors().size(); ++i) {
248 res.emplace(
convert(finfo.myFactors()[i]), finfo.myMultiplicities()[i]);
261 std::vector<Poly> res;
262 for (
auto& f: factorize(p, includeConstant)) {
263 res.emplace_back(std::move(f.first));
269 auto finfo = cocoawrapper::SqFreeFactor(
convert(p));
271 for (
const auto& f: finfo.myFactors()) {
277 auto GBasis(
const std::vector<Poly>& p)
const {
#define CARL_TIME_FINISH(timer, start)
#define CARL_TIME_START(variable)
carl is the main namespace for the library.
MultivariatePolynomial< C, O, P > squareFreePart(const MultivariatePolynomial< C, O, P > &polynomial)
Monomial::Arg createMonomial(T &&... t)
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.
BasicConstraint< ToPoly > convert(const typename ToPoly::ContextType &context, const BasicConstraint< FromPoly > &c)
void variables(const BasicConstraint< Pol > &c, carlVariables &vars)
std::vector< std::pair< Variable, std::size_t > > Content