Loading...
Searching...
No Matches
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
15namespace SymEngine
16{
17
18class mpc_class
19{
20private:
21 mpc_t mp;
22
23public:
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
79RCP<const Number> number(mpfr_ptr x);
80
82class ComplexMPC : public ComplexBase
83{
84private:
85 mpc_class i;
86
87public:
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
389inline RCP<const ComplexMPC> complex_mpc(mpc_class x)
390{
391 return rcp(new ComplexMPC(std::move(x)));
392}
393} // namespace SymEngine
394#else
395
396namespace SymEngine
397{
399{
400public:
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)
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 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 bool is_negative() const =0
virtual RCP< const Number > pow(const Number &other) const =0
Power.
virtual RCP< const Basic > conjugate() const
Definition: number.cpp:8
virtual bool is_positive() const =0
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
RCP< const Basic > div(const RCP< const Basic > &a, const RCP< const Basic > &b)
Division.
Definition: mul.cpp:431
RCP< const Basic > sub(const RCP< const Basic > &a, const RCP< const Basic > &b)
Substracts b from a.
Definition: add.cpp:495
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352
RCP< const Basic > add(const RCP< const Basic > &a, const RCP< const Basic > &b)
Adds two objects (safely).
Definition: add.cpp:425