real_double.cpp
1 
6 #include <symengine/complex_double.h>
8 
9 namespace SymEngine
10 {
11 
13 {
14  SYMENGINE_ASSIGN_TYPEID()
15  this->i = i;
16 }
17 
18 hash_t RealDouble::__hash__() const
19 {
20  hash_t seed = SYMENGINE_REAL_DOUBLE;
21  hash_combine<double>(seed, i);
22  return seed;
23 }
24 
25 bool RealDouble::__eq__(const Basic &o) const
26 {
27  if (is_a<RealDouble>(o)) {
28  const RealDouble &s = down_cast<const RealDouble &>(o);
29  return this->i == s.i;
30  }
31  return false;
32 }
33 
34 int RealDouble::compare(const Basic &o) const
35 {
36  SYMENGINE_ASSERT(is_a<RealDouble>(o))
37  const RealDouble &s = down_cast<const RealDouble &>(o);
38  if (i == s.i)
39  return 0;
40  return i < s.i ? -1 : 1;
41 }
42 
43 RCP<const RealDouble> real_double(double x)
44 {
45  return make_rcp<const RealDouble>(x);
46 }
47 
48 RCP<const Number> number(std::complex<double> x)
49 {
50  return complex_double(x);
51 }
52 
53 RCP<const Number> number(double x)
54 {
55  return real_double(x);
56 }
57 
59 template <class T>
60 class EvaluateDouble : public Evaluate
61 {
62  RCP<const Basic> sin(const Basic &x) const override
63  {
64  SYMENGINE_ASSERT(is_a<T>(x))
65  return number(std::sin(down_cast<const T &>(x).i));
66  }
67  RCP<const Basic> cos(const Basic &x) const override
68  {
69  SYMENGINE_ASSERT(is_a<T>(x))
70  return number(std::cos(down_cast<const T &>(x).i));
71  }
72  RCP<const Basic> tan(const Basic &x) const override
73  {
74  SYMENGINE_ASSERT(is_a<T>(x))
75  return number(std::tan(down_cast<const T &>(x).i));
76  }
77  RCP<const Basic> cot(const Basic &x) const override
78  {
79  SYMENGINE_ASSERT(is_a<T>(x))
80  return number(1.0 / std::tan(down_cast<const T &>(x).i));
81  }
82  RCP<const Basic> sec(const Basic &x) const override
83  {
84  SYMENGINE_ASSERT(is_a<T>(x))
85  return number(1.0 / std::cos(down_cast<const T &>(x).i));
86  }
87  RCP<const Basic> csc(const Basic &x) const override
88  {
89  SYMENGINE_ASSERT(is_a<T>(x))
90  return number(1.0 / std::sin(down_cast<const T &>(x).i));
91  }
92  RCP<const Basic> atan(const Basic &x) const override
93  {
94  SYMENGINE_ASSERT(is_a<T>(x))
95  return number(std::atan(down_cast<const T &>(x).i));
96  }
97  RCP<const Basic> acot(const Basic &x) const override
98  {
99  SYMENGINE_ASSERT(is_a<T>(x))
100  return number(std::atan(1.0 / down_cast<const T &>(x).i));
101  }
102  RCP<const Basic> sinh(const Basic &x) const override
103  {
104  SYMENGINE_ASSERT(is_a<T>(x))
105  return number(std::sinh(down_cast<const T &>(x).i));
106  }
107  RCP<const Basic> csch(const Basic &x) const override
108  {
109  SYMENGINE_ASSERT(is_a<T>(x))
110  return number(1.0 / std::sinh(down_cast<const T &>(x).i));
111  }
112  RCP<const Basic> cosh(const Basic &x) const override
113  {
114  SYMENGINE_ASSERT(is_a<T>(x))
115  return number(std::cosh(down_cast<const T &>(x).i));
116  }
117  RCP<const Basic> sech(const Basic &x) const override
118  {
119  SYMENGINE_ASSERT(is_a<T>(x))
120  return number(1.0 / std::cosh(down_cast<const T &>(x).i));
121  }
122  RCP<const Basic> tanh(const Basic &x) const override
123  {
124  SYMENGINE_ASSERT(is_a<T>(x))
125  return number(std::tanh(down_cast<const T &>(x).i));
126  }
127  RCP<const Basic> coth(const Basic &x) const override
128  {
129  SYMENGINE_ASSERT(is_a<T>(x))
130  return number(1.0 / std::tanh(down_cast<const T &>(x).i));
131  }
132  RCP<const Basic> asinh(const Basic &x) const override
133  {
134  SYMENGINE_ASSERT(is_a<T>(x))
135  return number(std::asinh(down_cast<const T &>(x).i));
136  }
137  RCP<const Basic> acsch(const Basic &x) const override
138  {
139  SYMENGINE_ASSERT(is_a<T>(x))
140  return number(std::asinh(1.0 / down_cast<const T &>(x).i));
141  }
142  RCP<const Basic> abs(const Basic &x) const override
143  {
144  SYMENGINE_ASSERT(is_a<T>(x))
145  return number(std::abs(down_cast<const T &>(x).i));
146  }
147  RCP<const Basic> exp(const Basic &x) const override
148  {
149  SYMENGINE_ASSERT(is_a<T>(x))
150  return number(std::exp(down_cast<const T &>(x).i));
151  }
152 };
153 
154 class EvaluateRealDouble : public EvaluateDouble<RealDouble>
155 {
156  RCP<const Basic> gamma(const Basic &x) const override
157  {
158  SYMENGINE_ASSERT(is_a<RealDouble>(x))
159  return number(std::tgamma(down_cast<const RealDouble &>(x).i));
160  }
161  RCP<const Basic> asin(const Basic &x) const override
162  {
163  SYMENGINE_ASSERT(is_a<RealDouble>(x))
164  double d = down_cast<const RealDouble &>(x).i;
165  if (d <= 1.0 and d >= -1.0) {
166  return number(std::asin(d));
167  } else {
168  return number(std::asin(std::complex<double>(d)));
169  }
170  }
171  RCP<const Basic> acos(const Basic &x) const override
172  {
173  SYMENGINE_ASSERT(is_a<RealDouble>(x))
174  double d = down_cast<const RealDouble &>(x).i;
175  if (d <= 1.0 and d >= -1.0) {
176  return number(std::acos(d));
177  } else {
178  return number(std::acos(std::complex<double>(d)));
179  }
180  }
181  RCP<const Basic> acsc(const Basic &x) const override
182  {
183  SYMENGINE_ASSERT(is_a<RealDouble>(x))
184  double d = down_cast<const RealDouble &>(x).i;
185  if (d >= 1.0 or d <= -1.0) {
186  return number(std::asin(1.0 / d));
187  } else {
188  return number(std::asin(1.0 / std::complex<double>(d)));
189  }
190  }
191  RCP<const Basic> asec(const Basic &x) const override
192  {
193  SYMENGINE_ASSERT(is_a<RealDouble>(x))
194  double d = down_cast<const RealDouble &>(x).i;
195  if (d >= 1.0 or d <= -1.0) {
196  return number(std::acos(1.0 / d));
197  } else {
198  return number(std::acos(1.0 / std::complex<double>(d)));
199  }
200  }
201  RCP<const Basic> acosh(const Basic &x) const override
202  {
203  SYMENGINE_ASSERT(is_a<RealDouble>(x))
204  double d = down_cast<const RealDouble &>(x).i;
205  if (d >= 1.0) {
206  return number(std::acosh(d));
207  } else {
208  return number(std::acosh(std::complex<double>(d)));
209  }
210  }
211  RCP<const Basic> atanh(const Basic &x) const override
212  {
213  SYMENGINE_ASSERT(is_a<RealDouble>(x))
214  double d = down_cast<const RealDouble &>(x).i;
215  if (d <= 1.0 and d >= -1.0) {
216  return number(std::atanh(d));
217  } else {
218  return number(std::atanh(std::complex<double>(d)));
219  }
220  }
221  RCP<const Basic> acoth(const Basic &x) const override
222  {
223  SYMENGINE_ASSERT(is_a<RealDouble>(x))
224  double d = down_cast<const RealDouble &>(x).i;
225  if (d >= 1.0 or d <= -1.0) {
226  return number(std::atanh(1.0 / d));
227  } else {
228  return number(std::atanh(1.0 / std::complex<double>(d)));
229  }
230  }
231  RCP<const Basic> asech(const Basic &x) const override
232  {
233  SYMENGINE_ASSERT(is_a<RealDouble>(x))
234  double d = down_cast<const RealDouble &>(x).i;
235  if (d <= 1.0 and d >= 0.0) {
236  return number(std::acosh(1.0 / d));
237  } else {
238  return number(std::acosh(1.0 / std::complex<double>(d)));
239  }
240  }
241  RCP<const Basic> log(const Basic &x) const override
242  {
243  SYMENGINE_ASSERT(is_a<RealDouble>(x))
244  double d = down_cast<const RealDouble &>(x).i;
245  if (d >= 0.0) {
246  return number(std::log(d));
247  } else {
248  return number(std::log(std::complex<double>(d)));
249  }
250  }
251  RCP<const Basic> floor(const Basic &x) const override
252  {
253  SYMENGINE_ASSERT(is_a<RealDouble>(x))
254  integer_class i;
255  mp_set_d(i, std::floor(down_cast<const RealDouble &>(x).i));
256  return integer(std::move(i));
257  }
258  RCP<const Basic> ceiling(const Basic &x) const override
259  {
260  SYMENGINE_ASSERT(is_a<RealDouble>(x))
261  integer_class i;
262  mp_set_d(i, std::ceil(down_cast<const RealDouble &>(x).i));
263  return integer(std::move(i));
264  }
265  RCP<const Basic> truncate(const Basic &x) const override
266  {
267  SYMENGINE_ASSERT(is_a<RealDouble>(x))
268  integer_class i;
269  mp_set_d(i, std::trunc(down_cast<const RealDouble &>(x).i));
270  return integer(std::move(i));
271  }
272  RCP<const Basic> erf(const Basic &x) const override
273  {
274  SYMENGINE_ASSERT(is_a<RealDouble>(x))
275  return number(std::erf(down_cast<const RealDouble &>(x).i));
276  }
277  RCP<const Basic> erfc(const Basic &x) const override
278  {
279  SYMENGINE_ASSERT(is_a<RealDouble>(x))
280  return number(std::erfc(down_cast<const RealDouble &>(x).i));
281  }
282 };
283 
284 class EvaluateComplexDouble : public EvaluateDouble<ComplexDouble>
285 {
286  RCP<const Basic> gamma(const Basic &x) const override
287  {
288  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
289  throw NotImplementedError("Not Implemented.");
290  }
291  RCP<const Basic> asin(const Basic &x) const override
292  {
293  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
294  return number(std::asin(down_cast<const ComplexDouble &>(x).i));
295  }
296  RCP<const Basic> acos(const Basic &x) const override
297  {
298  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
299  return number(std::acos(down_cast<const ComplexDouble &>(x).i));
300  }
301  RCP<const Basic> acsc(const Basic &x) const override
302  {
303  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
304  return number(std::asin(1.0 / down_cast<const ComplexDouble &>(x).i));
305  }
306  RCP<const Basic> asec(const Basic &x) const override
307  {
308  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
309  return number(std::acos(1.0 / down_cast<const ComplexDouble &>(x).i));
310  }
311  RCP<const Basic> acosh(const Basic &x) const override
312  {
313  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
314  return number(std::acosh(down_cast<const ComplexDouble &>(x).i));
315  }
316  RCP<const Basic> atanh(const Basic &x) const override
317  {
318  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
319  return number(std::atanh(down_cast<const ComplexDouble &>(x).i));
320  }
321  RCP<const Basic> acoth(const Basic &x) const override
322  {
323  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
324  return number(std::atanh(1.0 / down_cast<const ComplexDouble &>(x).i));
325  }
326  RCP<const Basic> asech(const Basic &x) const override
327  {
328  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
329  return number(std::acosh(1.0 / down_cast<const ComplexDouble &>(x).i));
330  }
331  RCP<const Basic> log(const Basic &x) const override
332  {
333  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
334  return number(std::log(down_cast<const ComplexDouble &>(x).i));
335  }
336  RCP<const Basic> floor(const Basic &x) const override
337  {
338  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
339  integer_class re, im;
340  mp_set_d(re, std::floor(down_cast<const ComplexDouble &>(x).i.real()));
341  mp_set_d(im, std::floor(down_cast<const ComplexDouble &>(x).i.imag()));
343  *integer(std::move(im)));
344  }
345  RCP<const Basic> ceiling(const Basic &x) const override
346  {
347  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
348  integer_class re, im;
349  mp_set_d(re, std::ceil(down_cast<const ComplexDouble &>(x).i.real()));
350  mp_set_d(im, std::ceil(down_cast<const ComplexDouble &>(x).i.imag()));
352  *integer(std::move(im)));
353  }
354  RCP<const Basic> truncate(const Basic &x) const override
355  {
356  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
357  integer_class re, im;
358  mp_set_d(re, std::trunc(down_cast<const ComplexDouble &>(x).i.real()));
359  mp_set_d(im, std::trunc(down_cast<const ComplexDouble &>(x).i.imag()));
361  *integer(std::move(im)));
362  }
363  RCP<const Basic> erf(const Basic &x) const override
364  {
365  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
366  throw NotImplementedError("erf is not implemented for Complex numbers");
367  }
368  RCP<const Basic> erfc(const Basic &x) const override
369  {
370  SYMENGINE_ASSERT(is_a<ComplexDouble>(x))
371  throw NotImplementedError(
372  "erfc is not implemented for Complex numbers");
373  }
374 };
375 
377 {
378  static EvaluateRealDouble evaluate_real_double;
379  return evaluate_real_double;
380 }
381 
383 {
384  static EvaluateComplexDouble evaluate_complex_double;
385  return evaluate_complex_double;
386 }
387 
388 } // namespace SymEngine
T acos(T... args)
T acosh(T... args)
T asin(T... args)
T asinh(T... args)
T atan(T... args)
T atanh(T... args)
T ceil(T... args)
The lowest unit of symbolic representation.
Definition: basic.h:97
Evaluate & get_eval() const override
Get Evaluate singleton to evaluate numerically.
static RCP< const Number > from_two_nums(const Number &re, const Number &im)
Definition: complex.cpp:109
Evaluate functions with double precision.
Definition: real_double.cpp:61
A class that will evaluate functions numerically.
Definition: number.h:200
RealDouble Class to hold double values.
Definition: real_double.h:20
hash_t __hash__() const override
Definition: real_double.cpp:18
Evaluate & get_eval() const override
Get Evaluate singleton to evaluate numerically.
bool __eq__(const Basic &o) const override
Definition: real_double.cpp:25
int compare(const Basic &o) const override
Definition: real_double.cpp:34
RealDouble(double i)
Constructor of RealDouble class.
Definition: real_double.cpp:12
T cos(T... args)
T cosh(T... args)
T erf(T... args)
T erfc(T... args)
T exp(T... args)
T floor(T... args)
T log(T... args)
T move(T... args)
Main namespace for SymEngine package.
Definition: add.cpp:19
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197
T sin(T... args)
T sinh(T... args)
T tan(T... args)
T tanh(T... args)
T tgamma(T... args)
T trunc(T... args)