57#define COERCE_RING(RingType, R) dynamic_cast<const RingType *>(R)
63template <
class RingType>
66 std::unique_ptr<RingType>
R;
76 typedef typename RingType::Element
Element;
80 template <
class... Args>
84 const RingType &
ring()
const {
return *
R; }
139 return ring().computeHashValue(b);
145 return std::pair<bool, long>(
false, 0);
155 R->set_from_long(a, n);
165 R->set_from_mpz(a, n);
172 bool ret =
R->set_from_mpq(a, q);
173 if (ret)
R->to_ring_elem(
result, a);
180 if (ret)
R->to_ring_elem(
result, a);
188 if (ret)
R->to_ring_elem(
result, a);
196 if (ret)
R->to_ring_elem(
result, a);
205 if (ret)
R->to_ring_elem(
result, a);
212 if (ret)
R->to_ring_elem(
result, a);
221 if (ret)
R->to_ring_elem(
result, a);
273 bool ret =
R->is_unit(a);
281 bool ret =
R->is_zero(a);
290 bool ret =
R->is_equal(a, b);
299 int ret =
R->compare_elems(a, b);
351 R->subtract(c, a, b);
374 R->power_mpz(b, a, n);
422 R->syzygy(a, b, xe, ye);
423 R->to_ring_elem(
x, xe);
424 R->to_ring_elem(y, ye);
441 bool p_parens =
false)
const
445 R->elem_text_out(o, a, p_one, p_plus, p_parens);
460 R->from_ring_elem(a, f);
461 R->eval(map, a, first_var,
result);
491 explicit RingQQ(std::unique_ptr<ARingQQ> R0)
499 auto R0 = std::make_unique<ARingQQ>();
514 mpz_srcptr numer = top.
get_mpz();
515 mpz_srcptr denom = bottom.
get_mpz();
518 mpz_set(mpq_numref(b), numer);
519 mpz_set(mpq_denref(b), denom);
539 if (mpq_sgn(a) >= 0)
return from_long(1);
549 int s = (sa == 0 ? sb : sa);
553 mpz_gcd(mpq_numref(
result), mpq_numref(a), mpq_numref(b));
554 mpz_lcm(mpq_denref(
result), mpq_denref(a), mpq_denref(b));
576 mpz_gcd(mpq_numref(
result), mpq_numref(a), mpq_numref(b));
577 mpz_lcm(mpq_denref(
result), mpq_denref(a), mpq_denref(b));
585template <
class RingType>
587 std::unique_ptr<RingType>
R)
602template <
class RingType>
603template <
class... Args>
607 std::make_unique<RingType>(std::forward<Args>(args)...));
617 template <
typename SourceRing,
typename TargetRing>
625 const SourceRing &R1 =
627 const TargetRing &S1 =
630 typename SourceRing::Element fR1(R1);
631 typename TargetRing::Element gS1(S1);
633 R1.from_ring_elem(fR1, fR);
634 bool retval =
mypromote(R1, S1, fR1, gS1);
635 if (retval) S1.to_ring_elem(resultS, gS1);
639 template <
typename SourceRing,
typename TargetRing>
647 const SourceRing &R1 =
649 const TargetRing &S1 =
652 typename SourceRing::Element fR1(R1);
653 typename TargetRing::Element gS1(S1);
655 S1.from_ring_elem(gS1, gS);
656 bool retval =
mylift(R1, S1, fR1, gS1);
657 if (retval) R1.to_ring_elem(result_gR, fR1);
662template <
typename RingType>
667 const Ring *S =
this;
688 return RP::promoter<ARingZZp, ARingZZpFFPACK>(
R, S, fR, resultS);
697 return RP::promoter<ARingZZpFFPACK, ARingZZp>(
R, S, fR, resultS);
699 return RP::promoter<ARingZZpFFPACK, ARingZZpFFPACK>(
708 return RP::promoter<ARingQQ, ARingRR>(
R, S, fR, resultS);
710 return RP::promoter<ARingQQ, ARingRRR>(
R, S, fR, resultS);
712 return RP::promoter<ARingQQ, ARingRRi>(
R, S, fR, resultS);
714 return RP::promoter<ARingQQ, ARingCC>(
R, S, fR, resultS);
716 return RP::promoter<ARingQQ, ARingCCC>(
R, S, fR, resultS);
718 return RP::promoter<ARingQQ, ARingCCi>(
R, S, fR, resultS);
726 return RP::promoter<ARingRR, ARingRR>(
R, S, fR, resultS);
728 return RP::promoter<ARingRR, ARingRRR>(
R, S, fR, resultS);
730 return RP::promoter<ARingRR, ARingRRi>(
R, S, fR, resultS);
732 return RP::promoter<ARingRR, ARingCC>(
R, S, fR, resultS);
734 return RP::promoter<ARingRR, ARingCCC>(
R, S, fR, resultS);
736 return RP::promoter<ARingRR, ARingCCi>(
R, S, fR, resultS);
744 return RP::promoter<ARingRRR, ARingRR>(
R, S, fR, resultS);
746 return RP::promoter<ARingRRR, ARingRRR>(
R, S, fR, resultS);
748 return RP::promoter<ARingRRR, ARingRRi>(
R, S, fR, resultS);
750 return RP::promoter<ARingRRR, ARingCC>(
R, S, fR, resultS);
752 return RP::promoter<ARingRRR, ARingCCC>(
R, S, fR, resultS);
754 return RP::promoter<ARingRRR, ARingCCi>(
R, S, fR, resultS);
762 return RP::promoter<ARingRRi, ARingRR>(
R, S, fR, resultS);
764 return RP::promoter<ARingRRi, ARingRRR>(
R, S, fR, resultS);
766 return RP::promoter<ARingRRi, ARingRRi>(
R, S, fR, resultS);
768 return RP::promoter<ARingRRi,ARingCCi>(
R, S, fR, resultS);
776 return RP::promoter<ARingCC, ARingCC>(
R, S, fR, resultS);
778 return RP::promoter<ARingCC, ARingCCC>(
R, S, fR, resultS);
780 return RP::promoter<ARingCC, ARingCCi>(
R, S, fR, resultS);
788 return RP::promoter<ARingCCC, ARingCCC>(
R, S, fR, resultS);
790 return RP::promoter<ARingCCC, ARingCC>(
R, S, fR, resultS);
792 return RP::promoter<ARingCCC, ARingCCi>(
R, S, fR, resultS);
800 return RP::promoter<ARingCCi, ARingCCi>(
R, S, fR, resultS);
813template <
typename RingType>
818 const Ring *S =
this;
828 printf(
"error!! lift called with no ZZ lifting method\n");
840 return RP::lifter<ARingZZp, ARingZZpFFPACK>(
R, S, result_gR, gS);
849 return RP::lifter<ARingZZpFFPACK, ARingZZp>(
R, S, result_gR, gS);
851 return RP::lifter<ARingZZpFFPACK, ARingZZpFFPACK>(
852 R, S, result_gR, gS);
860 return RP::lifter<ARingRR, ARingRR>(
R, S, result_gR, gS);
862 return RP::lifter<ARingRR, ARingRRR>(
R, S, result_gR, gS);
864 return RP::lifter<ARingRR, ARingRRi>(
R, S, result_gR, gS);
866 return RP::lifter<ARingRR, ARingCC>(
R, S, result_gR, gS);
868 return RP::lifter<ARingRR, ARingCCC>(
R, S, result_gR, gS);
876 return RP::lifter<ARingRRR, ARingRR>(
R, S, result_gR, gS);
878 return RP::lifter<ARingRRR, ARingRRR>(
R, S, result_gR, gS);
880 return RP::lifter<ARingRRR, ARingRRi>(
R, S, result_gR, gS);
882 return RP::lifter<ARingRRR, ARingCC>(
R, S, result_gR, gS);
884 return RP::lifter<ARingRRR, ARingCCC>(
R, S, result_gR, gS);
892 return RP::lifter<ARingCC, ARingCC>(
R, S, result_gR, gS);
894 return RP::lifter<ARingCCC, ARingCC>(
R, S, result_gR, gS);
902 return RP::lifter<ARingCC, ARingCCC>(
R, S, result_gR, gS);
904 return RP::lifter<ARingCCC, ARingCCC>(
R, S, result_gR, gS);
911 "oh no: rings not in list\n, R->ringID()=%d S->ringID()=%d\n",
924template <
typename RingType>
932 typename RingType::Element a(R);
933 R.from_ring_elem(a, f);
971 bool retval =
R->promote(Rf, f, a);
986 R->from_ring_elem(a, f);
987 bool retval =
R->lift(Rg, a,
result);
997 bool retval =
ring().promote(Rf, f, a);
1008 ring().from_ring_elem(a, f);
1019 bool retval =
ring().promote(Rf, f, a);
1030 ring().from_ring_elem(a, f);
1046 R->from_ring_elem(a, f);
1048 bool retval =
R->lift_to_mpz(b, a);
1059template <
typename RingType>
1067template <
typename RingType>
1080 R->from_ring_elem(a, f);
1081 R->zeroize_tiny(epsilon, a);
1092 R->from_ring_elem(a, f);
1093 R->zeroize_tiny(epsilon, a);
1104 R->from_ring_elem(a, f);
1105 R->zeroize_tiny(epsilon, a);
1116 R->from_ring_elem(a, f);
1117 R->zeroize_tiny(epsilon, a);
1127 ARingRR::Element a(*
R);
1130 if (mpfr_cmp_d(norm, a) < 0) mpfr_set_d(norm, a, MPFR_RNDN);
1137 const ARingRR &realR =
R->real_ring();
1138 ARingRR::Element a(realR);
1141 if (mpfr_cmp_d(norm, a) < 0) mpfr_set_d(norm, a, MPFR_RNDN);
1148 ARingRRR::Element a(*
R);
1151 if (mpfr_cmp(&a.value(), norm) > 0) mpfr_set(norm, &a.value(), MPFR_RNDN);
1159 ARingRRR::Element a(realR);
1162 if (mpfr_cmp(&a.value(), norm) > 0) mpfr_set(norm, &a.value(), MPFR_RNDN);
1165template <
typename RingType>
1174 return R->get_precision();
1180 return R->get_precision();
1186 return R->get_precision();
1192 return R->get_precision();
1198 return R->get_precision();
1204 return R->get_precision();
1207template <
typename RT>
1210 const typename RT::ElementType &b = ring.from_ring_elem_const(a);
1211 long result = ring.coerceToLongInteger(b);
1212 return std::pair<bool, long>(
true,
result);
1241 bool succeed =
ring().coerceToLongInteger(b, *a.
get_mpz());
1242 return std::pair<bool, long>(succeed, b);
1250 fmpz t =
reinterpret_cast<fmpz
>(
const_cast<Nterm *
>(a.
poly_val));
1251 bool succeed =
ring().coerceToLongInteger(b, t);
1252 return std::pair<bool, long>(succeed, b);
1282template <
typename RT>
1288 typename RT::Element b(R);
1289 R.from_ring_elem(b, a);
1290 R.lift_to_original_ring(c, b);
1314template <
typename ConcreteRT>
1318 typename ConcreteRT::Element a(R.ring());
1320 R.ring().getGenerator(a);
1321 R.ring().to_ring_elem(b, a);
void initializeRationalRing()
static const bool displayArithmeticCalls
Tiny dispatcher header that picks the default ARingQQ from among the QQ aring implementations.
Cross-ring coercion templates: mypromote / mylift between two aring rings, and get_from_* from an ext...
Shared base of the aring framework (namespace M2) that unifies the engine's coefficient rings.
aring-style adapter for double-precision real numbers.
aring-style adapter for arbitrary-precision real numbers, backed by MPFR.
bool isGaloisField() const
virtual void text_out(buffer &o) const
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
const RingElement * getRepresentation(const ring_elem &a) const
virtual bool from_Interval(gmp_RRi q, ring_elem &result) const
virtual ring_elem var(int v) const
virtual bool is_zero(const ring_elem f) const
virtual ring_elem invert(const ring_elem f) const
virtual void increase_maxnorm(gmp_RRmutable norm, const ring_elem f) const
virtual ring_elem power(const ring_elem f, int n) const
RingType::ElementType ElementType
virtual ring_elem from_long(long n) const
virtual unsigned long get_precision() const
virtual unsigned int computeHashValue(ring_elem a) const
const M2::ARingCCC & ring() const
virtual bool promote(const Ring *S, const ring_elem f, ring_elem &result) const
virtual void remove(ring_elem &f) const
virtual bool lift(const Ring *S, const ring_elem f, ring_elem &result) const
ConcreteRing(const ConcreteRing &ring)=delete
virtual ring_elem negate(const ring_elem f) const
const RingElement * getGenerator() const
virtual bool from_BigReal(gmp_RR q, ring_elem &result) const
virtual ring_elem divide(const ring_elem f, const ring_elem g) const
virtual ring_elem subtract(const ring_elem f, const ring_elem g) const
virtual bool from_complex_double(double re, double im, ring_elem &result) const
virtual ~ConcreteRing()=default
const RingElement * getMinimalPolynomial() const
virtual void syzygy(const ring_elem f, const ring_elem g, ring_elem &x, ring_elem &y) const
virtual int compare_elems(const ring_elem f, const ring_elem g) const
virtual bool from_ComplexInterval(gmp_CCi z, ring_elem &result) const
static ConcreteRing< RingType > * create(std::unique_ptr< RingType > R)
virtual bool is_unit(const ring_elem f) const
ConcreteRing(std::unique_ptr< RingType > R0)
virtual ring_elem from_int(mpz_srcptr n) const
virtual MutableMatrix * makeMutableMatrix(size_t nrows, size_t ncols, bool dense) const
Create either a dense or sparse MutableMatrix of the given size.
virtual ring_elem eval(const RingMap *map, const ring_elem f, int first_var) const
virtual bool from_BigComplex(gmp_CC q, ring_elem &result) const
virtual std::pair< bool, long > coerceToLongInteger(ring_elem a) const
virtual ring_elem zeroize_tiny(gmp_RR epsilon, const ring_elem f) const
virtual ring_elem power(const ring_elem f, mpz_srcptr n) const
Exponentiation. This is the default function, if a class doesn't define this.
virtual bool from_double(double q, ring_elem &result) const
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const
std::unique_ptr< M2::ARingCCC > R
virtual M2::RingID ringID() const
virtual long discreteLog(const ring_elem &a) const
static ConcreteRing< RingType > * create(Args &&...args)
virtual ring_elem random() const
virtual bool from_rational(mpq_srcptr q, ring_elem &result) const
virtual bool is_equal(const ring_elem f, const ring_elem g) const
RingType::Element Element
virtual ring_elem copy(const ring_elem f) const
virtual ring_elem add(const ring_elem f, const ring_elem g) const
bool isFinitePrimeField() const
RingQQ(std::unique_ptr< ARingQQ > R0)
ring_elem numerator(ring_elem q) const
ring_elem preferred_associate(ring_elem f) const
CoefficientType coefficient_type() const
ring_elem fraction(ring_elem top, ring_elem bottom) const
bool lower_associate_divisor(ring_elem &f, const ring_elem g) const
void lower_content(ring_elem &c, const ring_elem g) const
ring_elem denominator(ring_elem q) const
Ring-level QQ ring, a thin specialisation of ConcreteRing<ARingQQ> that marks itself with is_QQ() and...
Abstract base class for mutable matrices over an arbitrary engine Ring, the in-place counterpart of t...
virtual const PolynomialRing * getAmbientRing() const
Nterm * quotient_element(int i) const
Abstract base for the engine's polynomial-ring hierarchy.
virtual M2::RingID ringID() const
virtual ring_elem from_long(long n) const =0
long characteristic() const
virtual ring_elem copy(const ring_elem f) const =0
virtual ring_elem from_int(mpz_srcptr n) const =0
static RingElement * make_raw(const Ring *R, ring_elem f)
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
void mpz_reallocate_limbs(mpz_ptr _z)
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemstructtype(S)
struct gmp_CC_struct * gmp_CC
struct gmp_CCi_struct * gmp_CCi
Umbrella header that ties together MutableMat declarations, implementations, and the SLP variant.
std::pair< bool, long > coerceToLongIntegerFcn(const RT &ring, ring_elem a)
const RingElement * getLiftedRepresentation(const RT &R, const ring_elem &a)
bool get_from_Interval(const RT &R, typename RT::ElementType &a, gmp_RRi b)
const RingElement * getGen(const ConcreteRT &R)
const RingElement * findMinimalPolynomial(const PolynomialRing &originalR)
bool mypromote(const RingR &R, const RingS &S, const typename RingR::ElementType &fR, typename RingS::ElementType &result_fS)
bool get_from_BigComplex(const RT &R, typename RT::ElementType &a, gmp_CC b)
bool get_from_complex_double(const RT &R, typename RT::ElementType &a, double re, double im)
bool get_from_double(const RT &R, typename RT::ElementType &a, double b)
bool liftToInt(const RingType &R, const Ring *Rg, const ring_elem f, ring_elem &result)
bool get_from_ComplexInterval(const RT &R, typename RT::ElementType &a, gmp_CCi b)
bool get_from_BigReal(const RT &R, typename RT::ElementType &a, gmp_RR b)
bool mylift(const RingR &R, const RingS &S, typename RingR::ElementType &result_gR, const typename RingS::ElementType &gS)
Ring — the legacy abstract base class for every coefficient and polynomial ring.
Singly linked-list node carrying one term of a polynomial-ring element.
mpz_srcptr get_mpz() const