31 #ifndef ONCE_FPARSER_AUX_H_
32 #define ONCE_FPARSER_AUX_H_
38 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
39 #include "mpfr/MpfrFloat.h"
42 #ifdef FP_SUPPORT_GMP_INT_TYPE
43 #include "mpfr/GmpInt.h"
46 #ifdef FP_SUPPORT_COMPLEX_NUMBERS
50 #ifdef ONCE_FPARSER_H_
51 namespace FUNCTIONPARSERTYPES
56 enum { result =
false };
59 struct IsIntType<long>
61 enum { result =
true };
63 #ifdef FP_SUPPORT_GMP_INT_TYPE
65 struct IsIntType<GmpInt>
67 enum { result =
true };
74 enum { result =
false };
76 #ifdef FP_SUPPORT_COMPLEX_NUMBERS
78 struct IsComplexType<std::complex<T> >
80 enum { result =
true };
88 template<
typename Value_t>
89 inline Value_t fp_const_pi()
91 return Value_t(3.1415926535897932384626433832795028841971693993751L);
94 template<
typename Value_t>
95 inline Value_t fp_const_e()
97 return Value_t(2.7182818284590452353602874713526624977572L);
99 template<
typename Value_t>
100 inline Value_t fp_const_einv()
102 return Value_t(0.367879441171442321595523770161460867445811131L);
104 template<
typename Value_t>
105 inline Value_t fp_const_log2()
107 return Value_t(0.69314718055994530941723212145817656807550013436025525412L);
109 template<
typename Value_t>
110 inline Value_t fp_const_log10()
112 return Value_t(2.302585092994045684017991454684364207601101488628772976L);
114 template<
typename Value_t>
115 inline Value_t fp_const_log2inv()
117 return Value_t(1.442695040888963407359924681001892137426645954L);
119 template<
typename Value_t>
120 inline Value_t fp_const_log10inv()
122 return Value_t(0.434294481903251827651128918916605082294397L);
125 template<
typename Value_t>
126 inline const Value_t& fp_const_deg_to_rad()
128 static const Value_t factor = fp_const_pi<Value_t>() / Value_t(180);
132 template<
typename Value_t>
133 inline const Value_t& fp_const_rad_to_deg()
135 static const Value_t factor = Value_t(180) / fp_const_pi<Value_t>();
139 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
141 inline MpfrFloat fp_const_pi<MpfrFloat>() {
return MpfrFloat::const_pi(); }
144 inline MpfrFloat fp_const_e<MpfrFloat>() {
return MpfrFloat::const_e(); }
147 inline MpfrFloat fp_const_einv<MpfrFloat>() {
return MpfrFloat(1) / MpfrFloat::const_e(); }
150 inline MpfrFloat fp_const_log2<MpfrFloat>() {
return MpfrFloat::const_log2(); }
168 template<
typename Value_t>
169 inline Value_t fp_abs(
const Value_t& x) {
return std::fabs(x); }
171 template<
typename Value_t>
172 inline Value_t fp_acos(
const Value_t& x) {
return std::acos(x); }
174 template<
typename Value_t>
175 inline Value_t fp_asin(
const Value_t& x) {
return std::asin(x); }
177 template<
typename Value_t>
178 inline Value_t fp_atan(
const Value_t& x) {
return std::atan(x); }
180 template<
typename Value_t>
181 inline Value_t fp_atan2(
const Value_t& x,
const Value_t& y)
182 {
return std::atan2(x, y); }
184 template<
typename Value_t>
185 inline Value_t fp_ceil(
const Value_t& x) {
return std::ceil(x); }
187 template<
typename Value_t>
188 inline Value_t fp_cos(
const Value_t& x) {
return std::cos(x); }
190 template<
typename Value_t>
191 inline Value_t fp_cosh(
const Value_t& x) {
return std::cosh(x); }
193 template<
typename Value_t>
194 inline Value_t fp_exp(
const Value_t& x) {
return std::exp(x); }
196 template<
typename Value_t>
197 inline Value_t fp_floor(
const Value_t& x) {
return std::floor(x); }
199 template<
typename Value_t>
200 inline Value_t fp_log(
const Value_t& x) {
return std::log(x); }
202 template<
typename Value_t>
203 inline Value_t fp_mod(
const Value_t& x,
const Value_t& y)
204 {
return std::fmod(x, y); }
206 template<
typename Value_t>
207 inline Value_t fp_sin(
const Value_t& x) {
return std::sin(x); }
209 template<
typename Value_t>
210 inline Value_t fp_sinh(
const Value_t& x) {
return std::sinh(x); }
212 template<
typename Value_t>
213 inline Value_t fp_sqrt(
const Value_t& x) {
return std::sqrt(x); }
215 template<
typename Value_t>
216 inline Value_t fp_tan(
const Value_t& x) {
return std::tan(x); }
218 template<
typename Value_t>
219 inline Value_t fp_tanh(
const Value_t& x) {
return std::tanh(x); }
221 #ifdef O2SCL_NEVER_DEFINED
224 template<
typename Value_t>
225 inline Value_t fp_asinh(
const Value_t& x) {
return std::asinh(x); }
227 template<
typename Value_t>
228 inline Value_t fp_acosh(
const Value_t& x) {
return std::acosh(x); }
230 template<
typename Value_t>
231 inline Value_t fp_atanh(
const Value_t& x) {
return std::atanh(x); }
235 template<
typename Value_t>
236 inline Value_t fp_asinh(
const Value_t& x)
237 {
return fp_log(x + fp_sqrt(x*x + Value_t(1))); }
239 template<
typename Value_t>
240 inline Value_t fp_acosh(
const Value_t& x)
241 {
return fp_log(x + fp_sqrt(x*x - Value_t(1))); }
243 template<
typename Value_t>
244 inline Value_t fp_atanh(
const Value_t& x)
246 return fp_log( (Value_t(1)+x) / (Value_t(1)-x)) * Value_t(0.5);
251 #endif // FP_SUPPORT_ASINH
253 #if __cplusplus > 201100
254 template<
typename Value_t>
255 inline Value_t fp_hypot(
const Value_t& x,
const Value_t& y)
256 {
return hypot(x,y); }
258 template<
typename Value_t>
259 inline Value_t fp_hypot(
const Value_t& x,
const Value_t& y)
260 {
return fp_sqrt(x*x + y*y); }
263 template<
typename Value_t>
264 inline Value_t fp_pow_base(
const Value_t& x,
const Value_t& y)
265 {
return std::pow(x, y); }
267 #if __cplusplus > 201100
268 template<
typename Value_t>
269 inline Value_t fp_log2(
const Value_t& x) {
return log2(x); }
271 template<
typename Value_t>
272 inline Value_t fp_log2(
const Value_t& x)
274 return fp_log(x) * fp_const_log2inv<Value_t>();
276 #endif // FP_SUPPORT_LOG2
278 template<
typename Value_t>
279 inline Value_t fp_log10(
const Value_t& x)
281 return fp_log(x) * fp_const_log10inv<Value_t>();
284 template<
typename Value_t>
285 inline Value_t fp_trunc(
const Value_t& x)
287 return x < Value_t() ? fp_ceil(x) : fp_floor(x);
290 template<
typename Value_t>
291 inline Value_t fp_int(
const Value_t& x)
293 return x < Value_t() ?
294 fp_ceil(x - Value_t(0.5)) : fp_floor(x + Value_t(0.5));
297 template<
typename Value_t>
298 inline void fp_sinCos(Value_t& sinvalue, Value_t& cosvalue,
299 const Value_t& param)
303 cosvalue = fp_cos(param);
304 sinvalue = fp_sin(param);
307 template<
typename Value_t>
308 inline void fp_sinhCosh(Value_t& sinhvalue, Value_t& coshvalue,
309 const Value_t& param)
311 const Value_t ex(fp_exp(param)), emx(fp_exp(-param));
312 sinhvalue = Value_t(0.5)*(ex-emx);
313 coshvalue = Value_t(0.5)*(ex+emx);
316 template<
typename Value_t>
317 inline Value_t fp_epsilon()
319 return FunctionParserBase<Value_t>::epsilon();
324 inline void fp_sinCos(
double& sin,
double& cos,
const double& a)
326 sincos(a, &sin, &cos);
328 inline void fp_sinCos(
float& sin,
float& cos,
const float& a)
330 sincosf(a, &sin, &cos);
332 inline void fp_sinCos(
long double& sin,
long double& cos,
333 const long double& a)
335 sincosl(a, &sin, &cos);
343 inline long fp_abs(
const long& x) {
return x < 0 ? -x : x; }
344 inline long fp_acos(
const long&) {
return 0; }
345 inline long fp_asin(
const long&) {
return 0; }
346 inline long fp_atan(
const long&) {
return 0; }
347 inline long fp_atan2(
const long&,
const long&) {
return 0; }
348 inline long fp_cbrt(
const long&) {
return 0; }
349 inline long fp_ceil(
const long& x) {
return x; }
350 inline long fp_cos(
const long&) {
return 0; }
351 inline long fp_cosh(
const long&) {
return 0; }
352 inline long fp_exp(
const long&) {
return 0; }
353 inline long fp_exp2(
const long&) {
return 0; }
354 inline long fp_floor(
const long& x) {
return x; }
355 inline long fp_log(
const long&) {
return 0; }
356 inline long fp_log2(
const long&) {
return 0; }
357 inline long fp_log10(
const long&) {
return 0; }
358 inline long fp_mod(
const long& x,
const long& y) {
return x % y; }
359 inline long fp_pow(
const long&,
const long&) {
return 0; }
360 inline long fp_sin(
const long&) {
return 0; }
361 inline long fp_sinh(
const long&) {
return 0; }
362 inline long fp_sqrt(
const long&) {
return 1; }
363 inline long fp_tan(
const long&) {
return 0; }
364 inline long fp_tanh(
const long&) {
return 0; }
365 inline long fp_asinh(
const long&) {
return 0; }
366 inline long fp_acosh(
const long&) {
return 0; }
367 inline long fp_atanh(
const long&) {
return 0; }
368 inline long fp_pow_base(
const long&,
const long&) {
return 0; }
369 inline void fp_sinCos(
long&,
long&,
const long&) {}
370 inline void fp_sinhCosh(
long&,
long&,
const long&) {}
372 template<>
inline long fp_epsilon<long>() {
return 0; }
378 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
379 inline MpfrFloat fp_abs(
const MpfrFloat& x) {
return MpfrFloat::abs(x); }
380 inline MpfrFloat fp_acos(
const MpfrFloat& x) {
return MpfrFloat::acos(x); }
381 inline MpfrFloat fp_acosh(
const MpfrFloat& x) {
return MpfrFloat::acosh(x); }
382 inline MpfrFloat fp_asin(
const MpfrFloat& x) {
return MpfrFloat::asin(x); }
383 inline MpfrFloat fp_asinh(
const MpfrFloat& x) {
return MpfrFloat::asinh(x); }
384 inline MpfrFloat fp_atan(
const MpfrFloat& x) {
return MpfrFloat::atan(x); }
385 inline MpfrFloat fp_atan2(
const MpfrFloat& x,
const MpfrFloat& y)
386 {
return MpfrFloat::atan2(x, y); }
387 inline MpfrFloat fp_atanh(
const MpfrFloat& x) {
return MpfrFloat::atanh(x); }
388 inline MpfrFloat fp_cbrt(
const MpfrFloat& x) {
return MpfrFloat::cbrt(x); }
389 inline MpfrFloat fp_ceil(
const MpfrFloat& x) {
return MpfrFloat::ceil(x); }
390 inline MpfrFloat fp_cos(
const MpfrFloat& x) {
return MpfrFloat::cos(x); }
391 inline MpfrFloat fp_cosh(
const MpfrFloat& x) {
return MpfrFloat::cosh(x); }
392 inline MpfrFloat fp_exp(
const MpfrFloat& x) {
return MpfrFloat::exp(x); }
393 inline MpfrFloat fp_exp2(
const MpfrFloat& x) {
return MpfrFloat::exp2(x); }
394 inline MpfrFloat fp_floor(
const MpfrFloat& x) {
return MpfrFloat::floor(x); }
395 inline MpfrFloat fp_hypot(
const MpfrFloat& x,
const MpfrFloat& y)
396 {
return MpfrFloat::hypot(x, y); }
397 inline MpfrFloat fp_int(
const MpfrFloat& x) {
return MpfrFloat::round(x); }
398 inline MpfrFloat fp_log(
const MpfrFloat& x) {
return MpfrFloat::log(x); }
399 inline MpfrFloat fp_log2(
const MpfrFloat& x) {
return MpfrFloat::log2(x); }
400 inline MpfrFloat fp_log10(
const MpfrFloat& x) {
return MpfrFloat::log10(x); }
401 inline MpfrFloat fp_mod(
const MpfrFloat& x,
const MpfrFloat& y) {
return x % y; }
402 inline MpfrFloat fp_sin(
const MpfrFloat& x) {
return MpfrFloat::sin(x); }
403 inline MpfrFloat fp_sinh(
const MpfrFloat& x) {
return MpfrFloat::sinh(x); }
404 inline MpfrFloat fp_sqrt(
const MpfrFloat& x) {
return MpfrFloat::sqrt(x); }
405 inline MpfrFloat fp_tan(
const MpfrFloat& x) {
return MpfrFloat::tan(x); }
406 inline MpfrFloat fp_tanh(
const MpfrFloat& x) {
return MpfrFloat::tanh(x); }
407 inline MpfrFloat fp_trunc(
const MpfrFloat& x) {
return MpfrFloat::trunc(x); }
409 inline MpfrFloat fp_pow(
const MpfrFloat& x,
const MpfrFloat& y) {
return MpfrFloat::pow(x, y); }
410 inline MpfrFloat fp_pow_base(
const MpfrFloat& x,
const MpfrFloat& y) {
return MpfrFloat::pow(x, y); }
413 inline void fp_sinCos(MpfrFloat& sin, MpfrFloat& cos,
const MpfrFloat& a)
415 MpfrFloat::sincos(a, sin, cos);
418 inline void fp_sinhCosh(MpfrFloat& sinhvalue, MpfrFloat& coshvalue,
419 const MpfrFloat& param)
421 const MpfrFloat paramCopy = param;
422 sinhvalue = fp_sinh(paramCopy);
423 coshvalue = fp_cosh(paramCopy);
427 inline MpfrFloat fp_epsilon<MpfrFloat>() {
return MpfrFloat::someEpsilon(); }
428 #endif // FP_SUPPORT_MPFR_FLOAT_TYPE
434 #ifdef FP_SUPPORT_GMP_INT_TYPE
435 inline GmpInt fp_abs(
const GmpInt& x) {
return GmpInt::abs(x); }
436 inline GmpInt fp_acos(
const GmpInt&) {
return 0; }
437 inline GmpInt fp_acosh(
const GmpInt&) {
return 0; }
438 inline GmpInt fp_asin(
const GmpInt&) {
return 0; }
439 inline GmpInt fp_asinh(
const GmpInt&) {
return 0; }
440 inline GmpInt fp_atan(
const GmpInt&) {
return 0; }
441 inline GmpInt fp_atan2(
const GmpInt&,
const GmpInt&) {
return 0; }
442 inline GmpInt fp_atanh(
const GmpInt&) {
return 0; }
443 inline GmpInt fp_cbrt(
const GmpInt&) {
return 0; }
444 inline GmpInt fp_ceil(
const GmpInt& x) {
return x; }
445 inline GmpInt fp_cos(
const GmpInt&) {
return 0; }
446 inline GmpInt fp_cosh(
const GmpInt&) {
return 0; }
447 inline GmpInt fp_exp(
const GmpInt&) {
return 0; }
448 inline GmpInt fp_exp2(
const GmpInt&) {
return 0; }
449 inline GmpInt fp_floor(
const GmpInt& x) {
return x; }
450 inline GmpInt fp_hypot(
const GmpInt&,
const GmpInt&) {
return 0; }
451 inline GmpInt fp_int(
const GmpInt& x) {
return x; }
452 inline GmpInt fp_log(
const GmpInt&) {
return 0; }
453 inline GmpInt fp_log2(
const GmpInt&) {
return 0; }
454 inline GmpInt fp_log10(
const GmpInt&) {
return 0; }
455 inline GmpInt fp_mod(
const GmpInt& x,
const GmpInt& y) {
return x % y; }
456 inline GmpInt fp_pow(
const GmpInt&,
const GmpInt&) {
return 0; }
457 inline GmpInt fp_sin(
const GmpInt&) {
return 0; }
458 inline GmpInt fp_sinh(
const GmpInt&) {
return 0; }
459 inline GmpInt fp_sqrt(
const GmpInt&) {
return 0; }
460 inline GmpInt fp_tan(
const GmpInt&) {
return 0; }
461 inline GmpInt fp_tanh(
const GmpInt&) {
return 0; }
462 inline GmpInt fp_trunc(
const GmpInt& x) {
return x; }
463 inline GmpInt fp_pow_base(
const GmpInt&,
const GmpInt&) {
return 0; }
464 inline void fp_sinCos(GmpInt&, GmpInt&,
const GmpInt&) {}
465 inline void fp_sinhCosh(GmpInt&, GmpInt&,
const GmpInt&) {}
468 inline GmpInt fp_epsilon<GmpInt>() {
return 0; }
469 #endif // FP_SUPPORT_GMP_INT_TYPE
472 #if __cplusplus > 201100
473 template<
typename Value_t>
474 inline Value_t fp_cbrt(
const Value_t& x) {
return cbrt(x); }
476 template<
typename Value_t>
477 inline Value_t fp_cbrt(
const Value_t& x)
479 return (x > Value_t() ? fp_exp(fp_log( x) / Value_t(3)) :
480 x < Value_t() ? -fp_exp(fp_log(-x) / Value_t(3)) :
489 template<
typename Value_t>
inline Value_t fp_arg(
const Value_t& x);
490 template<
typename Value_t>
inline Value_t fp_exp2(
const Value_t& x);
491 template<
typename Value_t>
inline Value_t fp_int(
const Value_t& x);
492 template<
typename Value_t>
inline Value_t fp_trunc(
const Value_t& x);
493 template<
typename Value_t>
494 inline void fp_sinCos(Value_t& , Value_t& ,
const Value_t& );
495 template<
typename Value_t>
496 inline void fp_sinhCosh(Value_t& , Value_t& ,
const Value_t& );
498 #ifdef FP_SUPPORT_COMPLEX_NUMBERS
508 struct FP_ProbablyHasFastLibcComplex
509 {
enum { result =
false }; };
518 template<>
struct FP_ProbablyHasFastLibcComplex<float>
519 {
enum { result =
true }; };
520 template<>
struct FP_ProbablyHasFastLibcComplex<double>
521 {
enum { result =
true }; };
522 template<>
struct FP_ProbablyHasFastLibcComplex<long double>
523 {
enum { result =
true }; };
527 inline const std::complex<T> fp_make_imag(
const std::complex<T>& v)
529 return std::complex<T> ( T(), v.real() );
533 inline std::complex<T> fp_real(
const std::complex<T>& x)
538 inline std::complex<T> fp_imag(
const std::complex<T>& x)
543 inline std::complex<T> fp_arg(
const std::complex<T>& x)
548 inline std::complex<T> fp_conj(
const std::complex<T>& x)
552 template<
typename T,
bool>
553 inline std::complex<T> fp_polar(
const T& x,
const T& y)
555 T si, co; fp_sinCos(si, co, y);
556 return std::complex<T> (x*co, x*si);
559 inline std::complex<T> fp_polar(
const std::complex<T>& x,
const std::complex<T>& y)
562 return fp_polar<T,true> (x.real(), y.real());
569 inline std::complex<T> fp_floor(
const std::complex<T>& x)
571 return std::complex<T> (fp_floor(x.real()), fp_floor(x.imag()));
574 inline std::complex<T> fp_trunc(
const std::complex<T>& x)
576 return std::complex<T> (fp_trunc(x.real()), fp_trunc(x.imag()));
579 inline std::complex<T> fp_int(
const std::complex<T>& x)
581 return std::complex<T> (fp_int(x.real()), fp_int(x.imag()));
584 inline std::complex<T> fp_ceil(
const std::complex<T>& x)
586 return std::complex<T> (fp_ceil(x.real()), fp_ceil(x.imag()));
589 inline std::complex<T> fp_abs(
const std::complex<T>& x)
597 inline std::complex<T> fp_exp(
const std::complex<T>& x)
599 if(FP_ProbablyHasFastLibcComplex<T>::result)
601 return fp_polar<T,true>(fp_exp(x.real()), x.imag());
604 inline std::complex<T> fp_log(
const std::complex<T>& x)
606 if(FP_ProbablyHasFastLibcComplex<T>::result)
611 return std::complex<T>( fp_log(fp_abs(x.real())),
613 return std::complex<T>(
614 fp_log(std::norm(x)) * T(0.5),
618 inline std::complex<T> fp_sqrt(
const std::complex<T>& x)
620 if(FP_ProbablyHasFastLibcComplex<T>::result)
622 return fp_polar<T,true> (fp_sqrt(fp_abs(x).real()),
623 T(0.5)*fp_arg(x).real());
626 inline std::complex<T> fp_acos(
const std::complex<T>& x)
629 const std::complex<T> i (T(), T(1));
630 return -i * fp_log(x + i * fp_sqrt(T(1) - x*x));
635 inline std::complex<T> fp_asin(
const std::complex<T>& x)
638 const std::complex<T> i (T(), T(1));
639 return -i * fp_log(i*x + fp_sqrt(T(1) - x*x));
644 inline std::complex<T> fp_atan(
const std::complex<T>& x)
648 const std::complex<T> i (T(), T(1));
649 return (T(-0.5)*i) * fp_log( (T(1)+i*x) / (T(1)-i*x) );
655 inline std::complex<T> fp_cos(
const std::complex<T>& x)
667 inline std::complex<T> fp_sin(
const std::complex<T>& x)
679 inline void fp_sinCos(
680 std::complex<T>& sinvalue,
681 std::complex<T>& cosvalue,
682 const std::complex<T>& x)
688 T srx, crx; fp_sinCos(srx, crx, x.real());
689 T six, cix; fp_sinhCosh(six, cix, x.imag());
690 sinvalue = std::complex<T>(srx*cix, crx*six);
691 cosvalue = std::complex<T>(crx*cix, -srx*six);
694 inline void fp_sinhCosh(
695 std::complex<T>& sinhvalue,
696 std::complex<T>& coshvalue,
697 const std::complex<T>& x)
699 T srx, crx; fp_sinhCosh(srx, crx, x.real());
700 T six, cix; fp_sinCos(six, cix, x.imag());
701 sinhvalue = std::complex<T>(srx*cix, crx*six);
702 coshvalue = std::complex<T>(crx*cix, srx*six);
705 inline std::complex<T> fp_tan(
const std::complex<T>& x)
718 inline std::complex<T> fp_cosh(
const std::complex<T>& x)
728 inline std::complex<T> fp_sinh(
const std::complex<T>& x)
738 inline std::complex<T> fp_tanh(
const std::complex<T>& x)
750 #if __cplusplus > 201100
752 inline std::complex<T> fp_acosh(
const std::complex<T>& x)
753 {
return fp_log(x + fp_sqrt(x*x - std::complex<T>(1))); }
755 inline std::complex<T> fp_asinh(
const std::complex<T>& x)
756 {
return fp_log(x + fp_sqrt(x*x + std::complex<T>(1))); }
758 inline std::complex<T> fp_atanh(
const std::complex<T>& x)
759 {
return fp_log( (std::complex<T>(1)+x) / (std::complex<T>(1)-x))
760 * std::complex<T>(0.5); }
763 inline std::complex<T> fp_pow(
const std::complex<T>& x,
const std::complex<T>& y)
796 const std::complex<T> t =
799 : std::complex<T> (fp_log(fp_abs(x.real())),
801 return y.imag() != T()
803 : fp_polar<T,true> (fp_exp(y.real()*t.real()), y.real()*t.imag());
806 inline std::complex<T> fp_cbrt(
const std::complex<T>& x)
815 if(x.imag() == T())
return fp_cbrt(x.real());
816 const std::complex<T> t(fp_log(x));
817 return fp_polar<T,true> (fp_exp(t.real() / T(3)), t.imag() / T(3));
821 inline std::complex<T> fp_exp2(
const std::complex<T>& x)
825 return fp_polar<T,true> (fp_exp2(x.real()), x.imag()*fp_const_log2<T>());
828 inline std::complex<T> fp_mod(
const std::complex<T>& x,
const std::complex<T>& y)
833 if(y.imag() == 0)
return fp_mod(x.real(), y.real());
834 std::complex<T> n = fp_trunc(x / y);
844 inline std::ostream& operator<<(std::ostream& os, const std::complex<T>& value)
846 if(value.imag() == T())
return os << value.real();
847 if(value.real() == T())
return os << value.imag() <<
'i';
848 if(value.imag() < T())
849 return os <<
'(' << value.real() <<
"-" << -value.imag() <<
"i)";
851 return os <<
'(' << value.real() <<
"+" << value.imag() <<
"i)";
878 inline T fp_complexScalarize(
const std::complex<T>& x)
881 if(x.real() < T()) res = -res;
885 inline T fp_realComplexScalarize(
const T& x)
888 if(x < T()) res = -res;
893 template<typename T> \
894 inline bool operator op (const std::complex<T>& x, T y) \
895 { return fp_complexScalarize(x) op fp_realComplexScalarize(y); } \
896 template<typename T> \
897 inline bool operator op (const std::complex<T>& x, const std::complex<T>& y) \
898 { return fp_complexScalarize(x) op \
899 fp_complexScalarize(y); } \
900 template<typename T> \
901 inline bool operator op (T x, const std::complex<T>& y) \
902 { return fp_realComplexScalarize(x) op fp_complexScalarize(y); }
903 d( < ) d( <= ) d( > ) d( >= )
907 template<
typename Value_t>
908 inline Value_t fp_real(
const Value_t& x) {
return x; }
909 template<
typename Value_t>
910 inline Value_t fp_imag(
const Value_t& ) {
return Value_t(); }
911 template<
typename Value_t>
912 inline Value_t fp_arg(
const Value_t& x)
913 {
return x < Value_t() ? -fp_const_pi<Value_t>() : Value_t(); }
914 template<
typename Value_t>
915 inline Value_t fp_conj(
const Value_t& x) {
return x; }
916 template<
typename Value_t>
917 inline Value_t fp_polar(
const Value_t& x,
const Value_t& y)
918 {
return x * fp_cos(y); }
920 template<
typename Value_t>
921 inline std::complex<Value_t> fp_atan2(
const std::complex<Value_t>& y,
922 const std::complex<Value_t>& x)
924 if(y == Value_t())
return fp_arg(x);
925 if(x == Value_t())
return fp_const_pi<Value_t>() * Value_t(-0.5);
928 std::complex<Value_t> res( fp_atan(y / (fp_hypot(x,y) + x)) );
935 template<
typename Value_t>
936 inline bool fp_equal(
const Value_t& x,
const Value_t& y)
937 {
return IsIntType<Value_t>::result
939 : (fp_abs(x - y) <= fp_epsilon<Value_t>()); }
941 template<
typename Value_t>
942 inline bool fp_nequal(
const Value_t& x,
const Value_t& y)
943 {
return IsIntType<Value_t>::result
945 : (fp_abs(x - y) > fp_epsilon<Value_t>()); }
947 template<
typename Value_t>
948 inline bool fp_less(
const Value_t& x,
const Value_t& y)
949 {
return IsIntType<Value_t>::result
951 : (x < y - fp_epsilon<Value_t>()); }
953 template<
typename Value_t>
954 inline bool fp_lessOrEq(
const Value_t& x,
const Value_t& y)
955 {
return IsIntType<Value_t>::result
957 : (x <= y + fp_epsilon<Value_t>()); }
960 template<
typename Value_t>
961 inline bool fp_greater(
const Value_t& x,
const Value_t& y)
962 {
return fp_less(y, x); }
964 template<
typename Value_t>
965 inline bool fp_greaterOrEq(
const Value_t& x,
const Value_t& y)
966 {
return fp_lessOrEq(y, x); }
968 template<
typename Value_t>
969 inline bool fp_truth(
const Value_t& d)
971 return IsIntType<Value_t>::result
973 : fp_abs(d) >= Value_t(0.5);
976 template<
typename Value_t>
977 inline bool fp_absTruth(
const Value_t& abs_d)
979 return IsIntType<Value_t>::result
981 : abs_d >= Value_t(0.5);
984 template<
typename Value_t>
985 inline const Value_t& fp_min(
const Value_t& d1,
const Value_t& d2)
986 {
return d1<d2 ? d1 : d2; }
988 template<
typename Value_t>
989 inline const Value_t& fp_max(
const Value_t& d1,
const Value_t& d2)
990 {
return d1>d2 ? d1 : d2; }
992 template<
typename Value_t>
993 inline const Value_t fp_not(
const Value_t& b)
994 {
return Value_t(!fp_truth(b)); }
996 template<
typename Value_t>
997 inline const Value_t fp_notNot(
const Value_t& b)
998 {
return Value_t(fp_truth(b)); }
1000 template<
typename Value_t>
1001 inline const Value_t fp_absNot(
const Value_t& b)
1002 {
return Value_t(!fp_absTruth(b)); }
1004 template<
typename Value_t>
1005 inline const Value_t fp_absNotNot(
const Value_t& b)
1006 {
return Value_t(fp_absTruth(b)); }
1008 template<
typename Value_t>
1009 inline const Value_t fp_and(
const Value_t& a,
const Value_t& b)
1010 {
return Value_t(fp_truth(a) && fp_truth(b)); }
1012 template<
typename Value_t>
1013 inline const Value_t fp_or(
const Value_t& a,
const Value_t& b)
1014 {
return Value_t(fp_truth(a) || fp_truth(b)); }
1016 template<
typename Value_t>
1017 inline const Value_t fp_absAnd(
const Value_t& a,
const Value_t& b)
1018 {
return Value_t(fp_absTruth(a) && fp_absTruth(b)); }
1020 template<
typename Value_t>
1021 inline const Value_t fp_absOr(
const Value_t& a,
const Value_t& b)
1022 {
return Value_t(fp_absTruth(a) || fp_absTruth(b)); }
1024 template<
typename Value_t>
1025 inline const Value_t fp_make_imag(
const Value_t& )
1035 bool IsLogicalOpcode(
unsigned op);
1036 bool IsComparisonOpcode(
unsigned op);
1037 unsigned OppositeComparisonOpcode(
unsigned op);
1038 bool IsNeverNegativeValueOpcode(
unsigned op);
1039 bool IsAlwaysIntegerOpcode(
unsigned op);
1040 bool IsUnaryOpcode(
unsigned op);
1041 bool IsBinaryOpcode(
unsigned op);
1042 bool IsVarOpcode(
unsigned op);
1043 bool IsCommutativeOrParamSwappableBinaryOpcode(
unsigned op);
1044 unsigned GetParamSwappedBinaryOpcode(
unsigned op);
1046 template<
bool ComplexType>
1047 bool HasInvalidRangesOpcode(
unsigned op);
1049 template<
typename Value_t>
1050 inline Value_t DegreesToRadians(
const Value_t& degrees)
1052 return degrees * fp_const_deg_to_rad<Value_t>();
1055 template<
typename Value_t>
1056 inline Value_t RadiansToDegrees(
const Value_t& radians)
1058 return radians * fp_const_rad_to_deg<Value_t>();
1061 template<
typename Value_t>
1062 inline long makeLongInteger(
const Value_t& value)
1064 return (
long) fp_int(value);
1067 #ifdef FP_SUPPORT_COMPLEX_NUMBERS
1068 template<
typename T>
1069 inline long makeLongInteger(
const std::complex<T>& value)
1071 return (
long) fp_int( std::abs(value) );
1076 template<
typename Value_t>
1077 inline bool isLongInteger(
const Value_t& value)
1079 return value == Value_t( makeLongInteger(value) );
1082 template<
typename Value_t>
1083 inline bool isOddInteger(
const Value_t& value)
1085 const Value_t halfValue = (value + Value_t(1)) * Value_t(0.5);
1086 return fp_equal(halfValue, fp_floor(halfValue));
1089 template<
typename Value_t>
1090 inline bool isEvenInteger(
const Value_t& value)
1092 const Value_t halfValue = value * Value_t(0.5);
1093 return fp_equal(halfValue, fp_floor(halfValue));
1096 template<
typename Value_t>
1097 inline bool isInteger(
const Value_t& value)
1099 return fp_equal(value, fp_floor(value));
1102 #ifdef FP_SUPPORT_LONG_INT_TYPE
1104 inline bool isEvenInteger(
const long& value)
1106 return value%2 == 0;
1110 inline bool isInteger(
const long&) {
return true; }
1113 inline bool isLongInteger(
const long&) {
return true; }
1116 inline long makeLongInteger(
const long& value)
1122 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
1124 inline bool isInteger(
const MpfrFloat& value) {
return value.isInteger(); }
1127 inline bool isEvenInteger(
const MpfrFloat& value)
1129 return isInteger(value) && value%2 == 0;
1133 inline long makeLongInteger(
const MpfrFloat& value)
1135 return (
long) value.toInt();
1139 #ifdef FP_SUPPORT_GMP_INT_TYPE
1141 inline bool isEvenInteger(
const GmpInt& value)
1143 return value%2 == 0;
1147 inline bool isInteger(
const GmpInt&) {
return true; }
1150 inline long makeLongInteger(
const GmpInt& value)
1152 return (
long) value.toInt();
1156 #ifdef FP_SUPPORT_LONG_INT_TYPE
1158 inline bool isOddInteger(
const long& value)
1160 return value%2 != 0;
1164 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
1166 inline bool isOddInteger(
const MpfrFloat& value)
1168 return value.isInteger() && value%2 != 0;
1172 #ifdef FP_SUPPORT_GMP_INT_TYPE
1174 inline bool isOddInteger(
const GmpInt& value)
1176 return value%2 != 0;
1185 template<
typename Value_t>
1186 inline Value_t fp_pow_with_exp_log(
const Value_t& x,
const Value_t& y)
1188 return fp_exp(fp_log(x) * y);
1191 template<
typename Value_t>
1192 inline Value_t fp_powi(Value_t x,
unsigned long y)
1197 if(y & 1) { result *= x; y -= 1; }
1198 else { x *= x; y /= 2; }
1203 template<
typename Value_t>
1204 Value_t fp_pow(
const Value_t& x,
const Value_t& y)
1206 if(x == Value_t(1))
return Value_t(1);
1207 if(isLongInteger(y))
1210 return fp_powi(x, makeLongInteger(y));
1212 return Value_t(1) / fp_powi(x, -makeLongInteger(y));
1216 if(x > Value_t(0))
return fp_pow_with_exp_log(x, y);
1217 if(x == Value_t(0))
return Value_t(0);
1218 if(!isInteger(y*Value_t(16)))
1219 return -fp_pow_with_exp_log(-x, y);
1223 if(x > Value_t(0))
return fp_pow_with_exp_log(Value_t(1) / x, -y);
1226 if(!isInteger(y*Value_t(-16)))
1227 return -fp_pow_with_exp_log(Value_t(-1) / x, -y);
1230 return fp_pow_base(x, y);
1233 template<
typename Value_t>
1234 inline Value_t fp_exp2(
const Value_t& x)
1236 return fp_pow(Value_t(2), x);
1240 #endif // ONCE_FPARSER_H_
1243 #ifndef FP_DISABLE_DOUBLE_TYPE
1244 # define FUNCTIONPARSER_INSTANTIATE_D(g) g(double)
1246 # define FUNCTIONPARSER_INSTANTIATE_D(g)
1249 #ifdef FP_SUPPORT_FLOAT_TYPE
1250 # define FUNCTIONPARSER_INSTANTIATE_F(g) g(float)
1252 # define FUNCTIONPARSER_INSTANTIATE_F(g)
1255 #ifdef FP_SUPPORT_LONG_DOUBLE_TYPE
1256 # define FUNCTIONPARSER_INSTANTIATE_LD(g) g(long double)
1258 # define FUNCTIONPARSER_INSTANTIATE_LD(g)
1261 #ifdef FP_SUPPORT_LONG_INT_TYPE
1262 # define FUNCTIONPARSER_INSTANTIATE_LI(g) g(long)
1264 # define FUNCTIONPARSER_INSTANTIATE_LI(g)
1267 #ifdef FP_SUPPORT_MPFR_FLOAT_TYPE
1268 # define FUNCTIONPARSER_INSTANTIATE_MF(g) g(MpfrFloat)
1270 # define FUNCTIONPARSER_INSTANTIATE_MF(g)
1273 #ifdef FP_SUPPORT_GMP_INT_TYPE
1274 # define FUNCTIONPARSER_INSTANTIATE_GI(g) g(GmpInt)
1276 # define FUNCTIONPARSER_INSTANTIATE_GI(g)
1279 #ifdef FP_SUPPORT_COMPLEX_DOUBLE_TYPE
1280 # define FUNCTIONPARSER_INSTANTIATE_CD(cd) cd(std::complex<double>)
1282 # define FUNCTIONPARSER_INSTANTIATE_CD(cd)
1285 #ifdef FP_SUPPORT_COMPLEX_FLOAT_TYPE
1286 # define FUNCTIONPARSER_INSTANTIATE_CF(cd) cd(std::complex<float>)
1288 # define FUNCTIONPARSER_INSTANTIATE_CF(cd)
1291 #ifdef FP_SUPPORT_COMPLEX_LONG_DOUBLE_TYPE
1292 # define FUNCTIONPARSER_INSTANTIATE_CLD(cd) cd(std::complex<long double>)
1294 # define FUNCTIONPARSER_INSTANTIATE_CLD(cd)
1300 #define FUNCTIONPARSER_INSTANTIATE_BASE(type) \
1301 template class FunctionParserBase<type>;
1303 #define FUNCTIONPARSER_INSTANTIATE_TYPES \
1304 FUNCTIONPARSER_INSTANTIATE_D(FUNCTIONPARSER_INSTANTIATE_BASE) \
1305 FUNCTIONPARSER_INSTANTIATE_F(FUNCTIONPARSER_INSTANTIATE_BASE) \
1306 FUNCTIONPARSER_INSTANTIATE_LD(FUNCTIONPARSER_INSTANTIATE_BASE) \
1307 FUNCTIONPARSER_INSTANTIATE_LI(FUNCTIONPARSER_INSTANTIATE_BASE) \
1308 FUNCTIONPARSER_INSTANTIATE_MF(FUNCTIONPARSER_INSTANTIATE_BASE) \
1309 FUNCTIONPARSER_INSTANTIATE_GI(FUNCTIONPARSER_INSTANTIATE_BASE) \
1310 FUNCTIONPARSER_INSTANTIATE_CD(FUNCTIONPARSER_INSTANTIATE_BASE) \
1311 FUNCTIONPARSER_INSTANTIATE_CF(FUNCTIONPARSER_INSTANTIATE_BASE) \
1312 FUNCTIONPARSER_INSTANTIATE_CLD(FUNCTIONPARSER_INSTANTIATE_BASE)
1314 #endif // ONCE_FPARSER_AUX_H_
Type information for the FunctionParser class.