From 8c2d4b4d58d6845b50c47d166a0a9eb64a3551fe Mon Sep 17 00:00:00 2001 From: Keith O'Hara Date: Sun, 30 Jul 2023 09:30:35 -0400 Subject: [PATCH] add C++14 version of erf; update erf tests --- include/gcem_incl/erf.hpp | 54 ++++++++++++++++++++++++++++++++++++--- tests/erf.cpp | 5 ++++ 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/include/gcem_incl/erf.hpp b/include/gcem_incl/erf.hpp index d0bc83a..ce920fb 100644 --- a/include/gcem_incl/erf.hpp +++ b/include/gcem_incl/erf.hpp @@ -31,6 +31,28 @@ namespace internal // see // http://functions.wolfram.com/GammaBetaErf/Erf/10/01/0007/ +#if __cplusplus >= 201402L // C++14 version + +template +constexpr +T +erf_cf_large_recur(const T x, const int depth_end) +noexcept +{ + int depth = GCEM_ERF_MAX_ITER - 1; + T res = x; + + while (depth > depth_end - 1) { + res = x + 2 * depth / res; + + --depth; + } + + return res; +} + +#else // C++11 version + template constexpr T @@ -39,11 +61,13 @@ noexcept { return( depth < GCEM_ERF_MAX_ITER ? \ // if - x + 2*depth/erf_cf_large_recur(x,depth+1) : + x + 2 * depth / erf_cf_large_recur(x,depth+1) : // else x ); } +#endif + template constexpr T @@ -57,6 +81,28 @@ noexcept // see // http://functions.wolfram.com/GammaBetaErf/Erf/10/01/0005/ +#if __cplusplus >= 201402L // C++14 version + +template +constexpr +T +erf_cf_small_recur(const T xx, const int depth_end) +noexcept +{ + int depth = GCEM_ERF_MAX_ITER - 1; + T res = T(2*(depth+1) - 1) - 2 * xx; + + while (depth > depth_end - 1) { + res = T(2*depth - 1) - 2 * xx + 4 * depth * xx / res; + + --depth; + } + + return res; +} + +#else // C++11 version + template constexpr T @@ -65,12 +111,14 @@ noexcept { return( depth < GCEM_ERF_MAX_ITER ? \ // if - (2*depth - T(1)) - 2*xx \ - + 4*depth*xx / erf_cf_small_recur(xx,depth+1) : + (2*depth - T(1)) - 2 * xx \ + + 4 * depth * xx / erf_cf_small_recur(xx,depth+1) : // else (2*depth - T(1)) - 2*xx ); } +#endif + template constexpr T diff --git a/tests/erf.cpp b/tests/erf.cpp index d090817..242cc9c 100644 --- a/tests/erf.cpp +++ b/tests/erf.cpp @@ -37,7 +37,12 @@ int main() GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, -2.099L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, -2.0L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, -1.3L); + GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, -0.7L); + GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, -0.1L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 0.0L); + GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 0.1L); + GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 0.7L); + GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 1.3L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 1.3L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 2.0L); GCEM_TEST_COMPARE_VALS(gcem::erf, std::erf, 2.099L);