Macaulay2 Engine
Loading...
Searching...
No Matches
aring-RRi.hpp
Go to the documentation of this file.
1// Copyright 2012 Michael E. Stillman
2
3#ifndef _aring_RRi_hpp_
4#define _aring_RRi_hpp_
5
39
40#include <iostream>
41
42#include <mpfi.h>
43#include "interface/random.h"
44#include "aring.hpp"
45#include "buffer.hpp"
46#include "ringelem.hpp"
47#include "ringmap.hpp"
48#include "aring-RRR.hpp"
49
50class RRi;
51class RingMap;
52
53namespace M2 {
68class ARingRRi : public SimpleARing<ARingRRi>
69{
70 // Higher precision real intervals
71
72 public:
73 static const RingID ringID = ring_RRi;
74
75 typedef __mpfi_struct elem;
77
78 ARingRRi(unsigned long precision) : mPrecision(precision) {}
79 // ring informational
80 size_t characteristic() const { return 0; }
81 unsigned long get_precision() const { return mPrecision; }
82 void text_out(buffer &o) const;
83
84 unsigned int computeHashValue(const elem &a) const
85 {
86 double d = 12347. * mpfr_get_d(&(a.left), MPFR_RNDN) + 865800. * mpfr_get_d(&(a.right), MPFR_RNDN);
87 return static_cast<unsigned int>(d);
88 }
89
91 // ElementType informational ////
93
94 bool is_unit(const ElementType &f) const { return !is_zero(f); }
95 bool is_zero(const ElementType &f) const { return mpfr_cmp_si(&(f.left), 0) == 0 and mpfr_cmp_si(&(f.right), 0) == 0; }
96 bool is_equal(const ElementType &f, const ElementType &g) const
97 {
98 return mpfr_cmp(&(f.left), &(g.left)) == 0 and mpfr_cmp(&(f.right), &(g.right)) == 0;
99 }
100
101 int compare_elems(const ElementType &f, const ElementType &g) const
102 {
103 int cmp = mpfi_cmp(&f, &g);
104 if (cmp < 0) return -1;
105 if (cmp > 0) return 1;
106 return 0;
107 }
108
109 bool is_empty(const ElementType &f) const { return mpfi_is_empty(&f)>0; }
110
111 bool is_member(const ARingRRR::ElementType &a, const ElementType &f) const { return mpfi_cmp_fr(&f,&a) == 0; }
112 bool is_member(mpq_srcptr a, const ElementType &f) const { return mpfi_cmp_q(&f,a) == 0; }
113 bool is_member(mpz_srcptr a, const ElementType &f) const { return mpfi_cmp_z(&f,a) == 0; }
114 bool is_member(long a, const ElementType &f) const { return mpfi_cmp_si(&f,a) == 0; }
115 bool is_member(double a, const ElementType &f) const { return mpfi_cmp_d(&f,a) == 0; }
116
117 bool is_subset(const ElementType &g, const ElementType &f) const { return mpfi_cmp_fr(&f,&(g.left)) == 0 and mpfi_cmp_fr(&f,&(g.right)) == 0; }
118
120 // to/from ringelem ////////
122 // These simply repackage the element as either a ringelem or an
123 // 'ElementType'.
124 // No reinitialization is done.
125 // Do not take the same element and store it as two different ring_elem's!!
127 {
128 mpfi_ptr res = getmemstructtype(mpfi_ptr);
129 mpfi_init2(res,mPrecision);
130 mpfi_set(res, &a);
132 }
133
135 {
136 mpfi_set(&result, a.get_mpfi());
137 }
138
140 {
141 return *a.get_mpfi();
142 }
143 // 'init', 'init_set' functions
144
145 void init(ElementType &result) const {
146 mpfi_init2(&result, mPrecision); }
147 void init_set(ElementType &result, const ElementType &a) const
148 {
149 init(result);
150 mpfi_set(&result, &a);
151 }
152
153 void set(ElementType &result, const ElementType &a) const
154 {
155 mpfi_set(&result, &a);
156 }
157
159 {
160 mpfi_set_si(&result, 0);
161 }
162
163 static void clear(ElementType &result) { mpfi_clear(&result); }
164 void copy(ElementType &result, const ElementType &a) const
165 {
166 mpfi_set(&result, &a);
167 }
168
169 void set_from_long(ElementType &result, long a) const
170 {
171 mpfi_set_si(&result, a);
172 }
173
174 void set_var(ElementType &result, int v) const
175 {
176 mpfi_set_si(&result, v);
177 }
178
179 void set_from_mpz(ElementType &result, mpz_srcptr a) const
180 {
181 mpfi_set_z(&result, a);
182 }
183
184 bool set_from_mpq(ElementType &result, mpq_srcptr a) const
185 {
186 mpfi_set_q(&result, a);
187 return true;
188 }
189
190 bool set_from_double(ElementType &result, double a) const
191 {
192 mpfi_set_d(&result, a);
193 return true;
194 }
195
197 {
198 mpfi_set_fr(&result, a);
199 return true;
200 }
201
203 {
204 mpfi_set(&result, a);
205 return true;
206 }
207
208 // arithmetic
209 void negate(ElementType &result, const ElementType &a) const
210 {
211 mpfi_mul_si(&result, &a, -1);
212 }
213
214 void invert(ElementType &result, const ElementType &a) const
215 // we silently assume that a != 0. If it is, result is set to a^0, i.e. 1
216 {
217 mpfi_si_div(&result, 1, &a);
218 }
219
221 const ElementType &a,
222 const ElementType &b) const
223 {
224 mpfi_add(&result, &a, &b);
225 }
226
227
229 const ElementType &a,
230 const ElementType &b) const
231 {
232 ElementType ab;
233 init(ab);
234 mult(ab,a,b);
235 add(result,result,ab);
236 }
237
238
240 const ElementType &a,
241 const ElementType &b) const
242 {
243 mpfi_sub(&result, &a, &b);
244 }
245
247 const ElementType &a,
248 const ElementType &b) const
249 {
250 // result -= a*b
251 ElementType ab;
252 init(ab);
253 mult(ab, a, b);
254 subtract(result, result, ab);
255 clear(ab);
256 }
257
259 const ElementType &a,
260 const ElementType &b) const
261 {
262 mpfi_mul(&result, &a, &b);
263 }
264
266 const ElementType &a,
267 const ElementType &b) const
268 {
269 mpfi_div(&result, &a, &b);
270 }
271
272 void power(ElementType &result, const ElementType &a, int n) const
273 {
274 if (n >= 2)
275 {
276 if (n%2 == 0)
277 {
278 ElementType b;
279 init(b);
280 power(b,a,n/2);
281 mult(result,b,b);
282 }
283 else
284 {
285 ElementType b;
286 init(b);
287 power(b,a,n-1);
288 mult(result,a,b);
289 }
290 }
291 else if (n == 1)
292 mpfi_set(&result,&a);
293 else if (n == 0)
294 mpfi_set_si(&result,1);
295 else if (n<0)
296 throw 20;
297 }
298
299 /* Not entirely sure how to deal with this one. */
300 void power_mpz(ElementType &result, const ElementType &a, mpz_srcptr n) const
301 {
302 if (mpz_cmp_si(n,2)>=0)
303 {
304 mpz_t r;
305 mpz_init(r);
306 mpz_fdiv_r_ui(r,n,2);
307
308 ElementType b;
309 init(b);
310
311 mpz_t m;
312 mpz_init(m);
313
314 if (mpz_cmp_si(r,0) == 0)
315 {
316 mpz_cdiv_q_ui(m,n,2);
317
318 power_mpz(b,a,m);
319 mult(result,b,b);
320 }
321 else
322 {
323 mpz_sub_ui(m,n,1);
324
325 power_mpz(b,a,m);
326 mult(result,a,b);
327 }
328 mpz_clear(r);
329 mpz_clear(m);
330 }
331 else if (mpz_cmp_si(n,1)==0)
332 mpfi_set(&result,&a);
333 else if (mpz_cmp_si(n,0)==0)
334 mpfi_set_si(&result,1);
335 else if (mpz_cmp_si(n,0)<0)
336 throw 20;
337 }
338
339 void swap(ElementType &a, ElementType &b) const { mpfi_swap(&a, &b); }
340
341 void midpoint(ARingRRR::ElementType &a, const ElementType &b) const { mpfi_mid(&a,&b); }
342
343 void diameter(ARingRRR::ElementType &a, const ElementType &b) const { mpfi_diam_abs(&a,&b); }
344
345 void left(ARingRRR::ElementType &a, const ElementType &b) const { mpfi_get_left(&a,&b); }
346
347 void right(ARingRRR::ElementType &a, const ElementType &b) const { mpfi_get_right(&a,&b); }
348
349 void elem_text_out(buffer &o,
350 const ElementType &a,
351 bool p_one,
352 bool p_plus,
353 bool p_parens) const;
354
355 void syzygy(const ElementType &a,
356 const ElementType &b,
357 ElementType &x,
358 ElementType &y) const // remove?
359 // returns x,y s.y. x*a + y*b == 0.
360 // if possible, x is set to 1.
361 // no need to consider the case a==0 or b==0.
362 {
363 set_var(x, 0); // set x=1
364 if (!is_zero(b))
365 {
366 set(y, a);
367 negate(y, y);
368 divide(y, y, b);
369 }
370 }
371
372 /* rewrite this (in rand.cpp or just copy over?) */
373 void random(ElementType &result) const // redo?
374 {
376 }
377
378 /* Needs to be redone. */
379 void eval(const RingMap *map,
380 const ElementType &f,
381 int first_var,
382 ring_elem &result) const
383 {
384 (void) first_var;
385 if (!map->get_ring()->from_Interval(&f, result))
386 {
387 result = map->get_ring()->from_long(0);
388 ERROR("cannot coerce RRi value to ring type");
389 }
390 }
391
392/* Not ready */
393 void zeroize_tiny(gmp_RR epsilon, ElementType &a) const
394 {
395 (void) epsilon;
396 (void) a;
397 throw 20;
398 //if (mpfr_cmpabs(&a, epsilon) < 0) set_zero(a);
399 }
400 /* Not ready */
401 void increase_norm(gmp_RRmutable norm, const ElementType &a) const
402 {
403 (void) norm;
404 (void) a;
405 throw 20;
406 /* if (mpfr_cmpabs(&a, norm) > 0)
407 {
408 set(*norm, a);
409 abs(*norm, *norm);
410 }*/
411 }
412
413 void abs(ElementType &result, const ElementType &a) const
414 {
415 mpfi_abs(&result,&a);
416 }
417
419 {
420 abs(result,a);
422 }
423
424 double coerceToDouble(const ElementType &a) const
425 {
426 return mpfi_get_d(&a);
427 }
428
429 private:
430 unsigned long mPrecision;
431};
432
433}; // end namespace M2
434
435#endif
436
437// Local Variables:
438// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
439// indent-tabs-mode: nil
440// End:
M2::ARingRRR — arbitrary-precision real numbers backed by MPFR.
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.
bool is_empty(const ElementType &f) const
unsigned long mPrecision
void from_ring_elem(ElementType &result, const ring_elem &a) const
void init_set(ElementType &result, const ElementType &a) const
void divide(ElementType &result, const ElementType &a, const ElementType &b) const
static void clear(ElementType &result)
void subtract(ElementType &result, const ElementType &a, const ElementType &b) const
bool is_zero(const ElementType &f) const
Definition aring-RRi.hpp:95
size_t characteristic() const
Definition aring-RRi.hpp:80
static const RingID ringID
Definition aring-RRi.hpp:73
void set_var(ElementType &result, int v) const
__mpfi_struct elem
Definition aring-RRi.hpp:75
void left(ARingRRR::ElementType &a, const ElementType &b) const
void zeroize_tiny(gmp_RR epsilon, ElementType &a) const
void copy(ElementType &result, const ElementType &a) const
bool is_member(long a, const ElementType &f) const
void syzygy(const ElementType &a, const ElementType &b, ElementType &x, ElementType &y) const
void swap(ElementType &a, ElementType &b) const
void midpoint(ARingRRR::ElementType &a, const ElementType &b) const
void init(ElementType &result) const
void to_ring_elem(ring_elem &result, const ElementType &a) const
bool is_member(mpz_srcptr a, const ElementType &f) const
void random(ElementType &result) const
void negate(ElementType &result, const ElementType &a) const
void increase_norm(gmp_RRmutable norm, const ElementType &a) const
void set_zero(ElementType &result) const
bool set_from_Interval(ElementType &result, gmp_RRi a) const
const ElementType & from_ring_elem_const(const ring_elem &a) const
void subtract_multiple(ElementType &result, const ElementType &a, const ElementType &b) const
double coerceToDouble(const ElementType &a) const
bool is_subset(const ElementType &g, const ElementType &f) const
void addMultipleTo(ElementType &result, const ElementType &a, const ElementType &b) const
bool is_member(const ARingRRR::ElementType &a, const ElementType &f) const
void set(ElementType &result, const ElementType &a) const
void set_from_long(ElementType &result, long a) const
void add(ElementType &result, const ElementType &a, const ElementType &b) const
unsigned int computeHashValue(const elem &a) const
Definition aring-RRi.hpp:84
bool is_member(mpq_srcptr a, const ElementType &f) const
void set_from_mpz(ElementType &result, mpz_srcptr a) const
void invert(ElementType &result, const ElementType &a) const
void eval(const RingMap *map, const ElementType &f, int first_var, ring_elem &result) const
bool is_equal(const ElementType &f, const ElementType &g) const
Definition aring-RRi.hpp:96
int compare_elems(const ElementType &f, const ElementType &g) const
void power(ElementType &result, const ElementType &a, int n) const
bool is_unit(const ElementType &f) const
Definition aring-RRi.hpp:94
bool is_member(double a, const ElementType &f) const
ARingRRi(unsigned long precision)
Definition aring-RRi.hpp:78
void diameter(ARingRRR::ElementType &a, const ElementType &b) const
void right(ARingRRR::ElementType &a, const ElementType &b) const
void elem_text_out(buffer &o, const ElementType &a, bool p_one, bool p_plus, bool p_parens) const
Definition aring-RRi.cpp:6
unsigned long get_precision() const
Definition aring-RRi.hpp:81
void text_out(buffer &o) const
Definition aring-RRi.cpp:5
bool set_from_mpq(ElementType &result, mpq_srcptr a) const
void abs(ElementType &result, const ElementType &a) const
void mult(ElementType &result, const ElementType &a, const ElementType &b) const
bool set_from_double(ElementType &result, double a) const
void power_mpz(ElementType &result, const ElementType &a, mpz_srcptr n) const
void abs_squared(ElementType &result, const ElementType &a) const
bool set_from_BigReal(ElementType &result, gmp_RR a) const
A base class for simple ARings.
Definition aring.hpp:147
virtual bool from_Interval(gmp_RRi a, ring_elem &result) const
Definition ring.cpp:257
virtual ring_elem from_long(long n) const =0
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
mpfi_srcptr moveTo_gmpRRi(mpfi_ptr _z)
Definition gmp-util.h:159
RingID
Definition aring.hpp:75
@ ring_RRi
Definition aring.hpp:91
const int ERROR
Definition m2-mem.cpp:55
VALGRIND_MAKE_MEM_DEFINED & result(result)
#define getmemstructtype(S)
Definition m2-mem.h:143
mpfr_srcptr gmp_RR
Definition m2-types.h:148
mpfr_ptr gmp_RRmutable
Definition m2-types.h:150
mpfi_srcptr gmp_RRi
Definition m2-types.h:153
Definition aring-CC.cpp:3
volatile int x
#define abs(x)
Definition polyroots.cpp:51
void rawSetRandomRRi(mpfi_ptr result)
Definition random.cpp:258
Engine-boundary C API for the engine's PRNG and rational / real / complex random draws.
ring_elem — the universal value type carried by every Ring* in the engine.
RingMap — engine representation of a ring homomorphism.
mpfi_srcptr get_mpfi() const
Definition ringelem.hpp:131