real_double.h
1 
6 #ifndef SYMENGINE_REAL_DOUBLE_H
7 #define SYMENGINE_REAL_DOUBLE_H
8 
9 #include <symengine/complex.h>
10 #include <symengine/symengine_exception.h>
11 
12 namespace SymEngine
13 {
14 
15 RCP<const Number> number(std::complex<double> x);
16 RCP<const Number> number(double x);
17 
19 class RealDouble : public Number
20 {
21 public:
22  double i;
23 
24 public:
25  IMPLEMENT_TYPEID(SYMENGINE_REAL_DOUBLE)
27  explicit RealDouble(double i);
29  virtual hash_t __hash__() const;
34  virtual bool __eq__(const Basic &o) const;
35  virtual int compare(const Basic &o) const;
37  inline virtual bool is_positive() const
38  {
39  return i > 0;
40  }
42  inline virtual bool is_negative() const
43  {
44  return i < 0;
45  }
47  inline double as_double() const
48  {
49  return i;
50  }
52  inline virtual bool is_exact() const
53  {
54  return false;
55  }
57  virtual Evaluate &get_eval() const;
58 
60  virtual bool is_zero() const
61  {
62  return this->i == 0.0;
63  }
65  // A double is not exactly equal to `1`
66  virtual bool is_one() const
67  {
68  return false;
69  }
71  // A double is not exactly equal to `-1`
72  virtual bool is_minus_one() const
73  {
74  return false;
75  }
77  // False is returned because a RealDouble cannot have a imaginary part
78  virtual bool is_complex() const
79  {
80  return false;
81  }
82 
86  RCP<const Number> addreal(const Integer &other) const
87  {
88  return make_rcp<const RealDouble>(i
89  + mp_get_d(other.as_integer_class()));
90  }
91 
95  RCP<const Number> addreal(const Rational &other) const
96  {
97  return make_rcp<const RealDouble>(
98  i + mp_get_d(other.as_rational_class()));
99  }
100 
104  RCP<const Number> addreal(const Complex &other) const
105  {
106  return number(i
107  + std::complex<double>(mp_get_d(other.real_),
108  mp_get_d(other.imaginary_)));
109  }
110 
114  RCP<const Number> addreal(const RealDouble &other) const
115  {
116  return make_rcp<const RealDouble>(i + other.i);
117  }
118 
120  virtual RCP<const Number> add(const Number &other) const
121  {
122  if (is_a<Rational>(other)) {
123  return addreal(down_cast<const Rational &>(other));
124  } else if (is_a<Integer>(other)) {
125  return addreal(down_cast<const Integer &>(other));
126  } else if (is_a<Complex>(other)) {
127  return addreal(down_cast<const Complex &>(other));
128  } else if (is_a<RealDouble>(other)) {
129  return addreal(down_cast<const RealDouble &>(other));
130  } else {
131  return other.add(*this);
132  }
133  }
134 
138  RCP<const Number> subreal(const Integer &other) const
139  {
140  return make_rcp<const RealDouble>(i
141  - mp_get_d(other.as_integer_class()));
142  }
143 
147  RCP<const Number> subreal(const Rational &other) const
148  {
149  return make_rcp<const RealDouble>(
150  i - mp_get_d(other.as_rational_class()));
151  }
152 
156  RCP<const Number> subreal(const Complex &other) const
157  {
158  return number(i
159  - std::complex<double>(mp_get_d(other.real_),
160  mp_get_d(other.imaginary_)));
161  }
162 
166  RCP<const Number> subreal(const RealDouble &other) const
167  {
168  return make_rcp<const RealDouble>(i - other.i);
169  }
170 
172  virtual RCP<const Number> sub(const Number &other) const
173  {
174  if (is_a<Rational>(other)) {
175  return subreal(down_cast<const Rational &>(other));
176  } else if (is_a<Integer>(other)) {
177  return subreal(down_cast<const Integer &>(other));
178  } else if (is_a<Complex>(other)) {
179  return subreal(down_cast<const Complex &>(other));
180  } else if (is_a<RealDouble>(other)) {
181  return subreal(down_cast<const RealDouble &>(other));
182  } else {
183  return other.rsub(*this);
184  }
185  }
186 
190  RCP<const Number> rsubreal(const Integer &other) const
191  {
192  return make_rcp<const RealDouble>(mp_get_d(other.as_integer_class())
193  - i);
194  }
195 
199  RCP<const Number> rsubreal(const Rational &other) const
200  {
201  return make_rcp<const RealDouble>(mp_get_d(other.as_rational_class())
202  - i);
203  }
204 
208  RCP<const Number> rsubreal(const Complex &other) const
209  {
210  return number(-i
211  + std::complex<double>(mp_get_d(other.real_),
212  mp_get_d(other.imaginary_)));
213  }
214 
216  virtual RCP<const Number> rsub(const Number &other) const
217  {
218  if (is_a<Rational>(other)) {
219  return rsubreal(down_cast<const Rational &>(other));
220  } else if (is_a<Integer>(other)) {
221  return rsubreal(down_cast<const Integer &>(other));
222  } else if (is_a<Complex>(other)) {
223  return rsubreal(down_cast<const Complex &>(other));
224  } else {
225  throw NotImplementedError("Not Implemented");
226  }
227  }
228 
232  RCP<const Number> mulreal(const Integer &other) const
233  {
234  if (other.is_zero()) {
235  return zero;
236  }
237  return make_rcp<const RealDouble>(i
238  * mp_get_d(other.as_integer_class()));
239  }
240 
244  RCP<const Number> mulreal(const Rational &other) const
245  {
246  return make_rcp<const RealDouble>(
247  i * mp_get_d(other.as_rational_class()));
248  }
249 
253  RCP<const Number> mulreal(const Complex &other) const
254  {
255  return number(i
256  * std::complex<double>(mp_get_d(other.real_),
257  mp_get_d(other.imaginary_)));
258  }
259 
263  RCP<const Number> mulreal(const RealDouble &other) const
264  {
265  return make_rcp<const RealDouble>(i * other.i);
266  }
267 
269  virtual RCP<const Number> mul(const Number &other) const
270  {
271  if (is_a<Rational>(other)) {
272  return mulreal(down_cast<const Rational &>(other));
273  } else if (is_a<Integer>(other)) {
274  return mulreal(down_cast<const Integer &>(other));
275  } else if (is_a<Complex>(other)) {
276  return mulreal(down_cast<const Complex &>(other));
277  } else if (is_a<RealDouble>(other)) {
278  return mulreal(down_cast<const RealDouble &>(other));
279  } else {
280  return other.mul(*this);
281  }
282  }
283 
287  RCP<const Number> divreal(const Integer &other) const
288  {
289  return make_rcp<const RealDouble>(i
290  / mp_get_d(other.as_integer_class()));
291  }
292 
296  RCP<const Number> divreal(const Rational &other) const
297  {
298  return make_rcp<const RealDouble>(
299  i / mp_get_d(other.as_rational_class()));
300  }
301 
305  RCP<const Number> divreal(const Complex &other) const
306  {
307  return number(i
308  / std::complex<double>(mp_get_d(other.real_),
309  mp_get_d(other.imaginary_)));
310  }
311 
315  RCP<const Number> divreal(const RealDouble &other) const
316  {
317  return make_rcp<const RealDouble>(i / other.i);
318  }
319 
321  virtual RCP<const Number> div(const Number &other) const
322  {
323  if (is_a<Rational>(other)) {
324  return divreal(down_cast<const Rational &>(other));
325  } else if (is_a<Integer>(other)) {
326  return divreal(down_cast<const Integer &>(other));
327  } else if (is_a<Complex>(other)) {
328  return divreal(down_cast<const Complex &>(other));
329  } else if (is_a<RealDouble>(other)) {
330  return divreal(down_cast<const RealDouble &>(other));
331  } else {
332  return other.rdiv(*this);
333  }
334  }
335 
339  RCP<const Number> rdivreal(const Integer &other) const
340  {
341  return make_rcp<const RealDouble>(mp_get_d(other.as_integer_class())
342  / i);
343  }
344 
348  RCP<const Number> rdivreal(const Rational &other) const
349  {
350  return make_rcp<const RealDouble>(mp_get_d(other.as_rational_class())
351  / i);
352  }
353 
357  RCP<const Number> rdivreal(const Complex &other) const
358  {
359  return number(std::complex<double>(mp_get_d(other.real_),
360  mp_get_d(other.imaginary_))
361  / i);
362  }
363 
365  virtual RCP<const Number> rdiv(const Number &other) const
366  {
367  if (is_a<Rational>(other)) {
368  return rdivreal(down_cast<const Rational &>(other));
369  } else if (is_a<Integer>(other)) {
370  return rdivreal(down_cast<const Integer &>(other));
371  } else if (is_a<Complex>(other)) {
372  return rdivreal(down_cast<const Complex &>(other));
373  } else {
374  throw NotImplementedError("Not Implemented");
375  }
376  }
377 
381  RCP<const Number> powreal(const Integer &other) const
382  {
383  return make_rcp<const RealDouble>(
384  std::pow(i, mp_get_d(other.as_integer_class())));
385  }
386 
390  RCP<const Number> powreal(const Rational &other) const
391  {
392  if (i < 0) {
393  return number(std::pow(std::complex<double>(i),
394  mp_get_d(other.as_rational_class())));
395  }
396  return make_rcp<const RealDouble>(
397  std::pow(i, mp_get_d(other.as_rational_class())));
398  }
399 
403  RCP<const Number> powreal(const Complex &other) const
404  {
405  return number(
406  std::pow(i, std::complex<double>(mp_get_d(other.real_),
407  mp_get_d(other.imaginary_))));
408  }
409 
413  RCP<const Number> powreal(const RealDouble &other) const
414  {
415  if (i < 0) {
416  return number(std::pow(std::complex<double>(i), other.i));
417  }
418  return make_rcp<const RealDouble>(std::pow(i, other.i));
419  }
420 
422  virtual RCP<const Number> pow(const Number &other) const
423  {
424  if (is_a<Rational>(other)) {
425  return powreal(down_cast<const Rational &>(other));
426  } else if (is_a<Integer>(other)) {
427  return powreal(down_cast<const Integer &>(other));
428  } else if (is_a<Complex>(other)) {
429  return powreal(down_cast<const Complex &>(other));
430  } else if (is_a<RealDouble>(other)) {
431  return powreal(down_cast<const RealDouble &>(other));
432  } else {
433  return other.rpow(*this);
434  }
435  }
436 
440  RCP<const Number> rpowreal(const Integer &other) const
441  {
442  if (other.is_negative()) {
443  return number(std::pow(mp_get_d(other.as_integer_class()),
445  }
446  return make_rcp<const RealDouble>(
447  std::pow(mp_get_d(other.as_integer_class()), i));
448  }
449 
453  RCP<const Number> rpowreal(const Rational &other) const
454  {
455  if (other.is_negative()) {
456  return number(std::pow(std::complex<double>(i),
457  mp_get_d(other.as_rational_class())));
458  }
459  return make_rcp<const RealDouble>(
460  std::pow(mp_get_d(other.as_rational_class()), i));
461  }
462 
466  RCP<const Number> rpowreal(const Complex &other) const
467  {
468  return number(std::pow(std::complex<double>(mp_get_d(other.real_),
469  mp_get_d(other.imaginary_)),
470  i));
471  }
472 
474  virtual RCP<const Number> rpow(const Number &other) const
475  {
476  if (is_a<Rational>(other)) {
477  return rpowreal(down_cast<const Rational &>(other));
478  } else if (is_a<Integer>(other)) {
479  return rpowreal(down_cast<const Integer &>(other));
480  } else if (is_a<Complex>(other)) {
481  return rpowreal(down_cast<const Complex &>(other));
482  } else {
483  throw NotImplementedError("Not Implemented");
484  }
485  }
486 };
487 
488 RCP<const RealDouble> real_double(double x);
489 
490 } // namespace SymEngine
491 
492 #endif
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:340
The lowest unit of symbolic representation.
Definition: basic.h:95
Complex Class.
Definition: complex.h:33
rational_class real_
Definition: complex.h:38
A class that will evaluate functions numerically.
Definition: number.h:193
Integer Class.
Definition: integer.h:19
virtual bool is_zero() const
Definition: integer.h:53
const integer_class & as_integer_class() const
Convert to integer_class.
Definition: integer.h:48
virtual bool is_negative() const
Definition: integer.h:73
virtual RCP< const Number > mul(const Number &other) const =0
Multiplication.
virtual RCP< const Number > add(const Number &other) const =0
Addition.
Rational Class.
Definition: rational.h:16
const rational_class & as_rational_class() const
Convert to rational_class.
Definition: rational.h:50
virtual bool is_negative() const
Definition: rational.h:80
RealDouble Class to hold double values.
Definition: real_double.h:20
virtual RCP< const Number > add(const Number &other) const
Converts the param other appropriately and then calls addreal
Definition: real_double.h:120
virtual RCP< const Number > sub(const Number &other) const
Converts the param other appropriately and then calls subreal
Definition: real_double.h:172
RCP< const Number > addreal(const RealDouble &other) const
Definition: real_double.h:114
virtual RCP< const Number > div(const Number &other) const
Converts the param other appropriately and then calls divreal
Definition: real_double.h:321
RCP< const Number > powreal(const Rational &other) const
Definition: real_double.h:390
RCP< const Number > divreal(const Complex &other) const
Definition: real_double.h:305
RCP< const Number > mulreal(const Complex &other) const
Definition: real_double.h:253
RCP< const Number > mulreal(const Integer &other) const
Definition: real_double.h:232
virtual Evaluate & get_eval() const
Get Evaluate singleton to evaluate numerically.
RCP< const Number > powreal(const Complex &other) const
Definition: real_double.h:403
virtual RCP< const Number > mul(const Number &other) const
Converts the param other appropriately and then calls mulreal
Definition: real_double.h:269
RCP< const Number > rpowreal(const Rational &other) const
Definition: real_double.h:453
RCP< const Number > mulreal(const Rational &other) const
Definition: real_double.h:244
virtual RCP< const Number > rpow(const Number &other) const
Converts the param other appropriately and then calls powreal
Definition: real_double.h:474
RCP< const Number > divreal(const Integer &other) const
Definition: real_double.h:287
virtual RCP< const Number > rdiv(const Number &other) const
Converts the param other appropriately and then calls divreal
Definition: real_double.h:365
virtual bool is_exact() const
Definition: real_double.h:52
RCP< const Number > subreal(const Integer &other) const
Definition: real_double.h:138
virtual bool is_negative() const
Definition: real_double.h:42
RCP< const Number > rpowreal(const Complex &other) const
Definition: real_double.h:466
double as_double() const
Definition: real_double.h:47
virtual bool is_one() const
Definition: real_double.h:66
RCP< const Number > subreal(const Complex &other) const
Definition: real_double.h:156
virtual int compare(const Basic &o) const
Definition: real_double.cpp:34
RCP< const Number > rsubreal(const Rational &other) const
Definition: real_double.h:199
RCP< const Number > addreal(const Integer &other) const
Definition: real_double.h:86
RCP< const Number > addreal(const Complex &other) const
Definition: real_double.h:104
RCP< const Number > rpowreal(const Integer &other) const
Definition: real_double.h:440
virtual bool __eq__(const Basic &o) const
Definition: real_double.cpp:25
virtual bool is_zero() const
Definition: real_double.h:60
RCP< const Number > rdivreal(const Rational &other) const
Definition: real_double.h:348
virtual RCP< const Number > pow(const Number &other) const
Converts the param other appropriately and then calls powreal
Definition: real_double.h:422
virtual RCP< const Number > rsub(const Number &other) const
Converts the param other appropriately and then calls subreal
Definition: real_double.h:216
RCP< const Number > mulreal(const RealDouble &other) const
Definition: real_double.h:263
RCP< const Number > divreal(const RealDouble &other) const
Definition: real_double.h:315
virtual bool is_minus_one() const
Definition: real_double.h:72
virtual bool is_positive() const
Definition: real_double.h:37
RCP< const Number > addreal(const Rational &other) const
Definition: real_double.h:95
RCP< const Number > rsubreal(const Complex &other) const
Definition: real_double.h:208
RCP< const Number > rdivreal(const Complex &other) const
Definition: real_double.h:357
RCP< const Number > powreal(const Integer &other) const
Definition: real_double.h:381
RCP< const Number > rdivreal(const Integer &other) const
Definition: real_double.h:339
RCP< const Number > subreal(const RealDouble &other) const
Definition: real_double.h:166
virtual hash_t __hash__() const
Definition: real_double.cpp:18
RCP< const Number > powreal(const RealDouble &other) const
Definition: real_double.h:413
RCP< const Number > rsubreal(const Integer &other) const
Definition: real_double.h:190
RCP< const Number > subreal(const Rational &other) const
Definition: real_double.h:147
virtual bool is_complex() const
Definition: real_double.h:78
RealDouble(double i)
Constructor of RealDouble class.
Definition: real_double.cpp:12
RCP< const Number > divreal(const Rational &other) const
Definition: real_double.h:296
Main namespace for SymEngine package.
Definition: add.cpp:19
T pow(T... args)