perturbation based calculations
[maximus:emndl.git] / mp_real.h
1 #ifndef MP_REAL_H
2 #define MP_REAL_H 1
3
4 #include <algorithm>
5 #include <cmath>
6 #include <qd/dd_real.h>
7 #include <qd/qd_real.h>
8 #include <mpfr.h>
9 #define MPFR_RNDN GMP_RNDN
10
11 using namespace std;
12
13 class mp_real;
14 inline mp_real operator-(mp_real const &x, double const &y);
15
16 class mp_real {
17 public:
18   mpfr_t m;
19   mp_real() {
20     mpfr_init2(m, 53);
21     mpfr_set_d(m, 0, MPFR_RNDN);
22   }
23   mp_real(const double &s) {
24     mpfr_init2(m, 53);
25     mpfr_set_d(m, s, MPFR_RNDN);
26   }
27   mp_real(const int32_t &s) {
28     mpfr_init2(m, 53);
29     mpfr_set_si(m, s, MPFR_RNDN);
30   }
31   mp_real(const mp_real &s) {
32     mpfr_init2(m, mpfr_get_prec(s.m));
33     mpfr_set(m, s.m, MPFR_RNDN);
34   }
35   mp_real(mpfr_prec_t p) {
36     mpfr_init2(m, p);
37   }
38   mp_real(mpfr_t s, mpfr_prec_t p) {
39     mpfr_init2(m, p);
40     mpfr_set(m, s, MPFR_RNDN);
41   }
42   mp_real(const char *s, mpfr_prec_t p) {
43     mpfr_init2(m, p);
44     mpfr_set_str(m, s, 10, MPFR_RNDN);
45   }
46   mp_real(double s, mpfr_prec_t p) {
47     mpfr_init2(m, p);
48     mpfr_set_d(m, s, MPFR_RNDN);
49   }
50   mp_real(const mp_real &s, mpfr_prec_t p) {
51     mpfr_init2(m, p);
52     mpfr_set(m, s.m, MPFR_RNDN);
53   }
54   mp_real(dd_real s) {
55     mp_real a(s.x[0], 108);
56     mp_real b(s.x[1], 108);
57     mpfr_init2(m, 108);
58     mpfr_add(m, a.m, b.m, MPFR_RNDN);
59   }
60   mp_real(qd_real s) {
61     mp_real a(s[0], 216);
62     mp_real b(s[1], 216);
63     mp_real c(s[2], 216);
64     mp_real d(s[3], 216);
65     mpfr_init2(m, 216);
66     mpfr_add(m, a.m, b.m, MPFR_RNDN);
67     mpfr_add(m,   m, c.m, MPFR_RNDN);
68     mpfr_add(m,   m, d.m, MPFR_RNDN);
69   }
70
71   ~mp_real() {
72     mpfr_clear(m);
73   }
74   operator float() const {
75     return mpfr_get_d(m, MPFR_RNDN);
76   }
77   operator double() const {
78     return mpfr_get_d(m, MPFR_RNDN);
79   }
80   operator dd_real() const {
81     double  a = *this;
82     mp_real n = *this - a;
83     double  b = n;
84     return  dd_real(a, b);
85   }
86   operator qd_real() const {
87     double  a = *this;
88     mp_real n = *this - a;
89     double  b = n;
90     mp_real o = n - b;
91     double  c = o;
92     mp_real p = o - c;
93     double  d = p;
94     return  qd_real(a, b, c, d);
95   }
96 #define maxprec(x, y) max(mpfr_get_prec(x.m), mpfr_get_prec(y.m))
97   inline mp_real& operator=(mp_real const &y) {
98     mpfr_set_prec(m, maxprec((*this), y));
99     mpfr_set(m, y.m, MPFR_RNDN);
100     return *this;
101   }
102 };
103
104 inline bool operator<(mp_real const &x, mp_real const &y) {
105   return mpfr_less_p(x.m, y.m);
106 }
107
108 inline mp_real operator+(mp_real const &x, mp_real const &y) {
109   mp_real r(maxprec(x, y));
110   mpfr_add(r.m, x.m, y.m, MPFR_RNDN);
111   return r;
112 }
113
114 inline mp_real operator+(mp_real const &x, double const &y) {
115   mp_real r(max(mpfr_get_prec(x.m), mpfr_prec_t(53)));
116   mpfr_add_d(r.m, x.m, y, MPFR_RNDN);
117   return r;
118 }
119
120 inline mp_real operator-(mp_real const &x, mp_real const &y) {
121   mp_real r(maxprec(x, y));
122   mpfr_sub(r.m, x.m, y.m, MPFR_RNDN);
123   return r;
124 }
125
126 inline mp_real operator-(mp_real const &x, double const &y) {
127   mp_real r(max(mpfr_get_prec(x.m), mpfr_prec_t(53)));
128   mpfr_sub_d(r.m, x.m, y, MPFR_RNDN);
129   return r;
130 }
131
132 inline mp_real operator*(mp_real const &x, mp_real const &y) {
133   mp_real r(maxprec(x, y));
134   mpfr_mul(r.m, x.m, y.m, MPFR_RNDN);
135   return r;
136 }
137
138 inline mp_real operator*(double const &x, mp_real const &y) {
139   mp_real r(max(mpfr_prec_t(53), mpfr_get_prec(y.m)));
140   mpfr_mul_d(r.m, y.m, x, MPFR_RNDN);
141   return r;
142 }
143
144 inline mp_real operator*(mp_real const &x, double const &y) {
145   mp_real r(max(mpfr_get_prec(x.m), mpfr_prec_t(53)));
146   mpfr_mul_d(r.m, x.m, y, MPFR_RNDN);
147   return r;
148 }
149
150 inline mp_real operator/(mp_real const &x, mp_real const &y) {
151   mp_real r(maxprec(x, y));
152   mpfr_div(r.m, x.m, y.m, MPFR_RNDN);
153   return r;
154 }
155
156 inline mp_real sqr(mp_real const &x) {
157   mp_real r(mpfr_get_prec(x.m));
158   mpfr_sqr(r.m, x.m, MPFR_RNDN);
159   return r;
160 }
161
162 inline mp_real sqrt(mp_real const &x) {
163   mp_real r(mpfr_get_prec(x.m));
164   mpfr_sqrt(r.m, x.m, MPFR_RNDN);
165   return r;
166 }
167
168 inline mp_real log(mp_real const &x) {
169   mp_real r(mpfr_get_prec(x.m));
170   mpfr_log(r.m, x.m, MPFR_RNDN);
171   return r;
172 }
173
174 inline mp_real atan2(mp_real const &y, mp_real const &x) {
175   mp_real r(maxprec(x, y));
176   mpfr_atan2(r.m, y.m, x.m, MPFR_RNDN);
177   return r;
178 }
179
180 inline mp_real pow(mp_real const &y, mp_real const &x) {
181   mp_real r(maxprec(x, y));
182   mpfr_pow(r.m, y.m, x.m, MPFR_RNDN);
183   return r;
184 }
185
186 inline float to_float(mp_real const &x) {
187   return mpfr_get_d(x.m, MPFR_RNDN);
188 }
189
190 #undef maxprec
191
192 #endif