14#define Matrix FactoryMatrix
15#include <factory/factory.h>
18#pragma GCC diagnostic push
19#pragma GCC diagnostic ignored "-Wconversion"
21#pragma GCC diagnostic pop
39#define REVERSE_VARIABLES \
59 ERROR(
"characteristic is too large (max is 2^29)");
64 ERROR(
"expected coefficient ring of the form ZZ/n, ZZ, QQ, or GF");
76 NTL::SetSeed(NTL::ZZ::zero());
98 ? static_cast<
int>(P->characteristic())
120 setCharacteristic(0);
132 setCharacteristic(0);
182 static const unsigned int base = 1 << 16;
187 int RationalMode = isOn(SW_RATIONAL) ? (Off(SW_RATIONAL), 1) : 0;
197 CanonicalForm k = h % (
int)
base;
198 vec.push_back(
static_cast<int>(k.intval()));
201 if (RationalMode) On(SW_RATIONAL);
205 for (
int i = vec.size() - 1; i >= 0; i--)
208 mpz_add_ui(
x,
x,
static_cast<unsigned>(vec[i]));
210 if (sign == -1) mpz_neg(
x,
x);
217 const int n = R->
n_vars();
218 if (h.inCoeffDomain())
235 std::cout <<
"internal error: unexpected failure to lift "
236 "rational number to ring"
246 else if (h.inExtension())
250 for (
int j = h.taildegree(); j <= h.degree(); j++)
264 ERROR(
"conversion from factory over unknown type");
269 for (
int j = h.taildegree(); j <= h.degree(); j++)
294void showvar(Variable &t) { std::cout << t << std::endl; }
295void showcf(CanonicalForm &t) { std::cout << t << std::endl; }
296void showcfl(CFList &t) { std::cout << t << std::endl; }
297void showcffl(CFFList &t) { std::cout << t << std::endl; }
300 mpz_out_str(stdout, 10,
p);
301 std::cout << std::endl;
303void showmpz(mpz_srcptr
p)
305 mpz_out_str(stdout, 10,
p);
306 std::cout << std::endl;
315 int size =
p->_mp_size;
316 int sign = size < 0 ? -1 : 1;
317 if (size < 0) size = -size;
322 for (
int i = 0; i < mp_bits_per_limb; i++)
base *= 2;
325 for (
int i = size - 1; i >= 0; i--)
327 mp_limb_t digit =
p->_mp_d[i];
328 for (
int j = mp_bits_per_limb; j > 0;)
333 int subbase = 1 << n;
334 m = subbase * m + (
static_cast<int>(digit >> k) & (subbase - 1));
361 std::vector<long> &result_rep)
374 for (
int i = 0; i < repr.size(); i++)
376 if (repr[i] == 0)
continue;
377 CanonicalForm m = CanonicalForm(repr[i]);
388 std::vector<long> poly;
407 int coef =
static_cast<int>(res.second);
409 CanonicalForm m = CanonicalForm(coef);
424 ERROR(
"expected a polynomial ring");
427 const int n = P->
n_vars();
436 M->to_varpower(t->monom, vp);
437 if (foo.mode == modeZn)
439 std::pair<bool, long> res = foo.Zn->coerceToLongInteger(t->coeff);
441 coef = static_cast<int>(res.second);
445 ? CanonicalForm(coef)
452 mpq_numref(
MPQ_VAL(t->coeff))) /
454 mpq_denref(
MPQ_VAL(t->coeff))))
464 m *= power(index == 1 && inExtension ? algebraicElement_Fac
500 ERROR(
"expected polynomial ring");
505 ERROR(
"encountered different rings");
512 algebraicElement_M2 = nullptr;
517 assert(!inExtension);
518 set_GF_minimal_poly(P);
527 CanonicalForm h = gcd(
p, q);
532 P, P->var(P->n_vars() - 1));
543 if (ret->
is_zero())
return ret;
559 const bool inExtension =
false;
570 ERROR(
"expected polynomial ring");
575 ERROR(
"encountered different rings");
597 set_GF_minimal_poly(P);
602 CanonicalForm h = extgcd(
p, q, a, b);
628 const bool inExtension =
false;
633 ERROR(
"expected polynomial ring");
638 ERROR(
"encountered different rings");
646 set_GF_minimal_poly(P);
650 CanonicalForm h = Prem(
p, q);
670 bool inExtension = mipo !=
nullptr;
674 *result_factors =
nullptr;
675 *result_powers =
nullptr;
678 ERROR(
"expected polynomial ring");
690 Variable a = set_GF_minimal_poly(P);
691 CanonicalForm h = convertToFactory(*g, notInExtension);
694 else if (mipo !=
nullptr)
697 Variable a = rootOf(mipocf,
'a');
715 int nfactors = q.length();
717 *result_factors =
getmemarraytype(engine_RawRingElementArray, nfactors);
718 (*result_factors)->len = nfactors;
723 for (CFFListIterator i = q; i.hasItem(); i++)
725 (*result_factors)->array[next] =
convertToM2(P, i.getItem().factor());
726 (*result_powers)->array[next++] = i.getItem().exp();
729 if (
error()) *result_factors =
nullptr, *result_powers =
nullptr;
754 const bool inExtension =
false;
761 ERROR(
"expected polynomial ring");
764 const int N = P->
n_vars();
770 ERROR(
"not implemented yet");
776 for (i = 0; i < M->
n_rows(); i++)
778 for (
int j = 0; j < M->
n_cols(); j++)
788 if (I.length() == 0) {
789 ERROR(
"expected at least one generator");
793 List<int> t = neworderint(I);
797 ListIterator<int> ii(t);
798 for (i = 0; ii.hasItem(); ii++, i++)
799 u[i] = (n - 1) - (ii.getItem() - 1);
800 std::reverse(u.begin(), u.begin() + n);
801 for (i = n; i < N; i++) u[i] = i;
812 const bool inExtension =
false;
818 ERROR(
"expected polynomial ring");
828 ERROR(
"not implemented yet");
833 for (
int i = 0; i < M->
n_rows(); i++)
835 for (
int j = 0; j < M->
n_cols(); j++)
845 List<CFList> t = irrCharSeries(I);
847 engine_RawMatrixArray
result =
852 for (ListIterator<List<CanonicalForm> > ii = t; ii.hasItem(); ii++)
854 CFList u = ii.getItem();
855 engine_RawRingElementArray result1 =
857 result1->len = u.length();
859 for (ListIterator<CanonicalForm> j = u; j.hasItem(); j++)
861 result1->array[next1++] =
convertToM2(P, j.getItem());
862 if (
error())
return nullptr;
879 for (
int i = 0; i < M.
n_rows(); i++)
881 for (
int j = 0; j < M.
n_cols(); j++)
ExponentListIterator< int, true > index_varpower
Append-only GC-backed byte buffer used throughout the engine for text output.
ring_elem get_rep(ring_elem f) const
const PolynomialRing * originalR() const
Engine-side finite field GF(p^n) built on top of (Z/p)[t] / f(t) for a primitive element of the resul...
const Ring * get_ring() const
ring_elem elem(int i, int j) const
const FreeModule * rows() const
void to_varpower(const_monomial m, gc_vector< int > &result_vp) const
Engine-side commutative monomial monoid: variable names, ordering, multidegree machinery,...
ring_elem preferred_associate_divisor(ring_elem ff) const
const Ring * getCoefficientRing() const
virtual ring_elem var(int v) const =0
virtual const Monoid * getMonoid() const
virtual void mult_coeff_to(ring_elem a, ring_elem &f) const =0
virtual const Ring * getCoefficients() const
virtual const PolyRing * getNumeratorRing() const
Abstract base for the engine's polynomial-ring hierarchy.
virtual ring_elem var(int v) const
virtual const RingElement * getMinimalPolynomial() const
virtual bool isGaloisField() const
virtual std::pair< bool, long > coerceToLongInteger(ring_elem a) const
virtual ring_elem invert(const ring_elem f) const =0
virtual ring_elem from_long(long n) const =0
virtual const PolynomialRing * cast_to_PolynomialRing() const
long characteristic() const
virtual const RingZZ * cast_to_RingZZ() const
virtual const RingElement * getRepresentation(const ring_elem &a) const
virtual bool is_QQ() const
void add_to(ring_elem &f, const ring_elem &g) const
virtual ring_elem from_int(mpz_srcptr n) const =0
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 ring_elem mult(const ring_elem f, const ring_elem g) const =0
virtual bool isFinitePrimeField() const
virtual bool from_rational(const mpq_srcptr q, ring_elem &result) const =0
virtual const Tower * cast_to_Tower() const
ring_elem get_value() const
bool promote(const Ring *S, const RingElement *&result) const
static RingElement * make_raw(const Ring *R, ring_elem f)
bool getSmallIntegerCoefficients(std::vector< long > &result_coeffs) const
const Ring * get_ring() const
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
void rawFactor2(const RingElement *g, const RingElement *minpoly, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers)
const RingElement * rawExtendedGCDRingElement(const RingElement *f, const RingElement *g, const RingElement **A, const RingElement **B)
static struct enter_factory foo2
engine_RawMatrixArrayOrNull rawCharSeries(const Matrix *M)
static CanonicalForm base
void rawFactorBase(const RingElement *g, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers, const RingElement *mipo=nullptr)
static void getGFRepresentation(const Ring *kk1, const ring_elem &a, std::vector< long > &result_rep)
const RingElement * rawPseudoRemainder(const RingElement *f, const RingElement *g)
static const RingElement * convertToM2(const PolynomialRing *R, CanonicalForm h)
void rawFactor(const RingElement *g, engine_RawRingElementArrayOrNull *result_factors, M2_arrayintOrNull *result_powers)
CFList convertToCFList(const Matrix &M, bool inExtension)
const bool notInExtension
static __mpz_struct toInteger(CanonicalForm h)
static enum factoryCoeffMode coeffMode(const PolynomialRing *P)
M2_arrayintOrNull rawIdealReorder(const Matrix *M)
static CanonicalForm convertToFactory(mpz_srcptr p)
static Variable set_GF_minimal_poly(const PolynomialRing *P)
static CanonicalForm convertGFToFactory(const std::vector< long > &repr)
CanonicalForm algebraicElement_Fac
const RingElement * algebraicElement_M2
void displayCF(const PolynomialRing *R, const CanonicalForm &h)
const RingElement * rawGCDRingElement(const RingElement *f, const RingElement *g, const RingElement *mipo, const M2_bool inExtension)
bool factoryGoodRing(const PolynomialRing *P)
static struct enter_factory foo1
Engine-boundary C API for polynomial GCD, factorisation, and root finding.
const Matrix * IM2_Matrix_make1(const FreeModule *target, int ncols, const engine_RawRingElementArray M, int preference)
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemarraytype(S, len)
M2_arrayint M2_makearrayint(int n)
M2_arrayint M2_arrayintOrNull
engine_RawMatrixArray engine_RawMatrixArrayOrNull
engine_RawRingElementArray engine_RawRingElementArrayOrNull
Engine-boundary C API for constructing, transforming, and inspecting immutable Matrix objects.
Matrix — the engine's immutable homomorphism F -> G between free modules.
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
typename std::vector< T, gc_allocator< T > > gc_vector
a version of the STL vector, which allocates its backing memory with gc.
Concrete commutative PolyRing — standard polynomial ring inheriting from PolyRingFlat.
PolynomialRing — abstract polynomial-ring base, the engine's most-reused class.
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
Ring — the legacy abstract base class for every coefficient and polynomial ring.
ring_elem — the universal value type carried by every Ring* in the engine.
M2_string IM2_RingElement_to_string(const RingElement *f)
Engine-boundary C API for constructing, querying, and operating on RingElement values.
Singly linked-list node carrying one term of a polynomial-ring element.
enter_factory(const PolynomialRing *P)
enum factoryCoeffMode mode
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
const RingElement * towerExtendedGCD(const RingElement *F, const RingElement *G, const RingElement **A, const RingElement **B)
const RingElement * towerGCD(const RingElement *F, const RingElement *G)
Legacy Tower — Ring-derived iterated extension of Z/p (pre-aring).
M2_arrayint stdvector_to_M2_arrayint(const std::vector< T > &v)
Conversion helpers between M2 boundary types and standard C++ containers.