Loading...
Searching...
No Matches
eval.cpp
1#include <exception>
2#include <symengine/eval.h>
4#include <symengine/real_double.h>
5#include <symengine/complex_double.h>
6#include <symengine/symengine_rcp.h>
7#include <symengine/visitor.h>
8#ifdef HAVE_SYMENGINE_MPFR
9#include <mpfr.h>
10#include <symengine/real_mpfr.h>
11#include <symengine/eval_mpfr.h>
12#endif // HAVE_SYMENGINE_MPFR
13
14#ifdef HAVE_SYMENGINE_MPC
15#include <mpc.h>
16#include <symengine/complex_mpc.h>
17#include <symengine/eval_mpc.h>
18#endif // HAVE_SYMENGINE_MPC
19
20namespace SymEngine
21{
22
23RCP<const Number> evalf_numeric(const Basic &b, unsigned long bits, bool real)
24{
25 if (bits <= 53 && real) { // double
26 double d = eval_double(b);
27 return real_double(d);
28 } else if (bits <= 53 && !real) { // complex double
29 std::complex<double> d = eval_complex_double(b);
30 return complex_double(d);
31 } else if (bits > 53 && real) { // mpfr
32#ifdef HAVE_SYMENGINE_MPFR
33 mpfr_class mc = mpfr_class(bits);
34 mpfr_ptr result = mc.get_mpfr_t();
37#else
39 "For multiple bit precision, MPFR is needed");
40#endif // HAVE_SYMENGINE_MPFR
41 } else { // mpc
42#ifdef HAVE_SYMENGINE_MPC
43 mpc_class mc = mpc_class(bits);
44 mpc_ptr result = mc.get_mpc_t();
47#else
49 "For multiple bit precision, MPC is needed");
50#endif // HAVE_SYMENGINE_MPC
51 }
52}
53
54class EvalVisitor : public BaseVisitor<EvalVisitor, TransformVisitor>
55{
56protected:
57 unsigned long bits;
58
59public:
60 EvalVisitor(unsigned long bits) : bits(bits) {}
61 using TransformVisitor::apply;
62 using TransformVisitor::bvisit;
63 void bvisit(const Number &x)
64 {
65 result_ = evalf_numeric(x, bits, true);
66 }
67 void bvisit(const ComplexBase &x)
68 {
69 result_ = evalf_numeric(x, bits, false);
70 }
71 void bvisit(const Constant &x)
72 {
73 result_ = evalf_numeric(x, bits, true);
74 }
75 void bvisit(const NumberWrapper &x)
76 {
77 result_ = x.eval(bits)->rcp_from_this();
78 }
79 void bvisit(const FunctionWrapper &x)
80 {
81 result_ = x.eval(bits)->rcp_from_this();
82 }
83};
84
85RCP<const Basic> evalf(const Basic &b, unsigned long bits, EvalfDomain domain)
86{
87#ifndef HAVE_SYMENGINE_MPFR
88 if (bits > 53) {
90 "For multiple bit precision, MPFR is needed");
91 }
92#endif
93#ifndef HAVE_SYMENGINE_MPC
94 if (bits > 53 and domain == EvalfDomain::Complex) {
96 "For multiple bit precision, MPC is needed");
97 }
98#endif
99 if (domain == EvalfDomain::Real) {
100 return evalf_numeric(b, bits, true);
101 } else if (domain == EvalfDomain::Complex) {
102 return evalf_numeric(b, bits, false);
103 }
104
105 EvalVisitor v(bits);
106 return v.apply(b.rcp_from_this());
107}
108
109} // namespace SymEngine
The lowest unit of symbolic representation.
Definition basic.h:97
ComplexBase Class for deriving all complex classes.
Definition complex.h:16
RCP< T > rcp_from_this()
Get RCP<T> pointer to self (it will cast the pointer to T)
T move(T... args)
Main namespace for SymEngine package.
Definition add.cpp:19
void hash_combine(hash_t &seed, const T &v)
Definition basic-inl.h:95