Developer documentation

GMPXX.hpp
Go to the documentation of this file.
1 #ifndef realroot_ARITHM_GMP_H
2 #define realroot_ARITHM_GMP_H
3 
4 #include <realroot/config.hpp>
6 #include <realroot/Interval.hpp>
7 #include <realroot/sign.hpp>
8 
9 #include <gmpxx.h>
10 
11 
12 #ifdef HAVE_MPFR
13 #include <mpfr.h>
14 #endif
15 namespace mmx {
16 
17 struct GMP
18 {
19  typedef mpz_class integer;
20  typedef mpq_class rational;
21  typedef mpf_class floating;
22  typedef double ieee;
23 
24 };
25 
26 
27 typedef GMP::rational QQ;
28 typedef GMP::integer ZZ;
29 typedef GMP::floating RR;
30 
31 
32 inline long int bit_size(const ZZ& z) {return mpz_sizeinbase(z.get_mpz_t(),2);}
33 
34 namespace meta {
35 
36  template<class C> struct kernelof_;
37  template<> struct kernelof_< GMP::ieee > { typedef GMP T; };
38  template<> struct kernelof_< GMP::rational > { typedef GMP T; };
39  template<> struct kernelof_< GMP::integer > { typedef GMP T; };
40  template<> struct kernelof_< GMP::floating > { typedef GMP T; };
41 
42  template<class C> struct hasgcd_;
43  template<> struct hasgcd_<ZZ> { typedef meta::true_t T; };
44 
45  template<class C> struct structureof_;
46  template<> struct structureof_< GMP::rational > { typedef structure::scalar T; };
47  template<> struct structureof_< GMP::integer > { typedef structure::scalar T; };
48  template<> struct structureof_< GMP::floating > { typedef structure::scalar T; };
49 }
50 
51  inline ZZ gcd(const ZZ & a, const ZZ & b)
52  {
53  mpz_class r;
54  mpz_gcd(r.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());
55  return r;
56  }
57 
58  inline ZZ lcm(const ZZ & a, const ZZ & b) { return (a*b)/gcd(a,b); }
59 
60 
61  inline int sign(const QQ& a) { return sgn(a); }
62  inline int sign(const RR& a) { return sgn(a); }
63 
64  inline QQ Size(const QQ & r) { return abs(r); };
65  inline ZZ Size( const ZZ & z ) { return abs(z); };
66 
67  inline ZZ size( const ZZ & z ) { return abs(z); };
68  inline QQ size(const QQ & r) { return abs(r); };
69 
70 
71  inline int compare(const QQ& a, const QQ& b) { return cmp(a, b); }
72  inline int compare(const RR& a, const RR& b) { return cmp(a, b); }
73 
74  inline bool with_plus_sign(const ZZ & c) { return (c>0);}
75  inline bool with_plus_sign(const QQ & c) { return (c>0);}
76  inline bool with_plus_sign(const RR & c) { return (c>0);}
77 
78 
79  inline double to_double(const QQ& a) { return a.get_d(); }
80  inline double to_double( const ZZ & z ) { return z.get_d(); };
81  inline double to_double(const RR& a) { return a.get_d(); }
82 
83  inline QQ to_FT(const ZZ& a, const ZZ& b = 1)
84  {
85  QQ r(a, b);
86  r.canonicalize();
87  return r;
88  }
89  inline QQ to_FT(const QQ& a, const QQ& b = 1) { return a; }
90 
91  inline double to_XT(const ZZ& a) { return to_double(a); }
92  inline double to_XT(const QQ& a) { return to_double(a); }
93  inline double to_XT(const RR& a) { return to_double(a); }
94 
95  inline ZZ numerator(const QQ& a) { return a.get_num(); }
96  inline ZZ denominator(const QQ& a) { return a.get_den(); }
97 
98  inline ZZ pow(const ZZ& a, unsigned n)
99  {
100  mpz_class r;
101  mpz_pow_ui(r.get_mpz_t(), a.get_mpz_t(), n);
102  return r;
103  }
104  inline ZZ isqrt(const ZZ& a) { return sqrt(a) + 1; }
105  inline RR fracpart(const RR& r) { return r - trunc(r); }
106 
107 
108 //----------------------------------------------------------------------
112 inline void Precision(unsigned long l)
113 {
114  mpf_set_default_prec(l);
115 }
116 
117 //----------------------------------------------------------------------
121 inline void Precision( RR b, unsigned long l)
122 {
123  mpf_set_prec(b.get_mpf_t(),l);
124 
125  }
126 
127 /*
128 template<class X>
129 inline void precision( unsigned nb )
130 {
131  typedef kernelof<X>::T K;
132  K::precision(nb);
133 };
134 */
135 //======================================================================
136 
137 namespace let
138 {
139  inline void assign(QQ & x, char *s) { mpq_set_str(x.get_mpq_t(), s, 10);}
140 
141  inline void assign(ZZ& z, char * s) { mpz_set_str(z.get_mpz_t(), s, 10); }
142  inline void assign(ZZ& z, int n) { mpz_set_si(z.get_mpz_t(),n); }
143  inline void assign(ZZ& z, double d ) { z = (int)d; };
144  inline void assign(ZZ& x, const ZZ& r) { mpz_set(x.get_mpz_t(),r.get_mpz_t()); }
145  inline void assign(int& x, const ZZ& r) { x = mpz_get_si(r.get_mpz_t()); }
146  inline void assign(long int& x, const ZZ& r) { x = mpz_get_si(r.get_mpz_t()); }
147  inline void assign( double & r, const ZZ & z ) { r = z.get_d(); };
148 
149  inline void assign(ZZ& x, const QQ& r) { x= r.get_num(); x/=r.get_den();}
150  inline void assign(QQ& x, const ZZ& r) { mpq_set_z(x.get_mpq_t(), r.get_mpz_t());}
151  inline void assign(QQ & q, double d ) { q = d; };
152  inline void assign(RR & r, double d ) { r = d; };
153  inline void assign(double & d, const QQ & x )
154  {
155 #ifdef HAVE_MPFR
156  mp_rnd_t round=GMP_RNDU;
157  // if(numerics::get_rnd()==numerics::rnd_up())
158  // round=GMP_RNDU;
159 
160  if(numerics::get_rnd()==numerics::rnd_dw())
161  round=GMP_RNDD;
162 
163  mpfr_t r; mpfr_init2(r,53);
164  mpfr_set_q(r, x.get_mpq_t(), round);
165  d = mpfr_get_d(r,round);
166 #else
167  d = x.get_d();
168 #endif
169  }
170 
171  inline void assign(double & r, const RR & z ) { r = z.get_d(); };
172  inline void assign(RR& r, char* s) { mpf_set_str(r.get_mpf_t(),s,10); }
173  inline void assign(RR& x, const RR& r) { mpf_set(x.get_mpf_t(),r.get_mpf_t()); }
174 
175  inline double convert( const QQ & q, meta::As<double> ) { return q.get_d(); };
176  inline double convert( const ZZ & z, meta::As<double> ) { return z.get_d(); };
177  inline double convert( const RR & r, meta::As<double> ) { return r.get_d(); };
178 
179  inline void assign( Interval<double>& a,
180  const QQ & b )
181  {
182  double mn,mx;
183  {
184  numerics::rounding<double> rnd( numerics::rnd_up() );
185  assign(mx,b);
186  }
187  {
188  numerics::rounding<double> rnd( numerics::rnd_dw() );
189  assign(mn,b);
190  }
191 
192  if( mx < mn ) std::swap(mn,mx);
193  QQ MN(mn);
194  QQ MX(mx);
195  new (&a) Interval<double>(mn,mx);
196  };
197  inline void assign( Interval<double>& a,
198  const QQ & u,
199  const QQ & v )
200  {
201  double mn,mx;
202  {
203  numerics::rounding<double> rnd( numerics::rnd_up() );
204  assign(mx,v);
205  }
206  {
207  numerics::rounding<double> rnd( numerics::rnd_dw() );
208  assign(mn,u);
209  }
210  new (&a) Interval<double>(mn,mx);
211  };
212 
213 
214  inline void assign( Interval<QQ>& a,
215  const QQ & u,
216  const QQ & v )
217  {
218  a.lower()=u;
219  a.upper()=v;
220  }
221 }
222 
223 template<class T, class U> struct cast_helper;
224 
225 template<> struct cast_helper<QQ,ZZ> { static inline QQ cv(const ZZ& x) { QQ r;mpq_set_z(r.get_mpq_t(),x.get_mpz_t()); return r; } };
226 
227 template<> struct cast_helper<double,ZZ> { static inline double cv(const ZZ& x) { return x.get_d(); } };
228 template<> struct cast_helper<double,QQ> { static inline double cv(const QQ& x) { double r; let::assign(r,x); return r; } };
229 template<> struct cast_helper<double,RR> { static inline double cv(const RR& x) { return x.get_d(); } };
230 
231 //====================================================================
232 } //namespace mmx
233 #endif
mpz_class integer
Definition: GMPXX.hpp:19
texp::rationalof< C >::T to_FT(const C &a, const C &b)
Definition: contfrac_intervaldata.hpp:93
T pow(const T &a, int i)
Definition: binomials.hpp:12
const C & b
Definition: Interval_glue.hpp:25
void Precision(unsigned long l)
Definition: GMPXX.hpp:112
const T & upper() const
Definition: Interval.hpp:99
QQ Size(const QQ &r)
Definition: GMPXX.hpp:64
GMP T
Definition: GMPXX.hpp:37
MP swap(const MP &P, int var_i, int var_j)
Definition: sparse_monomials.hpp:988
bool with_plus_sign(const ZZ &c)
Definition: GMP.hpp:62
Definition: GMPXX.hpp:45
double gcd(const double &, const double &)
Definition: GMP.hpp:90
structure::scalar T
Definition: GMPXX.hpp:47
GMP::floating RR
Definition: GMP.hpp:39
static double cv(const QQ &x)
Definition: GMPXX.hpp:228
GMP T
Definition: GMPXX.hpp:40
Definition: GMPXX.hpp:42
Definition: texp_structureof.hpp:13
static QQ cv(const ZZ &x)
Definition: GMPXX.hpp:225
int get_rnd()
Definition: rounding_mode.hpp:22
meta::true_t T
Definition: GMPXX.hpp:43
double to_double(const RR &a)
Definition: GMP.hpp:66
int compare(const QQ &a, const QQ &b)
Definition: GMPXX.hpp:71
double convert(const QQ &q, meta::As< double >)
Definition: GMPXX.hpp:175
GMP T
Definition: GMPXX.hpp:38
Definition: rounding_mode.hpp:71
const T & lower() const
Definition: Interval.hpp:98
GMP::rational QQ
Definition: GMP.hpp:37
RR fracpart(const RR &r)
Definition: GMPXX.hpp:105
Definition: GMPXX.hpp:36
double ieee
Definition: GMPXX.hpp:22
mpf_class floating
Definition: GMPXX.hpp:21
double to_XT(const ZZ &a)
Definition: GMP.hpp:69
ZZ numerator(const QQ &a)
Definition: GMPXX.hpp:95
long int bit_size(const ZZ &z)
Definition: GMPXX.hpp:32
ZZ isqrt(const ZZ &a)
Definition: GMPXX.hpp:104
structure::scalar T
Definition: GMPXX.hpp:46
int sgn(FT a)
Sign of a.
Definition: solver_mv_monomial_tests.hpp:416
static double cv(const RR &x)
Definition: GMPXX.hpp:229
ZZ size(const ZZ &z)
Definition: GMPXX.hpp:67
void abs(Interval< C, r > &x, const Interval< C, r > &a)
Definition: Interval_fcts.hpp:185
scalar< T > sqrt(const scalar< T > &b)
Definition: scalar.hpp:501
ZZ denominator(const QQ &a)
Definition: GMPXX.hpp:96
const C & c
Definition: Interval_glue.hpp:45
mpq_class rational
Definition: GMPXX.hpp:20
int sign(const QQ &a)
Definition: GMP.hpp:60
GMP T
Definition: GMPXX.hpp:39
void assign(A &a, const B &b)
Generic definition of the assignement function.
Definition: assign.hpp:97
structure::scalar T
Definition: GMPXX.hpp:48
Definition: array.hpp:12
Definition: scalar.hpp:24
Numerical kernel based on gmp.
Definition: GMP.hpp:26
GMP::integer ZZ
Definition: GMP.hpp:38
Definition: GMPXX.hpp:223
ZZ lcm(const ZZ &a, const ZZ &b)
Definition: GMPXX.hpp:58
static double cv(const ZZ &x)
Definition: GMPXX.hpp:227
Home