Macaulay2 Engine
Loading...
Searching...
No Matches
aring-CC.hpp
Go to the documentation of this file.
1// Copyright 2012 Michael E. Stillman
2
3#ifndef _aring_CC_hpp_
4#define _aring_CC_hpp_
5
43
44#include "interface/gmp-util.h" // for moveTo_gmpCC
45#include "interface/random.h" // for randomDouble
46
47#include "aring.hpp"
48#include "buffer.hpp"
49#include "ringelem.hpp"
50#include "ringmap.hpp"
51
52#include "aring-RR.hpp"
53
54class RingMap;
55
56namespace M2 {
57
71class ARingCC : public SimpleARing<ARingCC>
72{
73 // approximate real numbers, implemented as doubles.
74
75 private:
76 const ARingRR mRR; // reals with the same precision
77 public:
78 static const RingID ringID = ring_CC;
79
84
86 // ring informational
87 size_t characteristic() const { return 0; }
88 unsigned long get_precision() const { return 53; }
89 void text_out(buffer& o) const;
90
91 const RealRingType& real_ring() const { return mRR; }
92 unsigned int computeHashValue(const elem& a) const
93 {
94 double v = 12347. * a.re + 865800. * a.im;
95 return static_cast<unsigned int>(v);
96 }
97
99 // ElementType informational ////
101
102 bool is_unit(const ElementType& f) const { return !is_zero(f); }
103 bool is_zero(const ElementType& f) const
104 {
105 return f.re == 0.0 and f.im == 0.0;
106 }
107
108 bool is_equal(const ElementType& f, const ElementType& g) const
109 {
110 return f.re == g.re and f.im == g.im;
111 }
112
113 int compare_elems(const ElementType& f, const ElementType& g) const
114 {
115 double cmp_re = f.re - g.re;
116 if (cmp_re < 0) return -1;
117 if (cmp_re > 0) return 1;
118 double cmp_im = f.im - g.im;
119 if (cmp_im < 0) return -1;
120 if (cmp_im > 0) return 1;
121 return 0;
122 }
123
125 // to/from ringelem ////////
127 // These simply repackage the element as either a ringelem or an
128 // 'ElementType'.
129 // No reinitialization is done.
130 // Do not take the same element and store it as two different ring_elem's!!
132 {
134 *res = a;
135 result = ring_elem(res);
136 }
137
139 {
140 result = * a.get_cc_doubles();
141 }
142
144 {
145 return *a.get_cc_doubles();
146 }
147
148 // 'init', 'init_set' functions
149
151 {
152 result.re = 0.0;
153 result.im = 0.0;
154 }
155
156 void init_set(ElementType& result, const ElementType& a) const { result = a; }
157 void set(ElementType& result, const ElementType& a) const { result = a; }
159 {
160 result.re = 0.0;
161 result.im = 0.0;
162 }
163
165 {
166 (void) result;
167 // do nothing
168 }
169
170 void copy(ElementType& result, const ElementType& a) const { set(result, a); }
171 void set_from_long(ElementType& result, long a) const
172 {
173 result.re = static_cast<double>(a);
174 result.im = 0.0;
175 }
176
177 void set_var(ElementType& result, int v) const
178 {
179 (void) v;
181 }
182
183 void set_from_mpz(ElementType& result, mpz_srcptr a) const
184 {
185 result.re = mpz_get_d(a);
186 result.im = 0.0;
187 }
188
189 bool set_from_mpq(ElementType& result, mpq_srcptr a) const
190 {
191 result.re = mpq_get_d(a);
192 result.im = 0.0;
193 return true;
194 }
195
197 {
198 result.re = mpfr_get_d(a, MPFR_RNDN);
199 result.im = 0.0;
200 return true;
201 }
203 {
204 result.re = mpfr_get_d(re, MPFR_RNDN);
205 result.im = mpfr_get_d(im, MPFR_RNDN);
206 return true;
207 }
209 {
210 result.re = mpfr_get_d(a->re, MPFR_RNDN);
211 result.im = mpfr_get_d(a->im, MPFR_RNDN);
212 return true;
213 }
214 bool set_from_double(ElementType& result, double a) const
215 {
216 result.re = a;
217 result.im = 0;
218 return true;
219 }
220 bool set_from_complex_double(ElementType& result, double re, double im) const
221 {
222 result.re = re;
223 result.im = im;
224 return true;
225 }
226
227 // arithmetic
228 void negate(ElementType& result, const ElementType& a) const
229 {
230 result.re = -a.re;
231 result.im = -a.im;
232 }
233
234 void invert(ElementType& res, const ElementType& a) const
235 // we silently assume that a != 0. If it is, result is set to a^0, i.e. 1
236 {
238 if (fabs(a.re) >= fabs(a.im))
239 {
240 double p = a.im / a.re;
241 double denom = a.re + p * a.im;
242 result.re = 1.0 / denom;
243 result.im = -p / denom;
244 }
245 else
246 {
247 double p = a.re / a.im;
248 double denom = a.im + p * a.re;
249 result.re = p / denom;
250 result.im = -1.0 / denom;
251 }
252 set(res, result);
253 }
254
255 void add(ElementType& res, const ElementType& a, const ElementType& b) const
256 {
258 result.re = a.re + b.re;
259 result.im = a.im + b.im;
260 set(res, result);
261 }
262
264 const RealElementType& a,
265 const ElementType& b) const
266 {
268 result.re += a * b.re;
269 result.im += a * b.im;
270 set(res, result);
271 }
272
274 const ElementType& a,
275 const ElementType& b) const
276 {
278 result.re += a.re * b.re - a.im * b.im;
279 result.im += a.im * b.re + a.re * b.im;
280 set(res, result);
281 }
282
284 const ElementType& a,
285 const ElementType& b) const
286 {
288 result.re = a.re - b.re;
289 result.im = a.im - b.im;
290 set(res, result);
291 }
292
294 const ElementType& a,
295 const ElementType& b) const
296 {
297 // result -= a*b
298 ElementType ab;
299 mult(ab, a, b);
300 subtract(result, result, ab);
301 }
302
303 void mult(ElementType& res,
304 const ElementType& a,
305 const RealElementType& b) const
306 {
307 res.re = a.re * b;
308 res.im = a.im * b;
309 }
310
311 void mult(ElementType& res, const ElementType& a, const ElementType& b) const
312 {
313 RealElementType tmp;
314 tmp = a.re * b.re - a.im * b.im;
315 res.im = a.re * b.im + a.im * b.re;
316 res.re = tmp;
317 }
318
320 const ElementType& a,
321 const RealElementType& b) const
322 {
323 res.re = a.re / b;
324 res.im = a.im / b;
325 }
326
328 const ElementType& a,
329 const ElementType& b) const
330 {
331 RealElementType p, denom; // double
332
334 if (fabs(b.re) >= fabs(b.im))
335 {
336 p = b.im / b.re;
337 denom = b.re + p * b.im;
338 result.re = (a.re + p * a.im) / denom;
339 result.im = (a.im - p * a.re) / denom;
340 }
341 else
342 {
343 p = b.re / b.im;
344 denom = b.im + p * b.re;
345 result.re = (a.im + p * a.re) / denom;
346 result.im = (p * a.im - a.re) / denom;
347 }
348 set(res, result);
349 }
350
352 {
353 result = a.re * a.re + a.im * a.im;
354 }
355
357 {
358 result = sqrt(a.re * a.re + a.im * a.im);
359 }
360
361 void power(ElementType& result, const ElementType& a, int n) const
362 {
363 ElementType curr_pow;
364 init(curr_pow);
366 if (n == 0)
367 {
368 }
369 else if (n < 0)
370 {
371 n = -n;
372 invert(curr_pow, a);
373 }
374 else
375 {
376 set(curr_pow, a);
377 }
378 while (n > 0)
379 {
380 if (n % 2)
381 {
382 mult(result, result, curr_pow);
383 }
384 n = n / 2;
385 mult(curr_pow, curr_pow, curr_pow);
386 }
387 clear(curr_pow);
388 }
389
390 void power_mpz(ElementType& result, const ElementType& a, mpz_srcptr n) const
391 {
392 std::pair<bool, int> n1 = RingZZ::get_si(n);
393 if (n1.first)
394 power(result, a, n1.second);
395 else
396 throw exc::engine_error("exponent too large");
397 }
398
399 void swap(ElementType& a, ElementType& b) const { std::swap(a, b); }
400 void elem_text_out(buffer& o,
401 const ElementType& a,
402 bool p_one = true,
403 bool p_plus = false,
404 bool p_parens = false) const;
405
406 void syzygy(const ElementType& a,
407 const ElementType& b,
408 ElementType& x,
409 ElementType& y) const // remove?
410 // returns x,y s.y. x*a + y*b == 0.
411 // if possible, x is set to 1.
412 // no need to consider the case a==0 or b==0.
413 {
414 // TODO: remove this?
415 set_var(x, 0); // set x=1
416 if (!is_zero(b))
417 {
418 set(y, a);
419 negate(y, y);
420 divide(y, y, b);
421 }
422 }
423
424 void random(ElementType& result) const // redo?
425 {
426 result.re = randomDouble();
427 result.im = randomDouble();
428 }
429
430 void eval(const RingMap* map,
431 ElementType& f,
432 int first_var,
433 ring_elem& result) const
434 {
435 (void) first_var;
436 if (!map->get_ring()->from_complex_double(f.re, f.im, result))
437 {
438 result = map->get_ring()->from_long(0);
439 if (not error()) ERROR("cannot coerce CC value to ring type");
440 }
441 }
442
444 {
446 result->re = getmemstructtype(mpfr_ptr);
447 result->im = getmemstructtype(mpfr_ptr);
448 mpfr_init2(result->re, get_precision());
449 mpfr_init2(result->im, get_precision());
450 mpfr_set_d(result->re, a.re, MPFR_RNDN);
451 mpfr_set_d(result->im, a.im, MPFR_RNDN);
452 return moveTo_gmpCC(result);
453 }
454
455 void set_from_doubles(ElementType& result, double re, double im) const
456 {
457 result.re = re;
458 result.im = im;
459 }
460
461 void zeroize_tiny(gmp_RR epsilon, ElementType& a) const
462 {
463 if (mpfr_cmp_d(epsilon, fabs(a.re)) > 0) a.re = 0.0;
464 if (mpfr_cmp_d(epsilon, fabs(a.im)) > 0) a.im = 0.0;
465 }
466
467 void increase_norm(gmp_RRmutable norm, const ElementType& a) const
468 {
469 double d;
470 abs(d, a);
471 if (mpfr_cmp_d(norm, d) < 0) mpfr_set_d(norm, d, MPFR_RNDN);
472 }
473};
474
475}; // end namespace M2
476
477#endif
478
479// Local Variables:
480// compile-command: "make -C $M2BUILDDIR/Macaulay2/e "
481// indent-tabs-mode: nil
482// End:
M2::ARingRR — machine-precision real numbers (IEEE 754 double).
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_long(ElementType &result, long a) const
Definition aring-CC.hpp:171
void set_zero(ElementType &result) const
Definition aring-CC.hpp:158
void text_out(buffer &o) const
Definition aring-CC.cpp:5
void abs_squared(ARingRR::ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:351
void swap(ElementType &a, ElementType &b) const
Definition aring-CC.hpp:399
RealRingType::ElementType RealElementType
Definition aring-CC.hpp:83
void subtract_multiple(ElementType &result, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:293
void negate(ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:228
void invert(ElementType &res, const ElementType &a) const
Definition aring-CC.hpp:234
cc_doubles_struct elem
Definition aring-CC.hpp:80
void set(ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:157
void zeroize_tiny(gmp_RR epsilon, ElementType &a) const
Definition aring-CC.hpp:461
unsigned int computeHashValue(const elem &a) const
Definition aring-CC.hpp:92
void power(ElementType &result, const ElementType &a, int n) const
Definition aring-CC.hpp:361
ARingRR RealRingType
Definition aring-CC.hpp:82
bool is_unit(const ElementType &f) const
Definition aring-CC.hpp:102
bool set_from_mpq(ElementType &result, mpq_srcptr a) const
Definition aring-CC.hpp:189
void power_mpz(ElementType &result, const ElementType &a, mpz_srcptr n) const
Definition aring-CC.hpp:390
void mult(ElementType &res, const ElementType &a, const RealElementType &b) const
Definition aring-CC.hpp:303
void copy(ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:170
elem ElementType
Definition aring-CC.hpp:81
void add(ElementType &res, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:255
void set_from_doubles(ElementType &result, double re, double im) const
Definition aring-CC.hpp:455
bool is_zero(const ElementType &f) const
Definition aring-CC.hpp:103
void to_ring_elem(ring_elem &result, const ElementType &a) const
Definition aring-CC.hpp:131
bool is_equal(const ElementType &f, const ElementType &g) const
Definition aring-CC.hpp:108
const ElementType & from_ring_elem_const(const ring_elem &a) const
Definition aring-CC.hpp:143
gmp_CC toBigComplex(const ElementType &a) const
Definition aring-CC.hpp:443
const ARingRR mRR
Definition aring-CC.hpp:76
int compare_elems(const ElementType &f, const ElementType &g) const
Definition aring-CC.hpp:113
void abs(ARingRR::ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:356
void init(ElementType &result) const
Definition aring-CC.hpp:150
void mult(ElementType &res, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:311
static const RingID ringID
Definition aring-CC.hpp:78
void syzygy(const ElementType &a, const ElementType &b, ElementType &x, ElementType &y) const
Definition aring-CC.hpp:406
const RealRingType & real_ring() const
Definition aring-CC.hpp:91
void random(ElementType &result) const
Definition aring-CC.hpp:424
void subtract(ElementType &res, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:283
void init_set(ElementType &result, const ElementType &a) const
Definition aring-CC.hpp:156
void addMultipleTo(ElementType &res, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:273
void set_var(ElementType &result, int v) const
Definition aring-CC.hpp:177
bool set_from_BigReals(ElementType &result, gmp_RR re, gmp_RR im) const
Definition aring-CC.hpp:202
void set_from_mpz(ElementType &result, mpz_srcptr a) const
Definition aring-CC.hpp:183
unsigned long get_precision() const
Definition aring-CC.hpp:88
void divide(ElementType &res, const ElementType &a, const RealElementType &b) const
Definition aring-CC.hpp:319
size_t characteristic() const
Definition aring-CC.hpp:87
bool set_from_BigComplex(ElementType &result, gmp_CC a) const
Definition aring-CC.hpp:208
void increase_norm(gmp_RRmutable norm, const ElementType &a) const
Definition aring-CC.hpp:467
bool set_from_double(ElementType &result, double a) const
Definition aring-CC.hpp:214
bool set_from_complex_double(ElementType &result, double re, double im) const
Definition aring-CC.hpp:220
void elem_text_out(buffer &o, const ElementType &a, bool p_one=true, bool p_plus=false, bool p_parens=false) const
Definition aring-CC.cpp:6
void divide(ElementType &res, const ElementType &a, const ElementType &b) const
Definition aring-CC.hpp:327
bool set_from_BigReal(ElementType &result, gmp_RR a) const
Definition aring-CC.hpp:196
void from_ring_elem(ElementType &result, const ring_elem &a) const
Definition aring-CC.hpp:138
static void clear(ElementType &result)
Definition aring-CC.hpp:164
void addMultipleTo(ElementType &res, const RealElementType &a, const ElementType &b) const
Definition aring-CC.hpp:263
void eval(const RingMap *map, ElementType &f, int first_var, ring_elem &result) const
Definition aring-CC.hpp:430
elem ElementType
Definition aring-RR.hpp:68
aring-style adapter for double-precision real numbers.
Definition aring-RR.hpp:62
A base class for simple ARings.
Definition aring.hpp:147
virtual ring_elem from_long(long n) const =0
virtual bool from_complex_double(double re, double im, ring_elem &result) const
Definition ring.cpp:276
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 std::pair< bool, int > get_si(mpz_srcptr n)
Definition ZZ.cpp:46
int error()
Definition error.c:48
gmp_CC moveTo_gmpCC(gmp_CCmutable _z)
Definition gmp-util.h:166
Inline helpers that move GMP / MPFR / MPFI limbs from malloc-managed storage into the bdwgc heap.
int p
RingID
Definition aring.hpp:75
@ ring_CC
Definition aring.hpp:88
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
struct gmp_CC_struct * gmp_CC
Definition m2-types.h:156
mpfr_ptr gmp_RRmutable
Definition m2-types.h:150
struct gmp_CCmutable_struct * gmp_CCmutable
Definition m2-types.h:159
Definition aring-CC.cpp:3
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition mpreal.h:3244
volatile int x
#define abs(x)
Definition polyroots.cpp:51
double randomDouble()
Definition random.cpp:248
Engine-boundary C API for the engine's PRNG and rational / real / complex random draws.
cc_doubles_struct * cc_doubles_ptr
Definition ringelem.hpp:69
ring_elem — the universal value type carried by every Ring* in the engine.
RingMap — engine representation of a ring homomorphism.
cc_doubles_srcptr get_cc_doubles() const
Definition ringelem.hpp:135