Macaulay2 Engine
Loading...
Searching...
No Matches
ZZp.cpp
Go to the documentation of this file.
1// Copyright 1995 Michael E. Stillman
2
3#include "ZZp.hpp"
4#include "text-io.hpp"
5#include "monoid.hpp"
6#include "ringmap.hpp"
7#include "ZZ.hpp"
8#include "gbring.hpp"
9
10#include "aring-zzp.hpp"
11#include "error.h"
12
13extern RingZZ *globalZZ;
14
16{
18 P = p;
19
21 int i, j, q, n;
22
23 if (P == 2)
24 _minus_one = 0;
25 else
26 _minus_one = (P - 1) / 2;
27
28 if (P == 2)
29 _prim_root = 1;
30 else
31 {
32 j = 1;
33 for (i = 2; (i < P && j < P - 1); i++)
34 for (q = i, j = 1; (q != 1 && j < P); q = (q * i) % P, j++)
35 ;
36 _prim_root = i - 1;
37 }
38
39 // cerr << "z_mod_p: creating table for P = " << P << endl;
42 for (i = 0, n = 1; i < P - 1; i++, n = (n * _prim_root) % P)
43 {
44 _log_table[n] = i; // i = log_(base _prim_root)(n)
45 _exp_table[i] = n; // n = (_prim_root)^i
46 }
47 _ZERO = P - 1;
48 _exp_table[_ZERO] = 0;
49 _log_table[0] = _ZERO;
50
51 _P1 = P - 1;
52
53 zeroV = from_long(0);
54 oneV = from_long(1);
56
58 aringZZp = new M2::ARingZZp(P); // WARNING: this uses that the primitive
59 // element is the SAME as computed above!!
60 // Remove this warning once Z_mod is not in existence any longer.
61 return true;
62}
63
65{
66 Z_mod *result = new Z_mod;
67 if (!result->initialize_Z_mod(p)) return nullptr;
68
69 return result;
70}
71
72void Z_mod::text_out(buffer &o) const { o << "ZZ/" << P; }
73int Z_mod::to_int(int f) const
74{
75 int n = _exp_table[f];
76 if (n > P / 2) n -= P;
77 return n;
78}
79
80std::pair<bool, long> Z_mod::coerceToLongInteger(ring_elem a) const
81{
82 return std::pair<bool, long>(true, to_int(a.get_int()));
83}
84
85long Z_mod::discreteLog(const ring_elem &a) const
86{
87 if (a.get_int() == _ZERO) return -1;
88 return a.get_int();
89}
90
91static inline int modulus_add(int a, int b, int p)
92{
93 int t = a + b;
94 return (t < p ? t : t - p);
95}
96
97static inline int modulus_sub(int a, int b, int p)
98{
99 int t = a - b;
100 return (t < 0 ? t + p : t);
101}
102
103inline int Z_mod::int_to_exp(int a) const
104{
105 int n = a % P;
106 return _log_table[(n < 0 ? n + P : n)];
107}
108
109unsigned int Z_mod::computeHashValue(const ring_elem a) const
110{
111 return a.get_int();
112}
113
115 const ring_elem a,
116 bool p_one,
117 bool p_plus,
118 bool p_parens) const
119{
120 (void) p_parens;
121 int n = to_int(a.get_int());
122 if (n < 0)
123 {
124 o << '-';
125 n = -n;
126 }
127 else if (p_plus)
128 o << '+';
129 if (p_one || n != 1) o << n;
130}
131
133{
134 int m = static_cast<int>(n % P);
135 if (m < 0) m += P;
136 m = _log_table[m];
137 return ring_elem(m);
138}
139
140ring_elem Z_mod::from_int(mpz_srcptr n) const
141{
142 // cout << "from_int(";
143 // bignum_text_out(cout, n);
144 // cout << ") = " << endl;
145 mpz_t result;
146 mpz_init(result);
147 mpz_mod_ui(result, n, P);
148 int m = static_cast<int>(mpz_get_si(result));
149 mpz_clear(result);
150 // cout << m << endl;
151 if (m < 0) m += P;
152 m = _log_table[m];
153 return ring_elem(m);
154}
155
156bool Z_mod::from_rational(mpq_srcptr q, ring_elem &result) const
157{
158 ring_elem a = Z_mod::from_int(mpq_numref(q));
159 ring_elem b = Z_mod::from_int(mpq_denref(q));
160 if (b.get_int() == _ZERO) return false;
161 result = Z_mod::divide(a, b);
162 return true;
163}
164
165bool Z_mod::promote(const Ring *Rf, const ring_elem f, ring_elem &result) const
166{
167 // Rf = Z ---> Z/p
168 if (Rf == globalZZ)
169 {
170 result = from_int(f.get_mpz());
171 return true;
172 }
173 return false;
174}
175
176bool Z_mod::lift(const Ring *Rg, const ring_elem f, ring_elem &result) const
177{
178 // Rg = Z ---> Z/p
179 if (Rg == globalZZ)
180 {
181 result = Rg->from_long(to_int(f.get_int()));
182 return true;
183 }
184 return false;
185}
186
187bool Z_mod::is_unit(const ring_elem f) const { return (f.get_int() != _P1); }
188bool Z_mod::is_zero(const ring_elem f) const { return (f.get_int() == _P1); }
189bool Z_mod::is_equal(const ring_elem f, const ring_elem g) const
190{
191 return f.get_int() == g.get_int();
192}
193
194int Z_mod::compare_elems(const ring_elem f, const ring_elem g) const
195{
196 int cmp = f.get_int() - g.get_int();
197 if (cmp < 0) return -1;
198 if (cmp == 0) return 0;
199 return 1;
200}
201
202ring_elem Z_mod::copy(const ring_elem f) const { return f; }
204{
205 // nothing needed to remove.
206}
207
209{
210 if (f != _ZERO) return modulus_add(f, _minus_one, _P1);
211 return _ZERO;
212}
213
214int Z_mod::internal_add(int f, int g) const
215{
216 if (g == _ZERO) return f;
217 if (f == _ZERO) return g;
218 int n = modulus_add(_exp_table[f], _exp_table[g], P);
219 return _log_table[n];
220}
221
222int Z_mod::internal_subtract(int f, int g) const
223{
224 if (g == _ZERO) return f;
225 if (f == _ZERO) return internal_negate(g);
226 int n = modulus_sub(_exp_table[f], _exp_table[g], P);
227 return _log_table[n];
228}
229
231{
232 return ring_elem(internal_negate(f.get_int()));
233}
234
236{
237 return ring_elem(internal_add(f.get_int(), g.get_int()));
238}
239
241{
242 return ring_elem(internal_subtract(f.get_int(), g.get_int()));
243}
244
246{
247 if (f.get_int() == _ZERO || g.get_int() == _ZERO) return ring_elem(_ZERO);
248 return ring_elem(modulus_add(f.get_int(), g.get_int(), _P1));
249}
250
251ring_elem Z_mod::power(const ring_elem f, int n) const
252{
253 if (f.get_int() == _ZERO) {
254 if (n < 0)
256 else if (n == 0)
257 return ring_elem(0); // this is the element one in this ring. (P-1) is the zero element...
258 return ring_elem(_ZERO);
259 }
260 int m = (f.get_int() * n) % _P1;
261 if (m < 0) m += _P1;
262 return ring_elem(m);
263}
264ring_elem Z_mod::power(const ring_elem f, mpz_srcptr n) const
265{
266 if (f.get_int() == _ZERO) {
267 if (mpz_sgn(n)<0) throw exc::division_by_zero_error();
268 else if (mpz_sgn(n) == 0)
269 return ring_elem(0);
270 return ring_elem(_ZERO);
271 }
272 int n1 = RingZZ::mod_ui(n, _P1);
273 int m = (f.get_int() * n1) % _P1;
274 if (m < 0) m += _P1;
275 return ring_elem(m);
276}
277
279{
280 int a = f.get_int();
281 if (a == _ZERO) throw exc::division_by_zero_error();
282 if (a == 0) return 0; // this is the case f == ONE
283 return ring_elem(P - 1 - a);
284}
285
287{
288 if (g.get_int() == _ZERO) throw exc::division_by_zero_error();
289 if (f.get_int() == _ZERO) return ring_elem(_ZERO);
290 int h = modulus_sub(f.get_int(), g.get_int(), _P1);
291 return ring_elem(h);
292}
293
295 const ring_elem b,
296 ring_elem &x,
297 ring_elem &y) const
298{
299 assert(!Z_mod::is_zero(b));
300 x = Z_mod::from_long(1);
301 y = Z_mod::divide(a, b);
303}
304
305ring_elem Z_mod::eval(const RingMap *map, const ring_elem f, int) const
306{
307 int a = to_int(f.get_int());
308 return map->get_ring()->from_long(a);
309}
310
312{
313 int exp = rawRandomInt((int32_t)P);
314 return ring_elem(exp);
315}
316
317// Local Variables:
318// compile-command: "make -C $M2BUILDDIR/Macaulay2/e ZZp.o "
319// indent-tabs-mode: nil
320// End:
static int modulus_add(int a, int b, int p)
Definition GF.cpp:169
static int modulus_sub(int a, int b, int p)
Definition GF.cpp:175
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
static int modulus_add(int a, int b, int p)
Definition ZZp.cpp:91
static int modulus_sub(int a, int b, int p)
Definition ZZp.cpp:97
Legacy Z_mod — a Ring-derived Z/p with log / exp tables.
M2::ARingZZp — portable Z/p for small primes via log / exp tables.
Discrete-log Z/p adapter that represents non-zero residues by their exponent index relative to a gene...
aring-style adapter for Z/p using a discrete-log (Zech) representation: every non-zero residue is its...
Definition aring-zzp.hpp:67
ring_elem minus_oneV
Definition ring.hpp:131
void initialize_ring(long charac, const PolynomialRing *DR=nullptr, const std::vector< int > &heft_vec={})
Definition ring.cpp:30
virtual ring_elem from_long(long n) const =0
ring_elem oneV
Definition ring.hpp:130
bool declare_field()
Definition ring.cpp:69
ring_elem zeroV
Definition ring.hpp:129
Ring()
Definition ring.hpp:136
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
static unsigned int mod_ui(mpz_srcptr n, unsigned int p)
Definition ZZ.cpp:55
Engine-side ring of integers, backed by GMP mpz_ptr elements.
Definition ZZ.hpp:77
virtual ring_elem negate(const ring_elem f) const
Definition ZZp.cpp:230
int P
Definition ZZp.hpp:65
bool initialize_Z_mod(int p)
Definition ZZp.cpp:15
virtual ring_elem mult(const ring_elem f, const ring_elem g) const
Definition ZZp.cpp:245
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 ZZp.cpp:264
virtual bool is_unit(const ring_elem f) const
Definition ZZp.cpp:187
int to_int(int a) const
Definition ZZp.cpp:73
virtual bool from_rational(mpq_srcptr q, ring_elem &result) const
Definition ZZp.cpp:156
virtual ring_elem from_long(long n) const
Definition ZZp.cpp:132
virtual ring_elem invert(const ring_elem f) const
Definition ZZp.cpp:278
virtual void text_out(buffer &o) const
Definition ZZp.cpp:72
int _ZERO
Definition ZZp.hpp:68
virtual void syzygy(const ring_elem a, const ring_elem b, ring_elem &x, ring_elem &y) const
Definition ZZp.cpp:294
virtual void remove(ring_elem &f) const
Definition ZZp.cpp:203
int internal_negate(int f) const
Definition ZZp.cpp:208
int internal_add(int f, int g) const
Definition ZZp.cpp:214
virtual int compare_elems(const ring_elem a, const ring_elem b) const
Definition ZZp.cpp:194
virtual bool is_zero(const ring_elem f) const
Definition ZZp.cpp:188
virtual ring_elem from_int(mpz_srcptr n) const
Definition ZZp.cpp:140
virtual std::pair< bool, long > coerceToLongInteger(ring_elem a) const
Definition ZZp.cpp:80
virtual void elem_text_out(buffer &o, const ring_elem f, bool p_one=true, bool p_plus=false, bool p_parens=false) const
Definition ZZp.cpp:114
virtual unsigned int computeHashValue(const ring_elem a) const
Definition ZZp.cpp:109
virtual ring_elem eval(const RingMap *map, const ring_elem f, int first_var) const
Definition ZZp.cpp:305
M2::ARingZZp * aringZZp
Definition ZZp.hpp:78
int _prim_root
Definition ZZp.hpp:70
static Z_mod * create(int p)
Definition ZZp.cpp:64
virtual ring_elem divide(const ring_elem f, const ring_elem g) const
Definition ZZp.cpp:286
long discreteLog(const ring_elem &a) const
Definition ZZp.cpp:85
virtual bool is_equal(const ring_elem f, const ring_elem g) const
Definition ZZp.cpp:189
virtual bool lift(const Ring *R, const ring_elem f, ring_elem &result) const
Definition ZZp.cpp:176
Z_mod()
Definition ZZp.hpp:83
virtual ring_elem copy(const ring_elem f) const
Definition ZZp.cpp:202
int internal_subtract(int f, int g) const
Definition ZZp.cpp:222
virtual ring_elem add(const ring_elem f, const ring_elem g) const
Definition ZZp.cpp:235
int * _exp_table
Definition ZZp.hpp:72
virtual ring_elem subtract(const ring_elem f, const ring_elem g) const
Definition ZZp.cpp:240
int _P1
Definition ZZp.hpp:67
virtual bool promote(const Ring *R, const ring_elem f, ring_elem &result) const
Definition ZZp.cpp:165
virtual ring_elem random() const
Definition ZZp.cpp:311
int int_to_exp(int a) const
Definition ZZp.cpp:103
int _minus_one
Definition ZZp.hpp:71
int * _log_table
Definition ZZp.hpp:73
CoefficientRingZZp * coeffR
Definition ZZp.hpp:77
Engine error-reporting primitives: ERROR, INTERNAL_ERROR, error, error_message.
RingZZ * globalZZ
Definition relem.cpp:13
GBRing and gbvector — the GB-tuned polynomial-ring view used by classical Buchberger code.
int p
VALGRIND_MAKE_MEM_DEFINED & result(result)
Monoid — variable count, naming, grading, and monomial order of a polynomial ring.
#define newarray_atomic(T, len)
Definition newdelete.hpp:91
volatile int x
int32_t rawRandomInt(int32_t max)
Definition random.cpp:44
RingMap — engine representation of a ring homomorphism.
Text-formatting helpers layered on buffer: bignum print, line wrapping, M2_gbTrace-gated emit.
mpz_srcptr get_mpz() const
Definition ringelem.hpp:127
int get_int() const
Definition ringelem.hpp:124