diff options
Diffstat (limited to 'src/third_party/boost-1.70.0/boost/math/special_functions/detail/lanczos_sse2.hpp')
-rw-r--r-- | src/third_party/boost-1.70.0/boost/math/special_functions/detail/lanczos_sse2.hpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/third_party/boost-1.70.0/boost/math/special_functions/detail/lanczos_sse2.hpp b/src/third_party/boost-1.70.0/boost/math/special_functions/detail/lanczos_sse2.hpp new file mode 100644 index 00000000000..df1a047435d --- /dev/null +++ b/src/third_party/boost-1.70.0/boost/math/special_functions/detail/lanczos_sse2.hpp @@ -0,0 +1,220 @@ +// (C) Copyright John Maddock 2006. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2 +#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS_SSE2 + +#ifdef _MSC_VER +#pragma once +#endif + +#include <emmintrin.h> + +#if defined(__GNUC__) || defined(__PGI) || defined(__SUNPRO_CC) +#define ALIGN16 __attribute__((__aligned__(16))) +#else +#define ALIGN16 __declspec(align(16)) +#endif + +namespace boost{ namespace math{ namespace lanczos{ + +template <> +inline double lanczos13m53::lanczos_sum<double>(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast<double>(2.506628274631000270164908177133837338626L), + static_cast<double>(1u), + static_cast<double>(210.8242777515793458725097339207133627117L), + static_cast<double>(66u), + static_cast<double>(8071.672002365816210638002902272250613822L), + static_cast<double>(1925u), + static_cast<double>(186056.2653952234950402949897160456992822L), + static_cast<double>(32670u), + static_cast<double>(2876370.628935372441225409051620849613599L), + static_cast<double>(357423u), + static_cast<double>(31426415.58540019438061423162831820536287L), + static_cast<double>(2637558u), + static_cast<double>(248874557.8620541565114603864132294232163L), + static_cast<double>(13339535u), + static_cast<double>(1439720407.311721673663223072794912393972L), + static_cast<double>(45995730u), + static_cast<double>(6039542586.35202800506429164430729792107L), + static_cast<double>(105258076u), + static_cast<double>(17921034426.03720969991975575445893111267L), + static_cast<double>(150917976u), + static_cast<double>(35711959237.35566804944018545154716670596L), + static_cast<double>(120543840u), + static_cast<double>(42919803642.64909876895789904700198885093L), + static_cast<double>(39916800u), + static_cast<double>(23531376880.41075968857200767445163675473L), + static_cast<double>(0u) + }; + __m128d vx = _mm_load1_pd(&x); + __m128d sum_even = _mm_load_pd(coeff); + __m128d sum_odd = _mm_load_pd(coeff+2); + __m128d nc_odd, nc_even; + __m128d vx2 = _mm_mul_pd(vx, vx); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 4); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 6); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 8); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 10); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 12); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 14); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 16); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 18); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 20); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 22); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 24); + sum_odd = _mm_mul_pd(sum_odd, vx); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_even = _mm_add_pd(sum_even, sum_odd); + + + double ALIGN16 t[2]; + _mm_store_pd(t, sum_even); + + return t[0] / t[1]; +} + +template <> +inline double lanczos13m53::lanczos_sum_expG_scaled<double>(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast<double>(0.006061842346248906525783753964555936883222L), + static_cast<double>(1u), + static_cast<double>(0.5098416655656676188125178644804694509993L), + static_cast<double>(66u), + static_cast<double>(19.51992788247617482847860966235652136208L), + static_cast<double>(1925u), + static_cast<double>(449.9445569063168119446858607650988409623L), + static_cast<double>(32670u), + static_cast<double>(6955.999602515376140356310115515198987526L), + static_cast<double>(357423u), + static_cast<double>(75999.29304014542649875303443598909137092L), + static_cast<double>(2637558u), + static_cast<double>(601859.6171681098786670226533699352302507L), + static_cast<double>(13339535u), + static_cast<double>(3481712.15498064590882071018964774556468L), + static_cast<double>(45995730u), + static_cast<double>(14605578.08768506808414169982791359218571L), + static_cast<double>(105258076u), + static_cast<double>(43338889.32467613834773723740590533316085L), + static_cast<double>(150917976u), + static_cast<double>(86363131.28813859145546927288977868422342L), + static_cast<double>(120543840u), + static_cast<double>(103794043.1163445451906271053616070238554L), + static_cast<double>(39916800u), + static_cast<double>(56906521.91347156388090791033559122686859L), + static_cast<double>(0u) + }; + __m128d vx = _mm_load1_pd(&x); + __m128d sum_even = _mm_load_pd(coeff); + __m128d sum_odd = _mm_load_pd(coeff+2); + __m128d nc_odd, nc_even; + __m128d vx2 = _mm_mul_pd(vx, vx); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 4); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 6); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 8); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 10); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 12); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 14); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 16); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 18); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 20); + sum_odd = _mm_mul_pd(sum_odd, vx2); + nc_odd = _mm_load_pd(coeff + 22); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_odd = _mm_add_pd(sum_odd, nc_odd); + + sum_even = _mm_mul_pd(sum_even, vx2); + nc_even = _mm_load_pd(coeff + 24); + sum_odd = _mm_mul_pd(sum_odd, vx); + sum_even = _mm_add_pd(sum_even, nc_even); + sum_even = _mm_add_pd(sum_even, sum_odd); + + + double ALIGN16 t[2]; + _mm_store_pd(t, sum_even); + + return t[0] / t[1]; +} + +#ifdef _MSC_VER + +BOOST_STATIC_ASSERT(sizeof(double) == sizeof(long double)); + +template <> +inline long double lanczos13m53::lanczos_sum<long double>(const long double& x) +{ + return lanczos_sum<double>(static_cast<double>(x)); +} +template <> +inline long double lanczos13m53::lanczos_sum_expG_scaled<long double>(const long double& x) +{ + return lanczos_sum_expG_scaled<double>(static_cast<double>(x)); +} +#endif + +} // namespace lanczos +} // namespace math +} // namespace boost + +#undef ALIGN16 + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS + + + + + |