Macaulay2 Engine
Loading...
Searching...
No Matches
aring-qq-gmp.hpp
Go to the documentation of this file.
1// Copyright 2013 Michael E. Stillman
2
3#ifndef _aring_QQ_gmp_hpp_
4#define _aring_QQ_gmp_hpp_
5
40
41#include "interface/gmp-util.h" // for mpz_reallocate_limbs
42#include "interface/random.h" // for rawSetRandomQQ
43
44#include "aring.hpp"
45#include "buffer.hpp"
46#include "ringelem.hpp"
47#include <iosfwd>
48#include "exceptions.hpp"
49
50// promote needs ring.hpp. After moving promote out, remove it here!
51#include "ring.hpp"
52
53namespace M2 {
59
60class ARingQQGMP : public SimpleARing<ARingQQGMP>
61{
62 public:
63 static const RingID ringID = ring_QQ;
64
65 typedef __mpq_struct ElementType;
67 typedef std::vector<elem> ElementContainerType;
68
69 ARingQQGMP();
71
72 public:
73 // ring informational
74 size_t characteristic() const { return 0; }
75 size_t cardinality() const { return static_cast<size_t>(-1); }
76 unsigned int computeHashValue(const ElementType& a) const
77 {
78 unsigned long numhash = mpz_get_ui(mpq_numref(&a));
79 unsigned long denhash = mpz_get_ui(mpq_denref(&a));
80 return static_cast<unsigned int>(13253 * numhash + 7647 * denhash);
81 }
82
86
87 bool is_pm_one(const ElementType& f) const
88 {
89 return (mpz_cmp_si(mpq_denref(&f), 1) == 0 and
90 (mpz_cmp_si(mpq_numref(&f), 1) == 0 or
91 mpz_cmp_si(mpq_numref(&f), -1) == 0));
92 }
93 bool is_unit(const ElementType& f) const { return not is_zero(f); }
94 bool is_zero(const ElementType& f) const { return mpq_sgn(&f) == 0; }
96
99
100 bool is_equal(const ElementType& f, const ElementType& g) const
101 {
102 return mpq_equal(&f, &g);
103 }
104 int compare_elems(const ElementType& f, const ElementType& g) const
105 {
106 int cmp = mpq_cmp(&f, &g);
107 if (cmp > 0) return 1;
108 if (cmp < 0) return -1;
109 return 0;
110 }
111
112
115
116 void init_set(ElementType& result, const ElementType& a) const
117 {
118 mpq_init(&result);
119 mpq_set(&result, &a);
120 }
121
122 void init(ElementType& result) const { mpq_init(&result); }
123 static void clear(ElementType& result) { mpq_clear(&result); }
124 void set(ElementType& result, const ElementType& a) const
125 {
126 mpq_set(&result, &a);
127 }
128
129 void set_zero(ElementType& result) const { mpq_set_si(&result, 0, 1); }
130 void set_from_long(ElementType& result, long a) const
131 {
132 mpq_set_si(&result, a, 1);
133 }
134
135 void set_from_mpz(ElementType& result, mpz_srcptr a) const
136 {
137 mpz_set(mpq_numref(&result), a);
138 mpz_set_ui(mpq_denref(&result), 1);
139 }
140
141 bool lift_to_mpz(mpz_ptr result, const ElementType& a) const
142 {
143 if (mpz_cmp_si(mpq_denref(&a), 1) == 0)
144 {
145 mpz_set(result, mpq_numref(&a));
146 return true;
147 }
148 return false;
149 }
150
151 bool set_from_mpq(ElementType& result, mpq_srcptr a) const
152 {
153 mpq_set(&result, a);
154 return true;
155 }
156
158 {
159 (void) result;
160 (void) a;
161 return false;
162 }
163
164 void set_var(ElementType& result, int v) const
165 {
166 (void) v;
167 mpq_set_si(&result, 1, 1);
168 }
169
171
174 void negate(ElementType& result, const ElementType& a) const
175 {
176 mpq_neg(&result, &a);
177 }
178
179 bool invert(ElementType& result, const ElementType& a) const
180 {
181 if (is_unit(a))
182 {
183 mpq_inv(&result, &a);
184 return true;
185 }
187 return false;
188 }
189
191 const ElementType& a,
192 const ElementType& b) const
193 {
194 mpq_add(&result, &a, &b);
195 }
196
198 const ElementType& a,
199 const ElementType& b) const
200 {
201 mpq_sub(&result, &a, &b);
202 }
203
205 const ElementType& a,
206 const ElementType& b) const
207 {
208 mpq_t tmp;
209 mpq_init(tmp);
210 mpq_mul(tmp, &a, &b);
211 mpq_sub(&result, &result, tmp);
212 mpq_clear(tmp);
213 }
214
216 const ElementType& a,
217 const ElementType& b) const
218 {
219 mpq_mul(&result, &a, &b);
220 }
221
224 const ElementType& a,
225 const ElementType& b) const
226 {
227 if (is_zero(b)) throw exc::division_by_zero_error();
228 mpq_div(&result, &a, &b);
229 }
230
231 void power(ElementType& result, const ElementType& a, long n) const
232 {
233 bool n_is_negative = false;
234 if (n < 0)
235 {
236 if (is_zero(a)) throw exc::division_by_zero_error();
237 n_is_negative = true;
238 n = -n;
239 }
240 mpz_pow_ui(mpq_numref(&result), mpq_numref(&a), n);
241 mpz_pow_ui(mpq_denref(&result), mpq_denref(&a), n);
242 if (n_is_negative)
243 mpq_inv(&result, &result);
244 }
245
247 const ElementType& a,
248 mpz_srcptr n) const
249 {
250 std::pair<bool, int> n1 = RingZZ::get_si(n);
251 if (n1.first)
252 power(result, a, n1.second);
253 else
254 throw exc::engine_error("exponent too large");
255 }
256
257 void syzygy(const ElementType& a,
258 const ElementType& b,
259 ElementType& x,
260 ElementType& y) const;
262
265 void swap(ElementType& a, ElementType& b) const { mpq_swap(&a, &b); }
267 {
268 rawSetRandomQQ(&result, nullptr);
269#if 0
270 mpz_urandomb(mpq_numref(&result), mRandomState, mMaxHeight);
271 mpz_urandomb(mpq_denref(&result), mRandomState, mMaxHeight);
272 mpz_add_ui(mpq_numref(&result), mpq_numref(&result), 1);
273 mpz_add_ui(mpq_denref(&result), mpq_denref(&result), 1);
274 mpq_canonicalize(&result);
275#endif
276 }
277
278
282 void text_out(buffer& o) const { o << "QQGMP"; }
283 void elem_text_out(buffer& o,
284 const ElementType& a,
285 bool p_one = true,
286 bool p_plus = false,
287 bool p_parens = false) const;
289
292
294 {
295 mpq_ptr b = getmemstructtype(mpq_ptr);
296 mpq_init(b);
297 mpq_set(b, &a);
298 mpz_reallocate_limbs(mpq_numref(b));
299 mpz_reallocate_limbs(mpq_denref(b));
300 result = ring_elem(b);
301 }
302
304 {
305 // Currently, until QQ becomes a ConcreteRing, elements of QQ are gmp_QQ
306 // (aka mpq_t)
307 mpq_set(&result, a.get_mpq());
308 }
309
311 {
312 return *a.get_mpq();
313 }
314
316
317#if 0
318 bool promote(const Ring *Rf, const ring_elem f, ElementType& result) const {
319 printf("ARingQQGMP::calling promote\n");
320 // Rf = ZZ ---> QQ
321 if (Rf->is_ZZ())
322 {
324 return true;
325 }
326 return false;
327 }
328
329 bool lift(const Ring *Rg, const ElementType& f, ring_elem &result) const {
330 return false;
331 }
332#endif
333
334 // map : this --> target(map)
335 // primelem --> map->elem(first_var)
336 // evaluate map(f)
337 void eval(const RingMap* map,
338 const ElementType& f,
339 int first_var,
340 ring_elem& result) const;
341
342 private:
343 mutable gmp_randstate_t mRandomState;
344 long int mMaxHeight;
345};
346};
347
348#endif
349
350// Local Variables:
351// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
352// indent-tabs-mode: nil
353// End:
Shared base of the aring framework (namespace M2) that unifies the engine's coefficient rings.
Append-only GC-backed byte buffer used throughout the engine for text output.
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void negate(ElementType &result, const ElementType &a) const
bool invert(ElementType &result, const ElementType &a) const
size_t cardinality() const
size_t characteristic() const
const ElementType & from_ring_elem_const(const ring_elem &a) const
void from_ring_elem(ElementType &result, const ring_elem &a) const
bool is_unit(const ElementType &f) const
bool set_from_BigReal(ElementType &result, gmp_RR a) const
static void clear(ElementType &result)
void swap(ElementType &a, ElementType &b) const
std::vector< elem > ElementContainerType
void set_zero(ElementType &result) const
bool lift_to_mpz(mpz_ptr result, const ElementType &a) const
bool is_equal(const ElementType &f, const ElementType &g) const
void to_ring_elem(ring_elem &result, const ElementType &a) const
void syzygy(const ElementType &a, const ElementType &b, ElementType &x, ElementType &y) const
bool set_from_mpq(ElementType &result, mpq_srcptr a) const
void set(ElementType &result, const ElementType &a) const
void subtract(ElementType &result, const ElementType &a, const ElementType &b) const
void random(ElementType &result) const
void subtract_multiple(ElementType &result, const ElementType &a, const ElementType &b) const
void set_from_long(ElementType &result, long a) const
void divide(ElementType &result, const ElementType &a, const ElementType &b) const
test doc
bool is_pm_one(const ElementType &f) const
gmp_randstate_t mRandomState
void power(ElementType &result, const ElementType &a, long n) const
void add(ElementType &result, const ElementType &a, const ElementType &b) const
void set_var(ElementType &result, int v) const
int compare_elems(const ElementType &f, const ElementType &g) const
static const RingID ringID
void elem_text_out(buffer &o, const ElementType &a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
unsigned int computeHashValue(const ElementType &a) const
void eval(const RingMap *map, const ElementType &f, int first_var, ring_elem &result) const
void mult(ElementType &result, const ElementType &a, const ElementType &b) const
bool is_zero(const ElementType &f) const
void text_out(buffer &o) const
__mpq_struct ElementType
void power_mpz(ElementType &result, const ElementType &a, mpz_srcptr n) const
void init_set(ElementType &result, const ElementType &a) const
void init(ElementType &result) const
ElementType elem
A base class for simple ARings.
Definition aring.hpp:147
virtual bool is_ZZ() const
Definition ring.hpp:171
xxx xxx xxx
Definition ring.hpp:102
static std::pair< bool, int > get_si(mpz_srcptr n)
Definition ZZ.cpp:46
namespace exc — internal C++ exception types and the TRY / CATCH macro pair.
void mpz_reallocate_limbs(mpz_ptr _z)
Definition gmp-util.h:46
Inline helpers that move GMP / MPFR / MPFI limbs from malloc-managed storage into the bdwgc heap.
RingID
Definition aring.hpp:75
@ ring_QQ
Definition aring.hpp:79
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemstructtype(S)
Definition m2-mem.h:143
mpfr_srcptr gmp_RR
Definition m2-types.h:148
Definition aring-CC.cpp:3
volatile int x
void rawSetRandomQQ(mpq_ptr result, gmp_ZZ height)
Definition random.cpp:170
Engine-boundary C API for the engine's PRNG and rational / real / complex random draws.
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.
mpq_srcptr get_mpq() const
Definition ringelem.hpp:129
mpz_srcptr get_mpz() const
Definition ringelem.hpp:127