Macaulay2 Engine
Loading...
Searching...
No Matches
aring-gf-flint.cpp
Go to the documentation of this file.
1// Copyright 2014 Michael E. Stillman
2
3#include "aring-gf-flint.hpp"
4#include "relem.hpp"
5#include "poly.hpp"
6#include "ringmap.hpp"
7
8namespace M2 {
9
11 : mOriginalRing(R),
14{
15 ring_elem b = R.copy(a);
17 ring_elem minpoly = mOriginalRing.quotient_element(0);
18
19 std::vector<long> poly;
20 RingElement F(&R, minpoly);
22
23 // warning: flint expects unsigned longs, so we must make
24 // all of these coeffs non-negative.
25 for (long i = poly.size() - 1; i >= 0; i--)
26 {
27 long a = poly[i];
28 if (a == 0) continue;
29 if (a < 0) poly[i] += characteristic();
30 }
31
32 mDimension = poly.size() - 1;
33
34#if 0
35 printf("minpoly: ");
36 for (long i=0; i<poly.size(); i++)
37 printf(" %ld", poly[i]);
38 printf("\n");
39#endif
40 nmod_poly_t mMinPoly;
41 nmod_poly_init(mMinPoly, R.characteristic());
42
43 for (long i = poly.size() - 1; i >= 0; i--)
44 if (poly[i] != 0) nmod_poly_set_coeff_ui(mMinPoly, i, poly[i]);
45
46 fq_zech_ctx_init_modulus(mContext, mMinPoly, "a");
47 fq_nmod_ctx_init_modulus(mBigContext, mMinPoly, "a");
48#if 0
49 fq_zech_ctx_print(mContext);
50#endif
51 nmod_poly_clear(mMinPoly);
52
53 // powers of p, as ulongs's
54 mPPowers = newarray_atomic(mp_limb_t, mDimension + 1);
55 mPPowers[0] = 1;
56 for (long i = 1; i <= mDimension; i++)
57 mPPowers[i] = mPPowers[i - 1] * static_cast<ulong>(mCharacteristic);
58
60}
61
63{
64 fq_zech_ctx_clear(mContext);
65 fq_nmod_ctx_clear(mBigContext);
66 mPrimitiveElement = nullptr;
69
70 if (mGeneratorComputed) fq_zech_clear(&mCachedGenerator, mContext);
71}
72
74 std::vector<long>& poly) const
75{
76 fq_nmod_t f;
77
78 fq_nmod_init(f, mBigContext);
79 fq_zech_get_fq_nmod(f, &a, mContext);
80 long deg = nmod_poly_degree(f);
81 poly.resize(deg + 1);
82 for (long i = deg; i >= 0; i--) poly[i] = nmod_poly_get_coeff_ui(f, i);
83 fq_nmod_clear(f, mBigContext);
84}
85
88 const std::vector<long>& poly) const
89{
90 fq_nmod_t f;
91
92 fq_nmod_init(f, mBigContext);
93
94#if 0
95 printf("input = ");
96 for (long i=0; i<poly.size(); i++)
97 printf("%ld ", poly[i]);
98 printf("\n");
99#endif
100 for (long i = poly.size() - 1; i >= 0; i--)
101 {
102 long a = poly[i];
103 if (a == 0) continue;
104 if (a < 0) a += characteristic();
105 nmod_poly_set_coeff_ui(f, i, a);
106 }
107#if 0
108 printf(" result before reduction = ");
109 fq_nmod_print_pretty(f, mBigContext);
110 printf("\n");
111#endif
112 fq_nmod_reduce(f, mBigContext);
113#if 0
114 printf(" result = ");
115 fq_nmod_print_pretty(f, mBigContext);
116 printf("\n");
117#endif
118 fq_zech_set_fq_nmod(&result, f, mContext);
119#if 0
120 printf(" zech result = %lu", result.value);
121 printf("\n");
122#endif
123 fq_nmod_clear(f, mBigContext);
124}
125
127{
128 if (not mGeneratorComputed)
129 {
130 fq_zech_init(&mCachedGenerator, mContext);
131 if (mCharacteristic == 2 and mDimension == 1)
132 // This is currently a bug in flint...
134 else
135 fq_zech_gen(&mCachedGenerator, mContext);
136
137 mGeneratorComputed = true;
138 }
139 copy(result_gen, mCachedGenerator);
140}
141
143 const ring_elem f,
144 ElementType& result) const
145{
146 if (&originalRing() != Rf) return false;
147 std::vector<long> poly;
148 RingElement F(Rf, f);
151 return true;
152}
153
155 const ElementType& f) const
156{
157 std::vector<long> poly;
159 result =
161}
162
164 const ElementType& f,
165 ring_elem& result) const
166{
167 // Rg = ZZ/p[x]/F(x) ---> GF(p,n)
168 if (&originalRing() != Rg) return false;
170 return true;
171}
172
174 const ElementType& f,
175 int first_var,
176 ring_elem& result) const
177{
178 // f is represented by: f.value, the power of the generator
179 if (is_zero(f))
180 result = map->get_ring()->zero();
181 else
182 result =
183 map->get_ring()->power(map->elem(first_var), static_cast<int>(f.value));
184}
185
187{
188 o << "GF(" << characteristic() << "^" << dimension() << ",Flint)";
189}
190
192 const ElementType& a,
193 bool p_one,
194 bool p_plus,
195 bool p_parens) const
196{
197 if (is_zero(a))
198 {
199 o << "0";
200 return;
201 }
202 ring_elem b;
203 lift(&originalRing(), a, b);
204 originalRing().elem_text_out(o, b, p_one, p_plus, p_parens);
205}
206
208 const ElementType& g) const
209{
210 if (f.value > g.value) return GT;
211 if (f.value < g.value) return LT;
212 return EQ;
213}
214};
215
216// Local Variables:
217// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
218// indent-tabs-mode: nil
219// End:
M2::ARingGFFlint — small GF(p^k) via FLINT Zech-logarithm tables.
#define FLINT_RAND_INIT(x)
Definition aring.hpp:59
#define FLINT_RAND_CLEAR(x)
Definition aring.hpp:60
void getGenerator(ElementType &result_gen) const
void getSmallIntegerCoefficients(const ElementType &a, std::vector< long > &poly) const
void text_out(buffer &o) const
fq_zech_struct ElementType
void copy(ElementType &result, const ElementType &a) const
bool promote(const Ring *Rf, const ring_elem f, ElementType &result) const
ARingGFFlint(const PolynomialRing &R, const ring_elem a)
void elem_text_out(buffer &o, const ElementType &a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
void eval(const RingMap *map, const ElementType &f, int first_var, ring_elem &result) const
long dimension() const
fq_nmod_ctx_t mBigContext
flint_rand_t mRandomState
bool is_zero(const ElementType &f) const
const RingElement * mPrimitiveElement
fq_zech_ctx_t mContext
const PolynomialRing & originalRing() const
void set_from_long(ElementType &result, long a) const
int compare_elems(const ElementType &f, const ElementType &g) const
void lift_to_original_ring(ring_elem &result, const ElementType &f) const
long characteristic() const
ElementType mCachedGenerator
void fromSmallIntegerCoefficients(ElementType &result, const std::vector< long > &poly) const
const PolynomialRing & mOriginalRing
bool lift(const Ring *Rg, const ElementType &f, ring_elem &result) const
ring_elem fromSmallIntegerCoefficients(const std::vector< long > &coeffs, int var) const
Definition poly.cpp:2249
virtual const PolyRing * getNumeratorRing() const
Definition polyring.hpp:259
Abstract base for the engine's polynomial-ring hierarchy.
Definition polyring.hpp:96
ring_elem zero() const
Definition ring.hpp:359
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const =0
long characteristic() const
Definition ring.hpp:159
virtual ring_elem copy(const ring_elem f) 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.
Definition ring.cpp:109
static RingElement * make_raw(const Ring *R, ring_elem f)
Definition relem.cpp:20
bool getSmallIntegerCoefficients(std::vector< long > &result_coeffs) const
Definition relem.cpp:421
Front-end-visible "ring element" value: an engine ring_elem paired with the Ring* that gives it meani...
Definition relem.hpp:67
xxx xxx xxx
Definition ring.hpp:102
const ring_elem elem(int i) const
Definition ringmap.hpp:114
const Ring * get_ring() const
Definition ringmap.hpp:111
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
unsigned long int ulong
Definition comb.cpp:7
void freemem(void *s)
Definition m2-mem.cpp:103
VALGRIND_MAKE_MEM_DEFINED & result(result)
Definition aring-CC.cpp:3
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
Concrete commutative PolyRing — standard polynomial ring inheriting from PolyRingFlat.
RingElement — tagged (Ring*, ring_elem) pair, the engine's universal element type.
RingMap — engine representation of a ring homomorphism.
const int EQ
Definition style.hpp:40
const int GT
Definition style.hpp:41
const int LT
Definition style.hpp:39