Created
September 25, 2015 09:04
-
-
Save anonymous/7072e9bf174cb5fe2e59 to your computer and use it in GitHub Desktop.
ExprTk MPFR Adaptor Type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
************************************************************** | |
* C++ Mathematical Expression Toolkit Library * | |
* * | |
* MPFR Adaptor type * | |
* Authors: Arash Partow and Pavel Holoborodko * | |
* URL: http://www.partow.net/programming/exprtk/index.html * | |
* * | |
* Copyright notice: * | |
* Free use of the Mathematical Expression Toolkit Library is * | |
* permitted under the guidelines and in accordance with the * | |
* most current version of the Common Public License. * | |
* http://www.opensource.org/licenses/cpl1.0.php * | |
* * | |
************************************************************** | |
*/ | |
#ifndef EXPRTK_MPFRREAL_ADAPTOR_HPP | |
#define EXPRTK_MPFRREAL_ADAPTOR_HPP | |
#include <string> | |
#include <mpreal.h> | |
namespace exprtk | |
{ | |
namespace details | |
{ | |
namespace numeric { namespace details { struct mpfrreal_type_tag; } } | |
inline bool is_true (const mpfr::mpreal& v); | |
inline bool is_false(const mpfr::mpreal& v); | |
template <typename Iterator> | |
inline bool string_to_real(Iterator& itr_external, const Iterator end, mpfr::mpreal& t, numeric::details::mpfrreal_type_tag); | |
} | |
namespace helper | |
{ | |
namespace details | |
{ | |
inline void print_type(const std::string&, const mpfr::mpreal& v, exprtk::details::numeric::details::mpfrreal_type_tag); | |
} | |
} | |
using details::is_true; | |
} | |
#include "exprtk.hpp" | |
namespace exprtk | |
{ | |
namespace details | |
{ | |
namespace constant | |
{ | |
static const mp_prec_t mpfr_precision = 128; | |
static const mp_rnd_t mpfr_round = mpfr::mpreal::get_default_rnd(); | |
static const mpfr::mpreal e = mpfr::const_euler(mpfr_precision,mpfr_round); | |
static const mpfr::mpreal pi = mpfr::const_pi (mpfr_precision,mpfr_round); | |
static const mpfr::mpreal pi_2 = mpfr::const_pi (mpfr_precision,mpfr_round) / mpfr::mpreal( 2.0); | |
static const mpfr::mpreal pi_4 = mpfr::const_pi (mpfr_precision,mpfr_round) / mpfr::mpreal( 4.0); | |
static const mpfr::mpreal pi_180 = mpfr::const_pi (mpfr_precision,mpfr_round) / mpfr::mpreal(180.0); | |
static const mpfr::mpreal _1_pi = mpfr::mpreal( 1.0) / mpfr::const_pi(mpfr_precision,mpfr_round); | |
static const mpfr::mpreal _2_pi = mpfr::mpreal( 2.0) / mpfr::const_pi(mpfr_precision,mpfr_round); | |
static const mpfr::mpreal _180_pi = mpfr::mpreal(180.0) / mpfr::const_pi(mpfr_precision,mpfr_round); | |
static const mpfr::mpreal log2 = mpfr::const_log2 (mpfr_precision,mpfr_round); | |
static const mpfr::mpreal sqrt2 = mpfr::sqrt(mpfr::mpreal(2.0)); | |
} | |
namespace numeric | |
{ | |
namespace details | |
{ | |
struct mpfrreal_type_tag {}; | |
template<> struct number_type<mpfr::mpreal> { typedef mpfrreal_type_tag type; }; | |
template <> | |
struct epsilon_type<mpfrreal_type_tag> | |
{ | |
static inline mpfr::mpreal value() | |
{ | |
static const mpfr::mpreal epsilon = | |
#ifndef exprtk_use_mpfr_epsilon | |
mpfr::mpreal(1.0) / mpfr::mpreal (1e+20); | |
#else | |
mpfr::machine_epsilon(); | |
#endif | |
return epsilon; | |
} | |
}; | |
inline bool is_nan_impl(const mpfr::mpreal& v, mpfrreal_type_tag) | |
{ | |
return mpfr::isnan(v); | |
} | |
template <typename T> | |
inline int to_int32_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return static_cast<int>(v.toLong()); | |
} | |
template <typename T> | |
inline long long to_int64_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return static_cast<long long int>(v.toLLong()); | |
} | |
template <typename T> inline T abs_impl(const T& v, mpfrreal_type_tag) { return mpfr::abs (v); } | |
template <typename T> inline T acos_impl(const T& v, mpfrreal_type_tag) { return mpfr::acos (v); } | |
template <typename T> inline T acosh_impl(const T& v, mpfrreal_type_tag) { return mpfr::acosh(v); } | |
template <typename T> inline T asin_impl(const T& v, mpfrreal_type_tag) { return mpfr::asin (v); } | |
template <typename T> inline T asinh_impl(const T& v, mpfrreal_type_tag) { return mpfr::asinh(v); } | |
template <typename T> inline T atan_impl(const T& v, mpfrreal_type_tag) { return mpfr::atan (v); } | |
template <typename T> inline T atanh_impl(const T& v, mpfrreal_type_tag) { return mpfr::atanh(v); } | |
template <typename T> inline T ceil_impl(const T& v, mpfrreal_type_tag) { return mpfr::ceil (v); } | |
template <typename T> inline T cos_impl(const T& v, mpfrreal_type_tag) { return mpfr::cos (v); } | |
template <typename T> inline T cosh_impl(const T& v, mpfrreal_type_tag) { return mpfr::cosh (v); } | |
template <typename T> inline T exp_impl(const T& v, mpfrreal_type_tag) { return mpfr::exp (v); } | |
template <typename T> inline T floor_impl(const T& v, mpfrreal_type_tag) { return mpfr::floor(v); } | |
template <typename T> inline T log_impl(const T& v, mpfrreal_type_tag) { return mpfr::log (v); } | |
template <typename T> inline T log10_impl(const T& v, mpfrreal_type_tag) { return mpfr::log10(v); } | |
template <typename T> inline T log2_impl(const T& v, mpfrreal_type_tag) { return mpfr::log2 (v); } | |
template <typename T> inline T neg_impl(const T& v, mpfrreal_type_tag) { return -v; } | |
template <typename T> inline T pos_impl(const T& v, mpfrreal_type_tag) { return v; } | |
template <typename T> inline T sin_impl(const T& v, mpfrreal_type_tag) { return mpfr::sin (v); } | |
template <typename T> inline T sinh_impl(const T& v, mpfrreal_type_tag) { return mpfr::sinh (v); } | |
template <typename T> inline T sqrt_impl(const T& v, mpfrreal_type_tag) { return mpfr::sqrt (v); } | |
template <typename T> inline T tan_impl(const T& v, mpfrreal_type_tag) { return mpfr::tan (v); } | |
template <typename T> inline T tanh_impl(const T& v, mpfrreal_type_tag) { return mpfr::tanh (v); } | |
template <typename T> inline T cot_impl(const T& v, mpfrreal_type_tag) { return mpfr::cot (v); } | |
template <typename T> inline T sec_impl(const T& v, mpfrreal_type_tag) { return mpfr::sec (v); } | |
template <typename T> inline T csc_impl(const T& v, mpfrreal_type_tag) { return mpfr::csc (v); } | |
template <typename T> inline T r2d_impl(const T& v, mpfrreal_type_tag) { return (v * exprtk::details::constant::_180_pi); } | |
template <typename T> inline T d2r_impl(const T& v, mpfrreal_type_tag) { return (v * exprtk::details::constant::pi_180 ); } | |
template <typename T> inline T d2g_impl(const T& v, mpfrreal_type_tag) { return (v * mpfr::mpreal(20.0/9.0)); } | |
template <typename T> inline T g2d_impl(const T& v, mpfrreal_type_tag) { return (v * mpfr::mpreal(9.0/20.0)); } | |
template <typename T> inline T notl_impl(const T& v, mpfrreal_type_tag) { return (v != mpfr::mpreal(0) ? mpfr::mpreal(0) : mpfr::mpreal(1)); } | |
template <typename T> inline T frac_impl(const T& v, mpfrreal_type_tag) { return mpfr::frac (v); } | |
template <typename T> inline T trunc_impl(const T& v, mpfrreal_type_tag) { return mpfr::trunc(v); } | |
inline bool is_true_impl (const mpfr::mpreal& v) | |
{ | |
return v.toBool(); | |
} | |
inline bool is_false_impl(const mpfr::mpreal& v) | |
{ | |
return !is_true_impl(v); | |
} | |
template <typename T> | |
inline T expm1_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::expm1(v); | |
} | |
template <typename T> | |
inline T min_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
using std::min; | |
return min(v0,v1); | |
} | |
template <typename T> | |
inline T max_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
using std::max; | |
return max(v0,v1); | |
} | |
template <typename T> | |
inline T nequal_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
const T epsilon = epsilon_type<T>::value(); | |
const T eps_norm = (mpfr::max(T(1),mpfr::max(mpfr::abs(v0),mpfr::abs(v1))) * epsilon); | |
return (mpfr::abs(v0 - v1) > eps_norm) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T sgn_impl(const T& v, mpfrreal_type_tag) | |
{ | |
if (v > T(0)) return T(+1); | |
else if (v < T(0)) return T(-1); | |
else return T( 0); | |
} | |
template <typename T> | |
inline T log1p_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::log1p(v); | |
} | |
template <typename T> | |
inline T erf_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::erf(v); | |
} | |
template <typename T> | |
inline T erfc_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::erfc(v); | |
} | |
template <typename T> | |
inline T ncdf_impl(const T& v, mpfrreal_type_tag) | |
{ | |
T cnd = T(0.5) * (T(1) + erf_impl( | |
mpfr::abs(v) / | |
T(constant::sqrt2),mpfrreal_type_tag())); | |
return (v < T(0)) ? (T(1) - cnd) : cnd; | |
} | |
template <typename T> | |
inline T modulus_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::fmod(v0,v1); | |
} | |
template <typename T> | |
inline T pow_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::pow(v0,v1); | |
} | |
template <typename T> | |
inline T logn_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::log(v0) / mpfr::log(v1); | |
} | |
template <typename T> | |
inline T sinc_impl(const T& v, mpfrreal_type_tag) | |
{ | |
if (mpfr::abs(v) >= epsilon_type<mpfr::mpreal>::value()) | |
return(mpfr::sin(v) / v); | |
else | |
return T(1); | |
} | |
template <typename T> | |
inline T xor_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return (is_false_impl(v0) != is_false_impl(v1)) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T xnor_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
const bool v0_true = is_true_impl(v0); | |
const bool v1_true = is_true_impl(v1); | |
if ((v0_true && v1_true) || (!v0_true && !v1_true)) | |
return T(1); | |
else | |
return T(0); | |
} | |
template <typename T> | |
inline T equal_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
const T epsilon = epsilon_type<T>::value(); | |
const T eps_norm = (mpfr::max(T(1),mpfr::max(mpfr::abs(v0),mpfr::abs(v1))) * epsilon); | |
return (mpfr::abs(v0 - v1) <= eps_norm) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T round_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::round(v); | |
} | |
template <typename T> | |
inline T roundn_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
const T p10 = mpfr::pow(T(10),mpfr::floor(v1)); | |
if (v0 < T(0)) | |
return T(mpfr::ceil ((v0 * p10) - T(0.5)) / p10); | |
else | |
return T(mpfr::floor((v0 * p10) + T(0.5)) / p10); | |
} | |
template <typename T> | |
inline bool is_integer_impl(const T& v, mpfrreal_type_tag) | |
{ | |
return mpfr::isint(v); | |
} | |
template <typename T> | |
inline T root_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::pow(v0,T(1) / v1); | |
} | |
template <typename T> | |
inline T hypot_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::hypot(v0,v1); | |
} | |
template <typename T> | |
inline T atan2_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return mpfr::atan2(v0,v1); | |
} | |
template <typename T> | |
inline T shr_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return v0 * (T(1) / mpfr::pow(T(2.0),v1)); | |
} | |
template <typename T> | |
inline T shl_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return v0 * mpfr::pow(T(2.0),v1); | |
} | |
template <typename T> | |
inline T and_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return (is_true_impl(v0) && is_true_impl(v1)) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T nand_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return (is_false_impl(v0) || is_false_impl(v1)) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T or_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return (is_true_impl(v0) || is_true_impl(v1)) ? T(1) : T(0); | |
} | |
template <typename T> | |
inline T nor_impl(const T& v0, const T& v1, mpfrreal_type_tag) | |
{ | |
return (is_false_impl(v0) && is_false_impl(v1)) ? T(1) : T(0); | |
} | |
} | |
} | |
template <typename Iterator> | |
inline bool string_to_real(Iterator& itr_external, const Iterator end, mpfr::mpreal& t, numeric::details::mpfrreal_type_tag) | |
{ | |
t = mpfr::mpreal(std::string(itr_external,end)); | |
return true; | |
} | |
inline bool is_true (const mpfr::mpreal& v) { return details::numeric::details::is_true_impl (v); } | |
inline bool is_false(const mpfr::mpreal& v) { return details::numeric::details::is_false_impl(v); } | |
} | |
namespace helper | |
{ | |
namespace details | |
{ | |
inline void print_type(const std::string&, const mpfr::mpreal& v, exprtk::details::numeric::details::mpfrreal_type_tag) | |
{ | |
printf("%s",v.toString().c_str()); | |
} | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment