complex_double.h
1 
6 #ifndef SYMENGINE_COMPLEX_DOUBLE_H
7 #define SYMENGINE_COMPLEX_DOUBLE_H
8 
9 #include <symengine/real_double.h>
10 #include <symengine/symengine_exception.h>
11 
12 namespace SymEngine
13 {
15 class ComplexDouble : public ComplexBase
16 {
17 public:
19 
20 public:
21  IMPLEMENT_TYPEID(SYMENGINE_COMPLEX_DOUBLE)
25  hash_t __hash__() const override;
30  bool __eq__(const Basic &o) const override;
31  int compare(const Basic &o) const override;
33  RCP<const Number> real_part() const override;
35  RCP<const Number> imaginary_part() const override;
37  RCP<const Basic> conjugate() const override;
39  // False is returned because complex cannot be compared with zero
40  inline bool is_positive() const override
41  {
42  return false;
43  }
45  // False is returned because complex cannot be compared with zero
46  inline bool is_negative() const override
47  {
48  return false;
49  }
51  inline bool is_complex() const override
52  {
53  return true;
54  }
57  {
58  return i;
59  }
61  // False is returned because std::complex<double> is not exact
62  inline bool is_exact() const override
63  {
64  return false;
65  }
67  Evaluate &get_eval() const override;
68 
70  bool is_zero() const override
71  {
72  return i == 0.0;
73  }
75  // A std::complex<double> is not exactly equal to `1`
76  bool is_one() const override
77  {
78  return false;
79  }
81  // A std::complex<double> is not exactly equal to `-1`
82  bool is_minus_one() const override
83  {
84  return false;
85  }
86 
90  RCP<const Number> addcomp(const Integer &other) const
91  {
92  return make_rcp<const ComplexDouble>(
93  i + mp_get_d(other.as_integer_class()));
94  }
95 
99  RCP<const Number> addcomp(const Rational &other) const
100  {
101  return make_rcp<const ComplexDouble>(
102  i + mp_get_d(other.as_rational_class()));
103  }
104 
108  RCP<const Number> addcomp(const Complex &other) const
109  {
110  return make_rcp<const ComplexDouble>(
111  i
112  + std::complex<double>(mp_get_d(other.real_),
113  mp_get_d(other.imaginary_)));
114  }
115 
119  RCP<const Number> addcomp(const RealDouble &other) const
120  {
121  return make_rcp<const ComplexDouble>(i + other.i);
122  }
123 
127  RCP<const Number> addcomp(const ComplexDouble &other) const
128  {
129  return make_rcp<const ComplexDouble>(i + other.i);
130  }
131 
133  RCP<const Number> add(const Number &other) const override
134  {
135  if (is_a<Rational>(other)) {
136  return addcomp(down_cast<const Rational &>(other));
137  } else if (is_a<Integer>(other)) {
138  return addcomp(down_cast<const Integer &>(other));
139  } else if (is_a<Complex>(other)) {
140  return addcomp(down_cast<const Complex &>(other));
141  } else if (is_a<RealDouble>(other)) {
142  return addcomp(down_cast<const RealDouble &>(other));
143  } else if (is_a<ComplexDouble>(other)) {
144  return addcomp(down_cast<const ComplexDouble &>(other));
145  } else {
146  return other.add(*this);
147  }
148  }
149 
153  RCP<const Number> subcomp(const Integer &other) const
154  {
155  return make_rcp<const ComplexDouble>(
156  i - mp_get_d(other.as_integer_class()));
157  }
158 
162  RCP<const Number> subcomp(const Rational &other) const
163  {
164  return make_rcp<const ComplexDouble>(
165  i - mp_get_d(other.as_rational_class()));
166  }
167 
171  RCP<const Number> subcomp(const Complex &other) const
172  {
173  return make_rcp<const ComplexDouble>(
174  i
175  - std::complex<double>(mp_get_d(other.real_),
176  mp_get_d(other.imaginary_)));
177  }
178 
182  RCP<const Number> subcomp(const RealDouble &other) const
183  {
184  return make_rcp<const ComplexDouble>(i - other.i);
185  }
186 
190  RCP<const Number> subcomp(const ComplexDouble &other) const
191  {
192  return make_rcp<const ComplexDouble>(i - other.i);
193  }
194 
196  RCP<const Number> sub(const Number &other) const override
197  {
198  if (is_a<Rational>(other)) {
199  return subcomp(down_cast<const Rational &>(other));
200  } else if (is_a<Integer>(other)) {
201  return subcomp(down_cast<const Integer &>(other));
202  } else if (is_a<Complex>(other)) {
203  return subcomp(down_cast<const Complex &>(other));
204  } else if (is_a<RealDouble>(other)) {
205  return subcomp(down_cast<const RealDouble &>(other));
206  } else if (is_a<ComplexDouble>(other)) {
207  return subcomp(down_cast<const ComplexDouble &>(other));
208  } else {
209  return other.rsub(*this);
210  }
211  }
212 
216  RCP<const Number> rsubcomp(const Integer &other) const
217  {
218  return make_rcp<const ComplexDouble>(mp_get_d(other.as_integer_class())
219  - i);
220  }
221 
225  RCP<const Number> rsubcomp(const Rational &other) const
226  {
227  return make_rcp<const ComplexDouble>(mp_get_d(other.as_rational_class())
228  - i);
229  }
230 
234  RCP<const Number> rsubcomp(const Complex &other) const
235  {
236  return make_rcp<const ComplexDouble>(
237  -i
238  + std::complex<double>(mp_get_d(other.real_),
239  mp_get_d(other.imaginary_)));
240  }
241 
245  RCP<const Number> rsubcomp(const RealDouble &other) const
246  {
247  return make_rcp<const ComplexDouble>(other.i - i);
248  }
249 
251  RCP<const Number> rsub(const Number &other) const override
252  {
253  if (is_a<Rational>(other)) {
254  return rsubcomp(down_cast<const Rational &>(other));
255  } else if (is_a<Integer>(other)) {
256  return rsubcomp(down_cast<const Integer &>(other));
257  } else if (is_a<Complex>(other)) {
258  return rsubcomp(down_cast<const Complex &>(other));
259  } else if (is_a<RealDouble>(other)) {
260  return rsubcomp(down_cast<const RealDouble &>(other));
261  } else {
262  throw NotImplementedError("Not Implemented");
263  }
264  }
265 
269  RCP<const Number> mulcomp(const Integer &other) const
270  {
271  return make_rcp<const ComplexDouble>(
272  i * mp_get_d(other.as_integer_class()));
273  }
274 
278  RCP<const Number> mulcomp(const Rational &other) const
279  {
280  return make_rcp<const ComplexDouble>(
281  i * mp_get_d(other.as_rational_class()));
282  }
283 
287  RCP<const Number> mulcomp(const Complex &other) const
288  {
289  return make_rcp<const ComplexDouble>(
290  i
291  * std::complex<double>(mp_get_d(other.real_),
292  mp_get_d(other.imaginary_)));
293  }
294 
298  RCP<const Number> mulcomp(const RealDouble &other) const
299  {
300  return make_rcp<const ComplexDouble>(i * other.i);
301  }
302 
306  RCP<const Number> mulcomp(const ComplexDouble &other) const
307  {
308  return make_rcp<const ComplexDouble>(i * other.i);
309  }
310 
312  RCP<const Number> mul(const Number &other) const override
313  {
314  if (is_a<Rational>(other)) {
315  return mulcomp(down_cast<const Rational &>(other));
316  } else if (is_a<Integer>(other)) {
317  return mulcomp(down_cast<const Integer &>(other));
318  } else if (is_a<Complex>(other)) {
319  return mulcomp(down_cast<const Complex &>(other));
320  } else if (is_a<RealDouble>(other)) {
321  return mulcomp(down_cast<const RealDouble &>(other));
322  } else if (is_a<ComplexDouble>(other)) {
323  return mulcomp(down_cast<const ComplexDouble &>(other));
324  } else {
325  return other.mul(*this);
326  }
327  }
328 
332  RCP<const Number> divcomp(const Integer &other) const
333  {
334  return make_rcp<const ComplexDouble>(
335  i / mp_get_d(other.as_integer_class()));
336  }
337 
341  RCP<const Number> divcomp(const Rational &other) const
342  {
343  return make_rcp<const ComplexDouble>(
344  i / mp_get_d(other.as_rational_class()));
345  }
346 
350  RCP<const Number> divcomp(const Complex &other) const
351  {
352  return make_rcp<const ComplexDouble>(
353  i
354  / std::complex<double>(mp_get_d(other.real_),
355  mp_get_d(other.imaginary_)));
356  }
357 
361  RCP<const Number> divcomp(const RealDouble &other) const
362  {
363  return make_rcp<const ComplexDouble>(i / other.i);
364  }
365 
369  RCP<const Number> divcomp(const ComplexDouble &other) const
370  {
371  return make_rcp<const ComplexDouble>(i / other.i);
372  }
373 
375  RCP<const Number> div(const Number &other) const override
376  {
377  if (is_a<Rational>(other)) {
378  return divcomp(down_cast<const Rational &>(other));
379  } else if (is_a<Integer>(other)) {
380  return divcomp(down_cast<const Integer &>(other));
381  } else if (is_a<Complex>(other)) {
382  return divcomp(down_cast<const Complex &>(other));
383  } else if (is_a<RealDouble>(other)) {
384  return divcomp(down_cast<const RealDouble &>(other));
385  } else if (is_a<ComplexDouble>(other)) {
386  return divcomp(down_cast<const ComplexDouble &>(other));
387  } else {
388  return other.rdiv(*this);
389  }
390  }
391 
395  RCP<const Number> rdivcomp(const Integer &other) const
396  {
397  return make_rcp<const ComplexDouble>(mp_get_d(other.as_integer_class())
398  / i);
399  }
400 
404  RCP<const Number> rdivcomp(const Rational &other) const
405  {
406  return make_rcp<const ComplexDouble>(mp_get_d(other.as_rational_class())
407  / i);
408  }
409 
413  RCP<const Number> rdivcomp(const Complex &other) const
414  {
415  return make_rcp<const ComplexDouble>(
416  std::complex<double>(mp_get_d(other.real_),
417  mp_get_d(other.imaginary_))
418  / i);
419  }
420 
424  RCP<const Number> rdivcomp(const RealDouble &other) const
425  {
426  return make_rcp<const ComplexDouble>(other.i / i);
427  }
428 
430  RCP<const Number> rdiv(const Number &other) const override
431  {
432  if (is_a<Rational>(other)) {
433  return rdivcomp(down_cast<const Rational &>(other));
434  } else if (is_a<Integer>(other)) {
435  return rdivcomp(down_cast<const Integer &>(other));
436  } else if (is_a<Complex>(other)) {
437  return rdivcomp(down_cast<const Complex &>(other));
438  } else if (is_a<RealDouble>(other)) {
439  return rdivcomp(down_cast<const RealDouble &>(other));
440  } else {
441  throw NotImplementedError("Not Implemented");
442  }
443  }
444 
448  RCP<const Number> powcomp(const Integer &other) const
449  {
450  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
451  i, mp_get_d(other.as_integer_class())));
452  }
453 
457  RCP<const Number> powcomp(const Rational &other) const
458  {
459  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
460  i, mp_get_d(other.as_rational_class())));
461  }
462 
466  RCP<const Number> powcomp(const Complex &other) const
467  {
468  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
469  i, std::complex<double>(mp_get_d(other.real_),
470  mp_get_d(other.imaginary_))));
471  }
475  RCP<const Number> powcomp(const RealDouble &other) const
476  {
477  return make_rcp<const ComplexDouble>(
478  (std::complex<double>)std::pow(i, other.i));
479  }
480 
484  RCP<const Number> powcomp(const ComplexDouble &other) const
485  {
486  return make_rcp<const ComplexDouble>(
487  (std::complex<double>)std::pow(i, other.i));
488  }
489 
491  RCP<const Number> pow(const Number &other) const override
492  {
493  if (is_a<Rational>(other)) {
494  return powcomp(down_cast<const Rational &>(other));
495  } else if (is_a<Integer>(other)) {
496  return powcomp(down_cast<const Integer &>(other));
497  } else if (is_a<Complex>(other)) {
498  return powcomp(down_cast<const Complex &>(other));
499  } else if (is_a<RealDouble>(other)) {
500  return powcomp(down_cast<const RealDouble &>(other));
501  } else if (is_a<ComplexDouble>(other)) {
502  return powcomp(down_cast<const ComplexDouble &>(other));
503  } else {
504  return other.rpow(*this);
505  }
506  }
507 
511  RCP<const Number> rpowcomp(const Integer &other) const
512  {
513  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
514  mp_get_d(other.as_integer_class()), i));
515  }
516 
520  RCP<const Number> rpowcomp(const Rational &other) const
521  {
522  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
523  mp_get_d(other.as_rational_class()), i));
524  }
525 
529  RCP<const Number> rpowcomp(const Complex &other) const
530  {
531  return make_rcp<const ComplexDouble>((std::complex<double>)std::pow(
532  std::complex<double>(mp_get_d(other.real_),
533  mp_get_d(other.imaginary_)),
534  i));
535  }
536 
540  RCP<const Number> rpowcomp(const RealDouble &other) const
541  {
542  return make_rcp<const ComplexDouble>(
543  (std::complex<double>)std::pow(other.i, i));
544  }
545 
547  RCP<const Number> rpow(const Number &other) const override
548  {
549  if (is_a<Rational>(other)) {
550  return rpowcomp(down_cast<const Rational &>(other));
551  } else if (is_a<Integer>(other)) {
552  return rpowcomp(down_cast<const Integer &>(other));
553  } else if (is_a<Complex>(other)) {
554  return rpowcomp(down_cast<const Complex &>(other));
555  } else if (is_a<RealDouble>(other)) {
556  return rpowcomp(down_cast<const RealDouble &>(other));
557  } else {
558  throw NotImplementedError("Not Implemented");
559  }
560  }
561 };
562 
563 RCP<const ComplexDouble> complex_double(std::complex<double> x);
564 RCP<const ComplexDouble> complex_double(double real, double imag);
565 
566 } // namespace SymEngine
567 
568 #endif
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:340
The lowest unit of symbolic representation.
Definition: basic.h:97
ComplexBase Class for deriving all complex classes.
Definition: complex.h:16
Complex Double Class to hold std::complex<double> values.
RCP< const Number > subcomp(const RealDouble &other) const
RCP< const Number > rdivcomp(const Rational &other) const
bool __eq__(const Basic &o) const override
RCP< const Number > addcomp(const Complex &other) const
RCP< const Number > addcomp(const Integer &other) const
RCP< const Number > rpowcomp(const Complex &other) const
RCP< const Number > sub(const Number &other) const override
Converts the param other appropriately and then calls subcomp
RCP< const Number > rsubcomp(const RealDouble &other) const
RCP< const Number > mulcomp(const RealDouble &other) const
RCP< const Number > rdivcomp(const Complex &other) const
RCP< const Number > mulcomp(const ComplexDouble &other) const
RCP< const Number > powcomp(const Integer &other) const
RCP< const Number > mul(const Number &other) const override
Converts the param other appropriately and then calls mulcomp
std::complex< double > as_complex_double() const
RCP< const Number > subcomp(const Integer &other) const
int compare(const Basic &o) const override
RCP< const Number > div(const Number &other) const override
Converts the param other appropriately and then calls divcomp
RCP< const Number > rsubcomp(const Rational &other) const
RCP< const Basic > conjugate() const override
Get the conjugate of the complex number.
RCP< const Number > powcomp(const Complex &other) const
RCP< const Number > rpowcomp(const Rational &other) const
RCP< const Number > addcomp(const ComplexDouble &other) const
RCP< const Number > rdivcomp(const Integer &other) const
bool is_positive() const override
bool is_negative() const override
RCP< const Number > rpowcomp(const Integer &other) const
RCP< const Number > rpowcomp(const RealDouble &other) const
RCP< const Number > subcomp(const Complex &other) const
bool is_zero() const override
RCP< const Number > addcomp(const RealDouble &other) const
RCP< const Number > subcomp(const ComplexDouble &other) const
hash_t __hash__() const override
RCP< const Number > rsubcomp(const Integer &other) const
RCP< const Number > mulcomp(const Integer &other) const
RCP< const Number > rdiv(const Number &other) const override
Converts the param other appropriately and then calls divcomp
RCP< const Number > real_part() const override
Get the real part of the complex number.
RCP< const Number > powcomp(const Rational &other) const
RCP< const Number > divcomp(const ComplexDouble &other) const
RCP< const Number > subcomp(const Rational &other) const
RCP< const Number > rdivcomp(const RealDouble &other) const
bool is_exact() const override
ComplexDouble(std::complex< double > i)
Constructor of ComplexDouble class.
RCP< const Number > divcomp(const Rational &other) const
RCP< const Number > divcomp(const RealDouble &other) const
RCP< const Number > powcomp(const RealDouble &other) const
RCP< const Number > add(const Number &other) const override
Converts the param other appropriately and then calls addcomp
RCP< const Number > rsubcomp(const Complex &other) const
RCP< const Number > rsub(const Number &other) const override
Converts the param other appropriately and then calls subcomp
RCP< const Number > rpow(const Number &other) const override
Converts the param other appropriately and then calls powcomp
bool is_complex() const override
RCP< const Number > divcomp(const Complex &other) const
Evaluate & get_eval() const override
Get Evaluate singleton to evaluate numerically.
RCP< const Number > imaginary_part() const override
Get the imaginary part of the complex number.
RCP< const Number > divcomp(const Integer &other) const
RCP< const Number > pow(const Number &other) const override
Converts the param other appropriately and then calls powcomp
bool is_one() const override
RCP< const Number > mulcomp(const Complex &other) const
bool is_minus_one() const override
RCP< const Number > powcomp(const ComplexDouble &other) const
RCP< const Number > mulcomp(const Rational &other) const
RCP< const Number > addcomp(const Rational &other) const
Complex Class.
Definition: complex.h:33
rational_class real_
Definition: complex.h:38
A class that will evaluate functions numerically.
Definition: number.h:200
Integer Class.
Definition: integer.h:19
const integer_class & as_integer_class() const
Convert to integer_class.
Definition: integer.h:45
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
RealDouble Class to hold double values.
Definition: real_double.h:20
Main namespace for SymEngine package.
Definition: add.cpp:19
T pow(T... args)