Macaulay2 Engine
Loading...
Searching...
No Matches
coeffrings.hpp
Go to the documentation of this file.
1// Copyright 2005 Michael E. Stillman
2
3#ifndef _coeffrings_hpp_
4#define _coeffrings_hpp_
5
42
43class Z_mod;
44#include "aring.hpp"
45#include "ringelem.hpp"
46#include "ZZ.hpp"
47
66class CoefficientRingZZp : public M2::SimpleARing<CoefficientRingZZp>
67{
68 int p;
69 int p1; // p-1
71 int zero;
72 int *log_table; // 0..p-1
73 int *exp_table; // 0..p-1
74
75 static inline int modulus_add(int a, int b, int p)
76 {
77 int t = a + b;
78 return (t < p ? t : t - p);
79 }
80
81 static inline int modulus_sub(int a, int b, int p)
82 {
83 int t = a - b;
84 return (t < 0 ? t + p : t);
85 }
86
87 public:
89 typedef int elem;
91
92 typedef std::vector<elem> ElementContainerType;
93
94 CoefficientRingZZp(int p0, int *log, int *exps)
95 : p(p0), p1(p - 1), zero(p - 1), log_table(log), exp_table(exps)
96 {
97 if (p == 2)
98 minus_one = 0;
99 else
100 minus_one = (p - 1) / 2;
101
102
103#if 0
104 fprintf(stderr, "char %d\n", p);
105 fprintf(stderr, "exp: ");
106 for (int i=0; i<p; i++)
107 fprintf(stderr, "%d ", exp_table[i]);
108 fprintf(stderr, "\nlog: ");
109 for (int i=0; i<p; i++)
110 fprintf(stderr, "%d ", log_table[i]);
111 fprintf(stderr, "\n");
112#endif
113 }
114
115 void set_from_long(elem &result, long a) const
116 {
117 a = a % p;
118 if (a < 0) a += p;
119 result = log_table[a];
120 }
121
122 void set_from_mpz(elem &result, mpz_t a) const
123 {
124 mpz_t tmp;
125 mpz_init_set_si(tmp, p); // Convert int p to mpz_t
126 mpz_mod(a, a, tmp); // a = a mod p (always non-negative)
127 mpz_clear(tmp);
128 result = log_table[mpz_get_si(a)];
129 }
130
131 long coerceToLongInteger(const elem &f) const
132 {
133 int n = exp_table[f];
134 if (n > p / 2) n -= p;
135 return n;
136 }
137
138 int to_int(int f) const { return exp_table[f]; }
139 void init(elem &result) const { (void) result; }
140 static void clear(elem &result) { (void) result; }
141 void init_set(elem &result, elem a) const { result = a; }
142 void set_zero(elem &result) const { result = zero; }
143 void set(elem &result, elem a) const { result = a; }
144 bool is_zero(elem result) const { return result == zero; }
145 bool is_equal(elem a, elem b) const { return a == b; }
146 void invert(elem &result, elem a) const
147 {
148 if (a == 0)
149 result = 0; // this is the case a == ONE
150 else
151 result = p - 1 - a;
152 }
153
154 void add(elem &result, elem a, elem b) const
155 {
156 if (a == zero)
157 result = b;
158 else if (b == zero)
159 result = a;
160 else
161 {
162 int n = modulus_add(exp_table[a], exp_table[b], p);
163 result = log_table[n];
164 }
165 }
166
167 void negate(elem &result, elem a) const
168 {
170 }
171
172 void subtract(elem &result, elem a, elem b) const
173 {
174 if (b == zero)
175 result = a;
176 else if (a == zero)
178 else
179 {
180 int n = modulus_sub(exp_table[a], exp_table[b], p);
181 result = log_table[n];
182 }
183 }
184
186 {
187 // we assume: a, b are NONZERO!!
188 // result -= a*b
189 elem ab = modulus_add(a, b, p1);
190 subtract(result, result, ab);
191 return;
192 // if (result==zero)
193 // result = ab;
194 // else
195 // {
196 // int n = modulus_sub(exp_table[result], exp_table[ab], p);
197 // result = log_table[n];
198 // }
199 }
200
201 void mult(elem &result, elem a, elem b) const
202 {
203 if (a == zero || b == zero)
204 result = zero;
205 else
206 result = modulus_add(a, b, p1);
207 }
208
209 void divide(elem &result, elem a, elem b) const
210 {
211 if (a == zero || b == zero)
212 result = zero;
213 else
214 result = modulus_sub(a, b, p1);
215 }
216
217 void to_ring_elem(ring_elem &result, const elem a) const
218 {
219 result = ring_elem(a);
220 }
221
222 void from_ring_elem(elem &result, const ring_elem &a) const
223 {
224 result = a.get_int();
225 }
226
227 void swap(elem &a, elem &b) const
228 {
229 elem tmp = a;
230 a = b;
231 b = tmp;
232 }
233
234 void elem_text_out(buffer &o,
235 ElementType a,
236 bool p_one = true,
237 bool p_plus = false,
238 bool p_parens = false) const;
239};
240
258{
259 const Ring *R;
260
261 public:
265 typedef VECTOR(elem) ElementContainerType;
266
277 class Element : public M2::ElementImpl<ElementType>, public our_new_delete
278 {
279 public:
280 explicit Element(const CoefficientRingR &ring) { ring.init(mValue); }
282 {
283 ring.init_set(mValue, value);
284 }
285 };
286
299 {
301 public:
302 ElementArray(const CoefficientRingR &ring, size_t size)
303 : mData(newarray(ElementType, size))
304 {
305 for (size_t i = 0; i < size; i++) ring.init(mData[i]);
306 }
308 ElementType &operator[](size_t idx) { return mData[idx]; }
309 const ElementType &operator[](size_t idx) const { return mData[idx]; }
310 ElementType *data() { return mData; }
311 const ElementType *data() const { return mData; }
312 };
313
314 CoefficientRingR(const Ring *R0) : R(R0) {}
315 void init_set(elem &result, elem a) const { result = a; }
316 void init(elem &result) const { result = R->zero(); }
317 void clear(elem &result) const { (void) result; }
318
319 void set_zero(elem &result) const { result = R->zero(); }
320 void set(elem &result, elem a) const { result = a; }
321 void set_from_long(elem &result, long a) const { result = R->from_long(a); }
322 void set_from_mpz(elem &result, mpz_t a) const { result = R->from_int(a); }
323 bool is_zero(elem result) const { return R->is_zero(result); }
324 bool is_equal(elem a, elem b) const { return R->is_equal(a, b); }
325 bool is_unit(elem f) const { return R->is_unit(f); }
326 void invert(elem &result, elem a) const { result = R->invert(a); }
328 {
329 // result -= a*b
330 elem tmp = R->mult(a,b);
331 result = R->subtract(result,tmp);
332 }
333
334 void add(elem &result, elem a, elem b) const { result = R->add(a, b); }
335 void negate(elem &result, elem a) const { result = R->negate(a); }
336 void subtract(elem &result, elem a, elem b) const
337 {
338 result = R->subtract(a, b);
339 }
340
341 void mult(elem &result, elem a, elem b) const { result = R->mult(a, b); }
342 void divide(elem &result, elem a, elem b) const { result = R->divide(a, b); }
343 void to_ring_elem(ring_elem &result, const elem &a) const { result = a; }
344 void from_ring_elem(elem &result, const ring_elem &a) const { result = a; }
345 // do not make the return type here a reference, otherwise
346 // dangling references become very easy to make
347 elem from_ring_elem_const(const ring_elem &a) const { return a; }
348 void swap(elem &a, elem &b) const
349 {
350 elem tmp = a;
351 a = b;
352 b = tmp;
353 }
354
355 void elem_text_out(buffer &o,
356 ElementType a,
357 bool p_one = true,
358 bool p_plus = false,
359 bool p_parens = false) const;
360
361 void text_out(buffer &o) const { o << "CoefficientRingR"; }
362};
363
364#endif
365
366// Local Variables:
367// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
368// indent-tabs-mode: nil
369// End:
Legacy RingZZ — a Ring-derived integer ring backed by GMP mpz_t.
Shared base of the aring framework (namespace M2) that unifies the engine's coefficient rings.
Element(const CoefficientRingR &ring, const ElementType &value)
Element(const CoefficientRingR &ring)
const ElementType & operator[](size_t idx) const
const ElementType * data() const
ElementType & operator[](size_t idx)
ElementArray(const CoefficientRingR &ring, size_t size)
void to_ring_elem(ring_elem &result, const elem &a) const
void init_set(elem &result, elem a) const
void elem_text_out(buffer &o, ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
void from_ring_elem(elem &result, const ring_elem &a) const
void subtract_multiple(elem &result, elem a, elem b) const
void clear(elem &result) const
const Ring * R
void set_zero(elem &result) const
elem from_ring_elem_const(const ring_elem &a) const
void set_from_mpz(elem &result, mpz_t a) const
bool is_unit(elem f) const
CoefficientRingR(const Ring *R0)
void negate(elem &result, elem a) const
void subtract(elem &result, elem a, elem b) const
void divide(elem &result, elem a, elem b) const
void set(elem &result, elem a) const
void set_from_long(elem &result, long a) const
void add(elem &result, elem a, elem b) const
bool is_zero(elem result) const
void invert(elem &result, elem a) const
typedef VECTOR(elem) ElementContainerType
void init(elem &result) const
void swap(elem &a, elem &b) const
void text_out(buffer &o) const
void mult(elem &result, elem a, elem b) const
bool is_equal(elem a, elem b) const
std::vector< elem > ElementContainerType
void subtract(elem &result, elem a, elem b) const
CoefficientRingZZp(int p0, int *log, int *exps)
void set_from_long(elem &result, long a) const
void negate(elem &result, elem a) const
static void clear(elem &result)
void to_ring_elem(ring_elem &result, const elem a) const
void divide(elem &result, elem a, elem b) const
void init(elem &result) const
void set_zero(elem &result) const
void swap(elem &a, elem &b) const
void set(elem &result, elem a) const
static int modulus_add(int a, int b, int p)
int to_int(int f) const
void invert(elem &result, elem a) const
void init_set(elem &result, elem a) const
void set_from_mpz(elem &result, mpz_t a) const
bool is_equal(elem a, elem b) const
void subtract_multiple(elem &result, elem a, elem b) const
void elem_text_out(buffer &o, ElementType a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
Definition coeffrings.cpp:3
void add(elem &result, elem a, elem b) const
void mult(elem &result, elem a, elem b) const
void from_ring_elem(elem &result, const ring_elem &a) const
static int modulus_sub(int a, int b, int p)
bool is_zero(elem result) const
long coerceToLongInteger(const elem &f) const
const ElementType & value() const
Definition aring.hpp:132
ElementType mValue
Definition aring.hpp:119
A base class for Element.
Definition aring.hpp:117
A base class for simple ARings.
Definition aring.hpp:147
xxx xxx xxx
Definition ring.hpp:102
Engine-side Z/p ring for small primes (p < 32767), using a discrete-log (Zech) representation.
Definition ZZp.hpp:63
void freemem(void *s)
Definition m2-mem.cpp:103
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define newarray(T, len)
Definition newdelete.hpp:82
ring_elem — the universal value type carried by every Ring* in the engine.
int get_int() const
Definition ringelem.hpp:124