Loading...
Searching...
No Matches
real_mpfr.h
1
6#ifndef SYMENGINE_REAL_MPFR_H
7#define SYMENGINE_REAL_MPFR_H
8
9#include <symengine/complex_double.h>
10#include <symengine/symengine_exception.h>
11
12#ifdef HAVE_SYMENGINE_MPFR
13#include <mpfr.h>
14
15namespace SymEngine
16{
17
18class mpfr_class
19{
20private:
21 mpfr_t mp;
22
23public:
24 mpfr_ptr get_mpfr_t()
25 {
26 return mp;
27 }
28 mpfr_srcptr get_mpfr_t() const
29 {
30 return mp;
31 }
32 explicit mpfr_class(mpfr_srcptr m)
33 {
34 mpfr_init2(mp, mpfr_get_prec(m));
35 mpfr_set(mp, m, MPFR_RNDN);
36 }
37 explicit mpfr_class(mpfr_prec_t prec = 53)
38 {
39 mpfr_init2(mp, prec);
40 }
41 mpfr_class(std::string s, mpfr_prec_t prec = 53, unsigned base = 10)
42 {
43 mpfr_init2(mp, prec);
44 mpfr_set_str(mp, s.c_str(), base, MPFR_RNDN);
45 }
46 mpfr_class(const mpfr_class &other)
47 {
48 mpfr_init2(mp, mpfr_get_prec(other.get_mpfr_t()));
49 mpfr_set(mp, other.get_mpfr_t(), MPFR_RNDN);
50 }
51 mpfr_class(mpfr_class &&other)
52 {
53 mp->_mpfr_d = nullptr;
54 mpfr_swap(mp, other.get_mpfr_t());
55 }
56 mpfr_class &operator=(const mpfr_class &other)
57 {
58 mpfr_set_prec(mp, mpfr_get_prec(other.get_mpfr_t()));
59 mpfr_set(mp, other.get_mpfr_t(), MPFR_RNDN);
60 return *this;
61 }
62 mpfr_class &operator=(mpfr_class &&other)
63 {
64 mpfr_swap(mp, other.get_mpfr_t());
65 return *this;
66 }
67 ~mpfr_class()
68 {
69 if (mp->_mpfr_d != nullptr) {
70 mpfr_clear(mp);
71 }
72 }
73 mpfr_prec_t get_prec() const
74 {
75 return mpfr_get_prec(mp);
76 }
77};
78
79void hash_combine_impl(hash_t &, mpfr_srcptr);
80
81RCP<const Number> number(mpfr_ptr x);
82
84class RealMPFR : public Number
85{
86public:
87 mpfr_class i;
88
89public:
90 IMPLEMENT_TYPEID(SYMENGINE_REAL_MPFR)
92 RealMPFR(mpfr_class i);
93 inline const mpfr_class &as_mpfr() const
94 {
95 return i;
96 }
97 inline mpfr_prec_t get_prec() const
98 {
99 return mpfr_get_prec(i.get_mpfr_t());
100 }
102 virtual hash_t __hash__() const;
107 virtual bool __eq__(const Basic &o) const;
108 virtual int compare(const Basic &o) const;
110 inline virtual bool is_positive() const
111 {
112 return mpfr_cmp_si(i.get_mpfr_t(), 0) > 0;
113 }
115 inline virtual bool is_negative() const
116 {
117 return mpfr_cmp_si(i.get_mpfr_t(), 0) < 0;
118 }
120 inline virtual bool is_exact() const
121 {
122 return false;
123 }
125 virtual Evaluate &get_eval() const;
126
128 virtual bool is_zero() const
129 {
130 return mpfr_cmp_si(i.get_mpfr_t(), 0) == 0;
131 }
133 // A mpfr_t is not exactly equal to `1`
134 virtual bool is_one() const
135 {
136 return false;
137 }
139 // A mpfr_t is not exactly equal to `-1`
140 virtual bool is_minus_one() const
141 {
142 return false;
143 }
145 // False is returned because an 'mpfr' cannot have an imaginary part
146 virtual bool is_complex() const
147 {
148 return false;
149 }
150
154 RCP<const Number> addreal(const Integer &other) const;
155 RCP<const Number> addreal(const Rational &other) const;
156 RCP<const Number> addreal(const Complex &other) const;
157 RCP<const Number> addreal(const RealDouble &other) const;
158 RCP<const Number> addreal(const ComplexDouble &other) const;
159 RCP<const Number> addreal(const RealMPFR &other) const;
160
162 virtual RCP<const Number> add(const Number &other) const
163 {
164 if (is_a<Rational>(other)) {
165 return addreal(down_cast<const Rational &>(other));
166 } else if (is_a<Integer>(other)) {
167 return addreal(down_cast<const Integer &>(other));
168 } else if (is_a<Complex>(other)) {
169 return addreal(down_cast<const Complex &>(other));
170 } else if (is_a<RealDouble>(other)) {
171 return addreal(down_cast<const RealDouble &>(other));
172 } else if (is_a<ComplexDouble>(other)) {
173 return addreal(down_cast<const ComplexDouble &>(other));
174 } else if (is_a<RealMPFR>(other)) {
175 return addreal(down_cast<const RealMPFR &>(other));
176 } else {
177 return other.add(*this);
178 }
179 }
180
181 RCP<const Number> subreal(const Integer &other) const;
182 RCP<const Number> subreal(const Rational &other) const;
183 RCP<const Number> subreal(const Complex &other) const;
184 RCP<const Number> subreal(const RealDouble &other) const;
185 RCP<const Number> subreal(const ComplexDouble &other) const;
186 RCP<const Number> subreal(const RealMPFR &other) const;
187
189 virtual RCP<const Number> sub(const Number &other) const
190 {
191 if (is_a<Rational>(other)) {
192 return subreal(down_cast<const Rational &>(other));
193 } else if (is_a<Integer>(other)) {
194 return subreal(down_cast<const Integer &>(other));
195 } else if (is_a<Complex>(other)) {
196 return subreal(down_cast<const Complex &>(other));
197 } else if (is_a<RealDouble>(other)) {
198 return subreal(down_cast<const RealDouble &>(other));
199 } else if (is_a<ComplexDouble>(other)) {
200 return subreal(down_cast<const ComplexDouble &>(other));
201 } else if (is_a<RealMPFR>(other)) {
202 return subreal(down_cast<const RealMPFR &>(other));
203 } else {
204 return other.rsub(*this);
205 }
206 }
207
208 RCP<const Number> rsubreal(const Integer &other) const;
209 RCP<const Number> rsubreal(const Rational &other) const;
210 RCP<const Number> rsubreal(const Complex &other) const;
211 RCP<const Number> rsubreal(const RealDouble &other) const;
212 RCP<const Number> rsubreal(const ComplexDouble &other) const;
213
215 virtual RCP<const Number> rsub(const Number &other) const
216 {
217 if (is_a<Rational>(other)) {
218 return rsubreal(down_cast<const Rational &>(other));
219 } else if (is_a<Integer>(other)) {
220 return rsubreal(down_cast<const Integer &>(other));
221 } else if (is_a<Complex>(other)) {
222 return rsubreal(down_cast<const Complex &>(other));
223 } else if (is_a<RealDouble>(other)) {
224 return rsubreal(down_cast<const RealDouble &>(other));
225 } else if (is_a<ComplexDouble>(other)) {
226 return rsubreal(down_cast<const ComplexDouble &>(other));
227 } else {
228 throw NotImplementedError("Not Implemented");
229 }
230 }
231
232 RCP<const Number> mulreal(const Integer &other) const;
233 RCP<const Number> mulreal(const Rational &other) const;
234 RCP<const Number> mulreal(const Complex &other) const;
235 RCP<const Number> mulreal(const RealDouble &other) const;
236 RCP<const Number> mulreal(const ComplexDouble &other) const;
237 RCP<const Number> mulreal(const RealMPFR &other) const;
238
240 virtual RCP<const Number> mul(const Number &other) const
241 {
242 if (is_a<Rational>(other)) {
243 return mulreal(down_cast<const Rational &>(other));
244 } else if (is_a<Integer>(other)) {
245 return mulreal(down_cast<const Integer &>(other));
246 } else if (is_a<Complex>(other)) {
247 return mulreal(down_cast<const Complex &>(other));
248 } else if (is_a<RealDouble>(other)) {
249 return mulreal(down_cast<const RealDouble &>(other));
250 } else if (is_a<ComplexDouble>(other)) {
251 return mulreal(down_cast<const ComplexDouble &>(other));
252 } else if (is_a<RealMPFR>(other)) {
253 return mulreal(down_cast<const RealMPFR &>(other));
254 } else {
255 return other.mul(*this);
256 }
257 }
258
259 RCP<const Number> divreal(const Integer &other) const;
260 RCP<const Number> divreal(const Rational &other) const;
261 RCP<const Number> divreal(const Complex &other) const;
262 RCP<const Number> divreal(const RealDouble &other) const;
263 RCP<const Number> divreal(const ComplexDouble &other) const;
264 RCP<const Number> divreal(const RealMPFR &other) const;
265
267 virtual RCP<const Number> div(const Number &other) const
268 {
269 if (is_a<Rational>(other)) {
270 return divreal(down_cast<const Rational &>(other));
271 } else if (is_a<Integer>(other)) {
272 return divreal(down_cast<const Integer &>(other));
273 } else if (is_a<Complex>(other)) {
274 return divreal(down_cast<const Complex &>(other));
275 } else if (is_a<RealDouble>(other)) {
276 return divreal(down_cast<const RealDouble &>(other));
277 } else if (is_a<ComplexDouble>(other)) {
278 return divreal(down_cast<const ComplexDouble &>(other));
279 } else if (is_a<RealMPFR>(other)) {
280 return divreal(down_cast<const RealMPFR &>(other));
281 } else {
282 return other.rdiv(*this);
283 }
284 }
285
286 RCP<const Number> rdivreal(const Integer &other) const;
287 RCP<const Number> rdivreal(const Rational &other) const;
288 RCP<const Number> rdivreal(const Complex &other) const;
289 RCP<const Number> rdivreal(const RealDouble &other) const;
290 RCP<const Number> rdivreal(const ComplexDouble &other) const;
291
293 virtual RCP<const Number> rdiv(const Number &other) const
294 {
295 if (is_a<Rational>(other)) {
296 return rdivreal(down_cast<const Rational &>(other));
297 } else if (is_a<Integer>(other)) {
298 return rdivreal(down_cast<const Integer &>(other));
299 } else if (is_a<Complex>(other)) {
300 return rdivreal(down_cast<const Complex &>(other));
301 } else if (is_a<RealDouble>(other)) {
302 return rdivreal(down_cast<const RealDouble &>(other));
303 } else if (is_a<ComplexDouble>(other)) {
304 return rdivreal(down_cast<const ComplexDouble &>(other));
305 } else {
306 throw NotImplementedError("Not Implemented");
307 }
308 }
309
310 RCP<const Number> powreal(const Integer &other) const;
311 RCP<const Number> powreal(const Rational &other) const;
312 RCP<const Number> powreal(const Complex &other) const;
313 RCP<const Number> powreal(const RealDouble &other) const;
314 RCP<const Number> powreal(const ComplexDouble &other) const;
315 RCP<const Number> powreal(const RealMPFR &other) const;
316
318 virtual RCP<const Number> pow(const Number &other) const
319 {
320 if (is_a<Rational>(other)) {
321 return powreal(down_cast<const Rational &>(other));
322 } else if (is_a<Integer>(other)) {
323 return powreal(down_cast<const Integer &>(other));
324 } else if (is_a<Complex>(other)) {
325 return powreal(down_cast<const Complex &>(other));
326 } else if (is_a<RealDouble>(other)) {
327 return powreal(down_cast<const RealDouble &>(other));
328 } else if (is_a<ComplexDouble>(other)) {
329 return powreal(down_cast<const ComplexDouble &>(other));
330 } else if (is_a<RealMPFR>(other)) {
331 return powreal(down_cast<const RealMPFR &>(other));
332 } else {
333 return other.rpow(*this);
334 }
335 }
336
337 RCP<const Number> rpowreal(const Integer &other) const;
338 RCP<const Number> rpowreal(const Rational &other) const;
339 RCP<const Number> rpowreal(const Complex &other) const;
340 RCP<const Number> rpowreal(const RealDouble &other) const;
341 RCP<const Number> rpowreal(const ComplexDouble &other) const;
342
344 virtual RCP<const Number> rpow(const Number &other) const
345 {
346 if (is_a<Rational>(other)) {
347 return rpowreal(down_cast<const Rational &>(other));
348 } else if (is_a<Integer>(other)) {
349 return rpowreal(down_cast<const Integer &>(other));
350 } else if (is_a<Complex>(other)) {
351 return rpowreal(down_cast<const Complex &>(other));
352 } else if (is_a<RealDouble>(other)) {
353 return rpowreal(down_cast<const RealDouble &>(other));
354 } else if (is_a<ComplexDouble>(other)) {
355 return rpowreal(down_cast<const ComplexDouble &>(other));
356 } else {
357 throw NotImplementedError("Not Implemented");
358 }
359 }
360};
361
362inline RCP<const RealMPFR> real_mpfr(mpfr_class x)
363{
364 return rcp(new RealMPFR(std::move(x)));
365}
366} // namespace SymEngine
367#else
368
369namespace SymEngine
370{
371class RealMPFR : public Number
372{
373public:
374 IMPLEMENT_TYPEID(SYMENGINE_REAL_MPFR)
375};
376} // namespace SymEngine
377
378#endif // HAVE_SYMENGINE_MPFR
379#endif // SymEngine
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:349
T c_str(T... args)
virtual bool __eq__(const Basic &o) const =0
Test equality.
virtual hash_t __hash__() const =0
virtual int compare(const Basic &o) const =0
virtual bool is_one() const =0
virtual bool is_complex() const =0
virtual bool is_exact() const
return true if the number is an exact representation
Definition: number.h:37
virtual RCP< const Number > add(const Number &other) const =0
Addition.
virtual bool is_negative() const =0
virtual RCP< const Number > pow(const Number &other) const =0
Power.
virtual RCP< const Number > mul(const Number &other) const =0
Multiplication.
virtual bool is_positive() const =0
virtual RCP< const Number > div(const Number &other) const
Division.
Definition: number.cpp:26
virtual RCP< const Number > sub(const Number &other) const
Subtraction.
Definition: number.cpp:16
virtual bool is_zero() const =0
virtual bool is_minus_one() const =0
virtual Evaluate & get_eval() const
Get Evaluate singleton to evaluate numerically.
Definition: number.h:47
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
void hash_combine_impl(hash_t &seed, const T &v, typename std::enable_if< std::is_base_of< Basic, T >::value >::type *=nullptr)
Templatised version to combine hash.
Definition: basic-inl.h:112