complex_mpc.h
1 
6 #ifndef SYMENGINE_REAL_MPC_H
7 #define SYMENGINE_REAL_MPC_H
8 
9 #include <symengine/real_mpfr.h>
10 #include <symengine/symengine_exception.h>
11 
12 #ifdef HAVE_SYMENGINE_MPC
13 #include <mpc.h>
14 
15 namespace SymEngine
16 {
17 
18 class mpc_class
19 {
20 private:
21  mpc_t mp;
22 
23 public:
24  mpc_ptr get_mpc_t()
25  {
26  return mp;
27  }
28  mpc_srcptr get_mpc_t() const
29  {
30  return mp;
31  }
32  explicit mpc_class(mpc_t m)
33  {
34  mpc_init2(mp, mpc_get_prec(m));
35  mpc_set(mp, m, MPFR_RNDN);
36  }
37  explicit mpc_class(mpfr_prec_t prec = 53)
38  {
39  mpc_init2(mp, prec);
40  }
41  mpc_class(std::string s, mpfr_prec_t prec = 53, unsigned base = 10)
42  {
43  mpc_init2(mp, prec);
44  mpc_set_str(mp, s.c_str(), base, MPFR_RNDN);
45  }
46  mpc_class(const mpc_class &other)
47  {
48  mpc_init2(mp, mpc_get_prec(other.get_mpc_t()));
49  mpc_set(mp, other.get_mpc_t(), MPFR_RNDN);
50  }
51  mpc_class(mpc_class &&other)
52  {
53  mp->re->_mpfr_d = nullptr;
54  mpc_swap(mp, other.get_mpc_t());
55  }
56  mpc_class &operator=(const mpc_class &other)
57  {
58  mpc_set_prec(mp, mpc_get_prec(other.get_mpc_t()));
59  mpc_set(mp, other.get_mpc_t(), MPFR_RNDN);
60  return *this;
61  }
62  mpc_class &operator=(mpc_class &&other)
63  {
64  mpc_swap(mp, other.get_mpc_t());
65  return *this;
66  }
67  ~mpc_class()
68  {
69  if (mp->re->_mpfr_d != nullptr) {
70  mpc_clear(mp);
71  }
72  }
73  mpfr_prec_t get_prec() const
74  {
75  return mpc_get_prec(mp);
76  }
77 };
78 
79 RCP<const Number> number(mpfr_ptr x);
80 
82 class ComplexMPC : public ComplexBase
83 {
84 private:
85  mpc_class i;
86 
87 public:
88  IMPLEMENT_TYPEID(SYMENGINE_COMPLEX_MPC)
90  ComplexMPC(mpc_class i);
91  inline const mpc_class &as_mpc() const
92  {
93  return i;
94  }
95  inline mpfr_prec_t get_prec() const
96  {
97  return mpc_get_prec(i.get_mpc_t());
98  }
100  hash_t __hash__() const override;
105  bool __eq__(const Basic &o) const override;
106  int compare(const Basic &o) const override;
108  RCP<const Number> real_part() const override;
110  RCP<const Number> imaginary_part() const override;
112  RCP<const Basic> conjugate() const override;
114  inline bool is_positive() const override
115  {
116  return false;
117  }
119  inline bool is_negative() const override
120  {
121  return false;
122  }
124  inline bool is_complex() const override
125  {
126  return true;
127  }
129  inline bool is_exact() const override
130  {
131  return false;
132  }
134  Evaluate &get_eval() const override;
135 
137  bool is_zero() const override
138  {
139  return mpc_cmp_si_si(i.get_mpc_t(), 0, 0) == 0;
140  }
142  // A mpc_t is not exactly equal to `1`
143  bool is_one() const override
144  {
145  return false;
146  }
148  // A mpc_t is not exactly equal to `-1`
149  bool is_minus_one() const override
150  {
151  return false;
152  }
153 
157  RCP<const Number> add(const Integer &other) const;
158  RCP<const Number> add(const Rational &other) const;
159  RCP<const Number> add(const Complex &other) const;
160  RCP<const Number> add(const RealDouble &other) const;
161  RCP<const Number> add(const ComplexDouble &other) const;
162  RCP<const Number> add(const RealMPFR &other) const;
163  RCP<const Number> add(const ComplexMPC &other) const;
164 
166  RCP<const Number> add(const Number &other) const override
167  {
168  if (is_a<Rational>(other)) {
169  return add(down_cast<const Rational &>(other));
170  } else if (is_a<Integer>(other)) {
171  return add(down_cast<const Integer &>(other));
172  } else if (is_a<Complex>(other)) {
173  return add(down_cast<const Complex &>(other));
174  } else if (is_a<RealDouble>(other)) {
175  return add(down_cast<const RealDouble &>(other));
176  } else if (is_a<ComplexDouble>(other)) {
177  return add(down_cast<const ComplexDouble &>(other));
178  } else if (is_a<RealMPFR>(other)) {
179  return add(down_cast<const RealMPFR &>(other));
180  } else if (is_a<ComplexMPC>(other)) {
181  return add(down_cast<const ComplexMPC &>(other));
182  } else {
183  return other.add(*this);
184  }
185  }
186 
187  RCP<const Number> sub(const Integer &other) const;
188  RCP<const Number> sub(const Rational &other) const;
189  RCP<const Number> sub(const Complex &other) const;
190  RCP<const Number> sub(const RealDouble &other) const;
191  RCP<const Number> sub(const ComplexDouble &other) const;
192  RCP<const Number> sub(const RealMPFR &other) const;
193  RCP<const Number> sub(const ComplexMPC &other) const;
194 
196  RCP<const Number> sub(const Number &other) const override
197  {
198  if (is_a<Rational>(other)) {
199  return sub(down_cast<const Rational &>(other));
200  } else if (is_a<Integer>(other)) {
201  return sub(down_cast<const Integer &>(other));
202  } else if (is_a<Complex>(other)) {
203  return sub(down_cast<const Complex &>(other));
204  } else if (is_a<RealDouble>(other)) {
205  return sub(down_cast<const RealDouble &>(other));
206  } else if (is_a<ComplexDouble>(other)) {
207  return sub(down_cast<const ComplexDouble &>(other));
208  } else if (is_a<RealMPFR>(other)) {
209  return sub(down_cast<const RealMPFR &>(other));
210  } else if (is_a<ComplexMPC>(other)) {
211  return sub(down_cast<const ComplexMPC &>(other));
212  } else {
213  return other.rsub(*this);
214  }
215  }
216 
217  RCP<const Number> rsub(const Integer &other) const;
218  RCP<const Number> rsub(const Rational &other) const;
219  RCP<const Number> rsub(const Complex &other) const;
220  RCP<const Number> rsub(const RealDouble &other) const;
221  RCP<const Number> rsub(const ComplexDouble &other) const;
222  RCP<const Number> rsub(const RealMPFR &other) const;
223 
225  RCP<const Number> rsub(const Number &other) const override
226  {
227  if (is_a<Rational>(other)) {
228  return rsub(down_cast<const Rational &>(other));
229  } else if (is_a<Integer>(other)) {
230  return rsub(down_cast<const Integer &>(other));
231  } else if (is_a<Complex>(other)) {
232  return rsub(down_cast<const Complex &>(other));
233  } else if (is_a<RealDouble>(other)) {
234  return rsub(down_cast<const RealDouble &>(other));
235  } else if (is_a<ComplexDouble>(other)) {
236  return rsub(down_cast<const ComplexDouble &>(other));
237  } else if (is_a<RealMPFR>(other)) {
238  return rsub(down_cast<const RealMPFR &>(other));
239  } else {
240  throw NotImplementedError("Not Implemented");
241  }
242  }
243 
244  RCP<const Number> mul(const Integer &other) const;
245  RCP<const Number> mul(const Rational &other) const;
246  RCP<const Number> mul(const Complex &other) const;
247  RCP<const Number> mul(const RealDouble &other) const;
248  RCP<const Number> mul(const ComplexDouble &other) const;
249  RCP<const Number> mul(const RealMPFR &other) const;
250  RCP<const Number> mul(const ComplexMPC &other) const;
251 
253  RCP<const Number> mul(const Number &other) const override
254  {
255  if (is_a<Rational>(other)) {
256  return mul(down_cast<const Rational &>(other));
257  } else if (is_a<Integer>(other)) {
258  return mul(down_cast<const Integer &>(other));
259  } else if (is_a<Complex>(other)) {
260  return mul(down_cast<const Complex &>(other));
261  } else if (is_a<RealDouble>(other)) {
262  return mul(down_cast<const RealDouble &>(other));
263  } else if (is_a<ComplexDouble>(other)) {
264  return mul(down_cast<const ComplexDouble &>(other));
265  } else if (is_a<RealMPFR>(other)) {
266  return mul(down_cast<const RealMPFR &>(other));
267  } else if (is_a<ComplexMPC>(other)) {
268  return mul(down_cast<const ComplexMPC &>(other));
269  } else {
270  return other.mul(*this);
271  }
272  }
273 
274  RCP<const Number> div(const Integer &other) const;
275  RCP<const Number> div(const Rational &other) const;
276  RCP<const Number> div(const Complex &other) const;
277  RCP<const Number> div(const RealDouble &other) const;
278  RCP<const Number> div(const ComplexDouble &other) const;
279  RCP<const Number> div(const RealMPFR &other) const;
280  RCP<const Number> div(const ComplexMPC &other) const;
281 
283  RCP<const Number> div(const Number &other) const override
284  {
285  if (is_a<Rational>(other)) {
286  return div(down_cast<const Rational &>(other));
287  } else if (is_a<Integer>(other)) {
288  return div(down_cast<const Integer &>(other));
289  } else if (is_a<Complex>(other)) {
290  return div(down_cast<const Complex &>(other));
291  } else if (is_a<RealDouble>(other)) {
292  return div(down_cast<const RealDouble &>(other));
293  } else if (is_a<ComplexDouble>(other)) {
294  return div(down_cast<const ComplexDouble &>(other));
295  } else if (is_a<RealMPFR>(other)) {
296  return div(down_cast<const RealMPFR &>(other));
297  } else if (is_a<ComplexMPC>(other)) {
298  return div(down_cast<const ComplexMPC &>(other));
299  } else {
300  return other.rdiv(*this);
301  }
302  }
303 
304  RCP<const Number> rdiv(const Integer &other) const;
305  RCP<const Number> rdiv(const Rational &other) const;
306  RCP<const Number> rdiv(const Complex &other) const;
307  RCP<const Number> rdiv(const RealDouble &other) const;
308  RCP<const Number> rdiv(const ComplexDouble &other) const;
309  RCP<const Number> rdiv(const RealMPFR &other) const;
310 
312  RCP<const Number> rdiv(const Number &other) const override
313  {
314  if (is_a<Rational>(other)) {
315  return rdiv(down_cast<const Rational &>(other));
316  } else if (is_a<Integer>(other)) {
317  return rdiv(down_cast<const Integer &>(other));
318  } else if (is_a<Complex>(other)) {
319  return rdiv(down_cast<const Complex &>(other));
320  } else if (is_a<RealDouble>(other)) {
321  return rdiv(down_cast<const RealDouble &>(other));
322  } else if (is_a<ComplexDouble>(other)) {
323  return rdiv(down_cast<const ComplexDouble &>(other));
324  } else if (is_a<RealMPFR>(other)) {
325  return rdiv(down_cast<const RealMPFR &>(other));
326  } else {
327  throw NotImplementedError("Not Implemented");
328  }
329  }
330 
331  RCP<const Number> pow(const Integer &other) const;
332  RCP<const Number> pow(const Rational &other) const;
333  RCP<const Number> pow(const Complex &other) const;
334  RCP<const Number> pow(const RealDouble &other) const;
335  RCP<const Number> pow(const ComplexDouble &other) const;
336  RCP<const Number> pow(const RealMPFR &other) const;
337  RCP<const Number> pow(const ComplexMPC &other) const;
338 
340  RCP<const Number> pow(const Number &other) const override
341  {
342  if (is_a<Rational>(other)) {
343  return pow(down_cast<const Rational &>(other));
344  } else if (is_a<Integer>(other)) {
345  return pow(down_cast<const Integer &>(other));
346  } else if (is_a<Complex>(other)) {
347  return pow(down_cast<const Complex &>(other));
348  } else if (is_a<RealDouble>(other)) {
349  return pow(down_cast<const RealDouble &>(other));
350  } else if (is_a<ComplexDouble>(other)) {
351  return pow(down_cast<const ComplexDouble &>(other));
352  } else if (is_a<RealMPFR>(other)) {
353  return pow(down_cast<const RealMPFR &>(other));
354  } else if (is_a<ComplexMPC>(other)) {
355  return pow(down_cast<const ComplexMPC &>(other));
356  } else {
357  return other.rpow(*this);
358  }
359  }
360 
361  RCP<const Number> rpow(const Integer &other) const;
362  RCP<const Number> rpow(const Rational &other) const;
363  RCP<const Number> rpow(const Complex &other) const;
364  RCP<const Number> rpow(const RealDouble &other) const;
365  RCP<const Number> rpow(const ComplexDouble &other) const;
366  RCP<const Number> rpow(const RealMPFR &other) const;
367 
369  RCP<const Number> rpow(const Number &other) const override
370  {
371  if (is_a<Rational>(other)) {
372  return rpow(down_cast<const Rational &>(other));
373  } else if (is_a<Integer>(other)) {
374  return rpow(down_cast<const Integer &>(other));
375  } else if (is_a<Complex>(other)) {
376  return rpow(down_cast<const Complex &>(other));
377  } else if (is_a<RealDouble>(other)) {
378  return rpow(down_cast<const RealDouble &>(other));
379  } else if (is_a<ComplexDouble>(other)) {
380  return rpow(down_cast<const ComplexDouble &>(other));
381  } else if (is_a<RealMPFR>(other)) {
382  return rpow(down_cast<const RealMPFR &>(other));
383  } else {
384  throw NotImplementedError("Not Implemented");
385  }
386  }
387 };
388 
389 inline RCP<const ComplexMPC> complex_mpc(mpc_class x)
390 {
391  return rcp(new ComplexMPC(std::move(x)));
392 }
393 } // namespace SymEngine
394 #else
395 
396 namespace SymEngine
397 {
398 class ComplexMPC : public ComplexBase
399 {
400 public:
401  IMPLEMENT_TYPEID(SYMENGINE_COMPLEX_MPC)
402 };
403 } // namespace SymEngine
404 
405 #endif // HAVE_SYMENGINE_MPC
406 #endif // SymEngine
#define IMPLEMENT_TYPEID(SYMENGINE_ID)
Inline members and functions.
Definition: basic.h:340
T c_str(T... args)
Basic()
Constructor.
Definition: basic.h:120
virtual bool __eq__(const Basic &o) const =0
Test equality.
virtual hash_t __hash__() const =0
virtual int compare(const Basic &o) const =0
ComplexBase Class for deriving all complex classes.
Definition: complex.h:16
virtual Evaluate & get_eval() const
Get Evaluate singleton to evaluate numerically.
Definition: number.h:47
virtual RCP< const Number > mul(const Number &other) const =0
Multiplication.
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 RCP< const Number > pow(const Number &other) const =0
Power.
virtual bool is_negative() const =0
virtual RCP< const Basic > conjugate() const
Definition: number.cpp:8
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
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19