Macaulay2 Engine
Loading...
Searching...
No Matches
aring-qq-flint.hpp
Go to the documentation of this file.
1// Copyright 2013 Michael E. Stillman
2
3#ifndef _aring_QQ_flint_hpp_
4#define _aring_QQ_flint_hpp_
5
38
39#include "interface/gmp-util.h" // for mpz_reallocate_limbs
40
41// The following needs to be included before any flint files are included.
42#include <M2/gc-include.h>
43
44#pragma GCC diagnostic push
45#pragma GCC diagnostic ignored "-Wconversion"
46#include <flint/flint.h> // for fmpq_denref, fmpq_numref, fmpq, flin...
47#include <flint/fmpq.h> // for fmpq_init, fmpq_set, fmpq_set_mpq
48#include <flint/fmpz.h> // for fmpz_get_ui, fmpz_cmp_si, fmpz_is_one
49#pragma GCC diagnostic pop
50
51#include "aring.hpp"
52#include "buffer.hpp"
53#include "ringelem.hpp"
54#include "exceptions.hpp"
55
56// promote needs ring.hpp. After moving promote out, remove it here!
57#include "ring.hpp"
58
59namespace M2 {
65
66class ARingQQFlint : public SimpleARing<ARingQQFlint>
67{
68 public:
69 static const RingID ringID = ring_QQFlint;
70
71 typedef fmpq ElementType;
73
76
77 public:
78 // ring informational
79 size_t characteristic() const { return 0; }
80 size_t cardinality() const { return static_cast<size_t>(-1); }
81 unsigned int computeHashValue(const ElementType& a) const
82 {
83 unsigned long numhash = fmpz_get_ui(fmpq_numref(&a));
84 unsigned long denhash = fmpz_get_ui(fmpq_denref(&a));
85 return static_cast<unsigned int>(13253 * numhash + 7647 * denhash);
86 }
87
91
92 bool is_pm_one(const ElementType& f) const
93 {
94 return fmpq_is_one(&f) or ((fmpz_cmp_si(fmpq_numref(&f), -1) == 0) and
95 fmpz_is_one(fmpq_denref(&f)));
96 }
97 bool is_unit(const ElementType& f) const { return not is_zero(f); }
98 bool is_zero(const ElementType& f) const { return fmpq_is_zero(&f); }
100
103
104 bool is_equal(const ElementType& f, const ElementType& g) const
105 {
106 return fmpq_equal(&f, &g);
107 }
108 int compare_elems(const ElementType& f, const ElementType& g) const
109 {
110 int cmp = fmpq_cmp(&f, &g);
111 if (cmp > 0) return 1;
112 if (cmp < 0) return -1;
113 return 0;
114 }
115
116
119
120 void init_set(ElementType& result, const ElementType& a) const
121 {
122 fmpq_init(&result);
123 fmpq_set(&result, &a);
124 }
125
126 void init(ElementType& result) const { fmpq_init(&result); }
127 static void clear(ElementType& result) { fmpq_clear(&result); }
128 void set(ElementType& result, const ElementType& a) const
129 {
130 fmpq_set(&result, &a);
131 }
132
133 void set_zero(ElementType& result) const { fmpq_zero(&result); }
134 void set_from_long(ElementType& result, long a) const
135 {
136 fmpq_set_si(&result, a, 1);
137 }
138
139 void set_from_mpz(ElementType& result, mpz_srcptr a) const
140 {
141 // printf("ARingQQFlint::calling set_from_mpz\n");
142 fmpz_set_mpz(fmpq_numref(&result), a);
143 fmpz_one(fmpq_denref(&result));
144 }
145
146 bool set_from_mpq(ElementType& result, mpq_srcptr a) const
147 {
148 fmpq_set_mpq(&result, a);
149 return true;
150 }
151
153 {
154 (void) result;
155 (void) a;
156 return false;
157 }
158
159 void set_var(ElementType& result, int v) const
160 {
161 (void) v;
162 fmpq_set_si(&result, 1, 1);
163 }
164
166
169 void negate(ElementType& result, const ElementType& a) const
170 {
171 fmpq_neg(&result, &a);
172 }
173
174 bool invert(ElementType& result, const ElementType& a) const
175 {
176 if (is_unit(a))
177 {
178 fmpq_inv(&result, &a);
179 return true;
180 }
182 return false;
183 }
184
186 const ElementType& a,
187 const ElementType& b) const
188 {
189 fmpq_add(&result, &a, &b);
190 }
191
193 const ElementType& a,
194 const ElementType& b) const
195 {
196 fmpq_sub(&result, &a, &b);
197 }
198
200 const ElementType& a,
201 const ElementType& b) const
202 {
203 fmpq_submul(&result, &a, &b);
204 }
205
207 const ElementType& a,
208 const ElementType& b) const
209 {
210 fmpq_mul(&result, &a, &b);
211 }
212
215 const ElementType& a,
216 const ElementType& b) const
217 {
218 if (is_zero(b)) throw exc::division_by_zero_error();
219 fmpq_div(&result, &a, &b);
220 }
221
222 void power(ElementType& result, const ElementType& a, long n) const
223 {
224 return fmpq_pow_si(&result, &a, n);
225 }
226
228 const ElementType& a,
229 mpz_srcptr n) const
230 {
231 std::pair<bool, int> n1 = RingZZ::get_si(n);
232 if (n1.first)
233 power(result, a, n1.second);
234 else
235 throw exc::engine_error("exponent too large");
236 }
237
238 void syzygy(const ElementType& a,
239 const ElementType& b,
240 ElementType& x,
241 ElementType& y) const;
243
246 void swap(ElementType& a, ElementType& b) const { fmpq_swap(&a, &b); }
248 {
249 fmpq_randtest(&result, mRandomState, mMaxHeight);
250 }
251
252
256 void text_out(buffer& o) const { o << "QQFlint"; }
257 void elem_text_out(buffer& o,
258 const ElementType& a,
259 bool p_one = true,
260 bool p_plus = false,
261 bool p_parens = false) const;
263
266
268 {
269 mpq_ptr b = getmemstructtype(mpq_ptr);
270 mpq_init(b);
271 fmpq_get_mpq(b, &a);
272 mpz_reallocate_limbs(mpq_numref(b));
273 mpz_reallocate_limbs(mpq_denref(b));
274 result = ring_elem(b);
275 }
276
278 {
279 fmpq_set_mpq(&result, a.get_mpq());
280 }
281
287 {
288 mpq_srcptr a1 = a.get_mpq();
289 fmpq result;
290 result.num = PTR_TO_COEFF(mpq_numref(a1));
291 result.den = PTR_TO_COEFF(mpq_denref(a1));
292 return result;
293 }
294
296
297 bool promote(const Ring* Rf, const ring_elem f, ElementType& result) const
298 {
299 // printf("ARingQQFlint::calling promote\n");
300 // Rf = ZZ ---> QQ
301 if (Rf->is_ZZ())
302 {
304 return true;
305 }
306 return false;
307 }
308
309 bool lift(const Ring* Rg, const ElementType& f, ring_elem& result) const
310 {
311 (void) Rg;
312 (void) f;
313 (void) result;
314 return false;
315 }
316
317 // map : this --> target(map)
318 // primelem --> map->elem(first_var)
319 // evaluate map(f)
320 void eval(const RingMap* map,
321 const ElementType& f,
322 int first_var,
323 ring_elem& result) const;
324
325 private:
326 mutable flint_rand_t mRandomState;
327 long int mMaxHeight;
328};
329};
330
331#endif
332
333// Local Variables:
334// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
335// indent-tabs-mode: nil
336// 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 init_set(ElementType &result, const ElementType &a) const
void add(ElementType &result, const ElementType &a, const ElementType &b) const
flint_rand_t mRandomState
void init(ElementType &result) const
bool promote(const Ring *Rf, const ring_elem f, ElementType &result) const
void divide(ElementType &result, const ElementType &a, const ElementType &b) const
test doc
static const RingID ringID
void power_mpz(ElementType &result, const ElementType &a, mpz_srcptr n) const
void mult(ElementType &result, const ElementType &a, const ElementType &b) const
bool is_equal(const ElementType &f, const ElementType &g) const
void from_ring_elem(ElementType &result, const ring_elem &a) const
void eval(const RingMap *map, const ElementType &f, int first_var, ring_elem &result) const
static void clear(ElementType &result)
void elem_text_out(buffer &o, const ElementType &a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
void text_out(buffer &o) const
void swap(ElementType &a, ElementType &b) const
void set_var(ElementType &result, int v) const
void negate(ElementType &result, const ElementType &a) const
bool is_pm_one(const ElementType &f) const
void subtract_multiple(ElementType &result, const ElementType &a, const ElementType &b) const
bool set_from_BigReal(ElementType &result, gmp_RR a) const
unsigned int computeHashValue(const ElementType &a) const
size_t cardinality() const
void power(ElementType &result, const ElementType &a, long n) const
void to_ring_elem(ring_elem &result, const ElementType &a) const
const ElementType from_ring_elem_const(const ring_elem &a) const
returns a read only view into the ring_elem The return value of this function should not be modified,...
void random(ElementType &result) const
bool invert(ElementType &result, const ElementType &a) const
int compare_elems(const ElementType &f, const ElementType &g) const
size_t characteristic() const
void set_from_long(ElementType &result, long a) const
bool lift(const Ring *Rg, const ElementType &f, ring_elem &result) const
void syzygy(const ElementType &a, const ElementType &b, ElementType &x, ElementType &y) const
void set(ElementType &result, const ElementType &a) const
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void subtract(ElementType &result, const ElementType &a, const ElementType &b) const
bool is_zero(const ElementType &f) const
bool set_from_mpq(ElementType &result, mpq_srcptr a) const
void set_zero(ElementType &result) const
bool is_unit(const ElementType &f) const
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
Engine-side ring homomorphism: stores, for each source-ring variable, the target-ring element it maps...
Definition ringmap.hpp:60
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_QQFlint
Definition aring.hpp:80
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
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