diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -37,6 +37,7 @@ Implemented Papers ------------------ +- P0226R1 - Mathematical Special Functions for C++17 Improvements and New Features ----------------------------- diff --git a/libcxx/docs/Status/Cxx17Papers.csv b/libcxx/docs/Status/Cxx17Papers.csv --- a/libcxx/docs/Status/Cxx17Papers.csv +++ b/libcxx/docs/Status/Cxx17Papers.csv @@ -26,7 +26,7 @@ "`P0013R1 `__","LWG","Logical type traits rev 2","Kona","|Complete|","3.8" "","","","","","" "`P0024R2 `__","LWG","The Parallelism TS Should be Standardized","Jacksonville","","" -"`P0226R1 `__","LWG","Mathematical Special Functions for C++17","Jacksonville","","" +"`P0226R1 `__","LWG","Mathematical Special Functions for C++17","Jacksonville","|Complete|","17.0" "`P0220R1 `__","LWG","Adopt Library Fundamentals V1 TS Components for C++17","Jacksonville","|Complete|","16.0" "`P0218R1 `__","LWG","Adopt the File System TS for C++17","Jacksonville","|Complete|","7.0" "`P0033R1 `__","LWG","Re-enabling shared_from_this","Jacksonville","|Complete|","3.9" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -411,6 +411,7 @@ __iterator/unreachable_sentinel.h __iterator/wrap_iter.h __locale + __math/special_functions.h __mbstate_t.h __memory/addressof.h __memory/align.h diff --git a/libcxx/include/__availability b/libcxx/include/__availability --- a/libcxx/include/__availability +++ b/libcxx/include/__availability @@ -161,6 +161,8 @@ // to use it when the mechanism isn't overriden at compile-time. // # define _LIBCPP_HAS_NO_VERBOSE_ABORT_IN_LIBRARY +# define _LIBCPP_AVAILABILITY_MATHEMATICAL_SPECIAL_FUNCTIONS + #elif defined(__APPLE__) # define _LIBCPP_AVAILABILITY_SHARED_MUTEX \ diff --git a/libcxx/include/__math/special_functions.h b/libcxx/include/__math/special_functions.h new file mode 100644 --- /dev/null +++ b/libcxx/include/__math/special_functions.h @@ -0,0 +1,553 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP___MATH_SPECIAL_FUNCTIONS_H +#define _LIBCPP___MATH_SPECIAL_FUNCTIONS_H + +#include <__availability> +#include <__config> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_arithmetic.h> +#include +#include +#include + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +#if _LIBCPP_STD_VER >= 17 + +_LIBCPP_BEGIN_NAMESPACE_STD + +template +struct __msf_result { + bool __domain_error; + _Tp __ret; + + operator _Tp() { +# if math_errhandling & MATH_ERRNO + if (__domain_error) + errno = EDOM; +# endif + +# if math_errhandling & MATH_ERREXCEPT + if (__domain_error) + feraiseexcept(FE_INVALID); +# endif + + return __ret; + } +}; + +# define _LIBCPP_LIBRARY_MSF \ + [[__gnu__::__const__]] _LIBCPP_FUNC_VIS _LIBCPP_AVAILABILITY_MATHEMATICAL_SPECIAL_FUNCTIONS + +# define _LIBCPP_HEADER_MSF \ + _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_MATHEMATICAL_SPECIAL_FUNCTIONS + +// assoc_laguerre +_LIBCPP_LIBRARY_MSF __msf_result __assoc_laguerre(unsigned int, unsigned int, float) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __assoc_laguerre(unsigned int, unsigned int, double) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __assoc_laguerre(unsigned int, unsigned int, long double) noexcept; + +_LIBCPP_HEADER_MSF inline float assoc_laguerre(unsigned int __n, unsigned int __m, float __x) noexcept { + return std::__assoc_laguerre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline double assoc_laguerre(unsigned int __n, unsigned int __m, double __x) noexcept { + return std::__assoc_laguerre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline long double assoc_laguerre(unsigned int __n, unsigned int __m, long double __x) noexcept { + return std::__assoc_laguerre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline float assoc_laguerref(unsigned int __n, unsigned int __m, float __x) noexcept { + return std::assoc_laguerre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline long double assoc_laguerrel(unsigned int __n, unsigned int __m, long double __x) noexcept { + return std::assoc_laguerre(__n, __m, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __v) noexcept { + return std::assoc_laguerre(__n, __m, static_cast(__v)); +} + +// assoc_legendre +_LIBCPP_LIBRARY_MSF __msf_result __assoc_legendre(unsigned int, unsigned int, float) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __assoc_legendre(unsigned int, unsigned int, double) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __assoc_legendre(unsigned int, unsigned int, long double) noexcept; + +_LIBCPP_HEADER_MSF inline float assoc_legendre(unsigned int __n, unsigned int __m, float __x) noexcept { + return std::__assoc_legendre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline double assoc_legendre(unsigned int __n, unsigned int __m, double __x) noexcept { + return std::__assoc_legendre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline long double assoc_legendre(unsigned int __n, unsigned int __m, long double __x) noexcept { + return std::__assoc_legendre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline float assoc_legendref(unsigned int __n, unsigned int __m, float __x) noexcept { + return std::assoc_legendre(__n, __m, __x); +} + +_LIBCPP_HEADER_MSF inline long double assoc_legendrel(unsigned int __n, unsigned int __m, long double __x) noexcept { + return std::assoc_legendre(__n, __m, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double assoc_legendre(unsigned int __n, unsigned int __m, _Tp __v) noexcept { + return std::assoc_legendre(__n, __m, static_cast(__v)); +} + +// beta +_LIBCPP_LIBRARY_MSF __msf_result __beta(float, float) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __beta(double, double) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __beta(long double, long double) noexcept; + +_LIBCPP_HEADER_MSF inline float beta(float __x, float __y) noexcept { return std::__beta(__x, __y); } +_LIBCPP_HEADER_MSF inline double beta(double __x, double __y) noexcept { return std::__beta(__x, __y); } +_LIBCPP_HEADER_MSF inline long double beta(long double __x, long double __y) noexcept { return std::__beta(__x, __y); } +_LIBCPP_HEADER_MSF inline float betaf(float __x, float __y) noexcept { return std::beta(__x, __y); } +_LIBCPP_HEADER_MSF inline long double betal(long double __x, long double __y) noexcept { return std::beta(__x, __y); } + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type beta(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::beta(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// comp_ellint_1 +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_1(float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_1(double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_1(long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float comp_ellint_1(float __x) noexcept { return std::__comp_ellint_1(__x); } +_LIBCPP_HEADER_MSF inline double comp_ellint_1(double __x) noexcept { return std::__comp_ellint_1(__x); } +_LIBCPP_HEADER_MSF inline long double comp_ellint_1(long double __x) noexcept { return std::__comp_ellint_1(__x); } +_LIBCPP_HEADER_MSF inline float comp_ellint_1f(float __x) noexcept { return std::comp_ellint_1(__x); } +_LIBCPP_HEADER_MSF inline long double comp_ellint_1l(long double __x) noexcept { return std::comp_ellint_1(__x); } + +template , int> = 0> +_LIBCPP_HEADER_MSF double comp_ellint_1(_Tp __x) noexcept { + return std::comp_ellint_1(static_cast(__x)); +} + +// comp_ellint_2 +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_2(float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_2(double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_2(long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float comp_ellint_2(float __x) noexcept { return std::__comp_ellint_2(__x); } +_LIBCPP_HEADER_MSF inline double comp_ellint_2(double __x) noexcept { return std::__comp_ellint_2(__x); } +_LIBCPP_HEADER_MSF inline long double comp_ellint_2(long double __x) noexcept { return std::__comp_ellint_2(__x); } +_LIBCPP_HEADER_MSF inline float comp_ellint_2f(float __x) noexcept { return std::comp_ellint_2(__x); } +_LIBCPP_HEADER_MSF inline long double comp_ellint_2l(long double __x) noexcept { return std::comp_ellint_2(__x); } + +template , int> = 0> +_LIBCPP_HEADER_MSF double comp_ellint_2(_Tp __x) noexcept { + return std::comp_ellint_2(static_cast(__x)); +} + +// comp_ellint_3 +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_3(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_3(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __comp_ellint_3(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float comp_ellint_3(float __x, float __y) noexcept { return std::__comp_ellint_3(__x, __y); } + +_LIBCPP_HEADER_MSF inline double comp_ellint_3(double __x, double __y) noexcept { + return std::__comp_ellint_3(__x, __y); +} + +_LIBCPP_HEADER_MSF inline long double comp_ellint_3(long double __x, long double __y) noexcept { + return std::__comp_ellint_3(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float comp_ellint_3f(float __x, float __y) noexcept { return std::comp_ellint_3(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double comp_ellint_3l(long double __x, long double __y) noexcept { + return std::comp_ellint_3(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type comp_ellint_3(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::comp_ellint_3(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// cyl_bessel_i +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_i(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_i(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_i(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float cyl_bessel_i(float __x, float __y) noexcept { return std::__cyl_bessel_i(__x, __y); } +_LIBCPP_HEADER_MSF inline double cyl_bessel_i(double __x, double __y) noexcept { return std::__cyl_bessel_i(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double cyl_bessel_i(long double __x, long double __y) noexcept { + return std::__cyl_bessel_i(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float cyl_bessel_if(float __x, float __y) noexcept { return std::cyl_bessel_i(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double cyl_bessel_il(long double __x, long double __y) noexcept { + return std::cyl_bessel_i(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type cyl_bessel_i(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::cyl_bessel_i(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// cyl_bessel_j +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_j(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_j(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_j(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float cyl_bessel_j(float __x, float __y) noexcept { return std::__cyl_bessel_j(__x, __y); } +_LIBCPP_HEADER_MSF inline double cyl_bessel_j(double __x, double __y) noexcept { return std::__cyl_bessel_j(__x, __y); } +_LIBCPP_HEADER_MSF inline long double cyl_bessel_j(long double __x, long double __y) noexcept { + return std::__cyl_bessel_j(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float cyl_bessel_jf(float __x, float __y) noexcept { return std::cyl_bessel_j(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double cyl_bessel_jl(long double __x, long double __y) noexcept { + return std::cyl_bessel_j(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type cyl_bessel_j(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::cyl_bessel_j(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// cyl_bessel_k +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_k(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_k(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_bessel_k(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float cyl_bessel_k(float __x, float __y) noexcept { return std::__cyl_bessel_k(__x, __y); } +_LIBCPP_HEADER_MSF inline double cyl_bessel_k(double __x, double __y) noexcept { return std::__cyl_bessel_k(__x, __y); } +_LIBCPP_HEADER_MSF inline long double cyl_bessel_k(long double __x, long double __y) noexcept { + return std::__cyl_bessel_k(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float cyl_bessel_kf(float __x, float __y) noexcept { return std::cyl_bessel_k(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double cyl_bessel_kl(long double __x, long double __y) noexcept { + return std::cyl_bessel_k(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type cyl_bessel_k(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::cyl_bessel_k(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// cyl_neumann +_LIBCPP_LIBRARY_MSF __msf_result __cyl_neumann(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_neumann(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __cyl_neumann(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float cyl_neumann(float __x, float __y) noexcept { return std::__cyl_neumann(__x, __y); } +_LIBCPP_HEADER_MSF inline double cyl_neumann(double __x, double __y) noexcept { return std::__cyl_neumann(__x, __y); } +_LIBCPP_HEADER_MSF inline long double cyl_neumann(long double __x, long double __y) noexcept { + return std::__cyl_neumann(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float cyl_neumannf(float __x, float __y) noexcept { return std::cyl_neumann(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double cyl_neumannl(long double __x, long double __y) noexcept { + return std::cyl_neumann(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type cyl_neumann(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::cyl_neumann(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// ellint_1 +_LIBCPP_LIBRARY_MSF __msf_result __ellint_1(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_1(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_1(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float ellint_1(float __x, float __y) noexcept { return std::__ellint_1(__x, __y); } +_LIBCPP_HEADER_MSF inline double ellint_1(double __x, double __y) noexcept { return std::__ellint_1(__x, __y); } +_LIBCPP_HEADER_MSF inline long double ellint_1(long double __x, long double __y) noexcept { + return std::__ellint_1(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float ellint_1f(float __x, float __y) noexcept { return std::ellint_1(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double ellint_1l(long double __x, long double __y) noexcept { + return std::ellint_1(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type ellint_1(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::ellint_1(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// ellint_2 +_LIBCPP_LIBRARY_MSF __msf_result __ellint_2(float __x, float __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_2(double __x, double __y) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_2(long double __x, long double __y) noexcept; + +_LIBCPP_HEADER_MSF inline float ellint_2(float __x, float __y) noexcept { return std::__ellint_2(__x, __y); } +_LIBCPP_HEADER_MSF inline double ellint_2(double __x, double __y) noexcept { return std::__ellint_2(__x, __y); } +_LIBCPP_HEADER_MSF inline long double ellint_2(long double __x, long double __y) noexcept { + return std::__ellint_2(__x, __y); +} + +_LIBCPP_HEADER_MSF inline float ellint_2f(float __x, float __y) noexcept { return std::ellint_2(__x, __y); } + +_LIBCPP_HEADER_MSF inline long double ellint_2l(long double __x, long double __y) noexcept { + return std::ellint_2(__x, __y); +} + +template && is_arithmetic_v<_Up>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up>::type ellint_2(_Tp __x, _Up __y) noexcept { + using __result_type = typename __promote<_Tp, _Up>::type; + return std::ellint_2(static_cast<__result_type>(__x), static_cast<__result_type>(__y)); +} + +// ellint_3 +_LIBCPP_LIBRARY_MSF __msf_result __ellint_3(float __x, float __y, float __z) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_3(double __x, double __y, double __z) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __ellint_3(long double __x, long double __y, long double __z) noexcept; + +_LIBCPP_HEADER_MSF inline float ellint_3(float __x, float __y, float __z) noexcept { + return std::__ellint_3(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline double ellint_3(double __x, double __y, double __z) noexcept { + return std::__ellint_3(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline long double ellint_3(long double __x, long double __y, long double __z) noexcept { + return std::__ellint_3(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline float ellint_3f(float __x, float __y, float __z) noexcept { + return std::ellint_3(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline long double ellint_3l(long double __x, long double __y, long double __z) noexcept { + return std::ellint_3(__x, __y, __z); +} + +template && is_arithmetic_v<_Up> && is_arithmetic_v<_Vp>, int> = 0> +_LIBCPP_HEADER_MSF typename __promote<_Tp, _Up, _Vp>::type ellint_3(_Tp __x, _Up __y, _Vp __z) noexcept { + using __result_type = typename __promote<_Tp, _Up, _Vp>::type; + return std::ellint_3( + static_cast<__result_type>(__x), static_cast<__result_type>(__y), static_cast<__result_type>(__z)); +} + +// expint +_LIBCPP_LIBRARY_MSF __msf_result __expint(float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __expint(double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __expint(long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float expint(float __x) noexcept { return std::__expint(__x); } +_LIBCPP_HEADER_MSF inline double expint(double __x) noexcept { return std::__expint(__x); } +_LIBCPP_HEADER_MSF inline long double expint(long double __x) noexcept { return std::__expint(__x); } +_LIBCPP_HEADER_MSF inline float expintf(float __x) noexcept { return std::expint(__x); } +_LIBCPP_HEADER_MSF inline long double expintl(long double __x) noexcept { return std::expint(__x); } + +template , int> = 0> +_LIBCPP_HEADER_MSF double expint(_Tp __x) noexcept { + return std::expint(static_cast(__x)); +} + +// hermite +_LIBCPP_LIBRARY_MSF __msf_result __hermite(unsigned int __n, float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __hermite(unsigned int __n, double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __hermite(unsigned int __n, long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float hermite(unsigned int __n, float __x) noexcept { return std::__hermite(__n, __x); } +_LIBCPP_HEADER_MSF inline double hermite(unsigned int __n, double __x) noexcept { return std::__hermite(__n, __x); } +_LIBCPP_HEADER_MSF inline long double hermite(unsigned int __n, long double __x) noexcept { + return std::__hermite(__n, __x); +} + +_LIBCPP_HEADER_MSF inline float hermitef(unsigned int __n, float __x) noexcept { return std::hermite(__n, __x); } + +_LIBCPP_HEADER_MSF inline long double hermitel(unsigned int __n, long double __x) noexcept { + return std::hermite(__n, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double hermite(unsigned int __n, _Tp __x) noexcept { + return std::hermite(__n, static_cast(__x)); +} + +// laguerre +_LIBCPP_LIBRARY_MSF __msf_result __laguerre(unsigned int __n, float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __laguerre(unsigned int __n, double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __laguerre(unsigned int __n, long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float laguerre(unsigned int __n, float __x) noexcept { return std::__laguerre(__n, __x); } +_LIBCPP_HEADER_MSF inline double laguerre(unsigned int __n, double __x) noexcept { return std::__laguerre(__n, __x); } +_LIBCPP_HEADER_MSF inline long double laguerre(unsigned int __n, long double __x) noexcept { + return std::__laguerre(__n, __x); +} + +_LIBCPP_HEADER_MSF inline float laguerref(unsigned int __n, float __x) noexcept { return std::laguerre(__n, __x); } + +_LIBCPP_HEADER_MSF inline long double laguerrel(unsigned int __n, long double __x) noexcept { + return std::laguerre(__n, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double laguerre(unsigned int __n, _Tp __x) noexcept { + return std::laguerre(__n, static_cast(__x)); +} + +// legendre +_LIBCPP_LIBRARY_MSF __msf_result __legendre(unsigned int __n, float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __legendre(unsigned int __n, double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __legendre(unsigned int __n, long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float legendre(unsigned int __n, float __x) noexcept { return std::__legendre(__n, __x); } +_LIBCPP_HEADER_MSF inline double legendre(unsigned int __n, double __x) noexcept { return std::__legendre(__n, __x); } +_LIBCPP_HEADER_MSF inline long double legendre(unsigned int __n, long double __x) noexcept { + return std::__legendre(__n, __x); +} + +_LIBCPP_HEADER_MSF inline float legendref(unsigned int __n, float __x) noexcept { return std::legendre(__n, __x); } + +_LIBCPP_HEADER_MSF inline long double legendrel(unsigned int __n, long double __x) noexcept { + return std::legendre(__n, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double legendre(unsigned int __n, _Tp __x) noexcept { + return std::legendre(__n, static_cast(__x)); +} + +// riemann_zeta +_LIBCPP_LIBRARY_MSF __msf_result __riemann_zeta(float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __riemann_zeta(double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __riemann_zeta(long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float riemann_zeta(float __x) noexcept { return std::__riemann_zeta(__x); } +_LIBCPP_HEADER_MSF inline double riemann_zeta(double __x) noexcept { return std::__riemann_zeta(__x); } +_LIBCPP_HEADER_MSF inline long double riemann_zeta(long double __x) noexcept { return std::__riemann_zeta(__x); } + +_LIBCPP_HEADER_MSF inline float riemann_zetaf(float __x) noexcept { return std::riemann_zeta(__x); } +_LIBCPP_HEADER_MSF inline long double riemann_zetal(long double __x) noexcept { return std::riemann_zeta(__x); } + +template , int> = 0> +_LIBCPP_HEADER_MSF double riemann_zeta(_Tp __v) noexcept { + return std::riemann_zeta(static_cast(__v)); +} + +// sph_bessel +_LIBCPP_LIBRARY_MSF __msf_result __sph_bessel(unsigned int __n, float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __sph_bessel(unsigned int __n, double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __sph_bessel(unsigned int __n, long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float sph_bessel(unsigned int __n, float __x) noexcept { return std::__sph_bessel(__n, __x); } + +_LIBCPP_HEADER_MSF inline double sph_bessel(unsigned int __n, double __x) noexcept { + return std::__sph_bessel(__n, __x); +} +_LIBCPP_HEADER_MSF inline long double sph_bessel(unsigned int __n, long double __x) noexcept { + return std::__sph_bessel(__n, __x); +} + +_LIBCPP_HEADER_MSF inline float sph_besself(unsigned int __n, float __x) noexcept { return std::sph_bessel(__n, __x); } + +_LIBCPP_HEADER_MSF inline long double sph_bessell(unsigned int __n, long double __x) noexcept { + return std::sph_bessel(__n, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double sph_bessel(unsigned int __n, _Tp __x) noexcept { + return std::sph_bessel(__n, static_cast(__x)); +} + +// sph_legendre +_LIBCPP_LIBRARY_MSF __msf_result __sph_legendre(unsigned int __x, unsigned int __y, float __z) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __sph_legendre(unsigned int __x, unsigned int __y, double __z) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result +__sph_legendre(unsigned int __x, unsigned int __y, long double __z) noexcept; + +_LIBCPP_HEADER_MSF inline float sph_legendre(unsigned int __x, unsigned int __y, float __z) noexcept { + return std::__sph_legendre(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline double sph_legendre(unsigned int __x, unsigned int __y, double __z) noexcept { + return std::__sph_legendre(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline long double sph_legendre(unsigned int __x, unsigned int __y, long double __z) noexcept { + return std::__sph_legendre(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline float sph_legendref(unsigned int __x, unsigned int __y, float __z) noexcept { + return std::sph_legendre(__x, __y, __z); +} + +_LIBCPP_HEADER_MSF inline long double sph_legendrel(unsigned int __x, unsigned int __y, long double __z) noexcept { + return std::sph_legendre(__x, __y, __z); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double sph_legendre(unsigned int __x, unsigned int __y, _Tp __z) noexcept { + return std::sph_legendre(__x, __y, static_cast(__z)); +} + +// sph_neumann +_LIBCPP_LIBRARY_MSF __msf_result __sph_neumann(unsigned int __n, float __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __sph_neumann(unsigned int __n, double __x) noexcept; +_LIBCPP_LIBRARY_MSF __msf_result __sph_neumann(unsigned int __n, long double __x) noexcept; + +_LIBCPP_HEADER_MSF inline float sph_neumann(unsigned int __n, float __x) noexcept { + return std::__sph_neumann(__n, __x); +} + +_LIBCPP_HEADER_MSF inline double sph_neumann(unsigned int __n, double __x) noexcept { + return std::__sph_neumann(__n, __x); +} + +_LIBCPP_HEADER_MSF inline long double sph_neumann(unsigned int __n, long double __x) noexcept { + return std::__sph_neumann(__n, __x); +} + +_LIBCPP_HEADER_MSF inline float sph_neumannf(unsigned int __n, float __x) noexcept { + return std::sph_neumann(__n, __x); +} + +_LIBCPP_HEADER_MSF inline long double sph_neumannl(unsigned int __n, long double __x) noexcept { + return std::sph_neumann(__n, __x); +} + +template , int> = 0> +_LIBCPP_HEADER_MSF double sph_neumann(unsigned int __n, _Tp __x) noexcept { + return std::sph_neumann(__n, static_cast(__x)); +} + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP_STD_VER >= 17 + +#endif // _LIBCPP___MATH_SPECIAL_FUNCTIONS_H diff --git a/libcxx/include/cmath b/libcxx/include/cmath --- a/libcxx/include/cmath +++ b/libcxx/include/cmath @@ -306,6 +306,7 @@ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#include <__math/special_functions.h> #include <__type_traits/enable_if.h> #include <__type_traits/is_arithmetic.h> #include <__type_traits/is_constant_evaluated.h> diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1054,6 +1054,9 @@ export initializer_list export * } + module __math { + module special_functions { private header "__math/special_functions.h" } + } module memory { header "memory" export * diff --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt --- a/libcxx/src/CMakeLists.txt +++ b/libcxx/src/CMakeLists.txt @@ -30,6 +30,7 @@ include/ryu/ryu.h include/to_chars_floating_point.h legacy_pointer_safety.cpp + mathematical_special_functions.cpp memory.cpp memory_resource.cpp mutex.cpp @@ -198,9 +199,10 @@ # Build the shared library. if (LIBCXX_ENABLE_SHARED) add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) - target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/third-party) target_link_libraries(cxx_shared PUBLIC cxx-headers PRIVATE ${LIBCXX_LIBRARIES}) + target_compile_definitions(cxx_shared PRIVATE "BOOST_MATH_STANDALONE") set_target_properties(cxx_shared PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" @@ -292,10 +294,11 @@ # Build the static library. if (LIBCXX_ENABLE_STATIC) add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) - target_include_directories(cxx_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_include_directories(cxx_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/third-party) target_link_libraries(cxx_static PUBLIC cxx-headers PRIVATE ${LIBCXX_LIBRARIES} PRIVATE libcxx-abi-static) + target_compile_definitions(cxx_static PRIVATE "BOOST_MATH_STANDALONE") set_target_properties(cxx_static PROPERTIES COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}" diff --git a/libcxx/src/mathematical_special_functions.cpp b/libcxx/src/mathematical_special_functions.cpp new file mode 100644 --- /dev/null +++ b/libcxx/src/mathematical_special_functions.cpp @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <__config> +#include +#include +#include +#include +#include + +_LIBCPP_BEGIN_NAMESPACE_STD + +namespace { +template +optional check_nan() { + return nullopt; +} + +template +optional check_nan(Arg arg, Args... args) { + if constexpr (is_floating_point_v) + if (std::isnan(arg)) + return arg; + return check_nan(args...); +} + +template > +auto invoke_boost_math(Func f, Args... args) -> __msf_result { + if (auto maybe_nan = check_nan(args...); maybe_nan.has_value()) + return {false, *maybe_nan}; + + try { + return {false, f(args...)}; + } catch (...) { + return {true, numeric_limits::quiet_NaN()}; + } +} +} // namespace + +__msf_result __assoc_laguerre(unsigned int n, unsigned int m, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, m, x); +} + +__msf_result __assoc_laguerre(unsigned int n, unsigned int m, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, m, x); +} + +__msf_result __assoc_laguerre(unsigned int n, unsigned int m, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, m, x); +} + +__msf_result __assoc_legendre(unsigned int n, unsigned int m, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, m, x); +} + +__msf_result __assoc_legendre(unsigned int n, unsigned int m, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, m, x); +} + +__msf_result __assoc_legendre(unsigned int n, unsigned int m, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, m, x); +} + +__msf_result __beta(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::beta(args...); }, x, y); +} + +__msf_result __beta(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::beta(args...); }, x, y); +} + +__msf_result __beta(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::beta(args...); }, x, y); +} + +__msf_result __comp_ellint_1(float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x); +} + +__msf_result __comp_ellint_1(double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x); +} + +__msf_result __comp_ellint_1(long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x); +} + +__msf_result __comp_ellint_2(float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x); +} + +__msf_result __comp_ellint_2(double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x); +} + +__msf_result __comp_ellint_2(long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x); +} + +__msf_result __comp_ellint_3(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y); +} + +__msf_result __comp_ellint_3(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y); +} + +__msf_result __comp_ellint_3(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y); +} + +__msf_result __cyl_bessel_i(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_i(args...); }, x, y); +} + +__msf_result __cyl_bessel_i(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_i(args...); }, x, y); +} + +__msf_result __cyl_bessel_i(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_i(args...); }, x, y); +} + +__msf_result __cyl_bessel_j(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_j(args...); }, x, y); +} + +__msf_result __cyl_bessel_j(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_j(args...); }, x, y); +} + +__msf_result __cyl_bessel_j(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_j(args...); }, x, y); +} + +__msf_result __cyl_bessel_k(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_k(args...); }, x, y); +} + +__msf_result __cyl_bessel_k(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_k(args...); }, x, y); +} + +__msf_result __cyl_bessel_k(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_bessel_k(args...); }, x, y); +} + +__msf_result __cyl_neumann(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_neumann(args...); }, x, y); +} + +__msf_result __cyl_neumann(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_neumann(args...); }, x, y); +} + +__msf_result __cyl_neumann(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::cyl_neumann(args...); }, x, y); +} + +__msf_result __ellint_1(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x, y); +} + +__msf_result __ellint_1(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x, y); +} + +__msf_result __ellint_1(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_1(args...); }, x, y); +} + +__msf_result __ellint_2(float x, float y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x, y); +} + +__msf_result __ellint_2(double x, double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x, y); +} + +__msf_result __ellint_2(long double x, long double y) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_2(args...); }, x, y); +} + +__msf_result __ellint_3(float x, float y, float z) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y, z); +} + +__msf_result __ellint_3(double x, double y, double z) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y, z); +} + +__msf_result __ellint_3(long double x, long double y, long double z) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::ellint_3(args...); }, x, y, z); +} + +__msf_result __expint(float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::expint(args...); }, x); +} + +__msf_result __expint(double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::expint(args...); }, x); +} + +__msf_result __expint(long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::expint(args...); }, x); +} + +__msf_result __hermite(unsigned int n, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::hermite(args...); }, n, x); +} + +__msf_result __hermite(unsigned int n, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::hermite(args...); }, n, x); +} + +__msf_result __hermite(unsigned int n, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::hermite(args...); }, n, x); +} + +__msf_result __laguerre(unsigned int n, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, x); +} + +__msf_result __laguerre(unsigned int n, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, x); +} + +__msf_result __laguerre(unsigned int n, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::laguerre(args...); }, n, x); +} + +__msf_result __legendre(unsigned int n, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, x); +} + +__msf_result __legendre(unsigned int n, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, x); +} + +__msf_result __legendre(unsigned int n, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::legendre_p(args...); }, n, x); +} + +__msf_result __riemann_zeta(float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::zeta(args...); }, x); +} + +__msf_result __riemann_zeta(double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::zeta(args...); }, x); +} + +__msf_result __riemann_zeta(long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::zeta(args...); }, x); +} + +__msf_result __sph_bessel(unsigned int n, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_bessel(args...); }, n, x); +} + +__msf_result __sph_bessel(unsigned int n, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_bessel(args...); }, n, x); +} + +__msf_result __sph_bessel(unsigned int n, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_bessel(args...); }, n, x); +} + +__msf_result __sph_legendre(unsigned int n, unsigned int m, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::spherical_harmonic_r(args..., 0.f); }, n, m, x); +} + +__msf_result __sph_legendre(unsigned int n, unsigned int m, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::spherical_harmonic_r(args..., 0.0); }, n, m, x); +} + +__msf_result __sph_legendre(unsigned int n, unsigned int m, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::spherical_harmonic_r(args..., 0.l); }, n, m, x); +} + +__msf_result __sph_neumann(unsigned int m, float x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_neumann(args...); }, m, x); +} + +__msf_result __sph_neumann(unsigned int m, double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_neumann(args...); }, m, x); +} + +__msf_result __sph_neumann(unsigned int m, long double x) noexcept { + return invoke_boost_math([&](auto... args) { return boost::math::sph_neumann(args...); }, m, x); +} + +_LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/src/third-party/LICENSE_1_0.txt b/libcxx/src/third-party/LICENSE_1_0.txt new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/libcxx/src/third-party/boost/math/bindings/detail/big_digamma.hpp b/libcxx/src/third-party/boost/math/bindings/detail/big_digamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/bindings/detail/big_digamma.hpp @@ -0,0 +1,297 @@ +// (C) Copyright John Maddock 2006-8. +// 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_NTL_DIGAMMA +#define BOOST_MATH_NTL_DIGAMMA + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T big_digamma_helper(T x) +{ + static const T P[61] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6660133691143982067148122682345055274952e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6365271516829242456324234577164675383137e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2991038873096202943405966144203628966976e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9211116495503170498076013367421231351115e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2090792764676090716286400360584443891749e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3730037777359591428226035156377978092809e79), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5446396536956682043376492370432031543834e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6692523966335177847425047827449069256345e77), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7062543624100864681625612653756619116848e76), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6499914905966283735005256964443226879158e75), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5280364564853225211197557708655426736091e74), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3823205608981176913075543599005095206953e73), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2486733714214237704739129972671154532415e72), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1462562139602039577983434547171318011675e71), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7821169065036815012381267259559910324285e69), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3820552182348155468636157988764435365078e68), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1711618296983598244658239925535632505062e67), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7056661618357643731419080738521475204245e65), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2685246896473614017356264531791459936036e64), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9455168125599643085283071944864977592391e62), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3087541626972538362237309145177486236219e61), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9367928873352980208052601301625005737407e59), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2645306130689794942883818547314327466007e58), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6961815141171454309161007351079576190079e56), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1709637824471794552313802669803885946843e55), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3921553258481531526663112728778759311158e53), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.8409006354449988687714450897575728228696e51), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1686755204461325935742097669030363344927e50), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3166653542877070999007425197729038754254e48), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5566029092358215049069560272835654229637e46), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9161766287916328133080586672953875116242e44), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1412317772330871298317974693514430627922000), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 20387991986727877473732570146112459874790), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 275557928713904105182512535678580359839.3), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3485719851040516559072031256589598330.723), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 41247046743564028399938106707656877.40859), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 456274078125709314602601667471879.0147312), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4714450683242899367025707077155.310613012), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 45453933537925041680009544258.75073849996), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 408437900487067278846361972.302331241052), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3415719344386166273085838.705771571751035), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 26541502879185876562320.93134691487351145), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 191261415065918713661.1571433274648417668), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1275349770108718421.645275944284937551702), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 7849171120971773.318910987434906905704272), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 44455946386549.80866460312682983576538056), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 230920362395.3198137186361608905136598046), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1095700096.240863858624279930600654130254), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4727085.467506050153744334085516289728134), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 18440.75118859447173303252421991479005424), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 64.62515887799460295677071749181651317052), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.201851568864688406206528472883512147547), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.0005565091674187978029138500039504078098143), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1338097668312907986354698683493366559613e-5), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.276308225077464312820179030238305271638e-8), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4801582970473168520375942100071070575043e-11), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6829184144212920949740376186058541800175e-14), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7634080076358511276617829524639455399182e-17), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6290035083727140966418512608156646142409e-20), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.339652245667538733044036638506893821352e-23), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9017518064256388530773585529891677854909e-27) + }; + static const T Q[61] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1386831185456898357379390197203894063459e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6467076379487574703291056110838151259438e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1394967823848615838336194279565285465161e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1872927317344192945218570366455046340458e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1772461045338946243584650759986310355937e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1267294892200258648315971144069595555118e82), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7157764838362416821508872117623058626589e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.329447266909948668265277828268378274513e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1264376077317689779509250183194342571207e81), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4118230304191980787640446056583623228873e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1154393529762694616405952270558316515261e80), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.281655612889423906125295485693696744275e79), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6037483524928743102724159846414025482077e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1145927995397835468123576831800276999614e78), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1938624296151985600348534009382865995154e77), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.293980925856227626211879961219188406675e76), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4015574518216966910319562902099567437832e75), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4961475457509727343545565970423431880907e74), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5565482348278933960215521991000378896338e73), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5686112924615820754631098622770303094938e72), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5305988545844796293285410303747469932856e71), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4533363413802585060568537458067343491358e70), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3553932059473516064068322757331575565718e69), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2561198565218704414618802902533972354203e68), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1699519313292900324098102065697454295572e67), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1039830160862334505389615281373574959236e66), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5873082967977428281000961954715372504986e64), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3065255179030575882202133042549783442446e63), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1479494813481364701208655943688307245459e62), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6608150467921598615495180659808895663164e60), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2732535313770902021791888953487787496976e59), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1046402297662493314531194338414508049069e58), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3711375077192882936085049147920021549622e56), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1219154482883895482637944309702972234576e55), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3708359374149458741391374452286837880162e53), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1044095509971707189716913168889769471468e52), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.271951506225063286130946773813524945052e50), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6548016291215163843464133978454065823866e48), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1456062447610542135403751730809295219344e47), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2986690175077969760978388356833006028929e45), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 5643149706574013350061247429006443326844000), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 98047545414467090421964387960743688053480), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1563378767746846395507385099301468978550), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 22823360528584500077862274918382796495), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 304215527004115213046601295970388750), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3690289075895685793844344966820325), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 40584512015702371433911456606050), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 402834190897282802772754873905), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3589522158493606918146495750), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 28530557707503483723634725), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 200714561335055753000730), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1237953783437761888641), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 6614698701445762950), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 30155495647727505), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 114953256021450), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 356398020013), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 863113950), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1531345), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1770), + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1) + }; + static const T PD[60] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6365271516829242456324234577164675383137e81), + 2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2991038873096202943405966144203628966976e81), + 3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9211116495503170498076013367421231351115e80), + 4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2090792764676090716286400360584443891749e80), + 5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3730037777359591428226035156377978092809e79), + 6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5446396536956682043376492370432031543834e78), + 7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6692523966335177847425047827449069256345e77), + 8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7062543624100864681625612653756619116848e76), + 9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6499914905966283735005256964443226879158e75), + 10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5280364564853225211197557708655426736091e74), + 11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3823205608981176913075543599005095206953e73), + 12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2486733714214237704739129972671154532415e72), + 13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1462562139602039577983434547171318011675e71), + 14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7821169065036815012381267259559910324285e69), + 15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3820552182348155468636157988764435365078e68), + 16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1711618296983598244658239925535632505062e67), + 17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7056661618357643731419080738521475204245e65), + 18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2685246896473614017356264531791459936036e64), + 19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9455168125599643085283071944864977592391e62), + 20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3087541626972538362237309145177486236219e61), + 21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9367928873352980208052601301625005737407e59), + 22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2645306130689794942883818547314327466007e58), + 23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6961815141171454309161007351079576190079e56), + 24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1709637824471794552313802669803885946843e55), + 25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3921553258481531526663112728778759311158e53), + 26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.8409006354449988687714450897575728228696e51), + 27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1686755204461325935742097669030363344927e50), + 28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3166653542877070999007425197729038754254e48), + 29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5566029092358215049069560272835654229637e46), + 30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9161766287916328133080586672953875116242e44), + 31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1412317772330871298317974693514430627922000), + 32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 20387991986727877473732570146112459874790), + 33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 275557928713904105182512535678580359839.3), + 34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3485719851040516559072031256589598330.723), + 35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 41247046743564028399938106707656877.40859), + 36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 456274078125709314602601667471879.0147312), + 37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4714450683242899367025707077155.310613012), + 38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 45453933537925041680009544258.75073849996), + 39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 408437900487067278846361972.302331241052), + 40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3415719344386166273085838.705771571751035), + 41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 26541502879185876562320.93134691487351145), + 42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 191261415065918713661.1571433274648417668), + 43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1275349770108718421.645275944284937551702), + 44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 7849171120971773.318910987434906905704272), + 45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 44455946386549.80866460312682983576538056), + 46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 230920362395.3198137186361608905136598046), + 47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1095700096.240863858624279930600654130254), + 48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 4727085.467506050153744334085516289728134), + 49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 18440.75118859447173303252421991479005424), + 50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 64.62515887799460295677071749181651317052), + 51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.201851568864688406206528472883512147547), + 52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.0005565091674187978029138500039504078098143), + 53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1338097668312907986354698683493366559613e-5), + 54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.276308225077464312820179030238305271638e-8), + 55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4801582970473168520375942100071070575043e-11), + 56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6829184144212920949740376186058541800175e-14), + 57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7634080076358511276617829524639455399182e-17), + 58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6290035083727140966418512608156646142409e-20), + 59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.339652245667538733044036638506893821352e-23), + 60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.9017518064256388530773585529891677854909e-27) + }; + static const T QD[60] = { + BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1386831185456898357379390197203894063459e81), + 2*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6467076379487574703291056110838151259438e81), + 3*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1394967823848615838336194279565285465161e82), + 4*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1872927317344192945218570366455046340458e82), + 5*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1772461045338946243584650759986310355937e82), + 6*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1267294892200258648315971144069595555118e82), + 7*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.7157764838362416821508872117623058626589e81), + 8*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.329447266909948668265277828268378274513e81), + 9*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1264376077317689779509250183194342571207e81), + 10*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4118230304191980787640446056583623228873e80), + 11*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1154393529762694616405952270558316515261e80), + 12*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.281655612889423906125295485693696744275e79), + 13*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6037483524928743102724159846414025482077e78), + 14*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1145927995397835468123576831800276999614e78), + 15*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1938624296151985600348534009382865995154e77), + 16*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.293980925856227626211879961219188406675e76), + 17*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4015574518216966910319562902099567437832e75), + 18*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4961475457509727343545565970423431880907e74), + 19*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5565482348278933960215521991000378896338e73), + 20*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5686112924615820754631098622770303094938e72), + 21*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5305988545844796293285410303747469932856e71), + 22*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.4533363413802585060568537458067343491358e70), + 23*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3553932059473516064068322757331575565718e69), + 24*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2561198565218704414618802902533972354203e68), + 25*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1699519313292900324098102065697454295572e67), + 26*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1039830160862334505389615281373574959236e66), + 27*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.5873082967977428281000961954715372504986e64), + 28*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3065255179030575882202133042549783442446e63), + 29*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1479494813481364701208655943688307245459e62), + 30*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6608150467921598615495180659808895663164e60), + 31*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2732535313770902021791888953487787496976e59), + 32*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1046402297662493314531194338414508049069e58), + 33*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3711375077192882936085049147920021549622e56), + 34*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1219154482883895482637944309702972234576e55), + 35*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.3708359374149458741391374452286837880162e53), + 36*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1044095509971707189716913168889769471468e52), + 37*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.271951506225063286130946773813524945052e50), + 38*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.6548016291215163843464133978454065823866e48), + 39*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.1456062447610542135403751730809295219344e47), + 40*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 0.2986690175077969760978388356833006028929e45), + 41*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 5643149706574013350061247429006443326844000), + 42*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 98047545414467090421964387960743688053480), + 43*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1563378767746846395507385099301468978550), + 44*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 22823360528584500077862274918382796495), + 45*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 304215527004115213046601295970388750), + 46*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3690289075895685793844344966820325), + 47*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 40584512015702371433911456606050), + 48*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 402834190897282802772754873905), + 49*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 3589522158493606918146495750), + 50*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 28530557707503483723634725), + 51*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 200714561335055753000730), + 52*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1237953783437761888641), + 53*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 6614698701445762950), + 54*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 30155495647727505), + 55*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 114953256021450), + 56*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 356398020013), + 57*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 863113950), + 58*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1531345), + 59*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1770), + 60*BOOST_MATH_BIG_CONSTANT(T, boost::math::tools::numeric_traits::digits, 1) + }; + static const double g = 63.192152; + + T zgh = x + g - 0.5; + + T result = (x - 0.5) / zgh; + result += log(zgh); + result += tools::evaluate_polynomial(PD, x) / tools::evaluate_polynomial(P, x); + result -= tools::evaluate_polynomial(QD, x) / tools::evaluate_polynomial(Q, x); + result -= 1; + + return result; +} + +template +T big_digamma(T x) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + return big_digamma_helper(static_cast(1-x)) + constants::pi() / tan(constants::pi() * (1-x)); + } + return big_digamma_helper(x); +} + +}}} + +#endif // include guard diff --git a/libcxx/src/third-party/boost/math/bindings/detail/big_lanczos.hpp b/libcxx/src/third-party/boost/math/bindings/detail/big_lanczos.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/bindings/detail/big_lanczos.hpp @@ -0,0 +1,777 @@ +// (C) Copyright John Maddock 2006-8. +// 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_BIG_LANCZOS_HPP +#define BOOST_BIG_LANCZOS_HPP + +#include + +namespace boost{ namespace math{ namespace lanczos{ + +// +// Lanczos Coefficients for N=13 G=13.144565 +// Max experimental error (with arbitrary precision arithmetic) 9.2213e-23 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +typedef lanczos13 lanczos13UDT; + +// +// Lanczos Coefficients for N=22 G=22.61891 +// Max experimental error (with arbitrary precision arithmetic) 2.9524e-38 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos22UDT : public std::integral_constant +{ + // + // Produces slightly better than 128-bit long-double precision when + // evaluated at higher precision: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 46198410803245094237463011094.12173081986)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 43735859291852324413622037436.321513777)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 19716607234435171720534556386.97481377748)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5629401471315018442177955161.245623932129)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1142024910634417138386281569.245580222392)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 175048529315951173131586747.695329230778)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 21044290245653709191654675.41581372963167)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2033001410561031998451380.335553678782601)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 160394318862140953773928.8736211601848891)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10444944438396359705707.48957290388740896)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 565075825801617290121.1466393747967538948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 25475874292116227538.99448534450411942597)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 957135055846602154.6720835535232270205725)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 29874506304047462.23662392445173880821515)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 769651310384737.2749087590725764959689181)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 16193289100889.15989633624378404096011797)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 273781151680.6807433264462376754578933261)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3630485900.32917021712188739762161583295)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 36374352.05577334277856865691538582936484)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 258945.7742115532455441786924971194951043)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1167.501919472435718934219997431551246996)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2.50662827463100050241576528481104525333)) + }; + static const T denom[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 6939996264376682180.277485395074954356211)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 6570067992110214451.87201438870245659384)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2961859037444440551.986724631496417064121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 845657339772791245.3541226499766163431651)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 171556737035449095.2475716923888737881837)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 26296059072490867.7822441885603400926007)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3161305619652108.433798300149816829198706)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 305400596026022.4774396904484542582526472)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 24094681058862.55120507202622377623528108)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1569055604375.919477574824168939428328839)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 84886558909.02047889339710230696942513159)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3827024985.166751989686050643579753162298)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 143782298.9273215199098728674282885500522)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 4487794.24541641841336786238909171265944)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 115618.2025760830513505888216285273541959)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432.580773108508276957461757328744780439)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 41.12782532742893597168530008461874360191)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.5453771709477689805460179187388702295792)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.005464211062612080347167337964166505282809)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.388992321263586767037090706042788910953e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.1753839324538447655939518484052327068859e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.3765495513732730583386223384116545391759e-9)) + }; + static const T denom[22] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 2432902008176640000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8752948036761600000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 13803759753640704000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 12870931245150988800.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8037811822645051776.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3599979517947607200.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1206647803780373360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 311333643161390640.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 63030812099294896.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 10142299865511450.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1307535010540395.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 135585182899530.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 11310276995381.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 756111184500.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 40171771630.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1672280820.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 53327946.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1256850.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 20615.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 210.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[21] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 8.318998691953337183034781139546384476554)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -63.15415991415959158214140353299240638675)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 217.3108224383632868591462242669081540163)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -448.5134281386108366899784093610397354889)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 619.2903759363285456927248474593012711346)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -604.1630177420625418522025080080444177046)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 428.8166750424646119935047118287362193314)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -224.6988753721310913866347429589434550302)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 87.32181627555510833499451817622786940961)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -25.07866854821128965662498003029199058098)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5.264398125689025351448861011657789005392)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.792518936256495243383586076579921559914)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.08317448364744713773350272460937904691566)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.005845345166274053157781068150827567998882)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.0002599412126352082483326238522490030412391)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6748102079670763884917431338234783496303e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.908824383434109002762325095643458603605e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.5299325929309389890892469299969669579725e-9)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.994306085859549890267983602248532869362e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3499893692975262747371544905820891835298e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7260746353663365145454867069182884694961e-20)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[21] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 75.39272007105208086018421070699575462226)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -572.3481967049935412452681346759966390319)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 1969.426202741555335078065370698955484358)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -4064.74968778032030891520063865996757519)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 5612.452614138013929794736248384309574814)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -5475.357667500026172903620177988213902339)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 3886.243614216111328329547926490398103492)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -2036.382026072125407192448069428134470564)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 791.3727954936062108045551843636692287652)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -227.2808432388436552794021219198885223122)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 47.70974355562144229897637024320739257284)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -7.182373807798293545187073539819697141572)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.7537866989631514559601547530490976100468)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.05297470142240154822658739758236594717787)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.00235577330936380542539812701472320434133)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.6115613067659273118098229498679502138802e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.8236417010170941915758315020695551724181e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.4802628430993048190311242611330072198089e-8)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.9011113376981524418952720279739624707342e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, -0.3171854152689711198382455703658589996796e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 120, 0.6580207998808093935798753964580596673177e-19)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 22.61890999999999962710717227309942245483; } +}; +// +// Lanczos Coefficients for N=31 G=32.08067 +// Max experimental error (with arbitrary precision arithmetic) 0.162e-52 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at May 9 2006 +// +struct lanczos31UDT +{ + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2579646553333513328235723061836959833277e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2444796504337453845497419271639377138264e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1119885499016017172212179730662673475329e46)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3301983829072723658949204487793889113715e45)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7041171040503851585152895336505379417066e44)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1156687509001223855125097826246939403504e44)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1522559363393940883866575697565974893306000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 164914363507650839510801418717701057005700)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14978522943127593263654178827041568394060)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1156707153701375383907746879648168666774)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 76739431129980851159755403434593664173.2)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4407916278928188620282281495575981079.306)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 220487883931812802092792125175269667.3004)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9644828280794966468052381443992828.433924)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 369996467042247229310044531282837.6549068)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12468380890717344610932904378961.13494291)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 369289245210898235894444657859.0529720075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9607992460262594951559461829.34885209022)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 219225935074853412540086410.981421315799)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4374309943598658046326340.720767382079549)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 76008779092264509404014.10530947173485581)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1143503533822162444712.335663112617754987)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14779233719977576920.37884890049671578409)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 162409028440678302.9992838032166348069916)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1496561553388385.733407609544964535634135)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11347624460661.81008311053190661436107043)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 68944915931.32004991941950530448472223832)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 322701221.6391432296123937035480931903651)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1092364.213992634267819050120261755371294)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2380.151399852411512711176940867823024864)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.506628274631000502415765284811045253007)), + }; + static const T denom[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)), + }; + return boost::math::tools::evaluate_rational(num, denom, z, 31); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 30137154810677525966583148469478.52374216)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 28561746428637727032849890123131.36314653)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13083250730789213354063781611435.74046294)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3857598154697777600846539129354.783647)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 822596651552555685068015316144.0952185852)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 135131964033213842052904200372.039133532)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17787555889683709693655685146.19771358863)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1926639793777927562221423874.149673297196)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 174989113988888477076973808.6991839697774)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13513425905835560387095425.01158383184045)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 896521313378762433091075.1446749283094845)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 51496223433749515758124.71524415105430686)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2575886794780078381228.37205955912263407)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 112677328855422964200.4155776009524490958)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4322545967487943330.625233358130724324796)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 145663957202380774.0362027607207590519723)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4314283729473470.686566233465428332496534)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 112246988185485.8877916434026906290603878)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2561143864972.040563435178307062626388193)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 51103611767.9626550674442537989885239605)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 887985348.0369447209508500133077232094491)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13359172.3954672607019822025834072685839)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 172660.8841147568768783928167105965064459)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1897.370795407433013556725714874693719617)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17.48383210090980598861217644749573257178)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1325705316732132940835251054350153028901)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0008054605783673449641889260501816356090452)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.377001130700104515644336869896819162464e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1276172868883867038813825443204454996531e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2780651912081116274907381023821492811093e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2928410648650955854121639682890739211234e-13)), + }; + static const T denom[31] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.8841761993739701954543616e31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3502799997985980526649278464e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.622621928420356134910574592e32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 66951000306085302338993639424000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 49361465831621147825759587123200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 26751280755793398822580822142976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11139316913434780466101123891200)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3674201658710345201899117607040)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 981347603630155088295475765440)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 215760462268683520394805979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 39539238727270799376544542000)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6097272817323042122728617800)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 796974693974455191377937300)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 88776380550648116217781890)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8459574446076318147830625)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 691254538651580660999025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 48487623689430693038025)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2918939500751087661105)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 150566737512021319125)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6634460278534540725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 248526574856284725)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7860403394108265)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 207912996295875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4539323721075)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80328850875)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1122686019)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11921175)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 90335)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 435)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1)), + }; + return boost::math::tools::evaluate_rational(num, denom, z, 31); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[30] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11.80038544942943603508206880307972596807)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -130.6355975335626214564236363322099481079)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 676.2177719145993049893392276809256538927)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2174.724497783850503069990936574060452057)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4869.877180638131076410069103742986502022)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8065.744271864238179992762265472478229172)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 10245.03825618572106228191509520638651539)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -10212.83902362683215459850403668669647192)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8110.289185383288952562767679576754140336)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -5179.310892558291062401828964000776095156)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2673.987492589052370230989109591011091273)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1118.342574651205183051884250033505609141)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 378.5812742511620662650096436471920295596)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -103.3725999812126067084828735543906768961)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 22.62913974335996321848099677797888917792)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -3.936414819950859548507275533569588041446)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5376818198843817355682124535902641644854)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0567827903603478957483409124122554243201)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.004545544993648879420352693271088478106482)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.0002689795568951033950042375135970897959935)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1139493459006846530734617710847103572122e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.3316581197839213921885210451302820192794e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.6285613334898374028443777562554713906213e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7222145115734409070310317999856424167091e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.4562976983547274766890241815002584238219e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1380593023819058919640038942493212141072e-14)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.1629663871586410129307496385264268190679e-17)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.5429994291916548849493889660077076739993e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2922682842441892106795386303084661338957e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.8456967065309046044689041041336866118459e-31)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[30] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 147.9979641587472136175636384176549713358)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1638.404318611773924210055619836375434296)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8480.981744216135641122944743711911653273)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -27274.93942104458448200467097634494071176)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 61076.98019918759324489193232276937262854)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -101158.8762737154296509560513952101409264)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 128491.1252383947174824913796141607174379)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -128087.2892038336581928787480535905496026)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 101717.5492545853663296795562084430123258)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -64957.8330410311808907869707511362206858)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 33536.59139229792478811870738772305570317)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -14026.01847115365926835980820243003785821)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4748.087094096186515212209389240715050212)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1296.477510211815971152205100242259733245)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 283.8099337545793198947620951499958085157)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -49.36969067101255103452092297769364837753)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6.743492833270653628580811118017061581404)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.7121578704864048548351804794951487823626)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0570092738016915476694118877057948681298)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.003373485297696102660302960722607722438643)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0001429128843527532859999752593761934089751)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.41595867130858508233493767243236888636e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.7883284669307241040059778207492255409785e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.905786322462384670803148223703187214379e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.5722790216999820323272452464661250331451e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1731510870832349779315841757234562309727e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.2043890314358438601429048378015983874378e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.6810185176079344204740000170500311171065e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3665567641131713928114853776588342403919e-24)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1060655106553177007425710511436497259484e-29)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 32.08066999999999779902282170951366424561; } +}; + +// +// Lanczos Coefficients for N=61 G=63.192152 +// Max experimental error (with 1000-bit precision arithmetic) 3.740e-113 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 12 2006 +// +struct lanczos61UDT +{ + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[61] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659584)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13349415823254323512107320481.3495396037261649201426994438803767191136434970492309775123879)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -300542621510568204264185787475.230003734889859348050696493467253861933279360152095861484548)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3273919938390136737194044982676.40271056035622723775417608127544182097346526115858803376474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -22989594065095806099337396006399.5874206181563663855129141706748733174902067950115092492439)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 116970582893952893160414263796102.542775878583510989850142808618916073286745084692189044738)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -459561969036479455224850813196807.283291532483532558959779434457349912822256480548436066098)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1450959909778264914956547227964788.89797179379520834974601372820249784303794436366366810477)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -3782846865486775046285288437885921.41537699732805465141128848354901016102326190612528503251)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 8305043213936355459145388670886540.09976337905520168067329932809302445437208115570138102767)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -15580988484396722546934484726970745.4927787160273626078250810989811865283255762028143642311)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 25262722284076250779006793435537600.0822901485517345545978818780090308947301031347345640449)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -35714428027687018805443603728757116.5304655170478705341887572982734901197345415291580897698)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 44334726194692443174715432419157343.2294160783772787096321009453791271387235388689346602833)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -48599573547617297831555162417695106.187829304963846482633791012658974681648157963911491985)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 47258466493366798944386359199482189.0753349196625125615316002614813737880755896979754845101)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -40913448215392412059728312039233342.142914753896559359297977982314043378636755884088383226)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 31626312914486892948769164616982902.7262756989418188077611392594232674722318027323102462687)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -21878079174441332123064991795834438.4699982361692990285700077902601657354101259411789722708)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 13567268503974326527361474986354265.3136632133935430378937191911532112778452274286122946396)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -7551494211746723529747611556474669.62996644923557605747803028485900789337467673523741066527)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3775516572689476384052312341432597.70584966904950490541958869730702790312581801585742038997)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1696271471453637244930364711513292.79902955514107737992185368006225264329876265486853482449)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 684857608019352767999083000986166.20765273693720041519286231015176745354062413008561259139)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -248397566275708464679881624417990.410438107634139924805871051723444048539177890346227250473)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 80880368999557992138783568858556.1512378233079327986518410244522800950609595592170022878937)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -23618197945394013802495450485616.9025005749893350650829964098117490779655546610665927669729)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6176884636893816103087134481332.06708966653493024119556843727320635285468825056891248447124)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1444348683723439589948246285262.64080678953468490544615312565485170860503207005915261691108)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 301342031656979076702313946827.961658905182634508217626783081241074250132289461989777865387)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -55959656587719766738301589651.3940625826610668990368881615587469329021742236397809951765678)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9223339169004064297247180402.36227016155682738556103138196079389248843082157924368301293963)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1344882881571942601385730283.42710150182526891377514071881534880944872423492272147871101373)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 172841913316760599352601139.54409257740173055624405575900164401527761357324625574736896079)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -19496120443876233531343952.3802212016691702737346568192063937387825469602063310488794471653)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1920907372583710284097959.44121420322495784420169085871802458519363819782779653621724219067)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -164429314798240461613359.399597503536657962383155875723527581699785846599051112719962464604)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12154026644351189572525.1452249886865981747374191977801688548318519692423556934568426042152)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -770443988366210815096.519382051977221101156336663806705367929328924137169970381042234329058)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 41558909851418707920.4696085656889424895313728719601503526476333404973280596225722152966128)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1890879946549708819.24562220042687554209318172044783707920086716716717574156283898330017796)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 71844996557297623.9583461685535340440524052492427928388171299145330229958643439878608673403)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2253785109518255.55600197759875781765803818232939130127735487613049577235879610065545755637)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 57616883849355.997562563968344493719962252675875692642406455612671495250543228005045106721)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1182495730353.08218118278997948852215670614084013289033222774171548915344541249351599628436)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 19148649358.6196967288062261380599423925174178776792840639099120170800869284300966978300613)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -239779605.891370259668403359614360511661030470269478602533200704639655585967442891496784613)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2267583.00284368310957842936892685032434505866445291643236133553754152047677944820353796872)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -15749.490806784673108773558070497383604733010677027764233749920147549999361110299643477893)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 77.7059495149052727171505425584459982871343274332635726864135949842508025564999785370162956)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.261619987273930331397625130282851629108569607193781378836014468617185550622160348688297247)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000572252321659691600529444769356185993188551770817110673186068921175991328434642504616377475)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.765167220661540041663007112207436426423746402583423562585653954743978584117929356523307954e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.579179571056209077507916813937971472839851499147582627425979879366849876944438724610663401e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.224804733043915149719206760378355636826808754704148660354494460792713189958510735070096991e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.392711975389579343321746945135488409914483448652884894759297584020979857734289645857714768e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.258603588346412049542768766878162221817684639789901440429511261589010049357907537684380983e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.499992460848751668441190360024540741752242879565548017176883304716370989218399797418478685e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.196211614533318174187346267877390498735734213905206562766348625767919122511096089367364025e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.874722648949676363732094858062907290148733370978226751462386623191111439121706262759209573e-37)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.163907874717737848669759890242660846846105433791283903651924563157080252845636658802930428e-44)), + }; + T result = d[0]; + for(unsigned k = 1; k < sizeof(d)/sizeof(d[0]); ++k) + { + result += d[k]/(z+(k-1)); + } + return result; + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[61] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.901751806425638853077358552989167785490911341809902155556127108480303870921448984935411583e-27)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4.80241125306810017699523302110401965428995345115391817406006361151407344955277298373661032)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -108.119283021710869401330097315436214587270846871451487282117128515476478251641970487922552)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1177.78262074811362219818923738088833932279000985161077740440010901595132448469513438139561)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8270.43570321334374279057432173814835581983913167617217749736484999327758232081395983082867)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 42079.807161997077661752306902088979258826568702655699995911391774839958572703348502730394)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -165326.003834443330215001219988296482004968548294447320869281647211603153902436231468280089)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 521978.361504895300685499370463597042533432134369277742485307843747923127933979566742421213)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1360867.51629992863544553419296636395576666570468519805449755596254912681418267100657262281)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2987713.73338656161102517003716335104823650191612448011720936412226357385029800040631754755)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -5605212.64915921452169919008770165304171481697939254152852673009005154549681704553438450709)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 9088186.58332916818449459635132673652700922052988327069535513580836143146727832380184335474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -12848155.5543636394746355365819800465364996596310467415907815393346205151090486190421959769)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 15949281.2867656960575878805158849857756293807220033618942867694361569866468996967761600898)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -17483546.9948295433308250581770557182576171673272450149400973735206019559576269174369907171)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 17001087.8599749419660906448951424280111036786456594738278573653160553115681287326064596964)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -14718487.0643665950346574802384331125115747311674609017568623694516187494204567579595827859)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 11377468.7255609717716845971105161298889777425898291183866813269222281486121330837791392732)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -7870571.64253038587947746661946939286858490057774448573157856145556080330153403858747655263)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4880783.08440908743641723492059912671377140680710345996273343885045364205895751515063844239)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2716626.7992639625103140035635916455652302249897918893040695025407382316653674141983775542)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1358230.46602865696544327299659410214201327791319846880787515156343361311278133805428800255)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -610228.440751458395860905749312275043435828322076830117123636938979942213530882048883969802)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 246375.416501158654327780901087115642493055617468601787093268312234390446439555559050129729)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -89360.2599028475206119333931211015869139511677735549267100272095432140508089207221096740632)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 29096.4637987498328341260960356772198979319790332957125131055960448759586930781530063775634)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -8496.57401431514433694413130585404918350686834939156759654375188338156288564260152505382438)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2222.11523574301594407443285016240908726891841242444092960094015874546135316534057865883047)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -519.599993280949289705514822058693289933461756514489674453254304308040888101533569480646682)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 108.406868361306987817730701109400305482972790224573776407166683184990131682003417239181112)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -20.1313142142558596796857948064047373605439974799116521459977609253211918146595346493447238)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3.31806787671783168020012913552384112429614503798293169239082032849759155847394955909684383)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.483817477111537877685595212919784447924875428848331771524426361483392903320495411973587861)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0621793463102927384924303843912913542297042029136293808338022462765755471002366206711862637)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00701366932085103924241526535768453911099671087892444015581511551813219720807206445462785293)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000691040514756294308758606917671220770856269030526647010461217455799229645004351524024364997)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.591529398871361458428147660822525365922497109038495896497692806150033516658042357799869656e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.437237367535177689875119370170434437030440227275583289093139147244747901678407875809020739e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.277164853397051135996651958345647824709602266382721185838782221179129726200661453504250697e-6)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.149506899012035980148891401548317536032574502641368034781671941165064546410613201579653674e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.68023824066463262779882895193964639544061678698791279217407325790147925675797085217462974e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.258460163734186329938721529982859244969655253624066115559707985878606277800329299821882688e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.810792256024669306744649981276512583535251727474303382740940985102669076169168931092026491e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.207274966207031327521921078048021807442500113231320959236850963529304158700096495799022922e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.425399199286327802950259994834798737777721414442095221716122926637623478450472871269742436e-15)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.688866766744198529064607574117697940084548375790020728788313274612845280173338912495478431e-17)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.862599751805643281578607291655858333628582704771553874199104377131082877406179933909898885e-19)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.815756005678735657200275584442908437977926312650210429668619446123450972547018343768177988e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.566583084099007858124915716926967268295318152203932871370429534546567151650626184750291695e-23)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.279544761599725082805446124351997692260093135930731230328454667675190245860598623539891708e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941169851584987983984201821679114408126982142904386301937192011680047611188837432096199601e-28)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.205866011331040736302780507155525142187875191518455173304638008169488993406425201915370746e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.27526655245712584371295491216289353976964567057707464008951584303679019796521332324352501e-33)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208358067979444305082929004102609366169534624348056112144990933897581971394396210379638792e-36)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.808728107661779323263133007119729988596844663194254976820030366188579170595441991680169012e-40)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.141276924383478964519776436955079978012672985961918248012931336621229652792338950573694356e-43)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.930318449287651389310440021745842417218125582685428432576258687100661462527604238849332053e-48)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.179870748819321661641184169834635133045197146966203370650788171790610563029431722308057539e-52)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.705865243912790337263229413370018392321238639017433365017168104310561824133229343750737083e-58)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.3146787805734405996448268100558028857930560442377698646099945108125281507396722995748398e-64)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.589653534231618730406843260601322236697428143603814281282790370329151249078338470962782338e-72)), + }; + T result = d[0]; + for(unsigned k = 1; k < sizeof(d)/sizeof(d[0]); ++k) + { + result += d[k]/(z+(k-1)); + } + return result; + } + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[60] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 23.2463658527729692390378860713647146932236940604550445351214987229819352880524561852919518)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -523.358012551815715084547614110229469295755088686612838322817729744722233637819564673967396)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 5701.12892340421080714956066268650092612647620400476183901625272640935853188559347587495571)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -40033.5506451901904954336453419007623117537868026994808919201793803506999271787018654246699)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 203689.884259074923009439144410340256983393397995558814367995938668111650624499963153485034)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -800270.648969745331278757692597096167418585957703057412758177038340791380011708874081291202)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 2526668.23380061659863999395867315313385499515711742092815402701950519696944982260718031476)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -6587362.57559198722630391278043503867973853468105110382293763174847657538179665571836023631)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 14462211.3454541602975917764900442754186801975533106565506542322063393991552960595701762805)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -27132375.1879227404375395522940895789625516798992585980380939378508607160857820002128106898)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 43991923.8735251977856804364757478459275087361742168436524951824945035673768875988985478116)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -62192284.0030124679010201921841372967696262036115679150017649233887633598058364494608060812)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 77203473.0770033513405070667417251568915937590689150831268228886281254637715669678358204991)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -84630180.2217173903516348977915150565994784278120192219937728967986198118628659866582594874)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 82294807.2253549409847505891112074804416229757832871133388349982640444405470371147991706317)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -71245738.2484649177928765605893043553453557808557887270209768163561363857395639001251515788)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 55073334.3180266913441333534260714059077572215147571872597651029894142803987981342430068594)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -38097984.1648990787690036742690550656061009857688125101191167768314179751258568264424911474)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 23625729.5032184580395130592017474282828236643586203914515183078852982915252442161768527976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -13149998.4348054726172055622442157883429575511528431835657668083088902165366619827169829685)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 6574597.77221556423683199818131482663205682902023554728024972161230111356285973623550338976)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2953848.1483469149918109110050192571921018042012905892107136410603990336401921230407043408)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1192595.29584357246380113611351829515963605337523874715861849584306265512819543347806085356)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -432553.812019608638388918135375154289816441900572658692369491476137741687213006403648722272)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 140843.215385933866391177743292449477205328233960902455943995092958295858485718885800427129)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -41128.186992679630058614841985110676526199977321524879849001760603476646382839182691529968)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 10756.2849191854701631989789887757784944313743544315113894758328432005767448056040879337769)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2515.15559672041299884426826962296210458052543246529646213159169885444118227871246315458787)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 524.750087004805200600237632074908875763734578390662349666321453103782638818305404274166951)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -97.4468596421732493988298219295878130651986131393383646674144877163795143930682205035917965)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 16.0613108128210806736384551896802799172445298357754547684100294231532127326987175444453058)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2.34194813526540240672426202485306862230641838409943369059203455578340880900483887447559874)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300982934748016059399829007219431333744032924923669397318820178988611410275964499475465815)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.033950095985367909789000959795708551814461844488183964432565731809399824963680858993718525)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.00334502394288921146242772614150438404658527112198421937945605441697314216921393987758378122)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.000286333429067523984607730553301991502191011265745476190940771685897687956262049750683013485)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.211647426149364947402896718485536530479491688838087899435991994237067890628274492042231115e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.134163345121302758109675190598169832775248626443483098532368562186356128620805552609175683e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.723697303042715085329782938306424498336642078597508935450663080894255773653328980495047891e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.329273487343139063533251321553223583999676337945788660475231347828772272134656322947906888e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.12510922551028971731767784013117088894558604838820475961392154031378891971216135267744134e-9)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.392468958215589939603666430583400537413757786057185505426804034745840192914621891690369903e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100332717101049934370760667782927946803279422001380028508200697081188326364078428184546051e-12)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.205917088291197705194762747639836655808855850989058813560983717575008725393428497910009756e-14)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.333450178247893143608439314203175490705783992567107481617660357577257627854979230819461489e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.417546693906616047110563550428133589051498362676394888715581845170969319500638944065594319e-18)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.394871691642184410859178529844325390739857256666676534513661579365702353214518478078730801e-20)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.274258012587811199757875927548699264063511843669070634471054184977334027224611843434000922e-22)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.135315354265459854889496635967343027244391821142592599244505313738163473730636430399785048e-24)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.455579032003288910408487905303223613382276173706542364543918076752861628464036586507967767e-27)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.99650703862462739161520123768147312466695159780582506041370833824093136783202694548427718e-30)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.1332444609228706921659395801935919548447859029572115502899861345555006827214220195650058e-32)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.100856999148765307000182397631280249632761913433008379786888200467467364474581430670889392e-35)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.39146979455613683472384690509165395074425354524713697428673406058157887065953366609738731e-39)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.683859606707931248105140296850112494069265272540298100341919970496564103098283709868586478e-43)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.450326344248604222735147147805963966503893913752040066400766411031387063854141246972061792e-47)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.870675378039492904184581895322153006461319724931909799151743284769901586333730037761678891e-52)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.341678395249272265744518787745356400350877656459401143889000625280131819505857966769964401e-57)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.152322191370871666358069530949353871960316638394428595988162174042653299702098929238880862e-63)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.285425405297633795767452984791738825078111150078605004958179057245980222485147999495352632e-71)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + using namespace boost; + static const T d[60] = { + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 557.56438192770795764344217888434355281097193198928944200046501607026919782564033547346298)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -12552.748616427645475141433405567201788681683808077269330800392600825597799119572762385222)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 136741.650054039199076788077149441364242294724343897779563222338447737802381279007988884806)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -960205.223613240309942047656967301131022760634321049075674684679438471862998829007639437133)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 4885504.47588736223774859617054275229642041717942140469884121916073195308537421162982679289)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -19194501.738192166918904824982935279260356575935661514109550613809352009246483412530545583)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 60602169.8633537742937457094837494059849674261357199218329545854990149896822944801504450843)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -157997975.522506767297528502540724511908584668874487506510120462561270100749019845014382885)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 346876323.86092543685419723290495817330608574729543216092477261152247521712190505658568876)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -650770365.471136883718747607976242475416651908858429752332176373467422603953536408709972919)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1055146856.05909309330903130910708372830487315684258450293308627289334336871273080305128138)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1491682726.25614447429071368736790697283307005456720192465860871846879804207692411263924608)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1851726287.94866167094858600116562210167031458934987154557042242638980748286188183300900268)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2029855953.68334371445800569238095379629407314338521720558391277508374519526853827142679839)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1973842002.53354868177824629525448788555435194808657489238517523691040148611221295436287925)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -1708829941.98209573247426625323314413060108441455314880934710595647408841619484540679859098)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 1320934627.12433688699625456833930317624783222321555050330381730035733198249283009357314954)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -913780636.858542526294419197161614811332299249415125108737474024007693329922089123296358727)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 566663423.929632170286007468016419798879660054391183200464733820209439185545886930103546787)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -315402880.436816230388857961460509181823167373029384218959199936902955049832392362044305869)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 157691811.550465734461741500275930418786875005567018699867961482249002625886064187146134966)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -70848085.5705405970640618473551954585013808128304384354476488268600720054598122945113512731)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 28604413.4050137708444142264980840059788755325900041515286382001704951527733220637586013815)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -10374808.7067303054787164054055989420809074792801592763124972441820101840292558840131568633)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 3378126.32016207486657791623723515804931231041318964254116390764473281291389374196880720069)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -986460.090390653140964189383080344920103075349535669020623874668558777188889544398718979744)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 257989.631187387317948158483575125380011593209850756066176921901006833159795100137743395985)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -60326.0391159227288325790327830741260824763549807922845004854215660451399733578621565837087)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 12586.1375399649496159880821645216260841794563919652590583420570326276086323953958907053394)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -2337.26417330316922535871922886167444795452055677161063205953141105726549966801856628447293)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 385.230745012608736644117458716226876976056390433401632749144285378123105481506733917763829)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -56.1716559403731491675970177460841997333796694857076749852739159067307309470690838101179615)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 7.21907953468550196348585224042498727840087634483369357697580053424523903859773769748599575)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.814293485887386870805786409956942772883474224091975496298369877683530509729332902182019049)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.0802304419995150047616460464220884371214157889148846405799324851793571580868840034085001373)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.00686771095380619535195996193943858680694970000948742557733102777115482017857981277171196115)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.000507636621977556438232617777542864427109623356049335590894564220687567763620803789858345916)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.32179095465362720747836116655088181481893063531138957363431280817392443948706754917605911e-4)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.173578890579848508947329833426585354230744194615295570820295052665075101971588563893718407e-5)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.789762880006288893888161070734302768702358633525134582027140158619195373770299678322596835e-7)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.300074637200885066788470310738617992259402710843493097610337134266720909870967550606601658e-8)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.941337297619721713151110244242536308266701344868601679868536153775533330272973088246835359e-10)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.24064815013182536657310186836079333949814111498828401548170442715552017773994482539471456e-11)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.493892399304811910466345686492277504628763169549384435563232052965821874553923373100791477e-13)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.799780678476644196901221989475355609743387528732994566453160178199295104357319723742820593e-15)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.100148627870893347527249092785257443532967736956154251497569191947184705954310833302770086e-16)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.947100256812658897084619699699028861352615460106539259289295071616221848196411749449858071e-19)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.657808193528898116367845405906343884364280888644748907819280236995018351085371701094007759e-21)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.324554050057463845012469010247790763753999056976705084126950591088538742509983426730851614e-23)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.10927068902162908990029309141242256163212535730975970310918370355165185052827948996110107e-25)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.239012340507870646690121104637467232366271566488184795459093215303237974655782634371712486e-28)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.31958700972990573259359660326375143524864710953063781494908314884519046349402409667329667e-31)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.241905641292988284384362036555782113275737930713192053073501265726048089991747342247551645e-34)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.93894080230619233745797029179332447129464915420290457418429337322820997038069119047864035e-38)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.164023814025085488413251990798690797467351995518990067783355251949198292596815470576539877e-41)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.108010831192689925518484618970761942019888832176355541674171850211917230280206410356465451e-45)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.208831600642796805563854019033577205240227465154130766898180386564934443551840379116390645e-50)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.819516067465171848863933747691434138146789031214932473898084756489529673230665363014007306e-56)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, 0.365344970579318347488211604761724311582675708113250505307342682118101409913523622073678179e-62)), + static_cast(BOOST_MATH_HUGE_CONSTANT(T, 150, -0.684593199208628857931267904308244537968349564351534581234005234847904343404822808648361291e-70)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 63.19215200000000010049916454590857028961181640625; } +}; + +}}} // namespaces + +#endif + + diff --git a/libcxx/src/third-party/boost/math/bindings/mpfr.hpp b/libcxx/src/third-party/boost/math/bindings/mpfr.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/bindings/mpfr.hpp @@ -0,0 +1,974 @@ +// Copyright John Maddock 2008. +// 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) +// +// Wrapper that works with mpfr_class defined in gmpfrxx.h +// See http://math.berkeley.edu/~wilken/code/gmpfrxx/ +// Also requires the gmp and mpfr libraries. +// + +#ifndef BOOST_MATH_MPLFR_BINDINGS_HPP +#define BOOST_MATH_MPLFR_BINDINGS_HPP + +#include + +#ifdef _MSC_VER +// +// We get a lot of warnings from the gmp, mpfr and gmpfrxx headers, +// disable them here, so we only see warnings from *our* code: +// +#pragma warning(push) +#pragma warning(disable: 4127 4800 4512) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +inline mpfr_class fabs(const mpfr_class& v) +{ + return abs(v); +} +template +inline mpfr_class fabs(const __gmp_expr& v) +{ + return abs(static_cast(v)); +} + +inline mpfr_class pow(const mpfr_class& b, const mpfr_class& e) +{ + mpfr_class result; + mpfr_pow(result.__get_mp(), b.__get_mp(), e.__get_mp(), GMP_RNDN); + return result; +} +/* +template +inline mpfr_class pow(const __gmp_expr& b, const __gmp_expr& e) +{ + return pow(static_cast(b), static_cast(e)); +} +*/ +inline mpfr_class ldexp(const mpfr_class& v, int e) +{ + //int e = mpfr_get_exp(*v.__get_mp()); + mpfr_class result(v); + mpfr_set_exp(result.__get_mp(), e); + return result; +} +template +inline mpfr_class ldexp(const __gmp_expr& v, int e) +{ + return ldexp(static_cast(v), e); +} + +inline mpfr_class frexp(const mpfr_class& v, int* expon) +{ + int e = mpfr_get_exp(v.__get_mp()); + mpfr_class result(v); + mpfr_set_exp(result.__get_mp(), 0); + *expon = e; + return result; +} +template +inline mpfr_class frexp(const __gmp_expr& v, int* expon) +{ + return frexp(static_cast(v), expon); +} + +inline mpfr_class fmod(const mpfr_class& v1, const mpfr_class& v2) +{ + mpfr_class n; + if(v1 < 0) + n = ceil(v1 / v2); + else + n = floor(v1 / v2); + return v1 - n * v2; +} +template +inline mpfr_class fmod(const __gmp_expr& v1, const __gmp_expr& v2) +{ + return fmod(static_cast(v1), static_cast(v2)); +} + +template +inline mpfr_class modf(const mpfr_class& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - boost::math::tools::real_cast(*ipart); +} +template +inline mpfr_class modf(const __gmp_expr& v, long long* ipart, const Policy& pol) +{ + return modf(static_cast(v), ipart, pol); +} + +template +inline int iround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline int iround(__gmp_expr const& x, const Policy& pol) +{ + return iround(static_cast(x), pol); +} + +template +inline long lround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline long lround(__gmp_expr const& x, const Policy& pol) +{ + return lround(static_cast(x), pol); +} + +template +inline long long llround(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::round(x, typename boost::math::policies::normalise >::type())); +} +template +inline long long llround(__gmp_expr const& x, const Policy& pol) +{ + return llround(static_cast(x), pol); +} + +template +inline int itrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline int itrunc(__gmp_expr const& x, const Policy& pol) +{ + return itrunc(static_cast(x), pol); +} + +template +inline long ltrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline long ltrunc(__gmp_expr const& x, const Policy& pol) +{ + return ltrunc(static_cast(x), pol); +} + +template +inline long long lltrunc(mpfr_class const& x, const Policy&) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, typename boost::math::policies::normalise >::type())); +} +template +inline long long lltrunc(__gmp_expr const& x, const Policy& pol) +{ + return lltrunc(static_cast(x), pol); +} + +namespace boost{ + +#ifdef BOOST_MATH_USE_FLOAT128 + template<> struct std::is_convertible : public std::integral_constant{}; +#endif + template<> struct std::is_convertible : public std::integral_constant{}; + +namespace math{ + +#if defined(__GNUC__) && (__GNUC__ < 4) + using ::iround; + using ::lround; + using ::llround; + using ::itrunc; + using ::ltrunc; + using ::lltrunc; + using ::modf; +#endif + +namespace lanczos{ + +struct mpfr_lanczos +{ + static mpfr_class lanczos_sum(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static mpfr_class lanczos_sum_expG_scaled(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static mpfr_class lanczos_sum_near_1(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static mpfr_class lanczos_sum_near_2(const mpfr_class& z) + { + unsigned long p = z.get_dprec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static mpfr_class g() + { + unsigned long p = mpfr_class::get_dprec(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef mpfr_lanczos type; +}; + +} // namespace lanczos + +namespace constants{ + +template +struct construction_traits; + +template +struct construction_traits +{ + typedef std::integral_constant type; +}; + +} + +namespace tools +{ + +template +struct promote_arg<__gmp_expr > +{ // If T is integral type, then promote to double. + typedef mpfr_class type; +}; + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) noexcept +{ + return mpfr_class::get_dprec(); +} + +namespace detail{ + +template +void convert_to_long_result(mpfr_class const& r, I& result) +{ + result = 0; + I last_result(0); + mpfr_class t(r); + double term; + do + { + term = real_cast(t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline mpfr_class real_cast(long long t) +{ + mpfr_class result; + int expon = 0; + int sign = 1; + if(t < 0) + { + sign = -1; + t = -t; + } + while(t) + { + result += ldexp(static_cast(t & 0xffffL), expon); + expon += 32; + t >>= 32; + } + return result * sign; +} +template <> +inline unsigned real_cast(mpfr_class t) +{ + return t.get_ui(); +} +template <> +inline int real_cast(mpfr_class t) +{ + return t.get_si(); +} +template <> +inline double real_cast(mpfr_class t) +{ + return t.get_d(); +} +template <> +inline float real_cast(mpfr_class t) +{ + return static_cast(t.get_d()); +} +template <> +inline long real_cast(mpfr_class t) +{ + long result; + detail::convert_to_long_result(t, result); + return result; +} +template <> +inline long long real_cast(mpfr_class t) +{ + long long result; + detail::convert_to_long_result(t, result); + return result; +} + +template <> +inline mpfr_class max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val; + if(!has_init) + { + val = 0.5; + mpfr_set_exp(val.__get_mp(), mpfr_get_emax()); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val; + if(!has_init) + { + val = 0.5; + mpfr_set_exp(val.__get_mp(), mpfr_get_emin()); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + static bool has_init = false; + static mpfr_class val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr_class epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr_class)) +{ + return ldexp(mpfr_class(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +namespace policies{ + +template +struct evaluation<__gmp_expr, Policy> +{ + typedef mpfr_class type; +}; + +} + +template +inline mpfr_class skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr skewness can not be calculated in standalone mode"); + #endif + + return static_cast("1.1395470994046486574927930193898461120875997958366"); +} + +template +inline mpfr_class skewness(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr skewness can not be calculated in standalone mode"); + #endif + + return static_cast("0.63111065781893713819189935154422777984404221106391"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 2 * root_pi() * pi_minus_three() / pow23_four_minus_pi(); +} + +template +inline mpfr_class kurtosis(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr kurtosis can not be calculated in standalone mode"); + #endif + + return static_cast("3.2450893006876380628486604106197544154170667057995"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 3 - (6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} + +template +inline mpfr_class kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + //using namespace boost::math::constants; + // Computed using NTL at 150 bit, about 50 decimal digits. + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpfr excess kurtosis can not be calculated in standalone mode"); + #endif + + return static_cast("0.2450893006876380628486604106197544154170667057995"); + // return -(6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} // kurtosis + +namespace detail{ + +// +// Version of Digamma accurate to ~100 decimal digits. +// +template +mpfr_class digamma_imp(mpfr_class x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // empfr_classor handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + mpfr_class result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + mpfr_class remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} +// +// Specialisations of this function provides the initial +// starting guess for Halley iteration: +// +template +inline mpfr_class erf_inv_imp(const mpfr_class& p, const mpfr_class& q, const Policy&, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + mpfr_class result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute empfr_classor compared to |Y|. + // + // double: Max empfr_classor found: 2.001849e-18 + // long double: Max empfr_classor found: 1.017064e-20 + // Maximum Deviation Found (actual empfr_classor term at infinite precision) 8.030e-21 + // + static const float Y = 0.0891314744949340820313f; + static const mpfr_class P[] = { + -0.000508781949658280665617, + -0.00836874819741736770379, + 0.0334806625409744615033, + -0.0126926147662974029034, + -0.0365637971411762664006, + 0.0219878681111168899165, + 0.00822687874676915743155, + -0.00538772965071242932965 + }; + static const mpfr_class Q[] = { + 1, + -0.970005043303290640362, + -1.56574558234175846809, + 1.56221558398423026363, + 0.662328840472002992063, + -0.71228902341542847553, + -0.0527396382340099713954, + 0.0795283687341571680018, + -0.00233393759374190016776, + 0.000886216390456424707504 + }; + mpfr_class g = p * (p + 10); + mpfr_class r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute empfr_classor compared to Y. + // + // double : Max empfr_classor found: 7.403372e-17 + // long double : Max empfr_classor found: 6.084616e-20 + // Maximum Deviation Found (empfr_classor term) 4.811e-20 + // + static const float Y = 2.249481201171875f; + static const mpfr_class P[] = { + -0.202433508355938759655, + 0.105264680699391713268, + 8.37050328343119927838, + 17.6447298408374015486, + -18.8510648058714251895, + -44.6382324441786960818, + 17.445385985570866523, + 21.1294655448340526258, + -3.67192254707729348546 + }; + static const mpfr_class Q[] = { + 1, + 6.24264124854247537712, + 3.9713437953343869095, + -28.6608180499800029974, + -20.1432634680485188801, + 48.5609213108739935468, + 10.8268667355460159008, + -22.6436933413139721736, + 1.72114765761200282724 + }; + mpfr_class g = sqrt(-2 * log(q)); + mpfr_class xs = q - 0.25; + mpfr_class r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute empfr_classor compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + mpfr_class x = sqrt(-log(q)); + if(x < 3) + { + // Max empfr_classor found: 1.089051e-20 + static const float Y = 0.807220458984375f; + static const mpfr_class P[] = { + -0.131102781679951906451, + -0.163794047193317060787, + 0.117030156341995252019, + 0.387079738972604337464, + 0.337785538912035898924, + 0.142869534408157156766, + 0.0290157910005329060432, + 0.00214558995388805277169, + -0.679465575181126350155e-6, + 0.285225331782217055858e-7, + -0.681149956853776992068e-9 + }; + static const mpfr_class Q[] = { + 1, + 3.46625407242567245975, + 5.38168345707006855425, + 4.77846592945843778382, + 2.59301921623620271374, + 0.848854343457902036425, + 0.152264338295331783612, + 0.01105924229346489121 + }; + mpfr_class xs = x - 1.125; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // Max empfr_classor found: 8.389174e-21 + static const float Y = 0.93995571136474609375f; + static const mpfr_class P[] = { + -0.0350353787183177984712, + -0.00222426529213447927281, + 0.0185573306514231072324, + 0.00950804701325919603619, + 0.00187123492819559223345, + 0.000157544617424960554631, + 0.460469890584317994083e-5, + -0.230404776911882601748e-9, + 0.266339227425782031962e-11 + }; + static const mpfr_class Q[] = { + 1, + 1.3653349817554063097, + 0.762059164553623404043, + 0.220091105764131249824, + 0.0341589143670947727934, + 0.00263861676657015992959, + 0.764675292302794483503e-4 + }; + mpfr_class xs = x - 3; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // Max empfr_classor found: 1.481312e-19 + static const float Y = 0.98362827301025390625f; + static const mpfr_class P[] = { + -0.0167431005076633737133, + -0.00112951438745580278863, + 0.00105628862152492910091, + 0.000209386317487588078668, + 0.149624783758342370182e-4, + 0.449696789927706453732e-6, + 0.462596163522878599135e-8, + -0.281128735628831791805e-13, + 0.99055709973310326855e-16 + }; + static const mpfr_class Q[] = { + 1, + 0.591429344886417493481, + 0.138151865749083321638, + 0.0160746087093676504695, + 0.000964011807005165528527, + 0.275335474764726041141e-4, + 0.282243172016108031869e-6 + }; + mpfr_class xs = x - 6; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // Max empfr_classor found: 5.697761e-20 + static const float Y = 0.99714565277099609375f; + static const mpfr_class P[] = { + -0.0024978212791898131227, + -0.779190719229053954292e-5, + 0.254723037413027451751e-4, + 0.162397777342510920873e-5, + 0.396341011304801168516e-7, + 0.411632831190944208473e-9, + 0.145596286718675035587e-11, + -0.116765012397184275695e-17 + }; + static const mpfr_class Q[] = { + 1, + 0.207123112214422517181, + 0.0169410838120975906478, + 0.000690538265622684595676, + 0.145007359818232637924e-4, + 0.144437756628144157666e-6, + 0.509761276599778486139e-9 + }; + mpfr_class xs = x - 18; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // Max empfr_classor found: 1.279746e-20 + static const float Y = 0.99941349029541015625f; + static const mpfr_class P[] = { + -0.000539042911019078575891, + -0.28398759004727721098e-6, + 0.899465114892291446442e-6, + 0.229345859265920864296e-7, + 0.225561444863500149219e-9, + 0.947846627503022684216e-12, + 0.135880130108924861008e-14, + -0.348890393399948882918e-21 + }; + static const mpfr_class Q[] = { + 1, + 0.0845746234001899436914, + 0.00282092984726264681981, + 0.468292921940894236786e-4, + 0.399968812193862100054e-6, + 0.161809290887904476097e-8, + 0.231558608310259605225e-11 + }; + mpfr_class xs = x - 44; + mpfr_class R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +inline mpfr_class bessel_i0(mpfr_class x) +{ + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(x) == 0, "mpfr bessel_i0 can not be calculated in standalone mode"); + #endif + + static const mpfr_class P1[] = { + static_cast("-2.2335582639474375249e+15"), + static_cast("-5.5050369673018427753e+14"), + static_cast("-3.2940087627407749166e+13"), + static_cast("-8.4925101247114157499e+11"), + static_cast("-1.1912746104985237192e+10"), + static_cast("-1.0313066708737980747e+08"), + static_cast("-5.9545626019847898221e+05"), + static_cast("-2.4125195876041896775e+03"), + static_cast("-7.0935347449210549190e+00"), + static_cast("-1.5453977791786851041e-02"), + static_cast("-2.5172644670688975051e-05"), + static_cast("-3.0517226450451067446e-08"), + static_cast("-2.6843448573468483278e-11"), + static_cast("-1.5982226675653184646e-14"), + static_cast("-5.2487866627945699800e-18"), + }; + static const mpfr_class Q1[] = { + static_cast("-2.2335582639474375245e+15"), + static_cast("7.8858692566751002988e+12"), + static_cast("-1.2207067397808979846e+10"), + static_cast("1.0377081058062166144e+07"), + static_cast("-4.8527560179962773045e+03"), + static_cast("1.0"), + }; + static const mpfr_class P2[] = { + static_cast("-2.2210262233306573296e-04"), + static_cast("1.3067392038106924055e-02"), + static_cast("-4.4700805721174453923e-01"), + static_cast("5.5674518371240761397e+00"), + static_cast("-2.3517945679239481621e+01"), + static_cast("3.1611322818701131207e+01"), + static_cast("-9.6090021968656180000e+00"), + }; + static const mpfr_class Q2[] = { + static_cast("-5.5194330231005480228e-04"), + static_cast("3.2547697594819615062e-02"), + static_cast("-1.1151759188741312645e+00"), + static_cast("1.3982595353892851542e+01"), + static_cast("-6.0228002066743340583e+01"), + static_cast("8.5539563258012929600e+01"), + static_cast("-3.1446690275135491500e+01"), + static_cast("1.0"), + }; + mpfr_class value, factor, r; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (x < 0) + { + x = -x; // even function + } + if (x == 0) + { + return static_cast(1); + } + if (x <= 15) // x in (0, 15] + { + mpfr_class y = x * x; + value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + } + else // x in (15, \infty) + { + mpfr_class y = 1 / x - mpfr_class(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(x) / sqrt(x); + value = factor * r; + } + + return value; +} + +inline mpfr_class bessel_i1(mpfr_class x) +{ + static const mpfr_class P1[] = { + static_cast("-1.4577180278143463643e+15"), + static_cast("-1.7732037840791591320e+14"), + static_cast("-6.9876779648010090070e+12"), + static_cast("-1.3357437682275493024e+11"), + static_cast("-1.4828267606612366099e+09"), + static_cast("-1.0588550724769347106e+07"), + static_cast("-5.1894091982308017540e+04"), + static_cast("-1.8225946631657315931e+02"), + static_cast("-4.7207090827310162436e-01"), + static_cast("-9.1746443287817501309e-04"), + static_cast("-1.3466829827635152875e-06"), + static_cast("-1.4831904935994647675e-09"), + static_cast("-1.1928788903603238754e-12"), + static_cast("-6.5245515583151902910e-16"), + static_cast("-1.9705291802535139930e-19"), + }; + static const mpfr_class Q1[] = { + static_cast("-2.9154360556286927285e+15"), + static_cast("9.7887501377547640438e+12"), + static_cast("-1.4386907088588283434e+10"), + static_cast("1.1594225856856884006e+07"), + static_cast("-5.1326864679904189920e+03"), + static_cast("1.0"), + }; + static const mpfr_class P2[] = { + static_cast("1.4582087408985668208e-05"), + static_cast("-8.9359825138577646443e-04"), + static_cast("2.9204895411257790122e-02"), + static_cast("-3.4198728018058047439e-01"), + static_cast("1.3960118277609544334e+00"), + static_cast("-1.9746376087200685843e+00"), + static_cast("8.5591872901933459000e-01"), + static_cast("-6.0437159056137599999e-02"), + }; + static const mpfr_class Q2[] = { + static_cast("3.7510433111922824643e-05"), + static_cast("-2.2835624489492512649e-03"), + static_cast("7.4212010813186530069e-02"), + static_cast("-8.5017476463217924408e-01"), + static_cast("3.2593714889036996297e+00"), + static_cast("-3.8806586721556593450e+00"), + static_cast("1.0"), + }; + mpfr_class value, factor, r, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 15) // w in (0, 15] + { + mpfr_class y = x * x; + r = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + factor = w; + value = factor * r; + } + else // w in (15, \infty) + { + mpfr_class y = 1 / w - mpfr_class(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(w) / sqrt(w); + value = factor * r; + } + + if (x < 0) + { + value *= -value; // odd function + } + return value; +} + +} // namespace detail + +} + +template<> struct std::is_convertible : public std::false_type{}; + +} + +#endif // BOOST_MATH_MPLFR_BINDINGS_HPP + diff --git a/libcxx/src/third-party/boost/math/bindings/mpreal.hpp b/libcxx/src/third-party/boost/math/bindings/mpreal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/bindings/mpreal.hpp @@ -0,0 +1,921 @@ +// Copyright John Maddock 2008. +// 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) +// +// Wrapper that works with mpfr::mpreal defined in gmpfrxx.h +// See http://math.berkeley.edu/~wilken/code/gmpfrxx/ +// Also requires the gmp and mpfr libraries. +// + +#ifndef BOOST_MATH_MPREAL_BINDINGS_HPP +#define BOOST_MATH_MPREAL_BINDINGS_HPP + +#include + +#ifdef _MSC_VER +// +// We get a lot of warnings from the gmp, mpfr and gmpfrxx headers, +// disable them here, so we only see warnings from *our* code: +// +#pragma warning(push) +#pragma warning(disable: 4127 4800 4512) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace mpfr{ + +template +inline mpreal operator + (const mpreal& r, const T& t){ return r + mpreal(t); } +template +inline mpreal operator - (const mpreal& r, const T& t){ return r - mpreal(t); } +template +inline mpreal operator * (const mpreal& r, const T& t){ return r * mpreal(t); } +template +inline mpreal operator / (const mpreal& r, const T& t){ return r / mpreal(t); } + +template +inline mpreal operator + (const T& t, const mpreal& r){ return mpreal(t) + r; } +template +inline mpreal operator - (const T& t, const mpreal& r){ return mpreal(t) - r; } +template +inline mpreal operator * (const T& t, const mpreal& r){ return mpreal(t) * r; } +template +inline mpreal operator / (const T& t, const mpreal& r){ return mpreal(t) / r; } + +template +inline bool operator == (const mpreal& r, const T& t){ return r == mpreal(t); } +template +inline bool operator != (const mpreal& r, const T& t){ return r != mpreal(t); } +template +inline bool operator <= (const mpreal& r, const T& t){ return r <= mpreal(t); } +template +inline bool operator >= (const mpreal& r, const T& t){ return r >= mpreal(t); } +template +inline bool operator < (const mpreal& r, const T& t){ return r < mpreal(t); } +template +inline bool operator > (const mpreal& r, const T& t){ return r > mpreal(t); } + +template +inline bool operator == (const T& t, const mpreal& r){ return mpreal(t) == r; } +template +inline bool operator != (const T& t, const mpreal& r){ return mpreal(t) != r; } +template +inline bool operator <= (const T& t, const mpreal& r){ return mpreal(t) <= r; } +template +inline bool operator >= (const T& t, const mpreal& r){ return mpreal(t) >= r; } +template +inline bool operator < (const T& t, const mpreal& r){ return mpreal(t) < r; } +template +inline bool operator > (const T& t, const mpreal& r){ return mpreal(t) > r; } + +/* +inline mpfr::mpreal fabs(const mpfr::mpreal& v) +{ + return abs(v); +} +inline mpfr::mpreal pow(const mpfr::mpreal& b, const mpfr::mpreal e) +{ + mpfr::mpreal result; + mpfr_pow(result.__get_mp(), b.__get_mp(), e.__get_mp(), GMP_RNDN); + return result; +} +*/ +inline mpfr::mpreal ldexp(const mpfr::mpreal& v, int e) +{ + return mpfr::ldexp(v, static_cast(e)); +} + +inline mpfr::mpreal frexp(const mpfr::mpreal& v, int* expon) +{ + mp_exp_t e; + mpfr::mpreal r = mpfr::frexp(v, &e); + *expon = e; + return r; +} + +#if (MPFR_VERSION < MPFR_VERSION_NUM(2,4,0)) +mpfr::mpreal fmod(const mpfr::mpreal& v1, const mpfr::mpreal& v2) +{ + mpfr::mpreal n; + if(v1 < 0) + n = ceil(v1 / v2); + else + n = floor(v1 / v2); + return v1 - n * v2; +} +#endif + +template +inline mpfr::mpreal modf(const mpfr::mpreal& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - boost::math::tools::real_cast(*ipart); +} +template +inline int iround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline long lround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline long long llround(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::round(x, pol)); +} + +template +inline int itrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +template +inline long ltrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +template +inline long long lltrunc(mpfr::mpreal const& x, const Policy& pol) +{ + return boost::math::tools::real_cast(boost::math::trunc(x, pol)); +} + +} + +namespace boost{ namespace math{ + +#if defined(__GNUC__) && (__GNUC__ < 4) + using ::iround; + using ::lround; + using ::llround; + using ::itrunc; + using ::ltrunc; + using ::lltrunc; + using ::modf; +#endif + +namespace lanczos{ + +struct mpreal_lanczos +{ + static mpfr::mpreal lanczos_sum(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static mpfr::mpreal lanczos_sum_expG_scaled(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static mpfr::mpreal lanczos_sum_near_1(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static mpfr::mpreal lanczos_sum_near_2(const mpfr::mpreal& z) + { + unsigned long p = z.get_default_prec(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static mpfr::mpreal g() + { + unsigned long p = mpfr::mpreal::get_default_prec(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef mpreal_lanczos type; +}; + +} // namespace lanczos + +namespace tools +{ + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + return mpfr::mpreal::get_default_prec(); +} + +namespace detail{ + +template +void convert_to_long_result(mpfr::mpreal const& r, I& result) +{ + result = 0; + I last_result(0); + mpfr::mpreal t(r); + double term; + do + { + term = real_cast(t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline mpfr::mpreal real_cast(long long t) +{ + mpfr::mpreal result; + int expon = 0; + int sign = 1; + if(t < 0) + { + sign = -1; + t = -t; + } + while(t) + { + result += ldexp(static_cast(t & 0xffffL), expon); + expon += 32; + t >>= 32; + } + return result * sign; +} +/* +template <> +inline unsigned real_cast(mpfr::mpreal t) +{ + return t.get_ui(); +} +template <> +inline int real_cast(mpfr::mpreal t) +{ + return t.get_si(); +} +template <> +inline double real_cast(mpfr::mpreal t) +{ + return t.get_d(); +} +template <> +inline float real_cast(mpfr::mpreal t) +{ + return static_cast(t.get_d()); +} +template <> +inline long real_cast(mpfr::mpreal t) +{ + long result; + detail::convert_to_long_result(t, result); + return result; +} +*/ +template <> +inline long long real_cast(mpfr::mpreal t) +{ + long long result; + detail::convert_to_long_result(t, result); + return result; +} + +template <> +inline mpfr::mpreal max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val(0.5); + if(!has_init) + { + val = ldexp(val, mpfr_get_emax()); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val(0.5); + if(!has_init) + { + val = ldexp(val, mpfr_get_emin()); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + static bool has_init = false; + static mpfr::mpreal val = max_value(); + if(!has_init) + { + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline mpfr::mpreal epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(mpfr::mpreal)) +{ + return ldexp(mpfr::mpreal(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +template +inline mpfr::mpreal skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal skewness can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("1.1395470994046486574927930193898461120875997958366"); +} + +template +inline mpfr::mpreal skewness(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal skewness can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("0.63111065781893713819189935154422777984404221106391"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 2 * root_pi() * pi_minus_three() / pow23_four_minus_pi(); +} + +template +inline mpfr::mpreal kurtosis(const rayleigh_distribution& /*dist*/) +{ + // using namespace boost::math::constants; + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal kurtosis can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("3.2450893006876380628486604106197544154170667057995"); + // Computed using NTL at 150 bit, about 50 decimal digits. + // return 3 - (6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} + +template +inline mpfr::mpreal kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + //using namespace boost::math::constants; + // Computed using NTL at 150 bit, about 50 decimal digits. + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(Policy) == 0, "mpreal excess kurtosis can not be calculated in standalone mode"); + #endif + + return boost::lexical_cast("0.2450893006876380628486604106197544154170667057995"); + // return -(6 * pi() * pi() - 24 * pi() + 16) / + // (four_minus_pi() * four_minus_pi()); +} // kurtosis + +namespace detail{ + +// +// Version of Digamma accurate to ~100 decimal digits. +// +template +mpfr::mpreal digamma_imp(mpfr::mpreal x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // empfr_classor handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + mpfr::mpreal result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + mpfr::mpreal remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} +// +// Specialisations of this function provides the initial +// starting guess for Halley iteration: +// +template +mpfr::mpreal erf_inv_imp(const mpfr::mpreal& p, const mpfr::mpreal& q, const Policy&, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + mpfr::mpreal result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute empfr_classor compared to |Y|. + // + // double: Max empfr_classor found: 2.001849e-18 + // long double: Max empfr_classor found: 1.017064e-20 + // Maximum Deviation Found (actual empfr_classor term at infinite precision) 8.030e-21 + // + static const float Y = 0.0891314744949340820313f; + static const mpfr::mpreal P[] = { + -0.000508781949658280665617, + -0.00836874819741736770379, + 0.0334806625409744615033, + -0.0126926147662974029034, + -0.0365637971411762664006, + 0.0219878681111168899165, + 0.00822687874676915743155, + -0.00538772965071242932965 + }; + static const mpfr::mpreal Q[] = { + 1, + -0.970005043303290640362, + -1.56574558234175846809, + 1.56221558398423026363, + 0.662328840472002992063, + -0.71228902341542847553, + -0.0527396382340099713954, + 0.0795283687341571680018, + -0.00233393759374190016776, + 0.000886216390456424707504 + }; + mpfr::mpreal g = p * (p + 10); + mpfr::mpreal r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute empfr_classor compared to Y. + // + // double : Max empfr_classor found: 7.403372e-17 + // long double : Max empfr_classor found: 6.084616e-20 + // Maximum Deviation Found (empfr_classor term) 4.811e-20 + // + static const float Y = 2.249481201171875f; + static const mpfr::mpreal P[] = { + -0.202433508355938759655, + 0.105264680699391713268, + 8.37050328343119927838, + 17.6447298408374015486, + -18.8510648058714251895, + -44.6382324441786960818, + 17.445385985570866523, + 21.1294655448340526258, + -3.67192254707729348546 + }; + static const mpfr::mpreal Q[] = { + 1, + 6.24264124854247537712, + 3.9713437953343869095, + -28.6608180499800029974, + -20.1432634680485188801, + 48.5609213108739935468, + 10.8268667355460159008, + -22.6436933413139721736, + 1.72114765761200282724 + }; + mpfr::mpreal g = sqrt(-2 * log(q)); + mpfr::mpreal xs = q - 0.25; + mpfr::mpreal r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute empfr_classor compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + mpfr::mpreal x = sqrt(-log(q)); + if(x < 3) + { + // Max empfr_classor found: 1.089051e-20 + static const float Y = 0.807220458984375f; + static const mpfr::mpreal P[] = { + -0.131102781679951906451, + -0.163794047193317060787, + 0.117030156341995252019, + 0.387079738972604337464, + 0.337785538912035898924, + 0.142869534408157156766, + 0.0290157910005329060432, + 0.00214558995388805277169, + -0.679465575181126350155e-6, + 0.285225331782217055858e-7, + -0.681149956853776992068e-9 + }; + static const mpfr::mpreal Q[] = { + 1, + 3.46625407242567245975, + 5.38168345707006855425, + 4.77846592945843778382, + 2.59301921623620271374, + 0.848854343457902036425, + 0.152264338295331783612, + 0.01105924229346489121 + }; + mpfr::mpreal xs = x - 1.125; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // Max empfr_classor found: 8.389174e-21 + static const float Y = 0.93995571136474609375f; + static const mpfr::mpreal P[] = { + -0.0350353787183177984712, + -0.00222426529213447927281, + 0.0185573306514231072324, + 0.00950804701325919603619, + 0.00187123492819559223345, + 0.000157544617424960554631, + 0.460469890584317994083e-5, + -0.230404776911882601748e-9, + 0.266339227425782031962e-11 + }; + static const mpfr::mpreal Q[] = { + 1, + 1.3653349817554063097, + 0.762059164553623404043, + 0.220091105764131249824, + 0.0341589143670947727934, + 0.00263861676657015992959, + 0.764675292302794483503e-4 + }; + mpfr::mpreal xs = x - 3; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // Max empfr_classor found: 1.481312e-19 + static const float Y = 0.98362827301025390625f; + static const mpfr::mpreal P[] = { + -0.0167431005076633737133, + -0.00112951438745580278863, + 0.00105628862152492910091, + 0.000209386317487588078668, + 0.149624783758342370182e-4, + 0.449696789927706453732e-6, + 0.462596163522878599135e-8, + -0.281128735628831791805e-13, + 0.99055709973310326855e-16 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.591429344886417493481, + 0.138151865749083321638, + 0.0160746087093676504695, + 0.000964011807005165528527, + 0.275335474764726041141e-4, + 0.282243172016108031869e-6 + }; + mpfr::mpreal xs = x - 6; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // Max empfr_classor found: 5.697761e-20 + static const float Y = 0.99714565277099609375f; + static const mpfr::mpreal P[] = { + -0.0024978212791898131227, + -0.779190719229053954292e-5, + 0.254723037413027451751e-4, + 0.162397777342510920873e-5, + 0.396341011304801168516e-7, + 0.411632831190944208473e-9, + 0.145596286718675035587e-11, + -0.116765012397184275695e-17 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.207123112214422517181, + 0.0169410838120975906478, + 0.000690538265622684595676, + 0.145007359818232637924e-4, + 0.144437756628144157666e-6, + 0.509761276599778486139e-9 + }; + mpfr::mpreal xs = x - 18; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // Max empfr_classor found: 1.279746e-20 + static const float Y = 0.99941349029541015625f; + static const mpfr::mpreal P[] = { + -0.000539042911019078575891, + -0.28398759004727721098e-6, + 0.899465114892291446442e-6, + 0.229345859265920864296e-7, + 0.225561444863500149219e-9, + 0.947846627503022684216e-12, + 0.135880130108924861008e-14, + -0.348890393399948882918e-21 + }; + static const mpfr::mpreal Q[] = { + 1, + 0.0845746234001899436914, + 0.00282092984726264681981, + 0.468292921940894236786e-4, + 0.399968812193862100054e-6, + 0.161809290887904476097e-8, + 0.231558608310259605225e-11 + }; + mpfr::mpreal xs = x - 44; + mpfr::mpreal R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +inline mpfr::mpreal bessel_i0(mpfr::mpreal x) +{ + #ifdef BOOST_MATH_STANDALONE + static_assert(sizeof(x) == 0, "mpreal bessel_i0 can not be calculated in standalone mode"); + #endif + + static const mpfr::mpreal P1[] = { + boost::lexical_cast("-2.2335582639474375249e+15"), + boost::lexical_cast("-5.5050369673018427753e+14"), + boost::lexical_cast("-3.2940087627407749166e+13"), + boost::lexical_cast("-8.4925101247114157499e+11"), + boost::lexical_cast("-1.1912746104985237192e+10"), + boost::lexical_cast("-1.0313066708737980747e+08"), + boost::lexical_cast("-5.9545626019847898221e+05"), + boost::lexical_cast("-2.4125195876041896775e+03"), + boost::lexical_cast("-7.0935347449210549190e+00"), + boost::lexical_cast("-1.5453977791786851041e-02"), + boost::lexical_cast("-2.5172644670688975051e-05"), + boost::lexical_cast("-3.0517226450451067446e-08"), + boost::lexical_cast("-2.6843448573468483278e-11"), + boost::lexical_cast("-1.5982226675653184646e-14"), + boost::lexical_cast("-5.2487866627945699800e-18"), + }; + static const mpfr::mpreal Q1[] = { + boost::lexical_cast("-2.2335582639474375245e+15"), + boost::lexical_cast("7.8858692566751002988e+12"), + boost::lexical_cast("-1.2207067397808979846e+10"), + boost::lexical_cast("1.0377081058062166144e+07"), + boost::lexical_cast("-4.8527560179962773045e+03"), + boost::lexical_cast("1.0"), + }; + static const mpfr::mpreal P2[] = { + boost::lexical_cast("-2.2210262233306573296e-04"), + boost::lexical_cast("1.3067392038106924055e-02"), + boost::lexical_cast("-4.4700805721174453923e-01"), + boost::lexical_cast("5.5674518371240761397e+00"), + boost::lexical_cast("-2.3517945679239481621e+01"), + boost::lexical_cast("3.1611322818701131207e+01"), + boost::lexical_cast("-9.6090021968656180000e+00"), + }; + static const mpfr::mpreal Q2[] = { + boost::lexical_cast("-5.5194330231005480228e-04"), + boost::lexical_cast("3.2547697594819615062e-02"), + boost::lexical_cast("-1.1151759188741312645e+00"), + boost::lexical_cast("1.3982595353892851542e+01"), + boost::lexical_cast("-6.0228002066743340583e+01"), + boost::lexical_cast("8.5539563258012929600e+01"), + boost::lexical_cast("-3.1446690275135491500e+01"), + boost::lexical_cast("1.0"), + }; + mpfr::mpreal value, factor, r; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (x < 0) + { + x = -x; // even function + } + if (x == 0) + { + return static_cast(1); + } + if (x <= 15) // x in (0, 15] + { + mpfr::mpreal y = x * x; + value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + } + else // x in (15, \infty) + { + mpfr::mpreal y = 1 / x - mpfr::mpreal(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(x) / sqrt(x); + value = factor * r; + } + + return value; +} + +inline mpfr::mpreal bessel_i1(mpfr::mpreal x) +{ + static const mpfr::mpreal P1[] = { + static_cast("-1.4577180278143463643e+15"), + static_cast("-1.7732037840791591320e+14"), + static_cast("-6.9876779648010090070e+12"), + static_cast("-1.3357437682275493024e+11"), + static_cast("-1.4828267606612366099e+09"), + static_cast("-1.0588550724769347106e+07"), + static_cast("-5.1894091982308017540e+04"), + static_cast("-1.8225946631657315931e+02"), + static_cast("-4.7207090827310162436e-01"), + static_cast("-9.1746443287817501309e-04"), + static_cast("-1.3466829827635152875e-06"), + static_cast("-1.4831904935994647675e-09"), + static_cast("-1.1928788903603238754e-12"), + static_cast("-6.5245515583151902910e-16"), + static_cast("-1.9705291802535139930e-19"), + }; + static const mpfr::mpreal Q1[] = { + static_cast("-2.9154360556286927285e+15"), + static_cast("9.7887501377547640438e+12"), + static_cast("-1.4386907088588283434e+10"), + static_cast("1.1594225856856884006e+07"), + static_cast("-5.1326864679904189920e+03"), + static_cast("1.0"), + }; + static const mpfr::mpreal P2[] = { + static_cast("1.4582087408985668208e-05"), + static_cast("-8.9359825138577646443e-04"), + static_cast("2.9204895411257790122e-02"), + static_cast("-3.4198728018058047439e-01"), + static_cast("1.3960118277609544334e+00"), + static_cast("-1.9746376087200685843e+00"), + static_cast("8.5591872901933459000e-01"), + static_cast("-6.0437159056137599999e-02"), + }; + static const mpfr::mpreal Q2[] = { + static_cast("3.7510433111922824643e-05"), + static_cast("-2.2835624489492512649e-03"), + static_cast("7.4212010813186530069e-02"), + static_cast("-8.5017476463217924408e-01"), + static_cast("3.2593714889036996297e+00"), + static_cast("-3.8806586721556593450e+00"), + static_cast("1.0"), + }; + mpfr::mpreal value, factor, r, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 15) // w in (0, 15] + { + mpfr::mpreal y = x * x; + r = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y); + factor = w; + value = factor * r; + } + else // w in (15, \infty) + { + mpfr::mpreal y = 1 / w - mpfr::mpreal(1) / 15; + r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y); + factor = exp(w) / sqrt(w); + value = factor * r; + } + + if (x < 0) + { + value *= -value; // odd function + } + return value; +} + +} // namespace detail +} // namespace math + +} + +#endif // BOOST_MATH_MPLFR_BINDINGS_HPP + diff --git a/libcxx/src/third-party/boost/math/bindings/rr.hpp b/libcxx/src/third-party/boost/math/bindings/rr.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/bindings/rr.hpp @@ -0,0 +1,876 @@ +// Copyright John Maddock 2007. +// 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_NTL_RR_HPP +#define BOOST_MATH_NTL_RR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace ntl +{ + +class RR; + +RR ldexp(RR r, int exp); +RR frexp(RR r, int* exp); + +class RR +{ +public: + // Constructors: + RR() {} + RR(const ::NTL::RR& c) : m_value(c){} + RR(char c) + { + m_value = c; + } + RR(wchar_t c) + { + m_value = c; + } + RR(unsigned char c) + { + m_value = c; + } + RR(signed char c) + { + m_value = c; + } + RR(unsigned short c) + { + m_value = c; + } + RR(short c) + { + m_value = c; + } + RR(unsigned int c) + { + assign_large_int(c); + } + RR(int c) + { + assign_large_int(c); + } + RR(unsigned long c) + { + assign_large_int(c); + } + RR(long c) + { + assign_large_int(c); + } + RR(unsigned long long c) + { + assign_large_int(c); + } + RR(long long c) + { + assign_large_int(c); + } + RR(float c) + { + m_value = c; + } + RR(double c) + { + m_value = c; + } + RR(long double c) + { + assign_large_real(c); + } + + // Assignment: + RR& operator=(char c) { m_value = c; return *this; } + RR& operator=(unsigned char c) { m_value = c; return *this; } + RR& operator=(signed char c) { m_value = c; return *this; } + RR& operator=(wchar_t c) { m_value = c; return *this; } + RR& operator=(short c) { m_value = c; return *this; } + RR& operator=(unsigned short c) { m_value = c; return *this; } + RR& operator=(int c) { assign_large_int(c); return *this; } + RR& operator=(unsigned int c) { assign_large_int(c); return *this; } + RR& operator=(long c) { assign_large_int(c); return *this; } + RR& operator=(unsigned long c) { assign_large_int(c); return *this; } + RR& operator=(long long c) { assign_large_int(c); return *this; } + RR& operator=(unsigned long long c) { assign_large_int(c); return *this; } + RR& operator=(float c) { m_value = c; return *this; } + RR& operator=(double c) { m_value = c; return *this; } + RR& operator=(long double c) { assign_large_real(c); return *this; } + + // Access: + NTL::RR& value(){ return m_value; } + NTL::RR const& value()const{ return m_value; } + + // Member arithmetic: + RR& operator+=(const RR& other) + { m_value += other.value(); return *this; } + RR& operator-=(const RR& other) + { m_value -= other.value(); return *this; } + RR& operator*=(const RR& other) + { m_value *= other.value(); return *this; } + RR& operator/=(const RR& other) + { m_value /= other.value(); return *this; } + RR operator-()const + { return -m_value; } + RR const& operator+()const + { return *this; } + + // RR compatibility: + const ::NTL::ZZ& mantissa() const + { return m_value.mantissa(); } + long exponent() const + { return m_value.exponent(); } + + static void SetPrecision(long p) + { ::NTL::RR::SetPrecision(p); } + + static long precision() + { return ::NTL::RR::precision(); } + + static void SetOutputPrecision(long p) + { ::NTL::RR::SetOutputPrecision(p); } + static long OutputPrecision() + { return ::NTL::RR::OutputPrecision(); } + + +private: + ::NTL::RR m_value; + + template + void assign_large_real(const V& a) + { + using std::frexp; + using std::ldexp; + using std::floor; + if (a == 0) { + clear(m_value); + return; + } + + if (a == 1) { + NTL::set(m_value); + return; + } + + if (!(boost::math::isfinite)(a)) + { + throw std::overflow_error("Cannot construct an instance of NTL::RR with an infinite value."); + } + + int e; + long double f, term; + ::NTL::RR t; + clear(m_value); + + f = frexp(a, &e); + + while(f) + { + // extract 30 bits from f: + f = ldexp(f, 30); + term = floor(f); + e -= 30; + conv(t.x, (int)term); + t.e = e; + m_value += t; + f -= term; + } + } + + template + void assign_large_int(V a) + { +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4146) +#endif + clear(m_value); + int exp = 0; + NTL::RR t; + bool neg = a < V(0) ? true : false; + if(neg) + a = -a; + while(a) + { + t = static_cast(a & 0xffff); + m_value += ldexp(RR(t), exp).value(); + a >>= 16; + exp += 16; + } + if(neg) + m_value = -m_value; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } +}; + +// Non-member arithmetic: +inline RR operator+(const RR& a, const RR& b) +{ + RR result(a); + result += b; + return result; +} +inline RR operator-(const RR& a, const RR& b) +{ + RR result(a); + result -= b; + return result; +} +inline RR operator*(const RR& a, const RR& b) +{ + RR result(a); + result *= b; + return result; +} +inline RR operator/(const RR& a, const RR& b) +{ + RR result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const RR& a, const RR& b) +{ return a.value() == b.value() ? true : false; } +inline bool operator != (const RR& a, const RR& b) +{ return a.value() != b.value() ? true : false;} +inline bool operator < (const RR& a, const RR& b) +{ return a.value() < b.value() ? true : false; } +inline bool operator <= (const RR& a, const RR& b) +{ return a.value() <= b.value() ? true : false; } +inline bool operator > (const RR& a, const RR& b) +{ return a.value() > b.value() ? true : false; } +inline bool operator >= (const RR& a, const RR& b) +{ return a.value() >= b.value() ? true : false; } + +#if 0 +// Non-member mixed compare: +template +inline bool operator == (const T& a, const RR& b) +{ + return a == b.value(); +} +template +inline bool operator != (const T& a, const RR& b) +{ + return a != b.value(); +} +template +inline bool operator < (const T& a, const RR& b) +{ + return a < b.value(); +} +template +inline bool operator > (const T& a, const RR& b) +{ + return a > b.value(); +} +template +inline bool operator <= (const T& a, const RR& b) +{ + return a <= b.value(); +} +template +inline bool operator >= (const T& a, const RR& b) +{ + return a >= b.value(); +} +#endif // Non-member mixed compare: + +// Non-member functions: +/* +inline RR acos(RR a) +{ return ::NTL::acos(a.value()); } +*/ +inline RR cos(RR a) +{ return ::NTL::cos(a.value()); } +/* +inline RR asin(RR a) +{ return ::NTL::asin(a.value()); } +inline RR atan(RR a) +{ return ::NTL::atan(a.value()); } +inline RR atan2(RR a, RR b) +{ return ::NTL::atan2(a.value(), b.value()); } +*/ +inline RR ceil(RR a) +{ return ::NTL::ceil(a.value()); } +/* +inline RR fmod(RR a, RR b) +{ return ::NTL::fmod(a.value(), b.value()); } +inline RR cosh(RR a) +{ return ::NTL::cosh(a.value()); } +*/ +inline RR exp(RR a) +{ return ::NTL::exp(a.value()); } +inline RR fabs(RR a) +{ return ::NTL::fabs(a.value()); } +inline RR abs(RR a) +{ return ::NTL::abs(a.value()); } +inline RR floor(RR a) +{ return ::NTL::floor(a.value()); } +/* +inline RR modf(RR a, RR* ipart) +{ + ::NTL::RR ip; + RR result = modf(a.value(), &ip); + *ipart = ip; + return result; +} +inline RR frexp(RR a, int* expon) +{ return ::NTL::frexp(a.value(), expon); } +inline RR ldexp(RR a, int expon) +{ return ::NTL::ldexp(a.value(), expon); } +*/ +inline RR log(RR a) +{ return ::NTL::log(a.value()); } +inline RR log10(RR a) +{ return ::NTL::log10(a.value()); } +/* +inline RR tan(RR a) +{ return ::NTL::tan(a.value()); } +*/ +inline RR pow(RR a, RR b) +{ return ::NTL::pow(a.value(), b.value()); } +inline RR pow(RR a, int b) +{ return ::NTL::power(a.value(), b); } +inline RR sin(RR a) +{ return ::NTL::sin(a.value()); } +/* +inline RR sinh(RR a) +{ return ::NTL::sinh(a.value()); } +*/ +inline RR sqrt(RR a) +{ return ::NTL::sqrt(a.value()); } +/* +inline RR tanh(RR a) +{ return ::NTL::tanh(a.value()); } +*/ + inline RR pow(const RR& r, long l) + { + return ::NTL::power(r.value(), l); + } + inline RR tan(const RR& a) + { + return sin(a)/cos(a); + } + inline RR frexp(RR r, int* exp) + { + *exp = r.value().e; + r.value().e = 0; + while(r >= 1) + { + *exp += 1; + r.value().e -= 1; + } + while(r < 0.5) + { + *exp -= 1; + r.value().e += 1; + } + BOOST_MATH_ASSERT(r < 1); + BOOST_MATH_ASSERT(r >= 0.5); + return r; + } + inline RR ldexp(RR r, int exp) + { + r.value().e += exp; + return r; + } + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const RR& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, RR& a) +{ + ::NTL::RR v; + is >> v; + a = v; + return is; +} + +} // namespace ntl + +namespace lanczos{ + +struct ntl_lanczos +{ + static ntl::RR lanczos_sum(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum(z); + } + static ntl::RR lanczos_sum_expG_scaled(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_expG_scaled(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_expG_scaled(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_expG_scaled(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_expG_scaled(z); + } + static ntl::RR lanczos_sum_near_1(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_1(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_1(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_1(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_1(z); + } + static ntl::RR lanczos_sum_near_2(const ntl::RR& z) + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::lanczos_sum_near_2(z); + else if(p <= 120) + return lanczos22UDT::lanczos_sum_near_2(z); + else if(p <= 170) + return lanczos31UDT::lanczos_sum_near_2(z); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::lanczos_sum_near_2(z); + } + static ntl::RR g() + { + unsigned long p = ntl::RR::precision(); + if(p <= 72) + return lanczos13UDT::g(); + else if(p <= 120) + return lanczos22UDT::g(); + else if(p <= 170) + return lanczos31UDT::g(); + else //if(p <= 370) approx 100 digit precision: + return lanczos61UDT::g(); + } +}; + +template +struct lanczos +{ + typedef ntl_lanczos type; +}; + +} // namespace lanczos + +namespace tools +{ + +template<> +inline int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + return ::NTL::RR::precision(); +} + +template <> +inline float real_cast(boost::math::ntl::RR t) +{ + double r; + conv(r, t.value()); + return static_cast(r); +} +template <> +inline double real_cast(boost::math::ntl::RR t) +{ + double r; + conv(r, t.value()); + return r; +} + +namespace detail{ + +template +void convert_to_long_result(NTL::RR const& r, I& result) +{ + result = 0; + I last_result(0); + NTL::RR t(r); + double term; + do + { + conv(term, t); + last_result = result; + result += static_cast(term); + t -= term; + }while(result != last_result); +} + +} + +template <> +inline long double real_cast(boost::math::ntl::RR t) +{ + long double result(0); + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline boost::math::ntl::RR real_cast(boost::math::ntl::RR t) +{ + return t; +} +template <> +inline unsigned real_cast(boost::math::ntl::RR t) +{ + unsigned result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline int real_cast(boost::math::ntl::RR t) +{ + int result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline long real_cast(boost::math::ntl::RR t) +{ + long result; + detail::convert_to_long_result(t.value(), result); + return result; +} +template <> +inline long long real_cast(boost::math::ntl::RR t) +{ + long long result; + detail::convert_to_long_result(t.value(), result); + return result; +} + +template <> +inline boost::math::ntl::RR max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = NTL_OVFBND-20; + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = -NTL_OVFBND+20; + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = NTL_OVFBND-20; + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + static bool has_init = false; + static NTL::RR val; + if(!has_init) + { + val = 1; + val.e = -NTL_OVFBND+20; + val = log(val); + has_init = true; + } + return val; +} + +template <> +inline boost::math::ntl::RR epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + return ldexp(boost::math::ntl::RR(1), 1-boost::math::policies::digits >()); +} + +} // namespace tools + +// +// The number of digits precision in RR can vary with each call +// so we need to recalculate these with each call: +// +namespace constants{ + +template<> inline boost::math::ntl::RR pi(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + NTL::RR result; + ComputePi(result); + return result; +} +template<> inline boost::math::ntl::RR e(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(boost::math::ntl::RR)) +{ + NTL::RR result; + result = 1; + return exp(result); +} + +} // namespace constants + +namespace ntl{ + // + // These are some fairly brain-dead versions of the math + // functions that NTL fails to provide. + // + + + // + // Inverse trig functions: + // + struct asin_root + { + asin_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR f0 = sin(p); + RR f1 = cos(p); + RR f2 = -f0; + f0 -= t; + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR asin(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + asin_root(z), + RR(std::asin(r)), + RR(-boost::math::constants::pi()/2), + RR(boost::math::constants::pi()/2), + NTL::RR::precision()); + } + + struct acos_root + { + acos_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR f0 = cos(p); + RR f1 = -sin(p); + RR f2 = -f0; + f0 -= t; + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR acos(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + acos_root(z), + RR(std::acos(r)), + RR(-boost::math::constants::pi()/2), + RR(boost::math::constants::pi()/2), + NTL::RR::precision()); + } + + struct atan_root + { + atan_root(RR const& target) : t(target){} + + boost::math::tuple operator()(RR const& p) + { + RR c = cos(p); + RR ta = tan(p); + RR f0 = ta - t; + RR f1 = 1 / (c * c); + RR f2 = 2 * ta / (c * c); + return boost::math::make_tuple(f0, f1, f2); + } + private: + RR t; + }; + + inline RR atan(RR z) + { + double r; + conv(r, z.value()); + return boost::math::tools::halley_iterate( + atan_root(z), + RR(std::atan(r)), + -boost::math::constants::pi()/2, + boost::math::constants::pi()/2, + NTL::RR::precision()); + } + + inline RR atan2(RR y, RR x) + { + if(x > 0) + return atan(y / x); + if(x < 0) + { + return y < 0 ? atan(y / x) - boost::math::constants::pi() : atan(y / x) + boost::math::constants::pi(); + } + return y < 0 ? -boost::math::constants::half_pi() : boost::math::constants::half_pi() ; + } + + inline RR sinh(RR z) + { + return (expm1(z.value()) - expm1(-z.value())) / 2; + } + + inline RR cosh(RR z) + { + return (exp(z) + exp(-z)) / 2; + } + + inline RR tanh(RR z) + { + return sinh(z) / cosh(z); + } + + inline RR fmod(RR x, RR y) + { + // This is a really crummy version of fmod, we rely on lots + // of digits to get us out of trouble... + RR factor = floor(x/y); + return x - factor * y; + } + + template + inline int iround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline long lround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline long long llround(RR const& x, const Policy& pol) + { + return tools::real_cast(round(x, pol)); + } + + template + inline int itrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + + template + inline long ltrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + + template + inline long long lltrunc(RR const& x, const Policy& pol) + { + return tools::real_cast(trunc(x, pol)); + } + +} // namespace ntl + +namespace detail{ + +template +ntl::RR digamma_imp(ntl::RR x, const std::integral_constant* , const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + ntl::RR result = 0; + // + // Check for negative arguments and use reflection: + // + if(x < 0) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + ntl::RR remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + result += big_digamma(x); + return result; +} + +} // namespace detail + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_REAL_CONCEPT_HPP + + diff --git a/libcxx/src/third-party/boost/math/ccmath/abs.hpp b/libcxx/src/third-party/boost/math/ccmath/abs.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/abs.hpp @@ -0,0 +1,87 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constepxr implementation of abs (see c.math.abs secion 26.8.2 of the ISO standard) + +#ifndef BOOST_MATH_CCMATH_ABS +#define BOOST_MATH_CCMATH_ABS + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T abs_impl(T x) noexcept +{ + if (boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (x == static_cast(-0)) + { + return static_cast(0); + } + + if constexpr (std::is_integral_v) + { + BOOST_MATH_ASSERT(x != (std::numeric_limits::min)()); + } + + return x >= 0 ? x : -x; +} + +} // Namespace detail + +template , bool> = true> +constexpr T abs(T x) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return detail::abs_impl(x); + } + else + { + using std::abs; + return abs(x); + } +} + +// If abs() is called with an argument of type X for which is_unsigned_v is true and if X +// cannot be converted to int by integral promotion (7.3.7), the program is ill-formed. +template , bool> = true> +constexpr T abs(T x) noexcept +{ + if constexpr (std::is_convertible_v) + { + return detail::abs_impl(static_cast(x)); + } + else + { + static_assert(sizeof(T) == 0, "Taking the absolute value of an unsigned value not covertible to int is UB."); + return T(0); // Unreachable, but suppresses warnings + } +} + +constexpr long int labs(long int j) noexcept +{ + return boost::math::ccmath::abs(j); +} + +constexpr long long int llabs(long long int j) noexcept +{ + return boost::math::ccmath::abs(j); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ABS diff --git a/libcxx/src/third-party/boost/math/ccmath/ccmath.hpp b/libcxx/src/third-party/boost/math/ccmath/ccmath.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/ccmath.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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_CCMATH_HPP +#define BOOST_MATH_CCMATH_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_MATH_CCMATH_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/ceil.hpp b/libcxx/src/third-party/boost/math/ccmath/ceil.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/ceil.hpp @@ -0,0 +1,75 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_CEIL_HPP +#define BOOST_MATH_CCMATH_CEIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T ceil_impl(T arg) noexcept +{ + T result = boost::math::ccmath::floor(arg); + + if(result == arg) + { + return result; + } + else + { + return result + 1; + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real ceil(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::ceil_impl(arg); + } + else + { + using std::ceil; + return ceil(arg); + } +} + +template , bool> = true> +inline constexpr double ceil(Z arg) noexcept +{ + return boost::math::ccmath::ceil(static_cast(arg)); +} + +inline constexpr float ceilf(float arg) noexcept +{ + return boost::math::ccmath::ceil(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double ceill(long double arg) noexcept +{ + return boost::math::ccmath::ceil(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_CEIL_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/copysign.hpp b/libcxx/src/third-party/boost/math/ccmath/copysign.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/copysign.hpp @@ -0,0 +1,81 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_COPYSIGN_HPP +#define BOOST_MATH_CCMATH_COPYSIGN_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T copysign_impl(const T mag, const T sgn) noexcept +{ + if (boost::math::ccmath::signbit(sgn)) + { + return -boost::math::ccmath::abs(mag); + } + else + { + return boost::math::ccmath::abs(mag); + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real copysign(Real mag, Real sgn) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(mag)) + { + return boost::math::ccmath::detail::copysign_impl(mag, sgn); + } + else + { + using std::copysign; + return copysign(mag, sgn); + } +} + +template +constexpr auto copysign(T1 mag, T2 sgn) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(mag)) + { + using promoted_type = boost::math::tools::promote_args_2_t; + return boost::math::ccmath::copysign(static_cast(mag), static_cast(sgn)); + } + else + { + using std::copysign; + return copysign(mag, sgn); + } +} + +constexpr float copysignf(float mag, float sgn) noexcept +{ + return boost::math::ccmath::copysign(mag, sgn); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double copysignl(long double mag, long double sgn) noexcept +{ + return boost::math::ccmath::copysign(mag, sgn); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_COPYSIGN_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/detail/swap.hpp b/libcxx/src/third-party/boost/math/ccmath/detail/swap.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/detail/swap.hpp @@ -0,0 +1,21 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_DETAIL_SWAP_HPP +#define BOOST_MATH_CCMATH_DETAIL_SWAP_HPP + +namespace boost::math::ccmath::detail { + +template +inline constexpr void swap(T& x, T& y) noexcept +{ + T temp = x; + x = y; + y = temp; +} + +} + +#endif // BOOST_MATH_CCMATH_DETAIL_SWAP_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/div.hpp b/libcxx/src/third-party/boost/math/ccmath/div.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/div.hpp @@ -0,0 +1,84 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_DIV_HPP +#define BOOST_MATH_CCMATH_DIV_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr ReturnType div_impl(const Z x, const Z y) noexcept +{ + // std::div_t/ldiv_t/lldiv_t/imaxdiv_t can be defined as either { Z quot; Z rem; }; or { Z rem; Z quot; }; + // so don't use braced initialziation to guarantee compatibility + ReturnType ans {0, 0}; + + ans.quot = x / y; + ans.rem = x % y; + + return ans; +} + +} // Namespace detail + +// Used for types other than built-ins (e.g. boost multiprecision) +template +struct div_t +{ + Z quot; + Z rem; +}; + +template +inline constexpr auto div(Z x, Z y) noexcept +{ + if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else if constexpr (std::is_same_v) + { + return detail::div_impl(x, y); + } + else + { + return detail::div_impl>(x, y); + } +} + +inline constexpr std::ldiv_t ldiv(long x, long y) noexcept +{ + return detail::div_impl(x, y); +} + +inline constexpr std::lldiv_t lldiv(long long x, long long y) noexcept +{ + return detail::div_impl(x, y); +} + +inline constexpr std::imaxdiv_t imaxdiv(std::intmax_t x, std::intmax_t y) noexcept +{ + return detail::div_impl(x, y); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_DIV_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fabs.hpp b/libcxx/src/third-party/boost/math/ccmath/fabs.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fabs.hpp @@ -0,0 +1,35 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constepxr implementation of fabs (see c.math.abs secion 26.8.2 of the ISO standard) + +#ifndef BOOST_MATH_CCMATH_FABS +#define BOOST_MATH_CCMATH_FABS + +#include + +namespace boost::math::ccmath { + +template +inline constexpr auto fabs(T x) noexcept +{ + return boost::math::ccmath::abs(x); +} + +inline constexpr float fabsf(float x) noexcept +{ + return boost::math::ccmath::abs(x); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double fabsl(long double x) noexcept +{ + return boost::math::ccmath::abs(x); +} +#endif + +} + +#endif // BOOST_MATH_CCMATH_FABS diff --git a/libcxx/src/third-party/boost/math/ccmath/fdim.hpp b/libcxx/src/third-party/boost/math/ccmath/fdim.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fdim.hpp @@ -0,0 +1,100 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_FDIM_HPP +#define BOOST_MATH_CCMATH_FDIM_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T fdim_impl(const T x, const T y) noexcept +{ + if (x <= y) + { + return 0; + } + else if ((y < 0) && (x > (std::numeric_limits::max)() + y)) + { + return std::numeric_limits::infinity(); + } + else + { + return x - y; + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real fdim(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::isnan(y) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::detail::fdim_impl(x, y); + } + else + { + using std::fdim; + return fdim(x, y); + } +} + +template +inline constexpr auto fdim(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>; + #else + >>; + #endif + + return boost::math::ccmath::fdim(promoted_type(x), promoted_type(y)); + } + else + { + using std::fdim; + return fdim(x, y); + } +} + +inline constexpr float fdimf(float x, float y) noexcept +{ + return boost::math::ccmath::fdim(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double fdiml(long double x, long double y) noexcept +{ + return boost::math::ccmath::fdim(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FDIM_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/floor.hpp b/libcxx/src/third-party/boost/math/ccmath/floor.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/floor.hpp @@ -0,0 +1,121 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_FLOOR_HPP +#define BOOST_MATH_CCMATH_FLOOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T floor_pos_impl(T arg) noexcept +{ + T result = 1; + + if(result < arg) + { + while(result < arg) + { + result *= 2; + } + while(result > arg) + { + --result; + } + + return result; + } + else + { + return T(0); + } +} + +template +inline constexpr T floor_neg_impl(T arg) noexcept +{ + T result = -1; + + if(result > arg) + { + while(result > arg) + { + result *= 2; + } + while(result < arg) + { + ++result; + } + if(result != arg) + { + --result; + } + } + + return result; +} + +template +inline constexpr T floor_impl(T arg) noexcept +{ + if(arg > 0) + { + return floor_pos_impl(arg); + } + else + { + return floor_neg_impl(arg); + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real floor(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::floor_impl(arg); + } + else + { + using std::floor; + return floor(arg); + } +} + +template , bool> = true> +inline constexpr double floor(Z arg) noexcept +{ + return boost::math::ccmath::floor(static_cast(arg)); +} + +inline constexpr float floorf(float arg) noexcept +{ + return boost::math::ccmath::floor(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double floorl(long double arg) noexcept +{ + return boost::math::ccmath::floor(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_FLOOR_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fma.hpp b/libcxx/src/third-party/boost/math/ccmath/fma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fma.hpp @@ -0,0 +1,128 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_FMA_HPP +#define BOOST_MATH_CCMATH_FMA_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fma_imp(const T x, const T y, const T z) noexcept +{ + #if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER) + if constexpr (std::is_same_v) + { + return __builtin_fmaf(x, y, z); + } + else if constexpr (std::is_same_v) + { + return __builtin_fma(x, y, z); + } + else if constexpr (std::is_same_v) + { + return __builtin_fmal(x, y, z); + } + #endif + + // If we can't use compiler intrinsics hope that -fma flag optimizes this call to fma instruction + return (x * y) + z; +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fma(Real x, Real y, Real z) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (x == 0 && boost::math::ccmath::isinf(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (y == 0 && boost::math::ccmath::isinf(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(z)) + { + return std::numeric_limits::quiet_NaN(); + } + + return boost::math::ccmath::detail::fma_imp(x, y, z); + } + else + { + using std::fma; + return fma(x, y, z); + } +} + +template +constexpr auto fma(T1 x, T2 y, T3 z) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T3p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>>>; + #else + >>>; + #endif + + return boost::math::ccmath::fma(promoted_type(x), promoted_type(y), promoted_type(z)); + } + else + { + using std::fma; + return fma(x, y, z); + } +} + +constexpr float fmaf(float x, float y, float z) noexcept +{ + return boost::math::ccmath::fma(x, y, z); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fmal(long double x, long double y, long double z) noexcept +{ + return boost::math::ccmath::fma(x, y, z); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMA_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fmax.hpp b/libcxx/src/third-party/boost/math/ccmath/fmax.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fmax.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_FMAX_HPP +#define BOOST_MATH_CCMATH_FMAX_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T fmax_impl(const T x, const T y) noexcept +{ + if (x > y) + { + return x; + } + else + { + return y; + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real fmax(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) && boost::math::ccmath::isnan(y) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::isnan(x) ? y : + boost::math::ccmath::isnan(y) ? x : + boost::math::ccmath::detail::fmax_impl(x, y); + } + else + { + using std::fmax; + return fmax(x, y); + } +} + +template +inline constexpr auto fmax(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>; + #else + >>; + #endif + + return boost::math::ccmath::fmax(promoted_type(x), promoted_type(y)); + } + else + { + using std::fmax; + return fmax(x, y); + } +} + +inline constexpr float fmaxf(float x, float y) noexcept +{ + return boost::math::ccmath::fmax(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double fmaxl(long double x, long double y) noexcept +{ + return boost::math::ccmath::fmax(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMAX_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fmin.hpp b/libcxx/src/third-party/boost/math/ccmath/fmin.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fmin.hpp @@ -0,0 +1,97 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_FMIN_HPP +#define BOOST_MATH_CCMATH_FMIN_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T fmin_impl(const T x, const T y) noexcept +{ + if (x < y) + { + return x; + } + else + { + return y; + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real fmin(Real x, Real y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) && boost::math::ccmath::isnan(y) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::isnan(x) ? y : + boost::math::ccmath::isnan(y) ? x : + boost::math::ccmath::detail::fmin_impl(x, y); + } + else + { + using std::fmin; + return fmin(x, y); + } +} + +template +inline constexpr auto fmin(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>; + #else + >>; + #endif + + return boost::math::ccmath::fmin(promoted_type(x), promoted_type(y)); + } + else + { + using std::fmin; + return fmin(x, y); + } +} + +inline constexpr float fminf(float x, float y) noexcept +{ + return boost::math::ccmath::fmin(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double fminl(long double x, long double y) noexcept +{ + return boost::math::ccmath::fmin(x, y); +} +#endif + +} // Namespace boost::math::ccmath + +#endif // BOOST_MATH_CCMATH_FMIN_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fmod.hpp b/libcxx/src/third-party/boost/math/ccmath/fmod.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fmod.hpp @@ -0,0 +1,112 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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_CCMATH_FMOD_HPP +#define BOOST_MATH_CCMATH_FMOD_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T fmod_impl(T x, T y) +{ + if (x == y) + { + return static_cast(0); + } + else + { + while (x >= y) + { + x -= y; + } + + return static_cast(x); + } +} + +} // Namespace detail + +template , bool> = true> +constexpr Real fmod(Real x, Real y) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::abs(x) == static_cast(0) && y != static_cast(0)) + { + return x; + } + else if (boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::abs(y) == static_cast(0) && !boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isinf(y) && boost::math::ccmath::isfinite(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::fmod_impl(x, y); + } + else + { + using std::fmod; + return fmod(x, y); + } +} + +template +constexpr auto fmod(T1 x, T2 y) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::fmod(promoted_type(x), promoted_type(y)); + } + else + { + using std::fmod; + return fmod(x, y); + } +} + +constexpr float fmodf(float x, float y) +{ + return boost::math::ccmath::fmod(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double fmodl(long double x, long double y) +{ + return boost::math::ccmath::fmod(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_FMOD_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/fpclassify.hpp b/libcxx/src/third-party/boost/math/ccmath/fpclassify.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/fpclassify.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_FPCLASSIFY +#define BOOST_MATH_CCMATH_FPCLASSIFY + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template , bool> = true> +inline constexpr int fpclassify(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) ? FP_NAN : + boost::math::ccmath::isinf(x) ? FP_INFINITE : + boost::math::ccmath::abs(x) == T(0) ? FP_ZERO : + boost::math::ccmath::abs(x) > 0 && boost::math::ccmath::abs(x) < (std::numeric_limits::min)() ? FP_SUBNORMAL : FP_NORMAL; + } + else + { + using std::fpclassify; + return fpclassify(x); + } +} + +template , bool> = true> +inline constexpr int fpclassify(Z x) +{ + return boost::math::ccmath::fpclassify(static_cast(x)); +} + +} + +#endif // BOOST_MATH_CCMATH_FPCLASSIFY diff --git a/libcxx/src/third-party/boost/math/ccmath/frexp.hpp b/libcxx/src/third-party/boost/math/ccmath/frexp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/frexp.hpp @@ -0,0 +1,98 @@ +// (C) Copyright Christopher Kormanyos 1999 - 2021. +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_FREXP_HPP +#define BOOST_MATH_CCMATH_FREXP_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail +{ + +template +inline constexpr Real frexp_zero_impl(Real arg, int* exp) +{ + *exp = 0; + return arg; +} + +template +inline constexpr Real frexp_impl(Real arg, int* exp) +{ + const bool negative_arg = (arg < Real(0)); + + Real f = negative_arg ? -arg : arg; + int e2 = 0; + constexpr Real two_pow_32 = Real(4294967296); + + while (f >= two_pow_32) + { + f = f / two_pow_32; + e2 += 32; + } + + while(f >= Real(1)) + { + f = f / Real(2); + ++e2; + } + + if(exp != nullptr) + { + *exp = e2; + } + + return !negative_arg ? f : -f; +} + +} // namespace detail + +template , bool> = true> +inline constexpr Real frexp(Real arg, int* exp) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return arg == Real(0) ? detail::frexp_zero_impl(arg, exp) : + arg == Real(-0) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::isinf(arg) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::isnan(arg) ? detail::frexp_zero_impl(arg, exp) : + boost::math::ccmath::detail::frexp_impl(arg, exp); + } + else + { + using std::frexp; + return frexp(arg, exp); + } +} + +template , bool> = true> +inline constexpr double frexp(Z arg, int* exp) +{ + return boost::math::ccmath::frexp(static_cast(arg), exp); +} + +inline constexpr float frexpf(float arg, int* exp) +{ + return boost::math::ccmath::frexp(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double frexpl(long double arg, int* exp) +{ + return boost::math::ccmath::frexp(arg, exp); +} +#endif + +} + +#endif // BOOST_MATH_CCMATH_FREXP_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/hypot.hpp b/libcxx/src/third-party/boost/math/ccmath/hypot.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/hypot.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2005-2021. +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_HYPOT_HPP +#define BOOST_MATH_CCMATH_HYPOT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T hypot_impl(T x, T y) noexcept +{ + x = boost::math::ccmath::abs(x); + y = boost::math::ccmath::abs(y); + + if (y > x) + { + boost::math::ccmath::detail::swap(x, y); + } + + if(x * std::numeric_limits::epsilon() >= y) + { + return x; + } + + T rat = y / x; + return x * boost::math::ccmath::sqrt(1 + rat * rat); +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real hypot(Real x, Real y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::abs(x) == Real(0) ? boost::math::ccmath::abs(y) : + boost::math::ccmath::abs(y) == Real(0) ? boost::math::ccmath::abs(x) : + boost::math::ccmath::isinf(x) ? std::numeric_limits::infinity() : + boost::math::ccmath::isinf(y) ? std::numeric_limits::infinity() : + boost::math::ccmath::isnan(x) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::isnan(y) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::detail::hypot_impl(x, y); + } + else + { + using std::hypot; + return hypot(x, y); + } +} + +template +inline constexpr auto hypot(T1 x, T2 y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // If the type is an integer (e.g. epsilon == 0) then set the epsilon value to 1 so that type is at a minimum + // cast to double + constexpr auto T1p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + constexpr auto T2p = std::numeric_limits::epsilon() > 0 ? std::numeric_limits::epsilon() : 1; + + using promoted_type = + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + std::conditional_t>>>; + #else + >>; + #endif + + return boost::math::ccmath::hypot(promoted_type(x), promoted_type(y)); + } + else + { + using std::hypot; + return hypot(x, y); + } +} + +inline constexpr float hypotf(float x, float y) noexcept +{ + return boost::math::ccmath::hypot(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double hypotl(long double x, long double y) noexcept +{ + return boost::math::ccmath::hypot(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_HYPOT_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/ilogb.hpp b/libcxx/src/third-party/boost/math/ccmath/ilogb.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/ilogb.hpp @@ -0,0 +1,57 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_ILOGB_HPP +#define BOOST_MATH_CCMATH_ILOGB_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +// If arg is not zero, infinite, or NaN, the value returned is exactly equivalent to static_cast(std::logb(arg)) +template , bool> = true> +inline constexpr int ilogb(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? FP_ILOGB0 : + boost::math::ccmath::isinf(arg) ? INT_MAX : + boost::math::ccmath::isnan(arg) ? FP_ILOGBNAN : + static_cast(boost::math::ccmath::logb(arg)); + } + else + { + using std::ilogb; + return ilogb(arg); + } +} + +template , bool> = true> +inline constexpr int ilogb(Z arg) noexcept +{ + return boost::math::ccmath::ilogb(static_cast(arg)); +} + +inline constexpr int ilogbf(float arg) noexcept +{ + return boost::math::ccmath::ilogb(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr int ilogbl(long double arg) noexcept +{ + return boost::math::ccmath::ilogb(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ILOGB_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/isfinite.hpp b/libcxx/src/third-party/boost/math/ccmath/isfinite.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isfinite.hpp @@ -0,0 +1,50 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_ISFINITE +#define BOOST_MATH_CCMATH_ISFINITE + +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isfinite(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + // bool isfinite (IntegralType arg) is a set of overloads accepting the arg argument of any integral type + // equivalent to casting the integral argument arg to double (e.g. static_cast(arg)) + if constexpr (std::is_integral_v) + { + return !boost::math::ccmath::isinf(static_cast(x)) && !boost::math::ccmath::isnan(static_cast(x)); + } + else + { + return !boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(x); + } + } + else + { + using std::isfinite; + + if constexpr (!std::is_integral_v) + { + return isfinite(x); + } + else + { + return isfinite(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISFINITE diff --git a/libcxx/src/third-party/boost/math/ccmath/isgreater.hpp b/libcxx/src/third-party/boost/math/ccmath/isgreater.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isgreater.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_ISGREATER_HPP +#define BOOST_MATH_CCMATH_ISGREATER_HPP + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isgreater(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x > y; + } + } + else + { + using std::isgreater; + return isgreater(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISGREATER_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/isgreaterequal.hpp b/libcxx/src/third-party/boost/math/ccmath/isgreaterequal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isgreaterequal.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_ISGREATEREQUAL_HPP +#define BOOST_MATH_CCMATH_ISGREATEREQUAL_HPP + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isgreaterequal(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x >= y; + } + } + else + { + using std::isgreaterequal; + return isgreaterequal(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISGREATEREQUAL_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/isinf.hpp b/libcxx/src/third-party/boost/math/ccmath/isinf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isinf.hpp @@ -0,0 +1,40 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_ISINF +#define BOOST_MATH_CCMATH_ISINF + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isinf(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return x == std::numeric_limits::infinity() || -x == std::numeric_limits::infinity(); + } + else + { + using std::isinf; + + if constexpr (!std::is_integral_v) + { + return isinf(x); + } + else + { + return isinf(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISINF diff --git a/libcxx/src/third-party/boost/math/ccmath/isless.hpp b/libcxx/src/third-party/boost/math/ccmath/isless.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isless.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_ISLESS_HPP +#define BOOST_MATH_CCMATH_ISLESS_HPP + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isless(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x < y; + } + } + else + { + using std::isless; + return isless(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISLESS_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/islessequal.hpp b/libcxx/src/third-party/boost/math/ccmath/islessequal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/islessequal.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_ISLESSEQUAL_HPP +#define BOOST_MATH_CCMATH_ISLESSEQUAL_HPP + +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool islessequal(T1 x, T2 y) noexcept +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y)) + { + return false; + } + else + { + return x <= y; + } + } + else + { + using std::islessequal; + return islessequal(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISLESSEQUAL_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/isnan.hpp b/libcxx/src/third-party/boost/math/ccmath/isnan.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isnan.hpp @@ -0,0 +1,39 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_ISNAN +#define BOOST_MATH_CCMATH_ISNAN + +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isnan(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return x != x; + } + else + { + using std::isnan; + + if constexpr (!std::is_integral_v) + { + return isnan(x); + } + else + { + return isnan(static_cast(x)); + } + } +} + +} + +#endif // BOOST_MATH_CCMATH_ISNAN diff --git a/libcxx/src/third-party/boost/math/ccmath/isnormal.hpp b/libcxx/src/third-party/boost/math/ccmath/isnormal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isnormal.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Matt Borland 2021. +// 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_ISNORMAL_HPP +#define BOOST_MATH_ISNORMAL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isnormal(T x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return x == T(0) ? false : + boost::math::ccmath::isinf(x) ? false : + boost::math::ccmath::isnan(x) ? false : + boost::math::ccmath::abs(x) < (std::numeric_limits::min)() ? false : true; + } + else + { + using std::isnormal; + + if constexpr (!std::is_integral_v) + { + return isnormal(x); + } + else + { + return isnormal(static_cast(x)); + } + } +} +} + +#endif // BOOST_MATH_ISNORMAL_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/isunordered.hpp b/libcxx/src/third-party/boost/math/ccmath/isunordered.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/isunordered.hpp @@ -0,0 +1,31 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_ISUNORDERED_HPP +#define BOOST_MATH_CCMATH_ISUNORDERED_HPP + +#include +#include +#include + +namespace boost::math::ccmath { + +template +inline constexpr bool isunordered(const T x, const T y) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) || boost::math::ccmath::isnan(y); + } + else + { + using std::isunordered; + return isunordered(x, y); + } +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ISUNORDERED_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/ldexp.hpp b/libcxx/src/third-party/boost/math/ccmath/ldexp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/ldexp.hpp @@ -0,0 +1,79 @@ +// (C) Copyright Matt Borland 2021. +// (C) Copyright John Maddock 2021. +// 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_CCMATH_LDEXP_HPP +#define BOOST_MATH_CCMATH_LDEXP_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real ldexp_impl(Real arg, int exp) noexcept +{ + while(exp > 0) + { + arg *= 2; + --exp; + } + while(exp < 0) + { + arg /= 2; + ++exp; + } + + return arg; +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real ldexp(Real arg, int exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::ldexp_impl(arg, exp); + } + else + { + using std::ldexp; + return ldexp(arg, exp); + } +} + +template , bool> = true> +inline constexpr double ldexp(Z arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(static_cast(arg), exp); +} + +inline constexpr float ldexpf(float arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double ldexpl(long double arg, int exp) noexcept +{ + return boost::math::ccmath::ldexp(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_LDEXP_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/logb.hpp b/libcxx/src/third-party/boost/math/ccmath/logb.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/logb.hpp @@ -0,0 +1,74 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_LOGB_HPP +#define BOOST_MATH_CCMATH_LOGB_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// The value of the exponent returned by std::logb is always 1 less than the exponent returned by +// std::frexp because of the different normalization requirements: for the exponent e returned by std::logb, +// |arg*r^-e| is between 1 and r (typically between 1 and 2), but for the exponent e returned by std::frexp, +// |arg*2^-e| is between 0.5 and 1. +template +inline constexpr T logb_impl(T arg) noexcept +{ + int exp = 0; + boost::math::ccmath::frexp(arg, &exp); + + return exp - 1; +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real logb(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? -std::numeric_limits::infinity() : + boost::math::ccmath::isinf(arg) ? std::numeric_limits::infinity() : + boost::math::ccmath::isnan(arg) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::detail::logb_impl(arg); + } + else + { + using std::logb; + return logb(arg); + } +} + +template , bool> = true> +inline constexpr double logb(Z arg) noexcept +{ + return boost::math::ccmath::logb(static_cast(arg)); +} + +inline constexpr float logbf(float arg) noexcept +{ + return boost::math::ccmath::logb(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double logbl(long double arg) noexcept +{ + return boost::math::ccmath::logb(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_LOGB_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/modf.hpp b/libcxx/src/third-party/boost/math/ccmath/modf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/modf.hpp @@ -0,0 +1,77 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_MODF_HPP +#define BOOST_MATH_CCMATH_MODF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real modf_error_impl(Real x, Real* iptr) +{ + *iptr = x; + return boost::math::ccmath::abs(x) == Real(0) ? x : + x > Real(0) ? Real(0) : -Real(0); +} + +template +inline constexpr Real modf_nan_impl(Real x, Real* iptr) +{ + *iptr = x; + return x; +} + +template +inline constexpr Real modf_impl(Real x, Real* iptr) +{ + *iptr = boost::math::ccmath::trunc(x); + return (x - *iptr); +} + +} // Namespace detail + +template +inline constexpr Real modf(Real x, Real* iptr) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::abs(x) == Real(0) ? detail::modf_error_impl(x, iptr) : + boost::math::ccmath::isinf(x) ? detail::modf_error_impl(x, iptr) : + boost::math::ccmath::isnan(x) ? detail::modf_nan_impl(x, iptr) : + boost::math::ccmath::detail::modf_impl(x, iptr); + } + else + { + using std::modf; + return modf(x, iptr); + } +} + +inline constexpr float modff(float x, float* iptr) +{ + return boost::math::ccmath::modf(x, iptr); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double modfl(long double x, long double* iptr) +{ + return boost::math::ccmath::modf(x, iptr); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_MODF_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/next.hpp b/libcxx/src/third-party/boost/math/ccmath/next.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/next.hpp @@ -0,0 +1,456 @@ +// (C) Copyright John Maddock 2008 - 2022. +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_NEXT_HPP +#define BOOST_MATH_CCMATH_NEXT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// Forward Declarations +template > +constexpr result_type float_prior(const T& val); + +template > +constexpr result_type float_next(const T& val); + +template +struct has_hidden_guard_digits; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +#ifdef BOOST_HAS_FLOAT128 +template <> +struct has_hidden_guard_digits<__float128> : public std::false_type {}; +#endif + +template +struct has_hidden_guard_digits_10 : public std::false_type {}; +template +struct has_hidden_guard_digits_10 : public std::integral_constant::digits10 != std::numeric_limits::max_digits10)> {}; + +template +struct has_hidden_guard_digits + : public has_hidden_guard_digits_10::is_specialized + && (std::numeric_limits::radix == 10) > +{}; + +template +constexpr T normalize_value(const T& val, const std::false_type&) { return val; } +template +constexpr T normalize_value(const T& val, const std::true_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + std::intmax_t shift = static_cast(std::numeric_limits::digits) - static_cast(boost::math::ccmath::ilogb(val)) - 1; + T result = boost::math::ccmath::scalbn(val, shift); + result = boost::math::ccmath::round(result); + return boost::math::ccmath::scalbn(result, -shift); +} + +template +constexpr T get_smallest_value(const std::true_type&) +{ + // + // numeric_limits lies about denorms being present - particularly + // when this can be turned on or off at runtime, as is the case + // when using the SSE2 registers in DAZ or FTZ mode. + // + constexpr T m = std::numeric_limits::denorm_min(); + return ((tools::min_value() / 2) == 0) ? tools::min_value() : m; +} + +template +constexpr T get_smallest_value(const std::false_type&) +{ + return tools::min_value(); +} + +template +constexpr T get_smallest_value() +{ + return get_smallest_value(std::integral_constant::is_specialized && (std::numeric_limits::has_denorm == std::denorm_present)>()); +} + +template +constexpr T calc_min_shifted(const std::true_type&) +{ + return boost::math::ccmath::ldexp(tools::min_value(), tools::digits() + 1); +} + +template +constexpr T calc_min_shifted(const std::false_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + return boost::math::ccmath::scalbn(tools::min_value(), std::numeric_limits::digits + 1); +} + +template +constexpr T get_min_shift_value() +{ + const T val = calc_min_shifted(std::integral_constant::is_specialized || std::numeric_limits::radix == 2>()); + return val; +} + +template > +struct exponent_type +{ + using type = int; +}; + +template +struct exponent_type +{ + using type = typename T::backend_type::exponent_type; +}; + +template > +using exponent_type_t = typename exponent_type::type; + +template +constexpr T float_next_imp(const T& val, const std::true_type&) +{ + using exponent_type = exponent_type_t; + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::ldexp(boost::math::ccmath::detail::float_next(static_cast(boost::math::ccmath::ldexp(val, 2 * tools::digits()))), -2 * tools::digits()); + } + + if (-0.5f == boost::math::ccmath::frexp(val, &expon)) + { + --expon; // reduce exponent when val is a power of two, and negative. + } + T diff = boost::math::ccmath::ldexp(static_cast(1), expon - tools::digits()); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + return val + diff; +} + +// +// Special version for some base other than 2: +// +template +constexpr T float_next_imp(const T& val, const std::false_type&) +{ + using exponent_type = exponent_type_t; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::scalbn(boost::math::ccmath::detail::float_next(static_cast(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits::digits))), -2 * std::numeric_limits::digits); + } + + expon = 1 + boost::math::ccmath::ilogb(val); + if(-1 == boost::math::ccmath::scalbn(val, -expon) * std::numeric_limits::radix) + { + --expon; // reduce exponent when val is a power of base, and negative. + } + + T diff = boost::math::ccmath::scalbn(static_cast(1), expon - std::numeric_limits::digits); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + + return val + diff; +} + +template +constexpr result_type float_next(const T& val) +{ + return detail::float_next_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>()); +} + +template +constexpr T float_prior_imp(const T& val, const std::true_type&) +{ + using exponent_type = exponent_type_t; + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return -detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::ldexp(boost::math::ccmath::detail::float_prior(static_cast(boost::math::ccmath::ldexp(val, 2 * tools::digits()))), -2 * tools::digits()); + } + + if(T remain = boost::math::ccmath::frexp(val, &expon); remain == 0.5f) + { + --expon; // when val is a power of two we must reduce the exponent + } + + T diff = boost::math::ccmath::ldexp(static_cast(1), expon - tools::digits()); + if(diff == 0) + { + diff = detail::get_smallest_value(); + } + + return val - diff; +} + +// +// Special version for bases other than 2: +// +template +constexpr T float_prior_imp(const T& val, const std::false_type&) +{ + using exponent_type = exponent_type_t; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + exponent_type expon {}; + + int fpclass = boost::math::ccmath::fpclassify(val); + + if (fpclass == FP_NAN) + { + return val; + } + else if (fpclass == FP_INFINITE) + { + return val; + } + else if (val <= -tools::max_value()) + { + return val; + } + + if (val == 0) + { + return -detail::get_smallest_value(); + } + + if ((fpclass != FP_SUBNORMAL) && (fpclass != FP_ZERO) + && (boost::math::ccmath::fabs(val) < detail::get_min_shift_value()) + && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return boost::math::ccmath::scalbn(boost::math::ccmath::detail::float_prior(static_cast(boost::math::ccmath::scalbn(val, 2 * std::numeric_limits::digits))), -2 * std::numeric_limits::digits); + } + + expon = 1 + boost::math::ccmath::ilogb(val); + + if (T remain = boost::math::ccmath::scalbn(val, -expon); remain * std::numeric_limits::radix == 1) + { + --expon; // when val is a power of two we must reduce the exponent + } + + T diff = boost::math::ccmath::scalbn(static_cast(1), expon - std::numeric_limits::digits); + if (diff == 0) + { + diff = detail::get_smallest_value(); + } + return val - diff; +} // float_prior_imp + +template +constexpr result_type float_prior(const T& val) +{ + return detail::float_prior_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>()); +} + +} // namespace detail + +template > +constexpr result_type nextafter(const T& val, const U& direction) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(val)) + { + if (boost::math::ccmath::isnan(val)) + { + return val; + } + else if (boost::math::ccmath::isnan(direction)) + { + return direction; + } + else if (val < direction) + { + return boost::math::ccmath::detail::float_next(val); + } + else if (val == direction) + { + // IEC 60559 recommends that from is returned whenever from == to. These functions return to instead, + // which makes the behavior around zero consistent: std::nextafter(-0.0, +0.0) returns +0.0 and + // std::nextafter(+0.0, -0.0) returns -0.0. + return direction; + } + + return boost::math::ccmath::detail::float_prior(val); + } + else + { + using std::nextafter; + return nextafter(static_cast(val), static_cast(direction)); + } +} + +constexpr float nextafterf(float val, float direction) +{ + return boost::math::ccmath::nextafter(val, direction); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + +constexpr long double nextafterl(long double val, long double direction) +{ + return boost::math::ccmath::nextafter(val, direction); +} + +template , typename return_type = std::conditional_t, double, T>> +constexpr return_type nexttoward(T val, long double direction) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(val)) + { + return static_cast(boost::math::ccmath::nextafter(static_cast(val), direction)); + } + else + { + using std::nexttoward; + return nexttoward(val, direction); + } +} + +constexpr float nexttowardf(float val, long double direction) +{ + return boost::math::ccmath::nexttoward(val, direction); +} + +constexpr long double nexttowardl(long double val, long double direction) +{ + return boost::math::ccmath::nexttoward(val, direction); +} + +#endif + +} // Namespaces + +#endif // BOOST_MATH_SPECIAL_NEXT_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/remainder.hpp b/libcxx/src/third-party/boost/math/ccmath/remainder.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/remainder.hpp @@ -0,0 +1,104 @@ +// (C) Copyright Matt Borland 2021 - 2022. +// 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_CCMATH_REMAINDER_HPP +#define BOOST_MATH_CCMATH_REMAINDER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +constexpr T remainder_impl(const T x, const T y) +{ + T n = 0; + + if (T fractional_part = boost::math::ccmath::modf((x / y), &n); fractional_part > static_cast(1.0/2)) + { + ++n; + } + else if (fractional_part < static_cast(-1.0/2)) + { + --n; + } + + return x - n*y; +} + +} // Namespace detail + +template , bool> = true> +constexpr Real remainder(Real x, Real y) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + if (boost::math::ccmath::isinf(x) && !boost::math::ccmath::isnan(y)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::abs(y) == static_cast(0) && !boost::math::ccmath::isnan(x)) + { + return std::numeric_limits::quiet_NaN(); + } + else if (boost::math::ccmath::isnan(x)) + { + return x; + } + else if (boost::math::ccmath::isnan(y)) + { + return y; + } + + return boost::math::ccmath::detail::remainder_impl(x, y); + } + else + { + using std::remainder; + return remainder(x, y); + } +} + +template +constexpr auto remainder(T1 x, T2 y) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + using promoted_type = boost::math::tools::promote_args_t; + return boost::math::ccmath::remainder(promoted_type(x), promoted_type(y)); + } + else + { + using std::remainder; + return remainder(x, y); + } +} + +constexpr float remainderf(float x, float y) +{ + return boost::math::ccmath::remainder(x, y); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +constexpr long double remainderl(long double x, long double y) +{ + return boost::math::ccmath::remainder(x, y); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_REMAINDER_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/round.hpp b/libcxx/src/third-party/boost/math/ccmath/round.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/round.hpp @@ -0,0 +1,176 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_ROUND_HPP +#define BOOST_MATH_CCMATH_ROUND_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +// Computes the nearest integer value to arg (in floating-point format), +// rounding halfway cases away from zero, regardless of the current rounding mode. +template +inline constexpr T round_impl(T arg) noexcept +{ + T iptr = 0; + const T x = boost::math::ccmath::modf(arg, &iptr); + constexpr T half = T(1)/2; + + if(x >= half && iptr > 0) + { + return iptr + 1; + } + else if(boost::math::ccmath::abs(x) >= half && iptr < 0) + { + return iptr - 1; + } + else + { + return iptr; + } +} + +template +inline constexpr ReturnType int_round_impl(T arg) +{ + const T rounded_arg = round_impl(arg); + + if(rounded_arg > static_cast((std::numeric_limits::max)())) + { + if constexpr (std::is_same_v) + { + throw std::domain_error("Rounded value cannot be represented by a long long type without overflow"); + } + else + { + throw std::domain_error("Rounded value cannot be represented by a long type without overflow"); + } + } + else + { + return static_cast(rounded_arg); + } +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real round(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::round_impl(arg); + } + else + { + using std::round; + return round(arg); + } +} + +template , bool> = true> +inline constexpr double round(Z arg) noexcept +{ + return boost::math::ccmath::round(static_cast(arg)); +} + +inline constexpr float roundf(float arg) noexcept +{ + return boost::math::ccmath::round(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double roundl(long double arg) noexcept +{ + return boost::math::ccmath::round(arg); +} +#endif + +template , bool> = true> +inline constexpr long lround(Real arg) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? 0l : + boost::math::ccmath::isinf(arg) ? 0l : + boost::math::ccmath::isnan(arg) ? 0l : + boost::math::ccmath::detail::int_round_impl(arg); + } + else + { + using std::lround; + return lround(arg); + } +} + +template , bool> = true> +inline constexpr long lround(Z arg) +{ + return boost::math::ccmath::lround(static_cast(arg)); +} + +inline constexpr long lroundf(float arg) +{ + return boost::math::ccmath::lround(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long lroundl(long double arg) +{ + return boost::math::ccmath::lround(arg); +} +#endif + +template , bool> = true> +inline constexpr long long llround(Real arg) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? 0ll : + boost::math::ccmath::isinf(arg) ? 0ll : + boost::math::ccmath::isnan(arg) ? 0ll : + boost::math::ccmath::detail::int_round_impl(arg); + } + else + { + using std::llround; + return llround(arg); + } +} + +template , bool> = true> +inline constexpr long llround(Z arg) +{ + return boost::math::ccmath::llround(static_cast(arg)); +} + +inline constexpr long long llroundf(float arg) +{ + return boost::math::ccmath::llround(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long long llroundl(long double arg) +{ + return boost::math::ccmath::llround(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_ROUND_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/scalbln.hpp b/libcxx/src/third-party/boost/math/ccmath/scalbln.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/scalbln.hpp @@ -0,0 +1,57 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_SCALBLN_HPP +#define BOOST_MATH_CCMATH_SCALBLN_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +template , bool> = true> +inline constexpr Real scalbln(Real arg, long exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::scalbn_impl(arg, exp); + } + else + { + using std::scalbln; + return scalbln(arg, exp); + } +} + +template , bool> = true> +inline constexpr double scalbln(Z arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(static_cast(arg), exp); +} + +inline constexpr float scalblnf(float arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double scalblnl(long double arg, long exp) noexcept +{ + return boost::math::ccmath::scalbln(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SCALBLN_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/scalbn.hpp b/libcxx/src/third-party/boost/math/ccmath/scalbn.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/scalbn.hpp @@ -0,0 +1,79 @@ +// (C) Copyright Matt Borland 2021. +// (C) Copyright John Maddock 2021. +// 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_CCMATH_SCALBN_HPP +#define BOOST_MATH_CCMATH_SCALBN_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real scalbn_impl(Real arg, Z exp) noexcept +{ + while(exp > 0) + { + arg *= FLT_RADIX; + --exp; + } + while(exp < 0) + { + arg /= FLT_RADIX; + ++exp; + } + + return arg; +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real scalbn(Real arg, int exp) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::scalbn_impl(arg, exp); + } + else + { + using std::scalbn; + return scalbn(arg, exp); + } +} + +template , bool> = true> +inline constexpr double scalbn(Z arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(static_cast(arg), exp); +} + +inline constexpr float scalbnf(float arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(arg, exp); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double scalbnl(long double arg, int exp) noexcept +{ + return boost::math::ccmath::scalbn(arg, exp); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SCALBN_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/signbit.hpp b/libcxx/src/third-party/boost/math/ccmath/signbit.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/signbit.hpp @@ -0,0 +1,217 @@ +// (C) Copyright Matt Borland 2022. +// 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_CCMATH_SIGNBIT_HPP +#define BOOST_MATH_CCMATH_SIGNBIT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __has_include +# if __has_include() +# include +# if __cpp_lib_bit_cast >= 201806L +# define BOOST_MATH_BIT_CAST(T, x) std::bit_cast(x) +# endif +# elif defined(__has_builtin) +# if __has_builtin(__builtin_bit_cast) +# define BOOST_MATH_BIT_CAST(T, x) __builtin_bit_cast(T, x) +# endif +# endif +#endif + +/* +The following error is given using Apple Clang version 13.1.6, and Clang 13, and 14 on Ubuntu 22.04.01 +TODO: Remove the following undef when Apple Clang supports + +ccmath_signbit_test.cpp:32:19: error: static_assert expression is not an integral constant expression + static_assert(boost::math::ccmath::signbit(T(-1)) == true); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../../../boost/math/ccmath/signbit.hpp:62:24: note: constexpr bit_cast involving bit-field is not yet supported + const auto u = BOOST_MATH_BIT_CAST(float_bits, arg); + ^ +../../../boost/math/ccmath/signbit.hpp:20:37: note: expanded from macro 'BOOST_MATH_BIT_CAST' +# define BOOST_MATH_BIT_CAST(T, x) __builtin_bit_cast(T, x) + ^ +*/ + +#if defined(__clang__) && defined(BOOST_MATH_BIT_CAST) +# undef BOOST_MATH_BIT_CAST +#endif + +namespace boost::math::ccmath { + +namespace detail { + +#ifdef BOOST_MATH_BIT_CAST + +struct IEEEf2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa : 23; + std::uint32_t exponent : 8; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 8; + std::uint32_t mantissa : 23; +#endif +}; + +struct IEEEd2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 20; + std::uint32_t exponent : 11; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 11; + std::uint32_t mantissa_h : 20; + std::uint32_t mantissa_l : 32; +#endif +}; + +// 80 bit long double +#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 32; + std::uint32_t exponent : 15; + std::uint32_t sign : 1; + std::uint32_t pad : 32; +#else // Big endian + std::uint32_t pad : 32; + std::uint32_t sign : 1; + std::uint32_t exponent : 15; + std::uint32_t mantissa_h : 32; + std::uint32_t mantissa_l : 32; +#endif +}; + +// 128 bit long double +#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint64_t mantissa_l : 64; + std::uint64_t mantissa_h : 48; + std::uint32_t exponent : 15; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 15; + std::uint64_t mantissa_h : 48; + std::uint64_t mantissa_l : 64; +#endif +}; + +// 64 bit long double (double == long double on ARM) +#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 + +struct IEEEl2bits +{ +#if BOOST_MATH_ENDIAN_LITTLE_BYTE + std::uint32_t mantissa_l : 32; + std::uint32_t mantissa_h : 20; + std::uint32_t exponent : 11; + std::uint32_t sign : 1; +#else // Big endian + std::uint32_t sign : 1; + std::uint32_t exponent : 11; + std::uint32_t mantissa_h : 20; + std::uint32_t mantissa_l : 32; +#endif +}; + +#else // Unsupported long double representation +# define BOOST_MATH_UNSUPPORTED_LONG_DOUBLE +#endif + +template +constexpr bool signbit_impl(T arg) +{ + if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEf2bits, arg); + return u.sign; + } + else if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEd2bits, arg); + return u.sign; + } + #ifndef BOOST_MATH_UNSUPPORTED_LONG_DOUBLE + else if constexpr (std::is_same_v) + { + const auto u = BOOST_MATH_BIT_CAST(IEEEl2bits, arg); + return u.sign; + } + #endif + else + { + BOOST_MATH_ASSERT_MSG(!boost::math::ccmath::isnan(arg), "NAN is not supported with this type or platform"); + BOOST_MATH_ASSERT_MSG(boost::math::ccmath::abs(arg) != 0, "Signed 0 is not support with this type or platform"); + + return arg < static_cast(0); + } +} + +#else + +// Typical implementations of signbit involve type punning via union and manipulating +// overflow (see libc++ or musl). Neither of these are allowed in constexpr contexts +// (technically type punning via union in general is UB in c++ but well defined in C) +// therefore we static assert these cases. + +template +constexpr bool signbit_impl(T arg) +{ + BOOST_MATH_ASSERT_MSG(!boost::math::ccmath::isnan(arg), "NAN is not supported without __builtin_bit_cast or std::bit_cast"); + BOOST_MATH_ASSERT_MSG(boost::math::ccmath::abs(arg) != 0, "Signed 0 is not support without __builtin_bit_cast or std::bit_cast"); + + return arg < static_cast(0); +} + +#endif + +} + +// Return value: true if arg is negative, false if arg is 0, NAN, or positive +template , bool> = true> +constexpr bool signbit(Real arg) +{ + if (BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::detail::signbit_impl(arg); + } + else + { + using std::signbit; + return signbit(arg); + } +} + +template , bool> = true> +constexpr bool signbit(Z arg) +{ + return boost::math::ccmath::signbit(static_cast(arg)); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SIGNBIT_HPP diff --git a/libcxx/src/third-party/boost/math/ccmath/sqrt.hpp b/libcxx/src/third-party/boost/math/ccmath/sqrt.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/sqrt.hpp @@ -0,0 +1,66 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// Constexpr implementation of sqrt function + +#ifndef BOOST_MATH_CCMATH_SQRT +#define BOOST_MATH_CCMATH_SQRT + +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr Real sqrt_impl_2(Real x, Real s, Real s2) +{ + return !(s < s2) ? s2 : sqrt_impl_2(x, (x / s + s) / 2, s); +} + +template +inline constexpr Real sqrt_impl_1(Real x, Real s) +{ + return sqrt_impl_2(x, (x / s + s) / 2, s); +} + +template +inline constexpr Real sqrt_impl(Real x) +{ + return sqrt_impl_1(x, x > 1 ? x : Real(1)); +} + +} // namespace detail + +template , bool> = true> +inline constexpr Real sqrt(Real x) +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(x)) + { + return boost::math::ccmath::isnan(x) ? std::numeric_limits::quiet_NaN() : + boost::math::ccmath::isinf(x) ? std::numeric_limits::infinity() : + detail::sqrt_impl(x); + } + else + { + using std::sqrt; + return sqrt(x); + } +} + +template , bool> = true> +inline constexpr double sqrt(Z x) +{ + return detail::sqrt_impl(static_cast(x)); +} + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_SQRT diff --git a/libcxx/src/third-party/boost/math/ccmath/trunc.hpp b/libcxx/src/third-party/boost/math/ccmath/trunc.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/ccmath/trunc.hpp @@ -0,0 +1,67 @@ +// (C) Copyright Matt Borland 2021. +// 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_CCMATH_TRUNC_HPP +#define BOOST_MATH_CCMATH_TRUNC_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::ccmath { + +namespace detail { + +template +inline constexpr T trunc_impl(T arg) noexcept +{ + return (arg > 0) ? boost::math::ccmath::floor(arg) : boost::math::ccmath::ceil(arg); +} + +} // Namespace detail + +template , bool> = true> +inline constexpr Real trunc(Real arg) noexcept +{ + if(BOOST_MATH_IS_CONSTANT_EVALUATED(arg)) + { + return boost::math::ccmath::abs(arg) == Real(0) ? arg : + boost::math::ccmath::isinf(arg) ? arg : + boost::math::ccmath::isnan(arg) ? arg : + boost::math::ccmath::detail::trunc_impl(arg); + } + else + { + using std::trunc; + return trunc(arg); + } +} + +template , bool> = true> +inline constexpr double trunc(Z arg) noexcept +{ + return boost::math::ccmath::trunc(static_cast(arg)); +} + +inline constexpr float truncf(float arg) noexcept +{ + return boost::math::ccmath::trunc(arg); +} + +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline constexpr long double truncl(long double arg) noexcept +{ + return boost::math::ccmath::trunc(arg); +} +#endif + +} // Namespaces + +#endif // BOOST_MATH_CCMATH_TRUNC_HPP diff --git a/libcxx/src/third-party/boost/math/common_factor.hpp b/libcxx/src/third-party/boost/math/common_factor.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/common_factor.hpp @@ -0,0 +1,23 @@ +// Boost common_factor.hpp header file -------------------------------------// + +// (C) Copyright Daryle Walker 2001-2002. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_HPP +#define BOOST_MATH_COMMON_FACTOR_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_HPP diff --git a/libcxx/src/third-party/boost/math/common_factor_ct.hpp b/libcxx/src/third-party/boost/math/common_factor_ct.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/common_factor_ct.hpp @@ -0,0 +1,34 @@ +// Boost common_factor_ct.hpp header file ----------------------------------// + +// (C) Copyright John Maddock 2017. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_MATH_COMMON_FACTOR_CT_HPP +#define BOOST_MATH_COMMON_FACTOR_CT_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost +{ +namespace math +{ + + using boost::integer::static_gcd; + using boost::integer::static_lcm; + using boost::integer::static_gcd_type; + +} // namespace math +} // namespace boost +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_CT_HPP diff --git a/libcxx/src/third-party/boost/math/common_factor_rt.hpp b/libcxx/src/third-party/boost/math/common_factor_rt.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/common_factor_rt.hpp @@ -0,0 +1,30 @@ +// (C) Copyright John Maddock 2017. + +// 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_COMMON_FACTOR_RT_HPP +#define BOOST_MATH_COMMON_FACTOR_RT_HPP + +#ifndef BOOST_MATH_STANDALONE +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost { + namespace math { + using boost::integer::gcd; + using boost::integer::lcm; + using boost::integer::gcd_range; + using boost::integer::lcm_range; + using boost::integer::gcd_evaluator; + using boost::integer::lcm_evaluator; + } +} +#else +#error Common factor is not available in standalone mode because it requires boost.integer. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_COMMON_FACTOR_RT_HPP diff --git a/libcxx/src/third-party/boost/math/complex.hpp b/libcxx/src/third-party/boost/math/complex.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex.hpp @@ -0,0 +1,32 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_INCLUDED +#define BOOST_MATH_COMPLEX_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ASINH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ACOS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ACOSH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATAN_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_FABS_INCLUDED +# include +#endif + + +#endif // BOOST_MATH_COMPLEX_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/acos.hpp b/libcxx/src/third-party/boost/math/complex/acos.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/acos.hpp @@ -0,0 +1,245 @@ +// (C) Copyright John Maddock 2005. +// Distributed under 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_COMPLEX_ACOS_INCLUDED +#define BOOST_MATH_COMPLEX_ACOS_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +std::complex acos(const std::complex& z) +{ + // + // This implementation is a transcription of the pseudo-code in: + // + // "Implementing the Complex Arcsine and Arccosine Functions using Exception Handling." + // T E Hull, Thomas F Fairgrieve and Ping Tak Peter Tang. + // ACM Transactions on Mathematical Software, Vol 23, No 3, Sept 1997. + // + + // + // These static constants should really be in a maths constants library, + // note that we have tweaked a_crossover as per: https://svn.boost.org/trac/boost/ticket/7290 + // + static const T one = static_cast(1); + //static const T two = static_cast(2); + static const T half = static_cast(0.5L); + static const T a_crossover = static_cast(10); + static const T b_crossover = static_cast(0.6417L); + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + // + // Get real and imaginary parts, discard the signs as we can + // figure out the sign of the result later: + // + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + + T real, imag; // these hold our result + + // + // Handle special cases specified by the C99 standard, + // many of these special cases aren't really needed here, + // but doing it this way prevents overflow/underflow arithmetic + // in the main body of the logic, which may trip up some machines: + // + if((boost::math::isinf)(x)) + { + if((boost::math::isinf)(y)) + { + real = quarter_pi; + imag = std::numeric_limits::infinity(); + } + else if((boost::math::isnan)(y)) + { + return std::complex(y, -std::numeric_limits::infinity()); + } + else + { + // y is not infinity or nan: + real = 0; + imag = std::numeric_limits::infinity(); + } + } + else if((boost::math::isnan)(x)) + { + if((boost::math::isinf)(y)) + return std::complex(x, ((boost::math::signbit)(z.imag())) ? std::numeric_limits::infinity() : -std::numeric_limits::infinity()); + return std::complex(x, x); + } + else if((boost::math::isinf)(y)) + { + real = half_pi; + imag = std::numeric_limits::infinity(); + } + else if((boost::math::isnan)(y)) + { + return std::complex((x == 0) ? half_pi : y, y); + } + else + { + // + // What follows is the regular Hull et al code, + // begin with the special case for real numbers: + // + if((y == 0) && (x <= one)) + return std::complex((x == 0) ? half_pi : std::acos(z.real()), (boost::math::changesign)(z.imag())); + // + // Figure out if our input is within the "safe area" identified by Hull et al. + // This would be more efficient with portable floating point exception handling; + // fortunately the quantities M and u identified by Hull et al (figure 3), + // match with the max and min methods of numeric_limits. + // + T safe_max = detail::safe_max(static_cast(8)); + T safe_min = detail::safe_min(static_cast(4)); + + T xp1 = one + x; + T xm1 = x - one; + + if((x < safe_max) && (x > safe_min) && (y < safe_max) && (y > safe_min)) + { + T yy = y * y; + T r = std::sqrt(xp1*xp1 + yy); + T s = std::sqrt(xm1*xm1 + yy); + T a = half * (r + s); + T b = x / a; + + if(b <= b_crossover) + { + real = std::acos(b); + } + else + { + T apx = a + x; + if(x <= one) + { + real = std::atan(std::sqrt(half * apx * (yy /(r + xp1) + (s-xm1)))/x); + } + else + { + real = std::atan((y * std::sqrt(half * (apx/(r + xp1) + apx/(s+xm1))))/x); + } + } + + if(a <= a_crossover) + { + T am1; + if(x < one) + { + am1 = half * (yy/(r + xp1) + yy/(s - xm1)); + } + else + { + am1 = half * (yy/(r + xp1) + (s + xm1)); + } + imag = boost::math::log1p(am1 + std::sqrt(am1 * (a + one))); + } + else + { + imag = std::log(a + std::sqrt(a*a - one)); + } + } + else + { + // + // This is the Hull et al exception handling code from Fig 6 of their paper: + // + if(y <= (std::numeric_limits::epsilon() * std::fabs(xm1))) + { + if(x < one) + { + real = std::acos(x); + imag = y / std::sqrt(xp1*(one-x)); + } + else + { + // This deviates from Hull et al's paper as per https://svn.boost.org/trac/boost/ticket/7290 + if(((std::numeric_limits::max)() / xp1) > xm1) + { + // xp1 * xm1 won't overflow: + real = y / std::sqrt(xm1*xp1); + imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1)); + } + else + { + real = y / x; + imag = log_two + std::log(x); + } + } + } + else if(y <= safe_min) + { + // There is an assumption in Hull et al's analysis that + // if we get here then x == 1. This is true for all "good" + // machines where : + // + // E^2 > 8*sqrt(u); with: + // + // E = std::numeric_limits::epsilon() + // u = (std::numeric_limits::min)() + // + // Hull et al provide alternative code for "bad" machines + // but we have no way to test that here, so for now just assert + // on the assumption: + // + BOOST_MATH_ASSERT(x == 1); + real = std::sqrt(y); + imag = std::sqrt(y); + } + else if(std::numeric_limits::epsilon() * y - one >= x) + { + real = half_pi; + imag = log_two + std::log(y); + } + else if(x > one) + { + real = std::atan(y/x); + T xoy = x/y; + imag = log_two + std::log(y) + half * boost::math::log1p(xoy*xoy); + } + else + { + real = half_pi; + T a = std::sqrt(one + y*y); + imag = half * boost::math::log1p(static_cast(2)*y*(y+a)); + } + } + } + + // + // Finish off by working out the sign of the result: + // + if((boost::math::signbit)(z.real())) + real = s_pi - real; + if(!(boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ACOS_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/acosh.hpp b/libcxx/src/third-party/boost/math/complex/acosh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/acosh.hpp @@ -0,0 +1,34 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_ACOSH_INCLUDED +#define BOOST_MATH_COMPLEX_ACOSH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +inline std::complex acosh(const std::complex& z) +{ + // + // We use the relation acosh(z) = +-i acos(z) + // Choosing the sign of multiplier to give real(acosh(z)) >= 0 + // as well as compatibility with C99. + // + std::complex result = boost::math::acos(z); + if(!(boost::math::isnan)(result.imag()) && signbit(result.imag())) + return detail::mult_i(result); + return detail::mult_minus_i(result); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ACOSH_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/asin.hpp b/libcxx/src/third-party/boost/math/complex/asin.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/asin.hpp @@ -0,0 +1,252 @@ +// (C) Copyright John Maddock 2005. +// Distributed under 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_COMPLEX_ASIN_INCLUDED +#define BOOST_MATH_COMPLEX_ASIN_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +inline std::complex asin(const std::complex& z) +{ + // + // This implementation is a transcription of the pseudo-code in: + // + // "Implementing the complex Arcsine and Arccosine Functions using Exception Handling." + // T E Hull, Thomas F Fairgrieve and Ping Tak Peter Tang. + // ACM Transactions on Mathematical Software, Vol 23, No 3, Sept 1997. + // + + // + // These static constants should really be in a maths constants library, + // note that we have tweaked the value of a_crossover as per https://svn.boost.org/trac/boost/ticket/7290: + // + static const T one = static_cast(1); + //static const T two = static_cast(2); + static const T half = static_cast(0.5L); + static const T a_crossover = static_cast(10); + static const T b_crossover = static_cast(0.6417L); + static const T s_pi = boost::math::constants::pi(); + static const T half_pi = s_pi / 2; + static const T log_two = boost::math::constants::ln_two(); + static const T quarter_pi = s_pi / 4; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + // + // Get real and imaginary parts, discard the signs as we can + // figure out the sign of the result later: + // + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + T real, imag; // our results + + // + // Begin by handling the special cases for infinities and nan's + // specified in C99, most of this is handled by the regular logic + // below, but handling it as a special case prevents overflow/underflow + // arithmetic which may trip up some machines: + // + if((boost::math::isnan)(x)) + { + if((boost::math::isnan)(y)) + return std::complex(x, x); + if((boost::math::isinf)(y)) + { + real = x; + imag = std::numeric_limits::infinity(); + } + else + return std::complex(x, x); + } + else if((boost::math::isnan)(y)) + { + if(x == 0) + { + real = 0; + imag = y; + } + else if((boost::math::isinf)(x)) + { + real = y; + imag = std::numeric_limits::infinity(); + } + else + return std::complex(y, y); + } + else if((boost::math::isinf)(x)) + { + if((boost::math::isinf)(y)) + { + real = quarter_pi; + imag = std::numeric_limits::infinity(); + } + else + { + real = half_pi; + imag = std::numeric_limits::infinity(); + } + } + else if((boost::math::isinf)(y)) + { + real = 0; + imag = std::numeric_limits::infinity(); + } + else + { + // + // special case for real numbers: + // + if((y == 0) && (x <= one)) + return std::complex(std::asin(z.real()), z.imag()); + // + // Figure out if our input is within the "safe area" identified by Hull et al. + // This would be more efficient with portable floating point exception handling; + // fortunately the quantities M and u identified by Hull et al (figure 3), + // match with the max and min methods of numeric_limits. + // + T safe_max = detail::safe_max(static_cast(8)); + T safe_min = detail::safe_min(static_cast(4)); + + T xp1 = one + x; + T xm1 = x - one; + + if((x < safe_max) && (x > safe_min) && (y < safe_max) && (y > safe_min)) + { + T yy = y * y; + T r = std::sqrt(xp1*xp1 + yy); + T s = std::sqrt(xm1*xm1 + yy); + T a = half * (r + s); + T b = x / a; + + if(b <= b_crossover) + { + real = std::asin(b); + } + else + { + T apx = a + x; + if(x <= one) + { + real = std::atan(x/std::sqrt(half * apx * (yy /(r + xp1) + (s-xm1)))); + } + else + { + real = std::atan(x/(y * std::sqrt(half * (apx/(r + xp1) + apx/(s+xm1))))); + } + } + + if(a <= a_crossover) + { + T am1; + if(x < one) + { + am1 = half * (yy/(r + xp1) + yy/(s - xm1)); + } + else + { + am1 = half * (yy/(r + xp1) + (s + xm1)); + } + imag = boost::math::log1p(am1 + std::sqrt(am1 * (a + one))); + } + else + { + imag = std::log(a + std::sqrt(a*a - one)); + } + } + else + { + // + // This is the Hull et al exception handling code from Fig 3 of their paper: + // + if(y <= (std::numeric_limits::epsilon() * std::fabs(xm1))) + { + if(x < one) + { + real = std::asin(x); + imag = y / std::sqrt(-xp1*xm1); + } + else + { + real = half_pi; + if(((std::numeric_limits::max)() / xp1) > xm1) + { + // xp1 * xm1 won't overflow: + imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1)); + } + else + { + imag = log_two + std::log(x); + } + } + } + else if(y <= safe_min) + { + // There is an assumption in Hull et al's analysis that + // if we get here then x == 1. This is true for all "good" + // machines where : + // + // E^2 > 8*sqrt(u); with: + // + // E = std::numeric_limits::epsilon() + // u = (std::numeric_limits::min)() + // + // Hull et al provide alternative code for "bad" machines + // but we have no way to test that here, so for now just assert + // on the assumption: + // + BOOST_MATH_ASSERT(x == 1); + real = half_pi - std::sqrt(y); + imag = std::sqrt(y); + } + else if(std::numeric_limits::epsilon() * y - one >= x) + { + real = x/y; // This can underflow! + imag = log_two + std::log(y); + } + else if(x > one) + { + real = std::atan(x/y); + T xoy = x/y; + imag = log_two + std::log(y) + half * boost::math::log1p(xoy*xoy); + } + else + { + T a = std::sqrt(one + y*y); + real = x/a; // This can underflow! + imag = half * boost::math::log1p(static_cast(2)*y*(y+a)); + } + } + } + + // + // Finish off by working out the sign of the result: + // + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ASIN_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/asinh.hpp b/libcxx/src/third-party/boost/math/complex/asinh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/asinh.hpp @@ -0,0 +1,32 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_ASINH_INCLUDED +#define BOOST_MATH_COMPLEX_ASINH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +inline std::complex asinh(const std::complex& x) +{ + // + // We use asinh(z) = i asin(-i z); + // Note that C99 defines this the other way around (which is + // to say asin is specified in terms of asinh), this is consistent + // with C99 though: + // + return ::boost::math::detail::mult_i(::boost::math::asin(::boost::math::detail::mult_minus_i(x))); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ASINH_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/atan.hpp b/libcxx/src/third-party/boost/math/complex/atan.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/atan.hpp @@ -0,0 +1,36 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_ATAN_INCLUDED +#define BOOST_MATH_COMPLEX_ATAN_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_COMPLEX_ATANH_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +std::complex atan(const std::complex& x) +{ + // + // We're using the C99 definition here; atan(z) = -i atanh(iz): + // + if(x.real() == 0) + { + if(x.imag() == 1) + return std::complex(0, std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : static_cast(HUGE_VAL)); + if(x.imag() == -1) + return std::complex(0, std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -static_cast(HUGE_VAL)); + } + return ::boost::math::detail::mult_minus_i(::boost::math::atanh(::boost::math::detail::mult_i(x))); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ATAN_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/atanh.hpp b/libcxx/src/third-party/boost/math/complex/atanh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/atanh.hpp @@ -0,0 +1,214 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_ATANH_INCLUDED +#define BOOST_MATH_COMPLEX_ATANH_INCLUDED + +#ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED +# include +#endif +#ifndef BOOST_MATH_LOG1P_INCLUDED +# include +#endif +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; } +#endif + +namespace boost{ namespace math{ + +template +std::complex atanh(const std::complex& z) +{ + // + // References: + // + // Eric W. Weisstein. "Inverse Hyperbolic Tangent." + // From MathWorld--A Wolfram Web Resource. + // http://mathworld.wolfram.com/InverseHyperbolicTangent.html + // + // Also: The Wolfram Functions Site, + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/ + // + // Also "Abramowitz and Stegun. Handbook of Mathematical Functions." + // at : http://jove.prohosting.com/~skripty/toc.htm + // + // See also: https://svn.boost.org/trac/boost/ticket/7291 + // + + static const T pi = boost::math::constants::pi(); + static const T half_pi = pi / 2; + static const T one = static_cast(1.0L); + static const T two = static_cast(2.0L); + static const T four = static_cast(4.0L); + static const T zero = static_cast(0); + static const T log_two = boost::math::constants::ln_two(); + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + + T x = std::fabs(z.real()); + T y = std::fabs(z.imag()); + + T real, imag; // our results + + T safe_upper = detail::safe_max(two); + T safe_lower = detail::safe_min(static_cast(2)); + + // + // Begin by handling the special cases specified in C99: + // + if((boost::math::isnan)(x)) + { + if((boost::math::isnan)(y)) + return std::complex(x, x); + else if((boost::math::isinf)(y)) + return std::complex(0, ((boost::math::signbit)(z.imag()) ? -half_pi : half_pi)); + else + return std::complex(x, x); + } + else if((boost::math::isnan)(y)) + { + if(x == 0) + return std::complex(x, y); + if((boost::math::isinf)(x)) + return std::complex(0, y); + else + return std::complex(y, y); + } + else if((x > safe_lower) && (x < safe_upper) && (y > safe_lower) && (y < safe_upper)) + { + + T yy = y*y; + T mxm1 = one - x; + /// + // The real part is given by: + // + // real(atanh(z)) == log1p(4*x / ((x-1)*(x-1) + y^2)) + // + real = boost::math::log1p(four * x / (mxm1*mxm1 + yy)); + real /= four; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + + imag = std::atan2((y * two), (mxm1*(one+x) - yy)); + imag /= two; + if(z.imag() < 0) + imag = (boost::math::changesign)(imag); + } + else + { + // + // This section handles exception cases that would normally cause + // underflow or overflow in the main formulas. + // + // Begin by working out the real part, we need to approximate + // real = boost::math::log1p(4x / ((x-1)^2 + y^2)) + // without either overflow or underflow in the squared terms. + // + T mxm1 = one - x; + if(x >= safe_upper) + { + // x-1 = x to machine precision: + if((boost::math::isinf)(x) || (boost::math::isinf)(y)) + { + real = 0; + } + else if(y >= safe_upper) + { + // Big x and y: divide through by x*y: + real = boost::math::log1p((four/y) / (x/y + y/x)); + } + else if(y > one) + { + // Big x: divide through by x: + real = boost::math::log1p(four / (x + y*y/x)); + } + else + { + // Big x small y, as above but neglect y^2/x: + real = boost::math::log1p(four/x); + } + } + else if(y >= safe_upper) + { + if(x > one) + { + // Big y, medium x, divide through by y: + real = boost::math::log1p((four*x/y) / (y + mxm1*mxm1/y)); + } + else + { + // Small or medium x, large y: + real = four*x/y/y; + } + } + else if (x != one) + { + // y is small, calculate divisor carefully: + T div = mxm1*mxm1; + if(y > safe_lower) + div += y*y; + real = boost::math::log1p(four*x/div); + } + else + real = boost::math::changesign(two * (std::log(y) - log_two)); + + real /= four; + if((boost::math::signbit)(z.real())) + real = (boost::math::changesign)(real); + + // + // Now handle imaginary part, this is much easier, + // if x or y are large, then the formula: + // atan2(2y, (1-x)*(1+x) - y^2) + // evaluates to +-(PI - theta) where theta is negligible compared to PI. + // + if((x >= safe_upper) || (y >= safe_upper)) + { + imag = pi; + } + else if(x <= safe_lower) + { + // + // If both x and y are small then atan(2y), + // otherwise just x^2 is negligible in the divisor: + // + if(y <= safe_lower) + imag = std::atan2(two*y, one); + else + { + if((y == zero) && (x == zero)) + imag = 0; + else + imag = std::atan2(two*y, one - y*y); + } + } + else + { + // + // y^2 is negligible: + // + if((y == zero) && (x == one)) + imag = 0; + else + imag = std::atan2(two*y, mxm1*(one+x)); + } + imag /= two; + if((boost::math::signbit)(z.imag())) + imag = (boost::math::changesign)(imag); + } + return std::complex(real, imag); +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_ATANH_INCLUDED diff --git a/libcxx/src/third-party/boost/math/complex/details.hpp b/libcxx/src/third-party/boost/math/complex/details.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/details.hpp @@ -0,0 +1,69 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_DETAILS_INCLUDED +#define BOOST_MATH_COMPLEX_DETAILS_INCLUDED +// +// This header contains all the support code that is common to the +// inverse trig complex functions, it also contains all the includes +// that we need to implement all these functions. +// + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline T mult_minus_one(const T& t) +{ + return (boost::math::isnan)(t) ? t : (boost::math::changesign)(t); +} + +template +inline std::complex mult_i(const std::complex& t) +{ + return std::complex(mult_minus_one(t.imag()), t.real()); +} + +template +inline std::complex mult_minus_i(const std::complex& t) +{ + return std::complex(t.imag(), mult_minus_one(t.real())); +} + +template +inline T safe_max(T t) +{ + return std::sqrt((std::numeric_limits::max)()) / t; +} +inline long double safe_max(long double t) +{ + // long double sqrt often returns infinity due to + // insufficient internal precision: + return std::sqrt((std::numeric_limits::max)()) / t; +} + +template +inline T safe_min(T t) +{ + return std::sqrt((std::numeric_limits::min)()) * t; +} +inline long double safe_min(long double t) +{ + // long double sqrt often returns zero due to + // insufficient internal precision: + return std::sqrt((std::numeric_limits::min)()) * t; +} + +} } } // namespaces + +#endif // BOOST_MATH_COMPLEX_DETAILS_INCLUDED + diff --git a/libcxx/src/third-party/boost/math/complex/fabs.hpp b/libcxx/src/third-party/boost/math/complex/fabs.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/complex/fabs.hpp @@ -0,0 +1,23 @@ +// (C) Copyright John Maddock 2005. +// 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_COMPLEX_FABS_INCLUDED +#define BOOST_MATH_COMPLEX_FABS_INCLUDED + +#ifndef BOOST_MATH_HYPOT_INCLUDED +# include +#endif + +namespace boost{ namespace math{ + +template +inline T fabs(const std::complex& z) +{ + return ::boost::math::hypot(z.real(), z.imag()); +} + +} } // namespaces + +#endif // BOOST_MATH_COMPLEX_FABS_INCLUDED diff --git a/libcxx/src/third-party/boost/math/concepts/distributions.hpp b/libcxx/src/third-party/boost/math/concepts/distributions.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/concepts/distributions.hpp @@ -0,0 +1,497 @@ +// 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) + +// distributions.hpp provides definitions of the concept of a distribution +// and non-member accessor functions that must be implemented by all distributions. +// This is used to verify that +// all the features of a distributions have been fully implemented. + +#ifndef BOOST_MATH_DISTRIBUTION_CONCEPT_HPP +#define BOOST_MATH_DISTRIBUTION_CONCEPT_HPP + +#ifndef BOOST_MATH_STANDALONE + +#include +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4100) +#pragma warning(disable: 4510) +#pragma warning(disable: 4610) +#pragma warning(disable: 4189) // local variable is initialized but not referenced. +#endif +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include + +namespace boost{ +namespace math{ + +namespace concepts +{ +// Begin by defining a concept archetype +// for a distribution class: +// +template +class distribution_archetype +{ +public: + typedef RealType value_type; + + distribution_archetype(const distribution_archetype&); // Copy constructible. + distribution_archetype& operator=(const distribution_archetype&); // Assignable. + + // There is no default constructor, + // but we need a way to instantiate the archetype: + static distribution_archetype& get_object() + { + // will never get caled: + return *reinterpret_cast(nullptr); + } +}; // template class distribution_archetype + +// Non-member accessor functions: +// (This list defines the functions that must be implemented by all distributions). + +template +RealType pdf(const distribution_archetype& dist, const RealType& x); + +template +RealType cdf(const distribution_archetype& dist, const RealType& x); + +template +RealType quantile(const distribution_archetype& dist, const RealType& p); + +template +RealType cdf(const complemented2_type, RealType>& c); + +template +RealType quantile(const complemented2_type, RealType>& c); + +template +RealType mean(const distribution_archetype& dist); + +template +RealType standard_deviation(const distribution_archetype& dist); + +template +RealType variance(const distribution_archetype& dist); + +template +RealType hazard(const distribution_archetype& dist); + +template +RealType chf(const distribution_archetype& dist); +// http://en.wikipedia.org/wiki/Characteristic_function_%28probability_theory%29 + +template +RealType coefficient_of_variation(const distribution_archetype& dist); + +template +RealType mode(const distribution_archetype& dist); + +template +RealType skewness(const distribution_archetype& dist); + +template +RealType kurtosis_excess(const distribution_archetype& dist); + +template +RealType kurtosis(const distribution_archetype& dist); + +template +RealType median(const distribution_archetype& dist); + +template +std::pair range(const distribution_archetype& dist); + +template +std::pair support(const distribution_archetype& dist); + +// +// Next comes the concept checks for verifying that a class +// fulfils the requirements of a Distribution: +// +template +struct DistributionConcept +{ + typedef typename Distribution::value_type value_type; + + void constraints() + { + function_requires >(); + function_requires >(); + + const Distribution& dist = DistributionConcept::get_object(); + + value_type x = 0; + // The result values are ignored in all these checks. + value_type v = cdf(dist, x); + v = cdf(complement(dist, x)); + suppress_unused_variable_warning(v); + v = pdf(dist, x); + suppress_unused_variable_warning(v); + v = quantile(dist, x); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, x)); + suppress_unused_variable_warning(v); + v = mean(dist); + suppress_unused_variable_warning(v); + v = mode(dist); + suppress_unused_variable_warning(v); + v = standard_deviation(dist); + suppress_unused_variable_warning(v); + v = variance(dist); + suppress_unused_variable_warning(v); + v = hazard(dist, x); + suppress_unused_variable_warning(v); + v = chf(dist, x); + suppress_unused_variable_warning(v); + v = coefficient_of_variation(dist); + suppress_unused_variable_warning(v); + v = skewness(dist); + suppress_unused_variable_warning(v); + v = kurtosis(dist); + suppress_unused_variable_warning(v); + v = kurtosis_excess(dist); + suppress_unused_variable_warning(v); + v = median(dist); + suppress_unused_variable_warning(v); + std::pair pv; + pv = range(dist); + suppress_unused_variable_warning(pv); + pv = support(dist); + suppress_unused_variable_warning(pv); + + float f = 1; + v = cdf(dist, f); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, f)); + suppress_unused_variable_warning(v); + v = pdf(dist, f); + suppress_unused_variable_warning(v); + v = quantile(dist, f); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, f)); + suppress_unused_variable_warning(v); + v = hazard(dist, f); + suppress_unused_variable_warning(v); + v = chf(dist, f); + suppress_unused_variable_warning(v); + double d = 1; + v = cdf(dist, d); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, d)); + suppress_unused_variable_warning(v); + v = pdf(dist, d); + suppress_unused_variable_warning(v); + v = quantile(dist, d); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, d)); + suppress_unused_variable_warning(v); + v = hazard(dist, d); + suppress_unused_variable_warning(v); + v = chf(dist, d); + suppress_unused_variable_warning(v); +#ifndef TEST_MPFR + long double ld = 1; + v = cdf(dist, ld); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, ld)); + suppress_unused_variable_warning(v); + v = pdf(dist, ld); + suppress_unused_variable_warning(v); + v = quantile(dist, ld); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, ld)); + suppress_unused_variable_warning(v); + v = hazard(dist, ld); + suppress_unused_variable_warning(v); + v = chf(dist, ld); + suppress_unused_variable_warning(v); +#endif + int i = 1; + v = cdf(dist, i); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, i)); + suppress_unused_variable_warning(v); + v = pdf(dist, i); + suppress_unused_variable_warning(v); + v = quantile(dist, i); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, i)); + suppress_unused_variable_warning(v); + v = hazard(dist, i); + suppress_unused_variable_warning(v); + v = chf(dist, i); + suppress_unused_variable_warning(v); + unsigned long li = 1; + v = cdf(dist, li); + suppress_unused_variable_warning(v); + v = cdf(complement(dist, li)); + suppress_unused_variable_warning(v); + v = pdf(dist, li); + suppress_unused_variable_warning(v); + v = quantile(dist, li); + suppress_unused_variable_warning(v); + v = quantile(complement(dist, li)); + suppress_unused_variable_warning(v); + v = hazard(dist, li); + suppress_unused_variable_warning(v); + v = chf(dist, li); + suppress_unused_variable_warning(v); + test_extra_members(dist); + } + template + static void test_extra_members(const D&) + {} + template + static void test_extra_members(const boost::math::bernoulli_distribution& d) + { + value_type r = d.success_fraction(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::beta_distribution& d) + { + value_type r1 = d.alpha(); + value_type r2 = d.beta(); + r1 = boost::math::beta_distribution::find_alpha(r1, r2); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_beta(r1, r2); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_alpha(r1, r2, r1); + suppress_unused_variable_warning(r1); + r1 = boost::math::beta_distribution::find_beta(r1, r2, r1); + suppress_unused_variable_warning(r1); + } + template + static void test_extra_members(const boost::math::binomial_distribution& d) + { + value_type r = d.success_fraction(); + r = d.trials(); + r = Distribution::find_lower_bound_on_p(r, r, r); + r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); + r = Distribution::find_lower_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); + r = Distribution::find_upper_bound_on_p(r, r, r); + r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::clopper_pearson_exact_interval); + r = Distribution::find_upper_bound_on_p(r, r, r, Distribution::jeffreys_prior_interval); + r = Distribution::find_minimum_number_of_trials(r, r, r); + r = Distribution::find_maximum_number_of_trials(r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::cauchy_distribution& d) + { + value_type r = d.location(); + r = d.scale(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::chi_squared_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = Distribution::find_degrees_of_freedom(r, r, r, r); + r = Distribution::find_degrees_of_freedom(r, r, r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::exponential_distribution& d) + { + value_type r = d.lambda(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::extreme_value_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::fisher_f_distribution& d) + { + value_type r = d.degrees_of_freedom1(); + r = d.degrees_of_freedom2(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::gamma_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::inverse_chi_squared_distribution& d) + { + value_type r = d.scale(); + r = d.degrees_of_freedom(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::inverse_gamma_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::hypergeometric_distribution& d) + { + unsigned u = d.defective(); + u = d.sample_count(); + u = d.total(); + suppress_unused_variable_warning(u); + } + template + static void test_extra_members(const boost::math::laplace_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::logistic_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::lognormal_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::negative_binomial_distribution& d) + { + value_type r = d.success_fraction(); + r = d.successes(); + r = Distribution::find_lower_bound_on_p(r, r, r); + r = Distribution::find_upper_bound_on_p(r, r, r); + r = Distribution::find_minimum_number_of_trials(r, r, r); + r = Distribution::find_maximum_number_of_trials(r, r, r); + suppress_unused_variable_warning(r); + } + template + static void test_extra_members(const boost::math::non_central_beta_distribution& d) + { + value_type r1 = d.alpha(); + value_type r2 = d.beta(); + r1 = d.non_centrality(); + (void)r1; // warning suppression + (void)r2; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_chi_squared_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.non_centrality(); + r = Distribution::find_degrees_of_freedom(r, r, r); + r = Distribution::find_degrees_of_freedom(boost::math::complement(r, r, r)); + r = Distribution::find_non_centrality(r, r, r); + r = Distribution::find_non_centrality(boost::math::complement(r, r, r)); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_f_distribution& d) + { + value_type r = d.degrees_of_freedom1(); + r = d.degrees_of_freedom2(); + r = d.non_centrality(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::non_central_t_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.non_centrality(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::normal_distribution& d) + { + value_type r = d.scale(); + r = d.location(); + r = d.mean(); + r = d.standard_deviation(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::pareto_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::poisson_distribution& d) + { + value_type r = d.mean(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::rayleigh_distribution& d) + { + value_type r = d.sigma(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::students_t_distribution& d) + { + value_type r = d.degrees_of_freedom(); + r = d.find_degrees_of_freedom(r, r, r, r); + r = d.find_degrees_of_freedom(r, r, r, r, r); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::triangular_distribution& d) + { + value_type r = d.lower(); + r = d.mode(); + r = d.upper(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::weibull_distribution& d) + { + value_type r = d.scale(); + r = d.shape(); + (void)r; // warning suppression + } + template + static void test_extra_members(const boost::math::uniform_distribution& d) + { + value_type r = d.lower(); + r = d.upper(); + (void)r; // warning suppression + } +private: + static Distribution* pd; + static Distribution& get_object() + { + // In reality this will never get called: + return *pd; + } +}; // struct DistributionConcept + +template +Distribution* DistributionConcept::pd = 0; + +} // namespace concepts +} // namespace math +} // namespace boost + +#else +#error This header can not be used in standalone mode. +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_DISTRIBUTION_CONCEPT_HPP + diff --git a/libcxx/src/third-party/boost/math/concepts/real_concept.hpp b/libcxx/src/third-party/boost/math/concepts/real_concept.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/concepts/real_concept.hpp @@ -0,0 +1,380 @@ +// 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) + +// Test real concept. + +// real_concept is an archetype for User defined Real types. + +// This file defines the features, constructors, operators, functions... +// that are essential to use mathematical and statistical functions. +// The template typename "RealType" is used where this type +// (as well as the normal built-in types, float, double & long double) +// can be used. +// That this is the minimum set is confirmed by use as a type +// in tests of all functions & distributions, for example: +// test_spots(0.F); & test_spots(0.); for float and double, but also +// test_spots(boost::math::concepts::real_concept(0.)); +// NTL quad_float type is an example of a type meeting the requirements, +// but note minor additions are needed - see ntl.diff and documentation +// "Using With NTL - a High-Precision Floating-Point Library". + +#ifndef BOOST_MATH_REAL_CONCEPT_HPP +#define BOOST_MATH_REAL_CONCEPT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__SGI_STL_PORT) +# include +#endif +#include +#include +#include +#include +#include + +#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__) +# include +#endif + +namespace boost{ namespace math{ + +namespace concepts +{ + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + typedef double real_concept_base_type; +#else + typedef long double real_concept_base_type; +#endif + +class real_concept +{ +public: + // Constructors: + real_concept() : m_value(0){} + real_concept(char c) : m_value(c){} + real_concept(wchar_t c) : m_value(c){} + real_concept(unsigned char c) : m_value(c){} + real_concept(signed char c) : m_value(c){} + real_concept(unsigned short c) : m_value(c){} + real_concept(short c) : m_value(c){} + real_concept(unsigned int c) : m_value(c){} + real_concept(int c) : m_value(c){} + real_concept(unsigned long c) : m_value(c){} + real_concept(long c) : m_value(c){} + real_concept(unsigned long long c) : m_value(static_cast(c)){} + real_concept(long long c) : m_value(static_cast(c)){} + real_concept(float c) : m_value(c){} + real_concept(double c) : m_value(c){} + real_concept(long double c) : m_value(c){} +#ifdef BOOST_MATH_USE_FLOAT128 + real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){} +#endif + + // Assignment: + real_concept& operator=(char c) { m_value = c; return *this; } + real_concept& operator=(unsigned char c) { m_value = c; return *this; } + real_concept& operator=(signed char c) { m_value = c; return *this; } + real_concept& operator=(wchar_t c) { m_value = c; return *this; } + real_concept& operator=(short c) { m_value = c; return *this; } + real_concept& operator=(unsigned short c) { m_value = c; return *this; } + real_concept& operator=(int c) { m_value = c; return *this; } + real_concept& operator=(unsigned int c) { m_value = c; return *this; } + real_concept& operator=(long c) { m_value = c; return *this; } + real_concept& operator=(unsigned long c) { m_value = c; return *this; } + real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } + real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + real_concept& operator=(float c) { m_value = c; return *this; } + real_concept& operator=(double c) { m_value = c; return *this; } + real_concept& operator=(long double c) { m_value = c; return *this; } + + // Access: + real_concept_base_type value()const{ return m_value; } + + // Member arithmetic: + real_concept& operator+=(const real_concept& other) + { m_value += other.value(); return *this; } + real_concept& operator-=(const real_concept& other) + { m_value -= other.value(); return *this; } + real_concept& operator*=(const real_concept& other) + { m_value *= other.value(); return *this; } + real_concept& operator/=(const real_concept& other) + { m_value /= other.value(); return *this; } + real_concept operator-()const + { return -m_value; } + real_concept const& operator+()const + { return *this; } + real_concept& operator++() + { ++m_value; return *this; } + real_concept& operator--() + { --m_value; return *this; } + +private: + real_concept_base_type m_value; +}; + +// Non-member arithmetic: +inline real_concept operator+(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result += b; + return result; +} +inline real_concept operator-(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result -= b; + return result; +} +inline real_concept operator*(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result *= b; + return result; +} +inline real_concept operator/(const real_concept& a, const real_concept& b) +{ + real_concept result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const real_concept& a, const real_concept& b) +{ return a.value() == b.value(); } +inline bool operator != (const real_concept& a, const real_concept& b) +{ return a.value() != b.value();} +inline bool operator < (const real_concept& a, const real_concept& b) +{ return a.value() < b.value(); } +inline bool operator <= (const real_concept& a, const real_concept& b) +{ return a.value() <= b.value(); } +inline bool operator > (const real_concept& a, const real_concept& b) +{ return a.value() > b.value(); } +inline bool operator >= (const real_concept& a, const real_concept& b) +{ return a.value() >= b.value(); } + +// Non-member functions: +inline real_concept acos(real_concept a) +{ return std::acos(a.value()); } +inline real_concept cos(real_concept a) +{ return std::cos(a.value()); } +inline real_concept asin(real_concept a) +{ return std::asin(a.value()); } +inline real_concept atan(real_concept a) +{ return std::atan(a.value()); } +inline real_concept atan2(real_concept a, real_concept b) +{ return std::atan2(a.value(), b.value()); } +inline real_concept ceil(real_concept a) +{ return std::ceil(a.value()); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +// I've seen std::fmod(long double) crash on some platforms +// so use fmodl instead: +#ifdef _WIN32_WCE +// +// Ugly workaround for macro fmodl: +// +inline long double call_fmodl(long double a, long double b) +{ return fmodl(a, b); } +inline real_concept fmod(real_concept a, real_concept b) +{ return call_fmodl(a.value(), b.value()); } +#else +inline real_concept fmod(real_concept a, real_concept b) +{ return fmodl(a.value(), b.value()); } +#endif +#endif +inline real_concept cosh(real_concept a) +{ return std::cosh(a.value()); } +inline real_concept exp(real_concept a) +{ return std::exp(a.value()); } +inline real_concept fabs(real_concept a) +{ return std::fabs(a.value()); } +inline real_concept abs(real_concept a) +{ return std::abs(a.value()); } +inline real_concept floor(real_concept a) +{ return std::floor(a.value()); } +inline real_concept modf(real_concept a, real_concept* ipart) +{ +#ifdef __MINGW32__ + real_concept_base_type ip; + real_concept_base_type result = boost::math::modf(a.value(), &ip); + *ipart = ip; + return result; +#else + real_concept_base_type ip; + real_concept_base_type result = std::modf(a.value(), &ip); + *ipart = ip; + return result; +#endif +} +inline real_concept frexp(real_concept a, int* expon) +{ return std::frexp(a.value(), expon); } +inline real_concept ldexp(real_concept a, int expon) +{ return std::ldexp(a.value(), expon); } +inline real_concept log(real_concept a) +{ return std::log(a.value()); } +inline real_concept log10(real_concept a) +{ return std::log10(a.value()); } +inline real_concept tan(real_concept a) +{ return std::tan(a.value()); } +inline real_concept pow(real_concept a, real_concept b) +{ return std::pow(a.value(), b.value()); } +#if !defined(__SUNPRO_CC) +inline real_concept pow(real_concept a, int b) +{ return std::pow(a.value(), b); } +#else +inline real_concept pow(real_concept a, int b) +{ return std::pow(a.value(), static_cast(b)); } +#endif +inline real_concept sin(real_concept a) +{ return std::sin(a.value()); } +inline real_concept sinh(real_concept a) +{ return std::sinh(a.value()); } +inline real_concept sqrt(real_concept a) +{ return std::sqrt(a.value()); } +inline real_concept tanh(real_concept a) +{ return std::tanh(a.value()); } + +// +// C++11 ism's +// Note that these must not actually call the std:: versions as that precludes using this +// header to test in C++03 mode, call the Boost versions instead: +// +inline boost::math::concepts::real_concept asinh(boost::math::concepts::real_concept a) +{ + return boost::math::asinh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} +inline boost::math::concepts::real_concept acosh(boost::math::concepts::real_concept a) +{ + return boost::math::acosh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} +inline boost::math::concepts::real_concept atanh(boost::math::concepts::real_concept a) +{ + return boost::math::atanh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); +} + +// +// Conversion and truncation routines: +// +template +inline int iround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::iround(v.value(), pol); } +inline int iround(const concepts::real_concept& v) +{ return boost::math::iround(v.value(), policies::policy<>()); } +template +inline long lround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::lround(v.value(), pol); } +inline long lround(const concepts::real_concept& v) +{ return boost::math::lround(v.value(), policies::policy<>()); } + +template +inline long long llround(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::llround(v.value(), pol); } +inline long long llround(const concepts::real_concept& v) +{ return boost::math::llround(v.value(), policies::policy<>()); } + +template +inline int itrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::itrunc(v.value(), pol); } +inline int itrunc(const concepts::real_concept& v) +{ return boost::math::itrunc(v.value(), policies::policy<>()); } +template +inline long ltrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::ltrunc(v.value(), pol); } +inline long ltrunc(const concepts::real_concept& v) +{ return boost::math::ltrunc(v.value(), policies::policy<>()); } + +template +inline long long lltrunc(const concepts::real_concept& v, const Policy& pol) +{ return boost::math::lltrunc(v.value(), pol); } +inline long long lltrunc(const concepts::real_concept& v) +{ return boost::math::lltrunc(v.value(), policies::policy<>()); } + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const real_concept& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, real_concept& a) +{ + real_concept_base_type v; + is >> v; + a = v; + return is; +} + +} // namespace concepts + +namespace tools +{ + +template <> +inline concepts::real_concept make_big_value(boost::math::tools::largest_float val, const char* , std::false_type const&, std::false_type const&) +{ + return val; // Can't use lexical_cast here, sometimes it fails.... +} + +template <> +inline concepts::real_concept max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return max_value(); +} + +template <> +inline concepts::real_concept min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return min_value(); +} + +template <> +inline concepts::real_concept log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return log_max_value(); +} + +template <> +inline concepts::real_concept log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ + return log_min_value(); +} + +template <> +inline concepts::real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) +{ +#ifdef __SUNPRO_CC + return std::numeric_limits::epsilon(); +#else + return tools::epsilon(); +#endif +} + +template <> +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) noexcept +{ + // Assume number of significand bits is same as real_concept_base_type, + // unless std::numeric_limits::is_specialized to provide digits. + return tools::digits(); + // Note that if numeric_limits real concept is NOT specialized to provide digits10 + // (or max_digits10) then the default precision of 6 decimal digits will be used + // by Boost test (giving misleading error messages like + // "difference between {9.79796} and {9.79796} exceeds 5.42101e-19%" + // and by Boost lexical cast and serialization causing loss of accuracy. +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_REAL_CONCEPT_HPP + + diff --git a/libcxx/src/third-party/boost/math/concepts/real_type_concept.hpp b/libcxx/src/third-party/boost/math/concepts/real_type_concept.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/concepts/real_type_concept.hpp @@ -0,0 +1,119 @@ +// Copyright John Maddock 2007-8. +// 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_REAL_TYPE_CONCEPT_HPP +#define BOOST_MATH_REAL_TYPE_CONCEPT_HPP + +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4100) +#pragma warning(disable: 4510) +#pragma warning(disable: 4610) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include + + +namespace boost{ namespace math{ namespace concepts{ + +template +struct RealTypeConcept +{ + template + void check_binary_ops(Other o) const + { + RealType r(o); + r = o; + r -= o; + r += o; + r *= o; + r /= o; + r = r - o; + r = o - r; + r = r + o; + r = o + r; + r = o * r; + r = r * o; + r = r / o; + r = o / r; + bool b; + b = r == o; + suppress_unused_variable_warning(b); + b = o == r; + suppress_unused_variable_warning(b); + b = r != o; + suppress_unused_variable_warning(b); + b = o != r; + suppress_unused_variable_warning(b); + b = r <= o; + suppress_unused_variable_warning(b); + b = o <= r; + suppress_unused_variable_warning(b); + b = r >= o; + suppress_unused_variable_warning(b); + b = o >= r; + suppress_unused_variable_warning(b); + b = r < o; + suppress_unused_variable_warning(b); + b = o < r; + suppress_unused_variable_warning(b); + b = r > o; + suppress_unused_variable_warning(b); + b = o > r; + suppress_unused_variable_warning(b); + } + + void constraints() + { + BOOST_MATH_STD_USING + + RealType r; + check_binary_ops(r); + check_binary_ops(0.5f); + check_binary_ops(0.5); + //check_binary_ops(0.5L); + check_binary_ops(1); + //check_binary_ops(1u); + check_binary_ops(1L); + //check_binary_ops(1uL); + check_binary_ops(1LL); + RealType r2 = +r; + r2 = -r; + + r2 = fabs(r); + r2 = abs(r); + r2 = ceil(r); + r2 = floor(r); + r2 = exp(r); + r2 = pow(r, r2); + r2 = sqrt(r); + r2 = log(r); + r2 = cos(r); + r2 = sin(r); + r2 = tan(r); + r2 = asin(r); + r2 = acos(r); + r2 = atan(r); + int i {}; + r2 = ldexp(r, i); + r2 = frexp(r, &i); + i = boost::math::tools::digits(); + r2 = boost::math::tools::max_value(); + r2 = boost::math::tools::min_value(); + r2 = boost::math::tools::log_max_value(); + r2 = boost::math::tools::log_min_value(); + r2 = boost::math::tools::epsilon(); + } +}; // struct DistributionConcept + + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/concepts/std_real_concept.hpp b/libcxx/src/third-party/boost/math/concepts/std_real_concept.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/concepts/std_real_concept.hpp @@ -0,0 +1,421 @@ +// 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) + +// std_real_concept is an archetype for built-in Real types. + +// The main purpose in providing this type is to verify +// that std lib functions are found via a using declaration +// bringing those functions into the current scope, and not +// just because they happen to be in global scope. +// +// If ::pow is found rather than std::pow say, then the code +// will silently compile, but truncation of long doubles to +// double will cause a significant loss of precision. +// A template instantiated with std_real_concept will *only* +// compile if it std::whatever is in scope. + +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STD_REAL_CONCEPT_HPP +#define BOOST_MATH_STD_REAL_CONCEPT_HPP + +namespace boost{ namespace math{ + +namespace concepts +{ + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + typedef double std_real_concept_base_type; +#else + typedef long double std_real_concept_base_type; +#endif + +class std_real_concept +{ +public: + // Constructors: + std_real_concept() : m_value(0){} + std_real_concept(char c) : m_value(c){} +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + std_real_concept(wchar_t c) : m_value(c){} +#endif + std_real_concept(unsigned char c) : m_value(c){} + std_real_concept(signed char c) : m_value(c){} + std_real_concept(unsigned short c) : m_value(c){} + std_real_concept(short c) : m_value(c){} + std_real_concept(unsigned int c) : m_value(c){} + std_real_concept(int c) : m_value(c){} + std_real_concept(unsigned long c) : m_value(c){} + std_real_concept(long c) : m_value(c){} +#if defined(__DECCXX) || defined(__SUNPRO_CC) + std_real_concept(unsigned long long c) : m_value(static_cast(c)){} + std_real_concept(long long c) : m_value(static_cast(c)){} +#endif + std_real_concept(unsigned long long c) : m_value(static_cast(c)){} + std_real_concept(long long c) : m_value(static_cast(c)){} + std_real_concept(float c) : m_value(c){} + std_real_concept(double c) : m_value(c){} + std_real_concept(long double c) : m_value(c){} +#ifdef BOOST_MATH_USE_FLOAT128 + std_real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){} +#endif + + // Assignment: + std_real_concept& operator=(char c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned char c) { m_value = c; return *this; } + std_real_concept& operator=(signed char c) { m_value = c; return *this; } +#ifndef BOOST_NO_INTRINSIC_WCHAR_T + std_real_concept& operator=(wchar_t c) { m_value = c; return *this; } +#endif + std_real_concept& operator=(short c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned short c) { m_value = c; return *this; } + std_real_concept& operator=(int c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned int c) { m_value = c; return *this; } + std_real_concept& operator=(long c) { m_value = c; return *this; } + std_real_concept& operator=(unsigned long c) { m_value = c; return *this; } +#if defined(__DECCXX) || defined(__SUNPRO_CC) + std_real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + std_real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } +#endif + std_real_concept& operator=(long long c) { m_value = static_cast(c); return *this; } + std_real_concept& operator=(unsigned long long c) { m_value = static_cast(c); return *this; } + + std_real_concept& operator=(float c) { m_value = c; return *this; } + std_real_concept& operator=(double c) { m_value = c; return *this; } + std_real_concept& operator=(long double c) { m_value = c; return *this; } + + // Access: + std_real_concept_base_type value()const{ return m_value; } + + // Member arithmetic: + std_real_concept& operator+=(const std_real_concept& other) + { m_value += other.value(); return *this; } + std_real_concept& operator-=(const std_real_concept& other) + { m_value -= other.value(); return *this; } + std_real_concept& operator*=(const std_real_concept& other) + { m_value *= other.value(); return *this; } + std_real_concept& operator/=(const std_real_concept& other) + { m_value /= other.value(); return *this; } + std_real_concept operator-()const + { return -m_value; } + std_real_concept const& operator+()const + { return *this; } + +private: + std_real_concept_base_type m_value; +}; + +// Non-member arithmetic: +inline std_real_concept operator+(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result += b; + return result; +} +inline std_real_concept operator-(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result -= b; + return result; +} +inline std_real_concept operator*(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result *= b; + return result; +} +inline std_real_concept operator/(const std_real_concept& a, const std_real_concept& b) +{ + std_real_concept result(a); + result /= b; + return result; +} + +// Comparison: +inline bool operator == (const std_real_concept& a, const std_real_concept& b) +{ return a.value() == b.value(); } +inline bool operator != (const std_real_concept& a, const std_real_concept& b) +{ return a.value() != b.value();} +inline bool operator < (const std_real_concept& a, const std_real_concept& b) +{ return a.value() < b.value(); } +inline bool operator <= (const std_real_concept& a, const std_real_concept& b) +{ return a.value() <= b.value(); } +inline bool operator > (const std_real_concept& a, const std_real_concept& b) +{ return a.value() > b.value(); } +inline bool operator >= (const std_real_concept& a, const std_real_concept& b) +{ return a.value() >= b.value(); } + +} // namespace concepts +} // namespace math +} // namespace boost + +namespace std{ + +// Non-member functions: +inline boost::math::concepts::std_real_concept acos(boost::math::concepts::std_real_concept a) +{ return std::acos(a.value()); } +inline boost::math::concepts::std_real_concept cos(boost::math::concepts::std_real_concept a) +{ return std::cos(a.value()); } +inline boost::math::concepts::std_real_concept asin(boost::math::concepts::std_real_concept a) +{ return std::asin(a.value()); } +inline boost::math::concepts::std_real_concept atan(boost::math::concepts::std_real_concept a) +{ return std::atan(a.value()); } +inline boost::math::concepts::std_real_concept atan2(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::atan2(a.value(), b.value()); } +inline boost::math::concepts::std_real_concept ceil(boost::math::concepts::std_real_concept a) +{ return std::ceil(a.value()); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return fmodl(a.value(), b.value()); } +#else +inline boost::math::concepts::std_real_concept fmod(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::fmod(a.value(), b.value()); } +#endif +inline boost::math::concepts::std_real_concept cosh(boost::math::concepts::std_real_concept a) +{ return std::cosh(a.value()); } +inline boost::math::concepts::std_real_concept exp(boost::math::concepts::std_real_concept a) +{ return std::exp(a.value()); } +inline boost::math::concepts::std_real_concept fabs(boost::math::concepts::std_real_concept a) +{ return std::fabs(a.value()); } +inline boost::math::concepts::std_real_concept abs(boost::math::concepts::std_real_concept a) +{ return std::abs(a.value()); } +inline boost::math::concepts::std_real_concept floor(boost::math::concepts::std_real_concept a) +{ return std::floor(a.value()); } +inline boost::math::concepts::std_real_concept modf(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept* ipart) +{ + boost::math::concepts::std_real_concept_base_type ip; + boost::math::concepts::std_real_concept_base_type result = std::modf(a.value(), &ip); + *ipart = ip; + return result; +} +inline boost::math::concepts::std_real_concept frexp(boost::math::concepts::std_real_concept a, int* expon) +{ return std::frexp(a.value(), expon); } +inline boost::math::concepts::std_real_concept ldexp(boost::math::concepts::std_real_concept a, int expon) +{ return std::ldexp(a.value(), expon); } +inline boost::math::concepts::std_real_concept log(boost::math::concepts::std_real_concept a) +{ return std::log(a.value()); } +inline boost::math::concepts::std_real_concept log10(boost::math::concepts::std_real_concept a) +{ return std::log10(a.value()); } +inline boost::math::concepts::std_real_concept tan(boost::math::concepts::std_real_concept a) +{ return std::tan(a.value()); } +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return std::pow(a.value(), b.value()); } +#if !defined(__SUNPRO_CC) +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b) +{ return std::pow(a.value(), b); } +#else +inline boost::math::concepts::std_real_concept pow(boost::math::concepts::std_real_concept a, int b) +{ return std::pow(a.value(), static_cast(b)); } +#endif +inline boost::math::concepts::std_real_concept sin(boost::math::concepts::std_real_concept a) +{ return std::sin(a.value()); } +inline boost::math::concepts::std_real_concept sinh(boost::math::concepts::std_real_concept a) +{ return std::sinh(a.value()); } +inline boost::math::concepts::std_real_concept sqrt(boost::math::concepts::std_real_concept a) +{ return std::sqrt(a.value()); } +inline boost::math::concepts::std_real_concept tanh(boost::math::concepts::std_real_concept a) +{ return std::tanh(a.value()); } +inline boost::math::concepts::std_real_concept (nextafter)(boost::math::concepts::std_real_concept a, boost::math::concepts::std_real_concept b) +{ return (boost::math::nextafter)(a, b); } +// +// C++11 ism's +// Note that these must not actually call the std:: versions as that precludes using this +// header to test in C++03 mode, call the Boost versions instead: +// +inline boost::math::concepts::std_real_concept asinh(boost::math::concepts::std_real_concept a) +{ return boost::math::asinh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); } +inline boost::math::concepts::std_real_concept acosh(boost::math::concepts::std_real_concept a) +{ return boost::math::acosh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); } +inline boost::math::concepts::std_real_concept atanh(boost::math::concepts::std_real_concept a) +{ return boost::math::atanh(a.value(), boost::math::policies::make_policy(boost::math::policies::overflow_error())); } +inline bool (isfinite)(boost::math::concepts::std_real_concept a) +{ + return (boost::math::isfinite)(a.value()); +} + + +} // namespace std + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace concepts{ + +// +// Conversion and truncation routines: +// +template +inline int iround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::iround(v.value(), pol); +} +inline int iround(const concepts::std_real_concept& v) +{ + return boost::math::iround(v.value(), policies::policy<>()); +} + +template +inline long lround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::lround(v.value(), pol); +} +inline long lround(const concepts::std_real_concept& v) +{ + return boost::math::lround(v.value(), policies::policy<>()); +} + +template +inline long long llround(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::llround(v.value(), pol); +} +inline long long llround(const concepts::std_real_concept& v) +{ + return boost::math::llround(v.value(), policies::policy<>()); +} + +template +inline int itrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::itrunc(v.value(), pol); +} +inline int itrunc(const concepts::std_real_concept& v) +{ + return boost::math::itrunc(v.value(), policies::policy<>()); +} + +template +inline long ltrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::ltrunc(v.value(), pol); +} +inline long ltrunc(const concepts::std_real_concept& v) +{ + return boost::math::ltrunc(v.value(), policies::policy<>()); +} + +template +inline long long lltrunc(const concepts::std_real_concept& v, const Policy& pol) +{ + return boost::math::lltrunc(v.value(), pol); +} +inline long long lltrunc(const concepts::std_real_concept& v) +{ + return boost::math::lltrunc(v.value(), policies::policy<>()); +} + +// Streaming: +template +inline std::basic_ostream& operator<<(std::basic_ostream& os, const std_real_concept& a) +{ + return os << a.value(); +} +template +inline std::basic_istream& operator>>(std::basic_istream& is, std_real_concept& a) +{ +#if defined(__SGI_STL_PORT) || defined(_RWSTD_VER) || defined(__LIBCOMO__) || defined(_LIBCPP_VERSION) + std::string s; + std_real_concept_base_type d; + is >> s; + std::sscanf(s.c_str(), "%Lf", &d); + a = d; + return is; +#else + std_real_concept_base_type v; + is >> v; + a = v; + return is; +#endif +} + +} // namespace concepts +}} + +#include + +namespace boost{ namespace math{ +namespace tools +{ + +template <> +inline concepts::std_real_concept make_big_value(boost::math::tools::largest_float val, const char*, std::false_type const&, std::false_type const&) +{ + return val; // Can't use lexical_cast here, sometimes it fails.... +} + +template <> +inline concepts::std_real_concept max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return max_value(); +} + +template <> +inline concepts::std_real_concept min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return min_value(); +} + +template <> +inline concepts::std_real_concept log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return log_max_value(); +} + +template <> +inline concepts::std_real_concept log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return log_min_value(); +} + +template <> +inline concepts::std_real_concept epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) +{ + return tools::epsilon(); +} + +template <> +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::std_real_concept)) noexcept +{ // Assume number of significand bits is same as std_real_concept_base_type, + // unless std::numeric_limits::is_specialized to provide digits. + return digits(); +} + +template <> +inline double real_cast(concepts::std_real_concept r) +{ + return static_cast(r.value()); +} + + +} // namespace tools + +#if defined(_MSC_VER) && (_MSC_VER <= 1310) +using concepts::itrunc; +using concepts::ltrunc; +using concepts::lltrunc; +using concepts::iround; +using concepts::lround; +using concepts::llround; +#endif + +} // namespace math +} // namespace boost + +// +// These must go at the end, as they include stuff that won't compile until +// after std_real_concept has been defined: +// +#include +#include +#include + +#endif // BOOST_MATH_STD_REAL_CONCEPT_HPP diff --git a/libcxx/src/third-party/boost/math/constants/calculate_constants.hpp b/libcxx/src/third-party/boost/math/constants/calculate_constants.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/constants/calculate_constants.hpp @@ -0,0 +1,1110 @@ +// Copyright John Maddock 2010, 2012. +// Copyright Paul A. Bristow 2011, 2012. + +// 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_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED +#define BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED +#include + +namespace boost{ namespace math{ namespace constants{ namespace detail{ + +template +template +inline T constant_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + + return ldexp(acos(T(0)), 1); + + /* + // Although this code works well, it's usually more accurate to just call acos + // and access the number types own representation of PI which is usually calculated + // at slightly higher precision... + + T result; + T a = 1; + T b; + T A(a); + T B = 0.5f; + T D = 0.25f; + + T lim; + lim = boost::math::tools::epsilon(); + + unsigned k = 1; + + do + { + result = A + B; + result = ldexp(result, -2); + b = sqrt(B); + a += b; + a = ldexp(a, -1); + A = a * a; + B = A - result; + B = ldexp(B, 1); + result = A - B; + bool neg = boost::math::sign(result) < 0; + if(neg) + result = -result; + if(result <= lim) + break; + if(neg) + result = -result; + result = ldexp(result, k - 1); + D -= result; + ++k; + lim = ldexp(lim, 1); + } + while(true); + + result = B / D; + return result; + */ +} + +template +template +inline T constant_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 * pi > >(); +} + +template // 2 / pi +template +inline T constant_two_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 / pi > >(); +} + +template // sqrt(2/pi) +template +inline T constant_root_two_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt((2 / pi > >())); +} + +template +template +inline T constant_one_div_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / two_pi > >(); +} + +template +template +inline T constant_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(pi > >()); +} + +template +template +inline T constant_root_half_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(pi > >() / 2); +} + +template +template +inline T constant_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(two_pi > >()); +} + +template +template +inline T constant_log_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(root_two_pi > >()); +} + +template +template +inline T constant_root_ln_four::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(log(static_cast(4))); +} + +template +template +inline T constant_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // + // Although we can clearly calculate this from first principles, this hooks into + // T's own notion of e, which hopefully will more accurate than one calculated to + // a few epsilon: + // + BOOST_MATH_STD_USING + return exp(static_cast(1)); +} + +template +template +inline T constant_half::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / static_cast(2); +} + +template +template +inline T constant_euler::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + // + // This is the method described in: + // "Some New Algorithms for High-Precision Computation of Euler's Constant" + // Richard P Brent and Edwin M McMillan. + // Mathematics of Computation, Volume 34, Number 149, Jan 1980, pages 305-312. + // See equation 17 with p = 2. + // + T n = 3 + (M ? (std::min)(M, tools::digits()) : tools::digits()) / 4; + T lim = M ? ldexp(T(1), 1 - (std::min)(M, tools::digits())) : tools::epsilon(); + T lnn = log(n); + T term = 1; + T N = -lnn; + T D = 1; + T Hk = 0; + T one = 1; + + for(unsigned k = 1;; ++k) + { + term *= n * n; + term /= k * k; + Hk += one / k; + N += term * (Hk - lnn); + D += term; + + if(term < D * lim) + break; + } + return N / D; +} + +template +template +inline T constant_euler_sqr::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return euler > >() + * euler > >(); +} + +template +template +inline T constant_one_div_euler::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) + / euler > >(); +} + + +template +template +inline T constant_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(2)); +} + + +template +template +inline T constant_root_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(3)); +} + +template +template +inline T constant_half_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(2)) / 2; +} + +template +template +inline T constant_ln_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // + // Although there are good ways to calculate this from scratch, this hooks into + // T's own notion of log(2) which will hopefully be accurate to the full precision + // of T: + // + BOOST_MATH_STD_USING + return log(static_cast(2)); +} + +template +template +inline T constant_ln_ten::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(static_cast(10)); +} + +template +template +inline T constant_ln_ln_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log(log(static_cast(2))); +} + +template +template +inline T constant_third::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / static_cast(3); +} + +template +template +inline T constant_twothirds::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(2) / static_cast(3); +} + +template +template +inline T constant_two_thirds::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(2) / static_cast(3); +} + +template +template +inline T constant_three_quarters::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(3) / static_cast(4); +} + +template +template +inline T constant_sixth::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / static_cast(6); +} + +// Pi and related constants. +template +template +inline T constant_pi_minus_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return pi > >() - static_cast(3); +} + +template +template +inline T constant_four_minus_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(4) - pi > >(); +} + +template +template +inline T constant_exp_minus_half::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return exp(static_cast(-0.5)); +} + +template +template +inline T constant_exp_minus_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return exp(static_cast(-1.)); +} + +template +template +inline T constant_one_div_root_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_two > >(); +} + +template +template +inline T constant_one_div_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_pi > >(); +} + +template +template +inline T constant_one_div_root_two_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return static_cast(1) / root_two_pi > >(); +} + +template +template +inline T constant_root_one_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(static_cast(1) / pi > >()); +} + +template +template +inline T constant_four_thirds_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(4) / static_cast(3); +} + +template +template +inline T constant_half_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(2); +} + +template +template +inline T constant_third_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(3); +} + +template +template +inline T constant_sixth_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() / static_cast(6); +} + +template +template +inline T constant_two_thirds_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(2) / static_cast(3); +} + +template +template +inline T constant_three_quarters_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() * static_cast(3) / static_cast(4); +} + +template +template +inline T constant_pi_pow_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(pi > >(), e > >()); // +} + +template +template +inline T constant_pi_sqr::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() ; // +} + +template +template +inline T constant_pi_sqr_div_six::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() + / static_cast(6); // +} + +template +template +inline T constant_pi_cubed::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + * pi > >() + * pi > >() + ; // +} + +template +template +inline T constant_cbrt_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(pi > >(), static_cast(1)/ static_cast(3)); +} + +template +template +inline T constant_one_div_cbrt_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) + / pow(pi > >(), static_cast(1)/ static_cast(3)); +} + +// Euler's e + +template +template +inline T constant_e_pow_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pow(e > >(), pi > >()); // +} + +template +template +inline T constant_root_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sqrt(e > >()); +} + +template +template +inline T constant_log10_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log10(e > >()); +} + +template +template +inline T constant_one_div_log10_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / + log10(e > >()); +} + +// Trigonometric + +template +template +inline T constant_degree::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return pi > >() + / static_cast(180) + ; // +} + +template +template +inline T constant_radian::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(180) + / pi > >() + ; // +} + +template +template +inline T constant_sin_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sin(static_cast(1)) ; // +} + +template +template +inline T constant_cos_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return cos(static_cast(1)) ; // +} + +template +template +inline T constant_sinh_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return sinh(static_cast(1)) ; // +} + +template +template +inline T constant_cosh_one::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return cosh(static_cast(1)) ; // +} + +template +template +inline T constant_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return (static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ; // +} + +template +template +inline T constant_ln_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return log((static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ); +} + +template +template +inline T constant_one_div_ln_phi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + return static_cast(1) / + log((static_cast(1) + sqrt(static_cast(5)) )/static_cast(2) ); +} + +// Zeta + +template +template +inline T constant_zeta_two::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + BOOST_MATH_STD_USING + + return pi > >() + * pi > >() + /static_cast(6); +} + +template +template +inline T constant_zeta_three::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // http://mathworld.wolfram.com/AperysConstant.html + // http://en.wikipedia.org/wiki/Mathematical_constant + + // http://oeis.org/A002117/constant + //T zeta3("1.20205690315959428539973816151144999076" + // "4986292340498881792271555341838205786313" + // "09018645587360933525814619915"); + + //"1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915" A002117 + // 1.202056903159594285399738161511449990, 76498629234049888179227155534183820578631309018645587360933525814619915780, +00); + //"1.2020569031595942 double + // http://www.spaennare.se/SSPROG/ssnum.pdf // section 11, Algorithm for Apery's constant zeta(3). + // Programs to Calculate some Mathematical Constants to Large Precision, Document Version 1.50 + + // by Stefan Spannare September 19, 2007 + // zeta(3) = 1/64 * sum + BOOST_MATH_STD_USING + T n_fact=static_cast(1); // build n! for n = 0. + T sum = static_cast(77); // Start with n = 0 case. + // for n = 0, (77/1) /64 = 1.203125 + //double lim = std::numeric_limits::epsilon(); + T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits())) : tools::epsilon(); + for(unsigned int n = 1; n < 40; ++n) + { // three to five decimal digits per term, so 40 should be plenty for 100 decimal digits. + //cout << "n = " << n << endl; + n_fact *= n; // n! + T n_fact_p10 = n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact * n_fact; // (n!)^10 + T num = ((205 * n * n) + (250 * n) + 77) * n_fact_p10; // 205n^2 + 250n + 77 + // int nn = (2 * n + 1); + // T d = factorial(nn); // inline factorial. + T d = 1; + for(unsigned int i = 1; i <= (n+n + 1); ++i) // (2n + 1) + { + d *= i; + } + T den = d * d * d * d * d; // [(2n+1)!]^5 + //cout << "den = " << den << endl; + T term = num/den; + if (n % 2 != 0) + { //term *= -1; + sum -= term; + } + else + { + sum += term; + } + //cout << "term = " << term << endl; + //cout << "sum/64 = " << sum/64 << endl; + if(abs(term) < lim) + { + break; + } + } + return sum / 64; +} + +template +template +inline T constant_catalan::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // http://oeis.org/A006752/constant + //T c("0.915965594177219015054603514932384110774" + //"149374281672134266498119621763019776254769479356512926115106248574"); + + // 9.159655941772190150546035149323841107, 74149374281672134266498119621763019776254769479356512926115106248574422619, -01); + + // This is equation (entry) 31 from + // http://www-2.cs.cmu.edu/~adamchik/articles/catalan/catalan.htm + // See also http://www.mpfr.org/algorithms.pdf + BOOST_MATH_STD_USING + T k_fact = 1; + T tk_fact = 1; + T sum = 1; + T term; + T lim = N ? ldexp(T(1), 1 - (std::min)(N, tools::digits())) : tools::epsilon(); + + for(unsigned k = 1;; ++k) + { + k_fact *= k; + tk_fact *= (2 * k) * (2 * k - 1); + term = k_fact * k_fact / (tk_fact * (2 * k + 1) * (2 * k + 1)); + sum += term; + if(term < lim) + { + break; + } + } + return boost::math::constants::pi >() + * log(2 + boost::math::constants::root_three >()) + / 8 + + 3 * sum / 8; +} + +namespace khinchin_detail{ + +template +T zeta_polynomial_series(T s, T sc, int digits) +{ + BOOST_MATH_STD_USING + // + // This is algorithm 3 from: + // + // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, + // Canadian Mathematical Society, Conference Proceedings, 2000. + // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf + // + BOOST_MATH_STD_USING + int n = (digits * 19) / 53; + T sum = 0; + T two_n = ldexp(T(1), n); + int ej_sign = 1; + for(int j = 0; j < n; ++j) + { + sum += ej_sign * -two_n / pow(T(j + 1), s); + ej_sign = -ej_sign; + } + T ej_sum = 1; + T ej_term = 1; + for(int j = n; j <= 2 * n - 1; ++j) + { + sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s); + ej_sign = -ej_sign; + ej_term *= 2 * n - j; + ej_term /= j - n + 1; + ej_sum += ej_term; + } + return -sum / (two_n * (1 - pow(T(2), sc))); +} + +template +T khinchin(int digits) +{ + BOOST_MATH_STD_USING + T sum = 0; + T term; + T lim = ldexp(T(1), 1-digits); + T factor = 0; + unsigned last_k = 1; + T num = 1; + for(unsigned n = 1;; ++n) + { + for(unsigned k = last_k; k <= 2 * n - 1; ++k) + { + factor += num / k; + num = -num; + } + last_k = 2 * n; + term = (zeta_polynomial_series(T(2 * n), T(1 - T(2 * n)), digits) - 1) * factor / n; + sum += term; + if(term < lim) + break; + } + return exp(sum / boost::math::constants::ln_two >()); +} + +} + +template +template +inline T constant_khinchin::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + int n = N ? (std::min)(N, tools::digits()) : tools::digits(); + return khinchin_detail::khinchin(n); +} + +template +template +inline T constant_extreme_value_skewness::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // N[12 Sqrt[6] Zeta[3]/Pi^3, 1101] + BOOST_MATH_STD_USING + T ev(12 * sqrt(static_cast(6)) * zeta_three > >() + / pi_cubed > >() ); + +//T ev( +//"1.1395470994046486574927930193898461120875997958365518247216557100852480077060706857071875468869385150" +//"1894272048688553376986765366075828644841024041679714157616857834895702411080704529137366329462558680" +//"2015498788776135705587959418756809080074611906006528647805347822929577145038743873949415294942796280" +//"0895597703063466053535550338267721294164578901640163603544404938283861127819804918174973533694090594" +//"3094963822672055237678432023017824416203652657301470473548274848068762500300316769691474974950757965" +//"8640779777748741897542093874605477776538884083378029488863880220988107155275203245233994097178778984" +//"3488995668362387892097897322246698071290011857605809901090220903955815127463328974447572119951192970" +//"3684453635456559086126406960279692862247058250100678008419431185138019869693206366891639436908462809" +//"9756051372711251054914491837034685476095423926553367264355374652153595857163724698198860485357368964" +//"3807049634423621246870868566707915720704996296083373077647528285782964567312903914752617978405994377" +//"9064157147206717895272199736902453130842229559980076472936976287378945035706933650987259357729800315"); + + return ev; +} + +namespace detail{ +// +// Calculation of the Glaisher constant depends upon calculating the +// derivative of the zeta function at 2, we can then use the relation: +// zeta'(2) = 1/6 pi^2 [euler + ln(2pi)-12ln(A)] +// To get the constant A. +// See equation 45 at http://mathworld.wolfram.com/RiemannZetaFunction.html. +// +// The derivative of the zeta function is computed by direct differentiation +// of the relation: +// (1-2^(1-s))zeta(s) = SUM(n=0, INF){ (-n)^n / (n+1)^s } +// Which gives us 2 slowly converging but alternating sums to compute, +// for this we use Algorithm 1 from "Convergent Acceleration of Alternating Series", +// Henri Cohen, Fernando Rodriguez Villegas and Don Zagier, Experimental Mathematics 9:1 (1999). +// See http://www.math.utexas.edu/users/villegas/publications/conv-accel.pdf +// +template +T zeta_series_derivative_2(unsigned digits) +{ + // Derivative of the series part, evaluated at 2: + BOOST_MATH_STD_USING + int n = digits * 301 * 13 / 10000; + T d = pow(3 + sqrt(T(8)), n); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + T s = 0; + for(int k = 0; k < n; ++k) + { + T a = -log(T(k+1)) / ((k+1) * (k+1)); + c = b - c; + s = s + c * a; + b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); + } + return s / d; +} + +template +T zeta_series_2(unsigned digits) +{ + // Series part of zeta at 2: + BOOST_MATH_STD_USING + int n = digits * 301 * 13 / 10000; + T d = pow(3 + sqrt(T(8)), n); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + T s = 0; + for(int k = 0; k < n; ++k) + { + T a = T(1) / ((k + 1) * (k + 1)); + c = b - c; + s = s + c * a; + b = (k + n) * (k - n) * b / ((k + T(0.5f)) * (k + 1)); + } + return s / d; +} + +template +inline T zeta_series_lead_2() +{ + // lead part at 2: + return 2; +} + +template +inline T zeta_series_derivative_lead_2() +{ + // derivative of lead part at 2: + return -2 * boost::math::constants::ln_two(); +} + +template +inline T zeta_derivative_2(unsigned n) +{ + // zeta derivative at 2: + return zeta_series_derivative_2(n) * zeta_series_lead_2() + + zeta_series_derivative_lead_2() * zeta_series_2(n); +} + +} // namespace detail + +template +template +inline T constant_glaisher::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + + BOOST_MATH_STD_USING + typedef policies::policy > forwarding_policy; + int n = N ? (std::min)(N, tools::digits()) : tools::digits(); + T v = detail::zeta_derivative_2(n); + v *= 6; + v /= boost::math::constants::pi() * boost::math::constants::pi(); + v -= boost::math::constants::euler(); + v -= log(2 * boost::math::constants::pi()); + v /= -12; + return exp(v); + + /* + // from http://mpmath.googlecode.com/svn/data/glaisher.txt + // 20,000 digits of the Glaisher-Kinkelin constant A = exp(1/2 - zeta'(-1)) + // Computed using A = exp((6 (-zeta'(2))/pi^2 + log 2 pi + gamma)/12) + // with Euler-Maclaurin summation for zeta'(2). + T g( + "1.282427129100622636875342568869791727767688927325001192063740021740406308858826" + "46112973649195820237439420646120399000748933157791362775280404159072573861727522" + "14334327143439787335067915257366856907876561146686449997784962754518174312394652" + "76128213808180219264516851546143919901083573730703504903888123418813674978133050" + "93770833682222494115874837348064399978830070125567001286994157705432053927585405" + "81731588155481762970384743250467775147374600031616023046613296342991558095879293" + "36343887288701988953460725233184702489001091776941712153569193674967261270398013" + "52652668868978218897401729375840750167472114895288815996668743164513890306962645" + "59870469543740253099606800842447417554061490189444139386196089129682173528798629" + "88434220366989900606980888785849587494085307347117090132667567503310523405221054" + "14176776156308191919997185237047761312315374135304725819814797451761027540834943" + "14384965234139453373065832325673954957601692256427736926358821692159870775858274" + "69575162841550648585890834128227556209547002918593263079373376942077522290940187"); + + return g; + */ +} + +template +template +inline T constant_rayleigh_skewness::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // 1100 digits of the Rayleigh distribution skewness + // N[2 Sqrt[Pi] (Pi - 3)/((4 - Pi)^(3/2)), 1100] + + BOOST_MATH_STD_USING + T rs(2 * root_pi > >() + * pi_minus_three > >() + / pow(four_minus_pi > >(), static_cast(3./2)) + ); + // 6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264, + + //"0.6311106578189371381918993515442277798440422031347194976580945856929268196174737254599050270325373067" + //"9440004726436754739597525250317640394102954301685809920213808351450851396781817932734836994829371322" + //"5797376021347531983451654130317032832308462278373358624120822253764532674177325950686466133508511968" + //"2389168716630349407238090652663422922072397393006683401992961569208109477307776249225072042971818671" + //"4058887072693437217879039875871765635655476241624825389439481561152126886932506682176611183750503553" + //"1218982627032068396407180216351425758181396562859085306247387212297187006230007438534686340210168288" + //"8956816965453815849613622117088096547521391672977226658826566757207615552041767516828171274858145957" + //"6137539156656005855905288420585194082284972984285863898582313048515484073396332610565441264220790791" + //"0194897267890422924599776483890102027823328602965235306539844007677157873140562950510028206251529523" + //"7428049693650605954398446899724157486062545281504433364675815915402937209673727753199567661561209251" + //"4695589950526053470201635372590001578503476490223746511106018091907936826431407434894024396366284848"); ; + return rs; +} + +template +template +inline T constant_rayleigh_kurtosis_excess::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) + // Might provide and calculate this using pi_minus_four. + BOOST_MATH_STD_USING + return - (((static_cast(6) * pi > >() + * pi > >()) + - (static_cast(24) * pi > >()) + static_cast(16) ) + / + ((pi > >() - static_cast(4)) + * (pi > >() - static_cast(4))) + ); +} + +template +template +inline T constant_rayleigh_kurtosis::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ // 3 - (6 Pi^2 - 24 Pi + 16)/((Pi - 4)^2) + // Might provide and calculate this using pi_minus_four. + BOOST_MATH_STD_USING + return static_cast(3) - (((static_cast(6) * pi > >() + * pi > >()) + - (static_cast(24) * pi > >()) + static_cast(16) ) + / + ((pi > >() - static_cast(4)) + * (pi > >() - static_cast(4))) + ); +} + +template +template +inline T constant_log2_e::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / boost::math::constants::ln_two(); +} + +template +template +inline T constant_quarter_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return boost::math::constants::pi() / 4; +} + +template +template +inline T constant_one_div_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 1 / boost::math::constants::pi(); +} + +template +template +inline T constant_two_div_root_pi::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + return 2 * boost::math::constants::one_div_root_pi(); +} + +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) +template +template +inline T constant_first_feigenbaum::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // We know the constant to 1018 decimal digits. + // See: http://www.plouffe.fr/simon/constants/feigenbaum.txt + // Also: https://oeis.org/A006890 + // N is in binary digits; so we multiply by log_2(10) + + static_assert(N < 3.321*1018, "\nThe first Feigenbaum constant cannot be computed at runtime; it is too expensive. It is known to 1018 decimal digits; you must request less than that."); + T alpha{"4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171659848551898151344086271420279325223124429888908908599449354632367134115324817142199474556443658237932020095610583305754586176522220703854106467494942849814533917262005687556659523398756038256372256480040951071283890611844702775854285419801113440175002428585382498335715522052236087250291678860362674527213399057131606875345083433934446103706309452019115876972432273589838903794946257251289097948986768334611626889116563123474460575179539122045562472807095202198199094558581946136877445617396074115614074243754435499204869180982648652368438702799649017397793425134723808737136211601860128186102056381818354097598477964173900328936171432159878240789776614391395764037760537119096932066998361984288981837003229412030210655743295550388845849737034727532121925706958414074661841981961006129640161487712944415901405467941800198133253378592493365883070459999938375411726563553016862529032210862320550634510679399023341675"}; + return alpha; +} + +template +template +inline T constant_plastic::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + using std::cbrt; + using std::sqrt; + return (cbrt(9-sqrt(T(69))) + cbrt(9+sqrt(T(69))))/cbrt(T(18)); +} + + +template +template +inline T constant_gauss::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + using std::sqrt; + T a = sqrt(T(2)); + T g = 1; + const T scale = sqrt(std::numeric_limits::epsilon())/512; + while (a-g > scale*g) + { + T anp1 = (a + g)/2; + g = sqrt(a*g); + a = anp1; + } + + return 2/(a + g); +} + +template +template +inline T constant_dottie::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // Error analysis: cos(x(1+d)) - x(1+d) = -(sin(x)+1)xd; plug in x = 0.739 gives -1.236d; take d as half an ulp gives the termination criteria we want. + using std::cos; + using std::abs; + using std::sin; + T x{".739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246"}; + T residual = cos(x) - x; + do { + x += residual/(sin(x)+1); + residual = cos(x) - x; + } while(abs(residual) > std::numeric_limits::epsilon()); + return x; +} + + +template +template +inline T constant_reciprocal_fibonacci::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // Wikipedia says Gosper has deviced a faster algorithm for this, but I read the linked paper and couldn't see it! + // In any case, k bits per iteration is fine, though it would be better to sum from smallest to largest. + // That said, the condition number is unity, so it should be fine. + T x0 = 1; + T x1 = 1; + T sum = 2; + T diff = 1; + while (diff > std::numeric_limits::epsilon()) { + T tmp = x1 + x0; + diff = 1/tmp; + sum += diff; + x0 = x1; + x1 = tmp; + } + return sum; +} + +template +template +inline T constant_laplace_limit::compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant))) +{ + // If x is the exact root, then the approximate root is given by x(1+delta). + // Plugging this into the equation for the Laplace limit gives the residual of approximately + // 2.6389delta. Take delta as half an epsilon and give some leeway so we don't get caught in an infinite loop, + // gives a termination condition as 2eps. + using std::abs; + using std::exp; + using std::sqrt; + T x{"0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168"}; + T tmp = sqrt(1+x*x); + T etmp = exp(tmp); + T residual = x*exp(tmp) - 1 - tmp; + T df = etmp -x/tmp + etmp*x*x/tmp; + do { + x -= residual/df; + tmp = sqrt(1+x*x); + etmp = exp(tmp); + residual = x*exp(tmp) - 1 - tmp; + df = etmp -x/tmp + etmp*x*x/tmp; + } while(abs(residual) > 2*std::numeric_limits::epsilon()); + return x; +} + +#endif + +} +} +} +} // namespaces + +#endif // BOOST_MATH_CALCULATE_CONSTANTS_CONSTANTS_INCLUDED diff --git a/libcxx/src/third-party/boost/math/constants/constants.hpp b/libcxx/src/third-party/boost/math/constants/constants.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/constants/constants.hpp @@ -0,0 +1,345 @@ +// Copyright John Maddock 2005-2006, 2011. +// Copyright Paul A. Bristow 2006-2011. +// 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_CONSTANTS_CONSTANTS_INCLUDED +#define BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED + +#include +#include +#include +#include +#include +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4127 4701) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math +{ + namespace constants + { + // To permit other calculations at about 100 decimal digits with some UDT, + // it is obviously necessary to define constants to this accuracy. + + // However, some compilers do not accept decimal digits strings as long as this. + // So the constant is split into two parts, with the 1st containing at least + // long double precision, and the 2nd zero if not needed or known. + // The 3rd part permits an exponent to be provided if necessary (use zero if none) - + // the other two parameters may only contain decimal digits (and sign and decimal point), + // and may NOT include an exponent like 1.234E99. + // The second digit string is only used if T is a User-Defined Type, + // when the constant is converted to a long string literal and lexical_casted to type T. + // (This is necessary because you can't use a numeric constant + // since even a long double might not have enough digits). + + enum construction_method + { + construct_from_float = 1, + construct_from_double = 2, + construct_from_long_double = 3, + construct_from_string = 4, + construct_from_float128 = 5, + // Must be the largest value above: + construct_max = construct_from_float128 + }; + + // + // Traits class determines how to convert from string based on whether T has a constructor + // from const char* or not: + // + template + struct dummy_size{}; + + // + // Max number of binary digits in the string representations of our constants: + // + static constexpr int max_string_digits = (101 * 1000L) / 301L; + + template + struct construction_traits + { + private: + using real_precision = typename policies::precision::type; + using float_precision = typename policies::precision::type; + using double_precision = typename policies::precision::type; + using long_double_precision = typename policies::precision::type; + public: + using type = std::integral_constant::value && (real_precision::value <= float_precision::value)? construct_from_float : + std::is_convertible::value && (real_precision::value <= double_precision::value)? construct_from_double : + std::is_convertible::value && (real_precision::value <= long_double_precision::value)? construct_from_long_double : +#ifdef BOOST_MATH_USE_FLOAT128 + std::is_convertible::value && (real_precision::value <= 113) ? construct_from_float128 : +#endif + (real_precision::value <= max_string_digits) ? construct_from_string : real_precision::value + >; + }; + +#ifdef BOOST_HAS_THREADS +#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) \ + boost::once_flag f = BOOST_ONCE_INIT;\ + boost::call_once(f, &BOOST_JOIN(BOOST_JOIN(string_, get_), name)); +#else +#define BOOST_MATH_CONSTANT_THREAD_HELPER(name, prefix) +#endif + + namespace detail{ + + template > + struct constant_return + { + using construct_type = typename construction_traits::type; + using type = typename std::conditional< + (construct_type::value == construct_from_string) || (construct_type::value > construct_max), + const Real&, Real>::type; + }; + + template + struct constant_initializer + { + static void force_instantiate() + { + init.force_instantiate(); + } + private: + struct initializer + { + initializer() + { + F(); + } + void force_instantiate()const{} + }; + static const initializer init; + }; + + template + typename constant_initializer::initializer const constant_initializer::init; + + template )) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> + struct constant_initializer2 + { + static void force_instantiate() + { + init.force_instantiate(); + } + private: + struct initializer + { + initializer() + { + F(); + } + void force_instantiate()const{} + }; + static const initializer init; + }; + + template )) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T))> + typename constant_initializer2::initializer const constant_initializer2::init; + + } + +#ifdef BOOST_MATH_USE_FLOAT128 +# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ + static inline constexpr T get(const std::integral_constant&) noexcept\ + { return BOOST_JOIN(x, Q); } +#else +# define BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) +#endif + +#ifdef BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) constant_initializer::get_from_variable_precision>::force_instantiate(); +#else +# define BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name) +#endif + +#define BOOST_DEFINE_MATH_CONSTANT(name, x, y)\ + namespace detail{\ + template struct BOOST_JOIN(constant_, name){\ + private:\ + /* The default implementations come next: */ \ + static inline const T& get_from_string()\ + {\ + static const T result(boost::math::tools::convert_from_string(y));\ + return result;\ + }\ + /* This one is for very high precision that is none the less known at compile time: */ \ + template static T compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant)));\ + template static inline const T& get_from_compute(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC((std::integral_constant)))\ + {\ + static const T result = compute();\ + return result;\ + }\ + static inline const T& get_from_variable_precision()\ + {\ + static BOOST_MATH_THREAD_LOCAL int digits = 0;\ + static BOOST_MATH_THREAD_LOCAL T value;\ + int current_digits = boost::math::tools::digits();\ + if(digits != current_digits)\ + {\ + value = current_digits > max_string_digits ? compute<0>() : T(boost::math::tools::convert_from_string(y));\ + digits = current_digits; \ + }\ + return value;\ + }\ + /* public getters come next */\ + public:\ + static inline const T& get(const std::integral_constant&)\ + {\ + constant_initializer::get_from_string >::force_instantiate();\ + return get_from_string();\ + }\ + static inline constexpr T get(const std::integral_constant) noexcept\ + { return BOOST_JOIN(x, F); }\ + static inline constexpr T get(const std::integral_constant&) noexcept\ + { return x; }\ + static inline constexpr T get(const std::integral_constant&) noexcept\ + { return BOOST_JOIN(x, L); }\ + BOOST_MATH_FLOAT128_CONSTANT_OVERLOAD(x) \ + template static inline const T& get(const std::integral_constant&)\ + {\ + constant_initializer2::template get_from_compute >::force_instantiate();\ + return get_from_compute(); \ + }\ + /* This one is for true arbitrary precision, which may well vary at runtime: */ \ + static inline T get(const std::integral_constant&)\ + {\ + BOOST_MATH_PRECOMPUTE_IF_NOT_LOCAL(constant_, name)\ + return get_from_variable_precision(); }\ + }; /* end of struct */\ + } /* namespace detail */ \ + \ + \ + /* The actual forwarding function: */ \ + template inline constexpr typename detail::constant_return::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) BOOST_MATH_NOEXCEPT(T)\ + { return detail:: BOOST_JOIN(constant_, name)::get(typename construction_traits::type()); }\ + template inline constexpr typename detail::constant_return::type name(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) BOOST_MATH_NOEXCEPT(T)\ + { return name >(); }\ + \ + \ + /* Now the namespace specific versions: */ \ + } namespace float_constants{ static constexpr float name = BOOST_JOIN(x, F); }\ + namespace double_constants{ static constexpr double name = x; } \ + namespace long_double_constants{ static constexpr long double name = BOOST_JOIN(x, L); }\ + namespace constants{ + + BOOST_DEFINE_MATH_CONSTANT(half, 5.000000000000000000000000000000000000e-01, "5.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") + BOOST_DEFINE_MATH_CONSTANT(third, 3.333333333333333333333333333333333333e-01, "3.33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333e-01") + BOOST_DEFINE_MATH_CONSTANT(twothirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(two_thirds, 6.666666666666666666666666666666666666e-01, "6.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(sixth, 1.666666666666666666666666666666666666e-01, "1.66666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667e-01") + BOOST_DEFINE_MATH_CONSTANT(three_quarters, 7.500000000000000000000000000000000000e-01, "7.50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-01") + BOOST_DEFINE_MATH_CONSTANT(root_two, 1.414213562373095048801688724209698078e+00, "1.41421356237309504880168872420969807856967187537694807317667973799073247846210703885038753432764157273501384623e+00") + BOOST_DEFINE_MATH_CONSTANT(root_three, 1.732050807568877293527446341505872366e+00, "1.73205080756887729352744634150587236694280525381038062805580697945193301690880003708114618675724857567562614142e+00") + BOOST_DEFINE_MATH_CONSTANT(half_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") + BOOST_DEFINE_MATH_CONSTANT(ln_two, 6.931471805599453094172321214581765680e-01, "6.93147180559945309417232121458176568075500134360255254120680009493393621969694715605863326996418687542001481021e-01") + BOOST_DEFINE_MATH_CONSTANT(ln_ln_two, -3.665129205816643270124391582326694694e-01, "-3.66512920581664327012439158232669469454263447837105263053677713670561615319352738549455822856698908358302523045e-01") + BOOST_DEFINE_MATH_CONSTANT(root_ln_four, 1.177410022515474691011569326459699637e+00, "1.17741002251547469101156932645969963774738568938582053852252575650002658854698492680841813836877081106747157858e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_two, 7.071067811865475244008443621048490392e-01, "7.07106781186547524400844362104849039284835937688474036588339868995366239231053519425193767163820786367506923115e-01") + BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00") + BOOST_DEFINE_MATH_CONSTANT(half_pi, 1.570796326794896619231321691639751442e+00, "1.57079632679489661923132169163975144209858469968755291048747229615390820314310449931401741267105853399107404326e+00") + BOOST_DEFINE_MATH_CONSTANT(third_pi, 1.047197551196597746154214461093167628e+00, "1.04719755119659774615421446109316762806572313312503527365831486410260546876206966620934494178070568932738269550e+00") + BOOST_DEFINE_MATH_CONSTANT(sixth_pi, 5.235987755982988730771072305465838140e-01, "5.23598775598298873077107230546583814032861566562517636829157432051302734381034833104672470890352844663691347752e-01") + BOOST_DEFINE_MATH_CONSTANT(two_pi, 6.283185307179586476925286766559005768e+00, "6.28318530717958647692528676655900576839433879875021164194988918461563281257241799725606965068423413596429617303e+00") + BOOST_DEFINE_MATH_CONSTANT(two_thirds_pi, 2.094395102393195492308428922186335256e+00, "2.09439510239319549230842892218633525613144626625007054731662972820521093752413933241868988356141137865476539101e+00") + BOOST_DEFINE_MATH_CONSTANT(three_quarters_pi, 2.356194490192344928846982537459627163e+00, "2.35619449019234492884698253745962716314787704953132936573120844423086230471465674897102611900658780098661106488e+00") + BOOST_DEFINE_MATH_CONSTANT(four_thirds_pi, 4.188790204786390984616857844372670512e+00, "4.18879020478639098461685784437267051226289253250014109463325945641042187504827866483737976712282275730953078202e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_two_pi, 1.591549430918953357688837633725143620e-01, "1.59154943091895335768883763372514362034459645740456448747667344058896797634226535090113802766253085956072842727e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_two_pi, 3.989422804014326779399460599343818684e-01, "3.98942280401432677939946059934381868475858631164934657665925829670657925899301838501252333907306936430302558863e-01") + BOOST_DEFINE_MATH_CONSTANT(root_pi, 1.772453850905516027298167483341145182e+00, "1.77245385090551602729816748334114518279754945612238712821380778985291128459103218137495065673854466541622682362e+00") + BOOST_DEFINE_MATH_CONSTANT(root_half_pi, 1.253314137315500251207882642405522626e+00, "1.25331413731550025120788264240552262650349337030496915831496178817114682730392098747329791918902863305800498633e+00") + BOOST_DEFINE_MATH_CONSTANT(root_two_pi, 2.506628274631000502415765284811045253e+00, "2.50662827463100050241576528481104525300698674060993831662992357634229365460784197494659583837805726611600997267e+00") + BOOST_DEFINE_MATH_CONSTANT(log_root_two_pi, 9.189385332046727417803297364056176398e-01, "9.18938533204672741780329736405617639861397473637783412817151540482765695927260397694743298635954197622005646625e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_root_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") + BOOST_DEFINE_MATH_CONSTANT(root_one_div_pi, 5.641895835477562869480794515607725858e-01, "5.64189583547756286948079451560772585844050629328998856844085721710642468441493414486743660202107363443028347906e-01") + BOOST_DEFINE_MATH_CONSTANT(pi_minus_three, 1.415926535897932384626433832795028841e-01, "1.41592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513e-01") + BOOST_DEFINE_MATH_CONSTANT(four_minus_pi, 8.584073464102067615373566167204971158e-01, "8.58407346410206761537356616720497115802830600624894179025055407692183593713791001371965174657882932017851913487e-01") + //BOOST_DEFINE_MATH_CONSTANT(pow23_four_minus_pi, 7.953167673715975443483953350568065807e-01, "7.95316767371597544348395335056806580727639173327713205445302234388856268267518187590758006888600828436839800178e-01") + BOOST_DEFINE_MATH_CONSTANT(pi_pow_e, 2.245915771836104547342715220454373502e+01, "2.24591577183610454734271522045437350275893151339966922492030025540669260403991179123185197527271430315314500731e+01") + BOOST_DEFINE_MATH_CONSTANT(pi_sqr, 9.869604401089358618834490999876151135e+00, "9.86960440108935861883449099987615113531369940724079062641334937622004482241920524300177340371855223182402591377e+00") + BOOST_DEFINE_MATH_CONSTANT(pi_sqr_div_six, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") + BOOST_DEFINE_MATH_CONSTANT(pi_cubed, 3.100627668029982017547631506710139520e+01, "3.10062766802998201754763150671013952022252885658851076941445381038063949174657060375667010326028861930301219616e+01") + BOOST_DEFINE_MATH_CONSTANT(cbrt_pi, 1.464591887561523263020142527263790391e+00, "1.46459188756152326302014252726379039173859685562793717435725593713839364979828626614568206782035382089750397002e+00") + BOOST_DEFINE_MATH_CONSTANT(one_div_cbrt_pi, 6.827840632552956814670208331581645981e-01, "6.82784063255295681467020833158164598108367515632448804042681583118899226433403918237673501922595519865685577274e-01") + BOOST_DEFINE_MATH_CONSTANT(log2_e, 1.44269504088896340735992468100189213742664595415298, "1.44269504088896340735992468100189213742664595415298593413544940693110921918118507988552662289350634449699751830965e+00") + BOOST_DEFINE_MATH_CONSTANT(e, 2.718281828459045235360287471352662497e+00, "2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193e+00") + BOOST_DEFINE_MATH_CONSTANT(exp_minus_half, 6.065306597126334236037995349911804534e-01, "6.06530659712633423603799534991180453441918135487186955682892158735056519413748423998647611507989456026423789794e-01") + BOOST_DEFINE_MATH_CONSTANT(exp_minus_one, 3.678794411714423215955237701614608674e-01, "3.67879441171442321595523770161460867445811131031767834507836801697461495744899803357147274345919643746627325277e-01") + BOOST_DEFINE_MATH_CONSTANT(e_pow_pi, 2.314069263277926900572908636794854738e+01, "2.31406926327792690057290863679485473802661062426002119934450464095243423506904527835169719970675492196759527048e+01") + BOOST_DEFINE_MATH_CONSTANT(root_e, 1.648721270700128146848650787814163571e+00, "1.64872127070012814684865078781416357165377610071014801157507931164066102119421560863277652005636664300286663776e+00") + BOOST_DEFINE_MATH_CONSTANT(log10_e, 4.342944819032518276511289189166050822e-01, "4.34294481903251827651128918916605082294397005803666566114453783165864649208870774729224949338431748318706106745e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_log10_e, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") + BOOST_DEFINE_MATH_CONSTANT(ln_ten, 2.302585092994045684017991454684364207e+00, "2.30258509299404568401799145468436420760110148862877297603332790096757260967735248023599720508959829834196778404e+00") + BOOST_DEFINE_MATH_CONSTANT(degree, 1.745329251994329576923690768488612713e-02, "1.74532925199432957692369076848861271344287188854172545609719144017100911460344944368224156963450948221230449251e-02") + BOOST_DEFINE_MATH_CONSTANT(radian, 5.729577951308232087679815481410517033e+01, "5.72957795130823208767981548141051703324054724665643215491602438612028471483215526324409689958511109441862233816e+01") + BOOST_DEFINE_MATH_CONSTANT(sin_one, 8.414709848078965066525023216302989996e-01, "8.41470984807896506652502321630298999622563060798371065672751709991910404391239668948639743543052695854349037908e-01") + BOOST_DEFINE_MATH_CONSTANT(cos_one, 5.403023058681397174009366074429766037e-01, "5.40302305868139717400936607442976603732310420617922227670097255381100394774471764517951856087183089343571731160e-01") + BOOST_DEFINE_MATH_CONSTANT(sinh_one, 1.175201193643801456882381850595600815e+00, "1.17520119364380145688238185059560081515571798133409587022956541301330756730432389560711745208962339184041953333e+00") + BOOST_DEFINE_MATH_CONSTANT(cosh_one, 1.543080634815243778477905620757061682e+00, "1.54308063481524377847790562075706168260152911236586370473740221471076906304922369896426472643554303558704685860e+00") + BOOST_DEFINE_MATH_CONSTANT(phi, 1.618033988749894848204586834365638117e+00, "1.61803398874989484820458683436563811772030917980576286213544862270526046281890244970720720418939113748475408808e+00") + BOOST_DEFINE_MATH_CONSTANT(ln_phi, 4.812118250596034474977589134243684231e-01, "4.81211825059603447497758913424368423135184334385660519661018168840163867608221774412009429122723474997231839958e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_ln_phi, 2.078086921235027537601322606117795767e+00, "2.07808692123502753760132260611779576774219226778328348027813992191974386928553540901445615414453604821933918634e+00") + BOOST_DEFINE_MATH_CONSTANT(euler, 5.772156649015328606065120900824024310e-01, "5.77215664901532860606512090082402431042159335939923598805767234884867726777664670936947063291746749514631447250e-01") + BOOST_DEFINE_MATH_CONSTANT(one_div_euler, 1.732454714600633473583025315860829681e+00, "1.73245471460063347358302531586082968115577655226680502204843613287065531408655243008832840219409928068072365714e+00") + BOOST_DEFINE_MATH_CONSTANT(euler_sqr, 3.331779238077186743183761363552442266e-01, "3.33177923807718674318376136355244226659417140249629743150833338002265793695756669661263268631715977303039565603e-01") + BOOST_DEFINE_MATH_CONSTANT(zeta_two, 1.644934066848226436472415166646025189e+00, "1.64493406684822643647241516664602518921894990120679843773555822937000747040320087383362890061975870530400431896e+00") + BOOST_DEFINE_MATH_CONSTANT(zeta_three, 1.202056903159594285399738161511449990e+00, "1.20205690315959428539973816151144999076498629234049888179227155534183820578631309018645587360933525814619915780e+00") + BOOST_DEFINE_MATH_CONSTANT(catalan, 9.159655941772190150546035149323841107e-01, "9.15965594177219015054603514932384110774149374281672134266498119621763019776254769479356512926115106248574422619e-01") + BOOST_DEFINE_MATH_CONSTANT(glaisher, 1.282427129100622636875342568869791727e+00, "1.28242712910062263687534256886979172776768892732500119206374002174040630885882646112973649195820237439420646120e+00") + BOOST_DEFINE_MATH_CONSTANT(khinchin, 2.685452001065306445309714835481795693e+00, "2.68545200106530644530971483548179569382038229399446295305115234555721885953715200280114117493184769799515346591e+00") + BOOST_DEFINE_MATH_CONSTANT(extreme_value_skewness, 1.139547099404648657492793019389846112e+00, "1.13954709940464865749279301938984611208759979583655182472165571008524800770607068570718754688693851501894272049e+00") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_skewness, 6.311106578189371381918993515442277798e-01, "6.31110657818937138191899351544227779844042203134719497658094585692926819617473725459905027032537306794400047264e-01") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis, 3.245089300687638062848660410619754415e+00, "3.24508930068763806284866041061975441541706673178920936177133764493367904540874159051490619368679348977426462633e+00") + BOOST_DEFINE_MATH_CONSTANT(rayleigh_kurtosis_excess, 2.450893006876380628486604106197544154e-01, "2.45089300687638062848660410619754415417066731789209361771337644933679045408741590514906193686793489774264626328e-01") + + BOOST_DEFINE_MATH_CONSTANT(two_div_pi, 6.366197723675813430755350534900574481e-01, "6.36619772367581343075535053490057448137838582961825794990669376235587190536906140360455211065012343824291370907e-01") + BOOST_DEFINE_MATH_CONSTANT(root_two_div_pi, 7.978845608028653558798921198687637369e-01, "7.97884560802865355879892119868763736951717262329869315331851659341315851798603677002504667814613872860605117725e-01") + BOOST_DEFINE_MATH_CONSTANT(quarter_pi, 0.785398163397448309615660845819875721049292, "0.785398163397448309615660845819875721049292349843776455243736148076954101571552249657008706335529266995537021628320576661773") + BOOST_DEFINE_MATH_CONSTANT(one_div_pi, 0.3183098861837906715377675267450287240689192, "0.31830988618379067153776752674502872406891929148091289749533468811779359526845307018022760553250617191214568545351") + BOOST_DEFINE_MATH_CONSTANT(two_div_root_pi, 1.12837916709551257389615890312154517168810125, "1.12837916709551257389615890312154517168810125865799771368817144342128493688298682897348732040421472688605669581272") + +#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) + BOOST_DEFINE_MATH_CONSTANT(first_feigenbaum, 4.66920160910299067185320382046620161725818557747576863274, "4.6692016091029906718532038204662016172581855774757686327456513430041343302113147371386897440239480138171") + BOOST_DEFINE_MATH_CONSTANT(plastic, 1.324717957244746025960908854478097340734404056901733364534, "1.32471795724474602596090885447809734073440405690173336453401505030282785124554759405469934798178728032991") + BOOST_DEFINE_MATH_CONSTANT(gauss, 0.834626841674073186281429732799046808993993013490347002449, "0.83462684167407318628142973279904680899399301349034700244982737010368199270952641186969116035127532412906785") + BOOST_DEFINE_MATH_CONSTANT(dottie, 0.739085133215160641655312087673873404013411758900757464965, "0.739085133215160641655312087673873404013411758900757464965680635773284654883547594599376106931766531849801246") + BOOST_DEFINE_MATH_CONSTANT(reciprocal_fibonacci, 3.35988566624317755317201130291892717968890513, "3.35988566624317755317201130291892717968890513373196848649555381532513031899668338361541621645679008729704") + BOOST_DEFINE_MATH_CONSTANT(laplace_limit, 0.662743419349181580974742097109252907056233549115022417, "0.66274341934918158097474209710925290705623354911502241752039253499097185308651127724965480259895818168") +#endif + +template +inline constexpr T tau() { return two_pi(); } + +} // namespace constants +} // namespace math +} // namespace boost + +// +// We deliberately include this *after* all the declarations above, +// that way the calculation routines can call on other constants above: +// +#include + +#endif // BOOST_MATH_CONSTANTS_CONSTANTS_INCLUDED + + diff --git a/libcxx/src/third-party/boost/math/constants/info.hpp b/libcxx/src/third-party/boost/math/constants/info.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/constants/info.hpp @@ -0,0 +1,163 @@ +// Copyright John Maddock 2010. +// 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) + +#ifdef _MSC_VER +# pragma once +#endif + +#ifndef BOOST_MATH_CONSTANTS_INFO_INCLUDED +#define BOOST_MATH_CONSTANTS_INFO_INCLUDED + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace constants{ + + namespace detail{ + + template + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) + { + return typeid(T).name(); + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(float)) + { + return "float"; + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(double)) + { + return "double"; + } + template <> + const char* nameof(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(long double)) + { + return "long double"; + } + + } + +template +void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T) BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(Policy)) +{ + using detail::nameof; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + os << + "Information on the Implementation and Handling of \n" + "Mathematical Constants for Type " << nameof() << + "\n\n" + "Checking for std::numeric_limits<" << nameof() << "> specialisation: " << + (std::numeric_limits::is_specialized ? "yes" : "no") << std::endl; + if(std::numeric_limits::is_specialized) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the radix is " << std::numeric_limits::radix << ".\n"; + if (std::numeric_limits::radix == 2) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" << std::numeric_limits::digits << " binary digits.\n"; + } + else if (std::numeric_limits::radix == 10) + { + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" << std::numeric_limits::digits10 << " decimal digits.\n"; + os << + "std::numeric_limits<" << nameof() << ">::digits reports that the precision is \n" + << std::numeric_limits::digits * 1000L /301L << " binary digits.\n"; // divide by log2(10) - about 3 bits per decimal digit. + } + else + { + os << "Unknown radix = " << std::numeric_limits::radix << "\n"; + } + } + typedef typename boost::math::policies::precision::type precision_type; + if(precision_type::value) + { + if (std::numeric_limits::radix == 2) + { + os << + "boost::math::policies::precision<" << nameof() << ", " << nameof() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n"; + } + else if (std::numeric_limits::radix == 10) + { + os << + "boost::math::policies::precision<" << nameof() << ", " << nameof() << " reports that the compile time precision is \n" << precision_type::value << " binary digits.\n"; + } + else + { + os << "Unknown radix = " << std::numeric_limits::radix << "\n"; + } + } + else + { + os << + "boost::math::policies::precision<" << nameof() << ", Policy> \n" + "reports that there is no compile type precision available.\n" + "boost::math::tools::digits<" << nameof() << ">() \n" + "reports that the current runtime precision is \n" << + boost::math::tools::digits() << " binary digits.\n"; + } + + typedef typename construction_traits::type construction_type; + + switch(construction_type::value) + { + case 0: + os << + "No compile time precision is available, the construction method \n" + "will be decided at runtime and results will not be cached \n" + "- this may lead to poor runtime performance.\n" + "Current runtime precision indicates that\n"; + if(boost::math::tools::digits() > max_string_digits) + { + os << "the constant will be recalculated on each call.\n"; + } + else + { + os << "the constant will be constructed from a string on each call.\n"; + } + break; + case 1: + os << + "The constant will be constructed from a float.\n"; + break; + case 2: + os << + "The constant will be constructed from a double.\n"; + break; + case 3: + os << + "The constant will be constructed from a long double.\n"; + break; + case 4: + os << + "The constant will be constructed from a string (and the result cached).\n"; + break; + default: + os << + "The constant will be calculated (and the result cached).\n"; + break; + } + os << std::endl; +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +template +void print_info_on_type(std::ostream& os = std::cout BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) +{ + print_info_on_type >(os); +} + +}}} // namespaces + +#endif // BOOST_MATH_CONSTANTS_INFO_INCLUDED diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_cmath.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_cmath.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_cmath.hpp @@ -0,0 +1,1058 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement quadruple-precision support. + +#ifndef BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ +#define BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ + +#include +#include + +#if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) && defined(__GNUC__) + // Several versions of Mingw and probably cygwin too have broken + // libquadmath implementations that segfault as soon as you call + // expq or any function that depends on it. +#define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +#endif + +// Here is a helper function used for raising the value of a given +// floating-point type to the power of n, where n has integral type. +namespace boost { + namespace math { + namespace cstdfloat { + namespace detail { + + template + inline float_type pown(const float_type& x, const integer_type p) + { + const bool isneg = (x < 0); + const bool isnan = (x != x); + const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + if (isnan) { return x; } + + if (isinf) { return std::numeric_limits::quiet_NaN(); } + + const bool x_is_neg = (x < 0); + const float_type abs_x = (x_is_neg ? -x : x); + + if (p < static_cast(0)) + { + if (abs_x < (std::numeric_limits::min)()) + { + return (x_is_neg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + else + { + return float_type(1) / pown(x, static_cast(-p)); + } + } + + if (p == static_cast(0)) + { + return float_type(1); + } + else + { + if (p == static_cast(1)) { return x; } + + if (abs_x > (std::numeric_limits::max)()) + { + return (x_is_neg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + if (p == static_cast(2)) { return (x * x); } + else if (p == static_cast(3)) { return ((x * x) * x); } + else if (p == static_cast(4)) { const float_type x2 = (x * x); return (x2 * x2); } + else + { + // The variable xn stores the binary powers of x. + float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1)); + float_type xn(x); + + integer_type p2 = p; + + while (integer_type(p2 /= 2) != integer_type(0)) + { + // Square xn for each binary power. + xn *= xn; + + const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0)); + + if (has_binary_power) + { + // Multiply the result with each binary power contained in the exponent. + result *= xn; + } + } + + return result; + } + } + } + + } + } + } +} // boost::math::cstdfloat::detail + +// We will now define preprocessor symbols representing quadruple-precision functions. +#if defined(__INTEL_COMPILER) +#define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq +#define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq +#define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq +#define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq +#define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq +#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) +#define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq +#endif +#define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq +#define BOOST_CSTDFLOAT_FLOAT128_EXP __expq +#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q +#define BOOST_CSTDFLOAT_FLOAT128_POW __powq +#define BOOST_CSTDFLOAT_FLOAT128_LOG __logq +#define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q +#define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq +#define BOOST_CSTDFLOAT_FLOAT128_COS __cosq +#define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq +#define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq +#define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq +#define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq +#define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq +#define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq +#define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq +#define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq +#define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q +#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq +// begin more functions +#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER __remainderq +#define BOOST_CSTDFLOAT_FLOAT128_REMQUO __remquoq +#define BOOST_CSTDFLOAT_FLOAT128_FMA __fmaq +#define BOOST_CSTDFLOAT_FLOAT128_FMAX __fmaxq +#define BOOST_CSTDFLOAT_FLOAT128_FMIN __fminq +#define BOOST_CSTDFLOAT_FLOAT128_FDIM __fdimq +#define BOOST_CSTDFLOAT_FLOAT128_NAN __nanq +//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 __exp2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG2 __log2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG1P __log1pq +#define BOOST_CSTDFLOAT_FLOAT128_CBRT __cbrtq +#define BOOST_CSTDFLOAT_FLOAT128_HYPOT __hypotq +#define BOOST_CSTDFLOAT_FLOAT128_ERF __erfq +#define BOOST_CSTDFLOAT_FLOAT128_ERFC __erfcq +#define BOOST_CSTDFLOAT_FLOAT128_LLROUND __llroundq +#define BOOST_CSTDFLOAT_FLOAT128_LROUND __lroundq +#define BOOST_CSTDFLOAT_FLOAT128_ROUND __roundq +#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT __nearbyintq +#define BOOST_CSTDFLOAT_FLOAT128_LLRINT __llrintq +#define BOOST_CSTDFLOAT_FLOAT128_LRINT __lrintq +#define BOOST_CSTDFLOAT_FLOAT128_RINT __rintq +#define BOOST_CSTDFLOAT_FLOAT128_MODF __modfq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN __scalblnq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBN __scalbnq +#define BOOST_CSTDFLOAT_FLOAT128_ILOGB __ilogbq +#define BOOST_CSTDFLOAT_FLOAT128_LOGB __logbq +#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER __nextafterq +//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD __nexttowardq +#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN __copysignq +#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT __signbitq +//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY __fpclassifyq +//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE __isfiniteq +#define BOOST_CSTDFLOAT_FLOAT128_ISINF __isinfq +#define BOOST_CSTDFLOAT_FLOAT128_ISNAN __isnanq +//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL __isnormalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER __isgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL __isgreaterequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS __islessq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL __islessequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER __islessgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED __isunorderedq +// end more functions +#elif defined(__GNUC__) +#define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq +#define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq +#define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq +#define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq +#define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq +#if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT) +#define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq +#endif +#define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq +#define BOOST_CSTDFLOAT_FLOAT128_POW powq +#define BOOST_CSTDFLOAT_FLOAT128_LOG logq +#define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q +#define BOOST_CSTDFLOAT_FLOAT128_SIN sinq +#define BOOST_CSTDFLOAT_FLOAT128_COS cosq +#define BOOST_CSTDFLOAT_FLOAT128_TAN tanq +#define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq +#define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq +#define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq +#define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q +#define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq +#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) +#define BOOST_CSTDFLOAT_FLOAT128_EXP expq +#define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q +#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq +#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq +#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq +#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq +#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq +#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +#define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch +#define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch +#define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch +#define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch +#define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch +#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS +// begin more functions +#define BOOST_CSTDFLOAT_FLOAT128_REMAINDER remainderq +#define BOOST_CSTDFLOAT_FLOAT128_REMQUO remquoq +#define BOOST_CSTDFLOAT_FLOAT128_FMA fmaq +#define BOOST_CSTDFLOAT_FLOAT128_FMAX fmaxq +#define BOOST_CSTDFLOAT_FLOAT128_FMIN fminq +#define BOOST_CSTDFLOAT_FLOAT128_FDIM fdimq +#define BOOST_CSTDFLOAT_FLOAT128_NAN nanq +//#define BOOST_CSTDFLOAT_FLOAT128_EXP2 exp2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG2 log2q +#define BOOST_CSTDFLOAT_FLOAT128_LOG1P log1pq +#define BOOST_CSTDFLOAT_FLOAT128_CBRT cbrtq +#define BOOST_CSTDFLOAT_FLOAT128_HYPOT hypotq +#define BOOST_CSTDFLOAT_FLOAT128_ERF erfq +#define BOOST_CSTDFLOAT_FLOAT128_ERFC erfcq +#define BOOST_CSTDFLOAT_FLOAT128_LLROUND llroundq +#define BOOST_CSTDFLOAT_FLOAT128_LROUND lroundq +#define BOOST_CSTDFLOAT_FLOAT128_ROUND roundq +#define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT nearbyintq +#define BOOST_CSTDFLOAT_FLOAT128_LLRINT llrintq +#define BOOST_CSTDFLOAT_FLOAT128_LRINT lrintq +#define BOOST_CSTDFLOAT_FLOAT128_RINT rintq +#define BOOST_CSTDFLOAT_FLOAT128_MODF modfq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBLN scalblnq +#define BOOST_CSTDFLOAT_FLOAT128_SCALBN scalbnq +#define BOOST_CSTDFLOAT_FLOAT128_ILOGB ilogbq +#define BOOST_CSTDFLOAT_FLOAT128_LOGB logbq +#define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER nextafterq +//#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD nexttowardq +#define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN copysignq +#define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT signbitq +//#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY fpclassifyq +//#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE isfiniteq +#define BOOST_CSTDFLOAT_FLOAT128_ISINF isinfq +#define BOOST_CSTDFLOAT_FLOAT128_ISNAN isnanq +//#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL isnormalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER isgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL isgreaterequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESS islessq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL islessequalq +//#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER islessgreaterq +//#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED isunorderedq +// end more functions +#endif + +// Implement quadruple-precision functions in the namespace +// boost::math::cstdfloat::detail. Subsequently inject these into the +// std namespace via *using* directive. + +// Begin with some forward function declarations. Also implement patches +// for compilers that have broken float128 exponential functions. + +extern "C" int quadmath_snprintf(char*, std::size_t, const char*, ...) BOOST_MATH_NOTHROW; + +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP(boost::math::cstdfloat::detail::float_internal128_t, int) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP(boost::math::cstdfloat::detail::float_internal128_t, int*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMOD(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN2(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + +// begin more functions +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMAINDER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMQUO(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, int*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMA(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMAX(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMIN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FDIM(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NAN(const char*) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP2 (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG2(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG1P(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CBRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_HYPOT(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERF(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERFC(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ROUND(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLRINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LRINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_RINT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_MODF(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t*) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBLN(boost::math::cstdfloat::detail::float_internal128_t, long int) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBN(boost::math::cstdfloat::detail::float_internal128_t, int) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ILOGB(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOGB(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISFINITE (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISINF(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISNAN(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ISNORMAL (boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATER (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESS (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; +//extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + // end more functions + +#if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS) + +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; +extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW; + +#else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS + +// Forward declaration of the patched exponent function, exp(x). +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x); + +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Compute exp(x) - 1 for x small. + + // Use an order-12 Pade approximation of the exponential function. + // PadeApproximant[Exp[x] - 1, {x, 0, 12, 12}]. + + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + float_type sum; + + if (x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)) + { + sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1); + } + else + { + const float_type x2 = (x * x); + + const float_type top = ((((( float_type(BOOST_FLOAT128_C(2.4087176110456818621091195109360728010934088788572E-13)) * x2 + + float_type(BOOST_FLOAT128_C(9.2735628025258751691201101171038802842096241836000E-10))) * x2 + + float_type(BOOST_FLOAT128_C(9.0806726962333369656024118266681195742980640005812E-07))) * x2 + + float_type(BOOST_FLOAT128_C(3.1055900621118012422360248447204968944099378881988E-04))) * x2 + + float_type(BOOST_FLOAT128_C(3.6231884057971014492753623188405797101449275362319E-02))) * x2 + + float_type(BOOST_FLOAT128_C(1.00000000000000000000000000000000000000000000000000000))) + ; + + const float_type bot = (((((((((((( float_type(BOOST_FLOAT128_C(+7.7202487533515444298369215094104897470942592271063E-16)) * x + + float_type(BOOST_FLOAT128_C(-1.2043588055228409310545597554680364005467044394286E-13))) * x + + float_type(BOOST_FLOAT128_C(+9.2735628025258751691201101171038802842096241836000E-12))) * x + + float_type(BOOST_FLOAT128_C(-4.6367814012629375845600550585519401421048120918000E-10))) * x + + float_type(BOOST_FLOAT128_C(+1.6692413044546575304416198210786984511577323530480E-08))) * x + + float_type(BOOST_FLOAT128_C(-4.5403363481166684828012059133340597871490320002906E-07))) * x + + float_type(BOOST_FLOAT128_C(+9.5347063310450038138825324180015255530129672006102E-06))) * x + + float_type(BOOST_FLOAT128_C(-1.5527950310559006211180124223602484472049689440994E-04))) * x + + float_type(BOOST_FLOAT128_C(+1.9409937888198757763975155279503105590062111801242E-03))) * x + + float_type(BOOST_FLOAT128_C(-1.8115942028985507246376811594202898550724637681159E-02))) * x + + float_type(BOOST_FLOAT128_C(+1.1956521739130434782608695652173913043478260869565E-01))) * x + + float_type(BOOST_FLOAT128_C(-0.50000000000000000000000000000000000000000000000000000))) * x + + float_type(BOOST_FLOAT128_C(+1.00000000000000000000000000000000000000000000000000000))) + ; + + sum = (x * top) / bot; + } + + return sum; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the expq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + // Scale the argument x to the range (-ln2 < x < ln2). + constexpr float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299)); + const float_type x_over_ln2 = x * one_over_ln2; + + int n; + + if (x != x) + { + // The argument is NaN. + return std::numeric_limits::quiet_NaN(); + } + else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) + { + // The absolute value of the argument exceeds ln2. + n = static_cast(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2)); + } + else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255)) + { + // The absolute value of the argument is less than ln2. + n = 0; + } + else + { + // The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality). + return float_type(2); + } + + // Check if the argument is very near an integer. + const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS)) + { + // Return e^n for arguments very near an integer. + return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast(floor_of_x)); + } + + // Compute the scaled argument alpha. + const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255)); + + // Compute the polynomial approximation of expm1(alpha) and add to it + // in order to obtain the scaled result. + const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1); + + // Rescale the result and return it. + return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the sinhq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + // Here, we use the following: + // Set: ex = exp(x) + // Set: em1 = expm1(x) + // Then + // sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1 + // sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1 + + const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1)) + { + const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); + + return ((em1 * 2) + (em1 * em1)) / (ex * 2); + } + else + { + return (ex - (float_type(1) / ex)) / 2; + } +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the coshq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + return (ex + (float_type(1) / ex)) / 2; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) +{ + // Patch the tanhq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); + const float_type ex_minus = (float_type(1) / ex_plus); + return (ex_plus - ex_minus) / (ex_plus + ex_minus); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the asinh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1))); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the acosh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + const float_type zp(x + float_type(1)); + const float_type zm(x - float_type(1)); + + return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp))); +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the atanh() function since quadmath does not have it. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + return (::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x) + - ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2; +} +inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) BOOST_MATH_NOTHROW +{ + // Patch the tgammaq() function for a subset of broken GCC compilers + // like GCC 4.7, 4.8 on MinGW. + typedef boost::math::cstdfloat::detail::float_internal128_t float_type; + + if (x > float_type(0)) + { + return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x)); + } + else if (x < float_type(0)) + { + // For x < 0, compute tgamma(-x) and use the reflection formula. + const float_type positive_x = -x; + float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x); + const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x); + + // Take the reflection checks (slightly adapted) from . + const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x)); + + constexpr float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511); + + if (floor_of_z_is_equal_to_z) + { + const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); + + return (is_odd ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x); + + gamma_value *= sinpx_value; + + const bool result_is_too_large_to_represent = ((::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1)) + && (((std::numeric_limits::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi)); + + if (result_is_too_large_to_represent) + { + const bool is_odd = ((std::int32_t(floor_of_positive_x) % std::int32_t(2)) != std::int32_t(0)); + + return (is_odd ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + } + + gamma_value = -my_pi / gamma_value; + + if ((gamma_value > float_type(0)) || (gamma_value < float_type(0))) + { + return gamma_value; + } + else + { + // The value of gamma is too small to represent. Return 0.0 here. + return float_type(0); + } + } + else + { + // Gamma of zero is complex infinity. Return NaN here. + return std::numeric_limits::quiet_NaN(); + } +} +#endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS + +// Define the quadruple-precision functions in the namespace boost::math::cstdfloat::detail. + +namespace boost { + namespace math { + namespace cstdfloat { + namespace detail { + inline boost::math::cstdfloat::detail::float_internal128_t ldexp(boost::math::cstdfloat::detail::float_internal128_t x, int n) { return ::BOOST_CSTDFLOAT_FLOAT128_LDEXP(x, n); } + inline boost::math::cstdfloat::detail::float_internal128_t frexp(boost::math::cstdfloat::detail::float_internal128_t x, int* pn) { return ::BOOST_CSTDFLOAT_FLOAT128_FREXP(x, pn); } + inline boost::math::cstdfloat::detail::float_internal128_t fabs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t abs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t floor(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); } + inline boost::math::cstdfloat::detail::float_internal128_t ceil(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sqrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t trunc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC(x); } + inline boost::math::cstdfloat::detail::float_internal128_t exp(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); } + inline boost::math::cstdfloat::detail::float_internal128_t expm1(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); } + inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, a); } + inline boost::math::cstdfloat::detail::float_internal128_t pow(boost::math::cstdfloat::detail::float_internal128_t x, int a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW(x, boost::math::cstdfloat::detail::float_internal128_t(a)); } + inline boost::math::cstdfloat::detail::float_internal128_t log(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x); } + inline boost::math::cstdfloat::detail::float_internal128_t log10(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t asin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t acos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS(x); } + inline boost::math::cstdfloat::detail::float_internal128_t atan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t sinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t asinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t acosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t atanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH(x); } + inline boost::math::cstdfloat::detail::float_internal128_t fmod(boost::math::cstdfloat::detail::float_internal128_t a, boost::math::cstdfloat::detail::float_internal128_t b) { return ::BOOST_CSTDFLOAT_FLOAT128_FMOD(a, b); } + inline boost::math::cstdfloat::detail::float_internal128_t atan2(boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN2(y, x); } + inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); } + inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); } + // begin more functions + inline boost::math::cstdfloat::detail::float_internal128_t remainder(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_REMAINDER(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t remquo(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, int* z) { return ::BOOST_CSTDFLOAT_FLOAT128_REMQUO(x, y, z); } + inline boost::math::cstdfloat::detail::float_internal128_t fma(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return BOOST_CSTDFLOAT_FLOAT128_FMA(x, y, z); } + + inline boost::math::cstdfloat::detail::float_internal128_t fmax(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmax(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmax(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t fmin(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmin(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + fmin(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); } + + inline boost::math::cstdfloat::detail::float_internal128_t fdim(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FDIM(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t nanq(const char* x) { return ::BOOST_CSTDFLOAT_FLOAT128_NAN(x); } + inline boost::math::cstdfloat::detail::float_internal128_t exp2(boost::math::cstdfloat::detail::float_internal128_t x) + { + return ::BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t(2), x); + } + inline boost::math::cstdfloat::detail::float_internal128_t log2(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG2(x); } + inline boost::math::cstdfloat::detail::float_internal128_t log1p(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG1P(x); } + inline boost::math::cstdfloat::detail::float_internal128_t cbrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CBRT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x*x + y * y + z * z); } + inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + hypot(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + hypot(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); } + + + inline boost::math::cstdfloat::detail::float_internal128_t erf(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERF(x); } + inline boost::math::cstdfloat::detail::float_internal128_t erfc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERFC(x); } + inline long long int llround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLROUND(x); } + inline long int lround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LROUND(x); } + inline boost::math::cstdfloat::detail::float_internal128_t round(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ROUND(x); } + inline boost::math::cstdfloat::detail::float_internal128_t nearbyint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(x); } + inline long long int llrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLRINT(x); } + inline long int lrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LRINT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t rint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_RINT(x); } + inline boost::math::cstdfloat::detail::float_internal128_t modf(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t* y) { return ::BOOST_CSTDFLOAT_FLOAT128_MODF(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t scalbln(boost::math::cstdfloat::detail::float_internal128_t x, long int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBLN(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t scalbn(boost::math::cstdfloat::detail::float_internal128_t x, int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBN(x, y); } + inline int ilogb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ILOGB(x); } + inline boost::math::cstdfloat::detail::float_internal128_t logb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOGB(x); } + inline boost::math::cstdfloat::detail::float_internal128_t nextafter(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(x, y); } + inline boost::math::cstdfloat::detail::float_internal128_t nexttoward(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return -(::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(-x, -y)); } + inline boost::math::cstdfloat::detail::float_internal128_t copysign BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(x, y); } + inline bool signbit BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(x); } + inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) + { + if (::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x)) + return FP_NAN; + else if (::BOOST_CSTDFLOAT_FLOAT128_ISINF(x)) + return FP_INFINITE; + else if (x == BOOST_FLOAT128_C(0.0)) + return FP_ZERO; + + if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_CSTDFLOAT_FLOAT128_MIN) + return FP_SUBNORMAL; + else + return FP_NORMAL; + } + inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) + { + return !::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) && !::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); + } + inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); } + inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x); } + inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return boost::math::cstdfloat::detail::fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(x) == FP_NORMAL; } + inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x > y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x >= y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x < y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isless BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return x <= y; + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) + { + if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y)) + return false; + return (x < y) || (x > y); + } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) || ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); } + template + inline typename std::enable_if< + std::is_convertible::value + && !std::is_same::value, boost::math::cstdfloat::detail::float_internal128_t>::type + isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); } + + + // end more functions + } + } + } +} // boost::math::cstdfloat::detail + +// We will now inject the quadruple-precision functions +// into the std namespace. This is done via *using* directive. +namespace std +{ + using boost::math::cstdfloat::detail::ldexp; + using boost::math::cstdfloat::detail::frexp; + using boost::math::cstdfloat::detail::fabs; + +#if !(defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && (__GNUC__ >= 7)) +#if (defined(__clang__) && !(!defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128))) || (__GNUC__ <= 6 && !defined(__clang__)) + // workaround for clang using libstdc++ and old GCC + using boost::math::cstdfloat::detail::abs; +#endif +#endif + + using boost::math::cstdfloat::detail::floor; + using boost::math::cstdfloat::detail::ceil; + using boost::math::cstdfloat::detail::sqrt; + using boost::math::cstdfloat::detail::trunc; + using boost::math::cstdfloat::detail::exp; + using boost::math::cstdfloat::detail::expm1; + using boost::math::cstdfloat::detail::pow; + using boost::math::cstdfloat::detail::log; + using boost::math::cstdfloat::detail::log10; + using boost::math::cstdfloat::detail::sin; + using boost::math::cstdfloat::detail::cos; + using boost::math::cstdfloat::detail::tan; + using boost::math::cstdfloat::detail::asin; + using boost::math::cstdfloat::detail::acos; + using boost::math::cstdfloat::detail::atan; + using boost::math::cstdfloat::detail::sinh; + using boost::math::cstdfloat::detail::cosh; + using boost::math::cstdfloat::detail::tanh; + using boost::math::cstdfloat::detail::asinh; + using boost::math::cstdfloat::detail::acosh; + using boost::math::cstdfloat::detail::atanh; + using boost::math::cstdfloat::detail::fmod; + using boost::math::cstdfloat::detail::atan2; + using boost::math::cstdfloat::detail::lgamma; + using boost::math::cstdfloat::detail::tgamma; + + // begin more functions + using boost::math::cstdfloat::detail::remainder; + using boost::math::cstdfloat::detail::remquo; + using boost::math::cstdfloat::detail::fma; + using boost::math::cstdfloat::detail::fmax; + using boost::math::cstdfloat::detail::fmin; + using boost::math::cstdfloat::detail::fdim; + using boost::math::cstdfloat::detail::nanq; + using boost::math::cstdfloat::detail::exp2; + using boost::math::cstdfloat::detail::log2; + using boost::math::cstdfloat::detail::log1p; + using boost::math::cstdfloat::detail::cbrt; + using boost::math::cstdfloat::detail::hypot; + using boost::math::cstdfloat::detail::erf; + using boost::math::cstdfloat::detail::erfc; + using boost::math::cstdfloat::detail::llround; + using boost::math::cstdfloat::detail::lround; + using boost::math::cstdfloat::detail::round; + using boost::math::cstdfloat::detail::nearbyint; + using boost::math::cstdfloat::detail::llrint; + using boost::math::cstdfloat::detail::lrint; + using boost::math::cstdfloat::detail::rint; + using boost::math::cstdfloat::detail::modf; + using boost::math::cstdfloat::detail::scalbln; + using boost::math::cstdfloat::detail::scalbn; + using boost::math::cstdfloat::detail::ilogb; + using boost::math::cstdfloat::detail::logb; + using boost::math::cstdfloat::detail::nextafter; + using boost::math::cstdfloat::detail::nexttoward; + using boost::math::cstdfloat::detail::copysign; + using boost::math::cstdfloat::detail::signbit; + using boost::math::cstdfloat::detail::fpclassify; + using boost::math::cstdfloat::detail::isfinite; + using boost::math::cstdfloat::detail::isinf; + using boost::math::cstdfloat::detail::isnan; + using boost::math::cstdfloat::detail::isnormal; + using boost::math::cstdfloat::detail::isgreater; + using boost::math::cstdfloat::detail::isgreaterequal; + using boost::math::cstdfloat::detail::isless; + using boost::math::cstdfloat::detail::islessequal; + using boost::math::cstdfloat::detail::islessgreater; + using boost::math::cstdfloat::detail::isunordered; + // end more functions + + // + // Very basic iostream operator: + // + inline std::ostream& operator << (std::ostream& os, __float128 m_value) + { + std::streamsize digits = os.precision(); + std::ios_base::fmtflags f = os.flags(); + std::string s; + + char buf[100]; + std::unique_ptr buf2; + std::string format = "%"; + if (f & std::ios_base::showpos) + format += "+"; + if (f & std::ios_base::showpoint) + format += "#"; + format += ".*"; + if (digits == 0) + digits = 36; + format += "Q"; + if (f & std::ios_base::scientific) + format += "e"; + else if (f & std::ios_base::fixed) + format += "f"; + else + format += "g"; + + int v = quadmath_snprintf(buf, 100, format.c_str(), digits, m_value); + + if ((v < 0) || (v >= 99)) + { + int v_max = v; + buf2.reset(new char[v + 3]); + v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value); + if (v >= v_max + 3) + { + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed.")); + } + s = &buf2[0]; + } + else + s = buf; + std::streamsize ss = os.width(); + if (ss > static_cast(s.size())) + { + char fill = os.fill(); + if ((os.flags() & std::ios_base::left) == std::ios_base::left) + s.append(static_cast(ss - s.size()), fill); + else + s.insert(static_cast(0), static_cast(ss - s.size()), fill); + } + + return os << s; + } + + +} // namespace std + +// We will now remove the preprocessor symbols representing quadruple-precision +// functions from the preprocessor. + +#undef BOOST_CSTDFLOAT_FLOAT128_LDEXP +#undef BOOST_CSTDFLOAT_FLOAT128_FREXP +#undef BOOST_CSTDFLOAT_FLOAT128_FABS +#undef BOOST_CSTDFLOAT_FLOAT128_FLOOR +#undef BOOST_CSTDFLOAT_FLOAT128_CEIL +#undef BOOST_CSTDFLOAT_FLOAT128_SQRT +#undef BOOST_CSTDFLOAT_FLOAT128_TRUNC +#undef BOOST_CSTDFLOAT_FLOAT128_EXP +#undef BOOST_CSTDFLOAT_FLOAT128_EXPM1 +#undef BOOST_CSTDFLOAT_FLOAT128_POW +#undef BOOST_CSTDFLOAT_FLOAT128_LOG +#undef BOOST_CSTDFLOAT_FLOAT128_LOG10 +#undef BOOST_CSTDFLOAT_FLOAT128_SIN +#undef BOOST_CSTDFLOAT_FLOAT128_COS +#undef BOOST_CSTDFLOAT_FLOAT128_TAN +#undef BOOST_CSTDFLOAT_FLOAT128_ASIN +#undef BOOST_CSTDFLOAT_FLOAT128_ACOS +#undef BOOST_CSTDFLOAT_FLOAT128_ATAN +#undef BOOST_CSTDFLOAT_FLOAT128_SINH +#undef BOOST_CSTDFLOAT_FLOAT128_COSH +#undef BOOST_CSTDFLOAT_FLOAT128_TANH +#undef BOOST_CSTDFLOAT_FLOAT128_ASINH +#undef BOOST_CSTDFLOAT_FLOAT128_ACOSH +#undef BOOST_CSTDFLOAT_FLOAT128_ATANH +#undef BOOST_CSTDFLOAT_FLOAT128_FMOD +#undef BOOST_CSTDFLOAT_FLOAT128_ATAN2 +#undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA +#undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA + +// begin more functions +#undef BOOST_CSTDFLOAT_FLOAT128_REMAINDER +#undef BOOST_CSTDFLOAT_FLOAT128_REMQUO +#undef BOOST_CSTDFLOAT_FLOAT128_FMA +#undef BOOST_CSTDFLOAT_FLOAT128_FMAX +#undef BOOST_CSTDFLOAT_FLOAT128_FMIN +#undef BOOST_CSTDFLOAT_FLOAT128_FDIM +#undef BOOST_CSTDFLOAT_FLOAT128_NAN +#undef BOOST_CSTDFLOAT_FLOAT128_EXP2 +#undef BOOST_CSTDFLOAT_FLOAT128_LOG2 +#undef BOOST_CSTDFLOAT_FLOAT128_LOG1P +#undef BOOST_CSTDFLOAT_FLOAT128_CBRT +#undef BOOST_CSTDFLOAT_FLOAT128_HYPOT +#undef BOOST_CSTDFLOAT_FLOAT128_ERF +#undef BOOST_CSTDFLOAT_FLOAT128_ERFC +#undef BOOST_CSTDFLOAT_FLOAT128_LLROUND +#undef BOOST_CSTDFLOAT_FLOAT128_LROUND +#undef BOOST_CSTDFLOAT_FLOAT128_ROUND +#undef BOOST_CSTDFLOAT_FLOAT128_NEARBYINT +#undef BOOST_CSTDFLOAT_FLOAT128_LLRINT +#undef BOOST_CSTDFLOAT_FLOAT128_LRINT +#undef BOOST_CSTDFLOAT_FLOAT128_RINT +#undef BOOST_CSTDFLOAT_FLOAT128_MODF +#undef BOOST_CSTDFLOAT_FLOAT128_SCALBLN +#undef BOOST_CSTDFLOAT_FLOAT128_SCALBN +#undef BOOST_CSTDFLOAT_FLOAT128_ILOGB +#undef BOOST_CSTDFLOAT_FLOAT128_LOGB +#undef BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER +#undef BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD +#undef BOOST_CSTDFLOAT_FLOAT128_COPYSIGN +#undef BOOST_CSTDFLOAT_FLOAT128_SIGNBIT +#undef BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY +#undef BOOST_CSTDFLOAT_FLOAT128_ISFINITE +#undef BOOST_CSTDFLOAT_FLOAT128_ISINF +#undef BOOST_CSTDFLOAT_FLOAT128_ISNAN +#undef BOOST_CSTDFLOAT_FLOAT128_ISNORMAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATER +#undef BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESS +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL +#undef BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER +#undef BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED +// end more functions + +#endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_CMATH_2014_02_15_HPP_ + diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex.hpp @@ -0,0 +1,38 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement quadruple-precision (and extended) support for . + +#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ + + #include + #include + #include + #include + + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_LIMITS defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_IOSTREAM defined. + #endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + #define BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE boost::math::cstdfloat::detail::float_internal128_t + #include + #undef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_2014_02_15_HPP_ diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex_std.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex_std.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_complex_std.hpp @@ -0,0 +1,813 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement a specialization of std::complex<> for *anything* that +// is defined as BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE. + +#ifndef BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ + + #if defined(__GNUC__) + #pragma GCC system_header + #endif + + #include + #include + #include + + namespace std + { + // Forward declarations. + template + class complex; + + template<> + class complex; + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex&); + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex&); + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex&); + + inline complex conj (const complex&); + inline complex proj (const complex&); + + inline complex polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& = 0); + + inline complex sqrt (const complex&); + + inline complex sin (const complex&); + inline complex cos (const complex&); + inline complex tan (const complex&); + inline complex asin (const complex&); + inline complex acos (const complex&); + inline complex atan (const complex&); + + inline complex exp (const complex&); + inline complex log (const complex&); + inline complex log10(const complex&); + + inline complex pow (const complex&, + int); + inline complex pow (const complex&, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&); + inline complex pow (const complex&, + const complex&); + inline complex pow (const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE&, + const complex&); + + inline complex sinh (const complex&); + inline complex cosh (const complex&); + inline complex tanh (const complex&); + + inline complex asinh(const complex&); + inline complex acosh(const complex&); + inline complex atanh(const complex&); + + template + inline std::basic_ostream& operator<<(std::basic_ostream&, const std::complex&); + + template + inline std::basic_istream& operator>>(std::basic_istream&, std::complex&); + + // Template specialization of the complex class. + template<> + class complex + { + public: + typedef BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE value_type; + + complex(const complex&); + complex(const complex&); + complex(const complex&); + + #if defined(BOOST_NO_CXX11_CONSTEXPR) + complex(const value_type& r = value_type(), + const value_type& i = value_type()) : re(r), + im(i) { } + + template + explicit complex(const complex& x) : re(x.real()), + im(x.imag()) { } + + const value_type& real() const { return re; } + const value_type& imag() const { return im; } + + value_type& real() { return re; } + value_type& imag() { return im; } + #else + constexpr complex(const value_type& r = value_type(), + const value_type& i = value_type()) : re(r), + im(i) { } + + template + explicit constexpr complex(const complex& x) : re(x.real()), + im(x.imag()) { } + + value_type real() const { return re; } + value_type imag() const { return im; } + #endif + + void real(value_type r) { re = r; } + void imag(value_type i) { im = i; } + + complex& operator=(const value_type& v) + { + re = v; + im = value_type(0); + return *this; + } + + complex& operator+=(const value_type& v) + { + re += v; + return *this; + } + + complex& operator-=(const value_type& v) + { + re -= v; + return *this; + } + + complex& operator*=(const value_type& v) + { + re *= v; + im *= v; + return *this; + } + + complex& operator/=(const value_type& v) + { + re /= v; + im /= v; + return *this; + } + + template + complex& operator=(const complex& x) + { + re = x.real(); + im = x.imag(); + return *this; + } + + template + complex& operator+=(const complex& x) + { + re += x.real(); + im += x.imag(); + return *this; + } + + template + complex& operator-=(const complex& x) + { + re -= x.real(); + im -= x.imag(); + return *this; + } + + template + complex& operator*=(const complex& x) + { + const value_type tmp_real = (re * x.real()) - (im * x.imag()); + im = (re * x.imag()) + (im * x.real()); + re = tmp_real; + return *this; + } + + template + complex& operator/=(const complex& x) + { + const value_type tmp_real = (re * x.real()) + (im * x.imag()); + const value_type the_norm = std::norm(x); + im = ((im * x.real()) - (re * x.imag())) / the_norm; + re = tmp_real / the_norm; + return *this; + } + + private: + value_type re; + value_type im; + }; + + // Constructors from built-in complex representation of floating-point types. + inline complex::complex(const complex& f) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( f.imag())) { } + inline complex::complex(const complex& d) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE( d.imag())) { } + inline complex::complex(const complex& ld) : re(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.real())), im(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(ld.imag())) { } + } // namespace std + + namespace boost { namespace math { namespace cstdfloat { namespace detail { + template inline std::complex multiply_by_i(const std::complex& x) + { + // Multiply x (in C) by I (the imaginary component), and return the result. + return std::complex(-x.imag(), x.real()); + } + } } } } // boost::math::cstdfloat::detail + + namespace std + { + // ISO/IEC 14882:2011, Section 26.4.7, specific values. + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE real(const complex& x) { return x.real(); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE imag(const complex& x) { return x.imag(); } + + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE abs (const complex& x) { using std::sqrt; return sqrt ((real(x) * real(x)) + (imag(x) * imag(x))); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE arg (const complex& x) { using std::atan2; return atan2(x.imag(), x.real()); } + inline BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE norm(const complex& x) { return (real(x) * real(x)) + (imag(x) * imag(x)); } + + inline complex conj (const complex& x) { return complex(x.real(), -x.imag()); } + + inline complex proj (const complex& x) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE m = (std::numeric_limits::max)(); + if ( (x.real() > m) + || (x.real() < -m) + || (x.imag() > m) + || (x.imag() < -m)) + { + // We have an infinity, return a normalized infinity, respecting the sign of the imaginary part: + return complex(std::numeric_limits::infinity(), x.imag() < 0 ? -0 : 0); + } + return x; + } + + inline complex polar(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& rho, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& theta) + { + using std::sin; + using std::cos; + + return complex(rho * cos(theta), rho * sin(theta)); + } + + // Global add, sub, mul, div. + inline complex operator+(const complex& u, const complex& v) { return complex(u.real() + v.real(), u.imag() + v.imag()); } + inline complex operator-(const complex& u, const complex& v) { return complex(u.real() - v.real(), u.imag() - v.imag()); } + + inline complex operator*(const complex& u, const complex& v) + { + return complex((u.real() * v.real()) - (u.imag() * v.imag()), + (u.real() * v.imag()) + (u.imag() * v.real())); + } + + inline complex operator/(const complex& u, const complex& v) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE the_norm = std::norm(v); + + return complex(((u.real() * v.real()) + (u.imag() * v.imag())) / the_norm, + ((u.imag() * v.real()) - (u.real() * v.imag())) / the_norm); + } + + inline complex operator+(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() + v, u.imag()); } + inline complex operator-(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() - v, u.imag()); } + inline complex operator*(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() * v, u.imag() * v); } + inline complex operator/(const complex& u, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& v) { return complex(u.real() / v, u.imag() / v); } + + inline complex operator+(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u + v.real(), v.imag()); } + inline complex operator-(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u - v.real(), -v.imag()); } + inline complex operator*(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { return complex(u * v.real(), u * v.imag()); } + inline complex operator/(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& u, const complex& v) { const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE v_norm = norm(v); return complex((u * v.real()) / v_norm, (-u * v.imag()) / v_norm); } + + // Unary plus / minus. + inline complex operator+(const complex& u) { return u; } + inline complex operator-(const complex& u) { return complex(-u.real(), -u.imag()); } + + // Equality and inequality. + inline bool operator==(const complex& x, const complex& y) { return ((x.real() == y.real()) && (x.imag() == y.imag())); } + inline bool operator==(const complex& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() == y) && (x.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator==(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex& y) { return ((x == y.real()) && (y.imag() == BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator!=(const complex& x, const complex& y) { return ((x.real() != y.real()) || (x.imag() != y.imag())); } + inline bool operator!=(const complex& x, const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& y) { return ((x.real() != y) || (x.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + inline bool operator!=(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, const complex& y) { return ((x != y.real()) || (y.imag() != BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0))); } + + // ISO/IEC 14882:2011, Section 26.4.8, transcendentals. + inline complex sqrt(const complex& x) + { + using std::fabs; + using std::sqrt; + + // Compute sqrt(x) for x in C: + // sqrt(x) = (s , xi / 2s) : for xr > 0, + // (|xi| / 2s, +-s) : for xr < 0, + // (sqrt(xi), sqrt(xi) : for xr = 0, + // where s = sqrt{ [ |xr| + sqrt(xr^2 + xi^2) ] / 2 }, + // and the +- sign is the same as the sign of xi. + + if(x.real() > 0) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); + + return complex(s, x.imag() / (s * 2)); + } + else if(x.real() < 0) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE s = sqrt((fabs(x.real()) + std::abs(x)) / 2); + + const bool imag_is_neg = (x.imag() < 0); + + return complex(fabs(x.imag()) / (s * 2), (imag_is_neg ? -s : s)); + } + else + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sqrt_xi_half = sqrt(x.imag() / 2); + + return complex(sqrt_xi_half, sqrt_xi_half); + } + } + + inline complex sin(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return complex(sin_x * cosh_y, cos_x * sinh_y); + } + + inline complex cos(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return complex(cos_x * cosh_y, -(sin_x * sinh_y)); + } + + inline complex tan(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_x = sin (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_x = cos (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_yp = exp (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_ym = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_yp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_y = (exp_yp - exp_ym) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_y = (exp_yp + exp_ym) / 2; + + return ( complex(sin_x * cosh_y, cos_x * sinh_y) + / complex(cos_x * cosh_y, -sin_x * sinh_y)); + } + + inline complex asin(const complex& x) + { + return -boost::math::cstdfloat::detail::multiply_by_i(std::log(boost::math::cstdfloat::detail::multiply_by_i(x) + std::sqrt(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - (x * x)))); + } + + inline complex acos(const complex& x) + { + return boost::math::constants::half_pi() - std::asin(x); + } + + inline complex atan(const complex& x) + { + const complex izz = boost::math::cstdfloat::detail::multiply_by_i(x); + + return boost::math::cstdfloat::detail::multiply_by_i(std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - izz) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + izz)) / 2; + } + + inline complex exp(const complex& x) + { + using std::exp; + + return std::polar(exp(x.real()), x.imag()); + } + + inline complex log(const complex& x) + { + using std::atan2; + using std::log; + + const bool re_isneg = (x.real() < 0); + const bool re_isnan = (x.real() != x.real()); + const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits::max)()) + : bool(-x.real() > (std::numeric_limits::max)())); + + const bool im_isneg = (x.imag() < 0); + const bool im_isnan = (x.imag() != x.imag()); + const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits::max)()) + : bool(-x.imag() > (std::numeric_limits::max)())); + + if(re_isnan || im_isnan) { return x; } + + if(re_isinf || im_isinf) + { + return complex(std::numeric_limits::infinity(), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0)); + } + + const bool re_iszero = ((re_isneg || (x.real() > 0)) == false); + + if(re_iszero) + { + const bool im_iszero = ((im_isneg || (x.imag() > 0)) == false); + + if(im_iszero) + { + return std::complex + ( + -std::numeric_limits::infinity(), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0.0) + ); + } + else + { + if(im_isneg == false) + { + return std::complex + ( + log(x.imag()), + boost::math::constants::half_pi() + ); + } + else + { + return std::complex + ( + log(-x.imag()), + -boost::math::constants::half_pi() + ); + } + } + } + else + { + return complex(log(std::norm(x)) / 2, atan2(x.imag(), x.real())); + } + } + + inline complex log10(const complex& x) + { + return std::log(x) / boost::math::constants::ln_ten(); + } + + inline complex pow(const complex& x, + int p) + { + const bool re_isneg = (x.real() < 0); + const bool re_isnan = (x.real() != x.real()); + const bool re_isinf = ((!re_isneg) ? bool(+x.real() > (std::numeric_limits::max)()) + : bool(-x.real() > (std::numeric_limits::max)())); + + const bool im_isneg = (x.imag() < 0); + const bool im_isnan = (x.imag() != x.imag()); + const bool im_isinf = ((!im_isneg) ? bool(+x.imag() > (std::numeric_limits::max)()) + : bool(-x.imag() > (std::numeric_limits::max)())); + + if(re_isnan || im_isnan) { return x; } + + if(re_isinf || im_isinf) + { + return complex(std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN()); + } + + if(p < 0) + { + if(std::abs(x) < (std::numeric_limits::min)()) + { + return complex(std::numeric_limits::infinity(), + std::numeric_limits::infinity()); + } + else + { + return BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / std::pow(x, -p); + } + } + + if(p == 0) + { + return complex(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1)); + } + else + { + if(p == 1) { return x; } + + if(std::abs(x) > (std::numeric_limits::max)()) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE re = (re_isneg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE im = (im_isneg ? -std::numeric_limits::infinity() + : +std::numeric_limits::infinity()); + + return complex(re, im); + } + + if (p == 2) { return (x * x); } + else if(p == 3) { return ((x * x) * x); } + else if(p == 4) { const complex x2 = (x * x); return (x2 * x2); } + else + { + // The variable xn stores the binary powers of x. + complex result(((p % 2) != 0) ? x : complex(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); + complex xn (x); + + int p2 = p; + + while((p2 /= 2) != 0) + { + // Square xn for each binary power. + xn *= xn; + + const bool has_binary_power = ((p2 % 2) != 0); + + if(has_binary_power) + { + // Multiply the result with each binary power contained in the exponent. + result *= xn; + } + } + + return result; + } + } + } + + inline complex pow(const complex& x, + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& a) + { + const bool x_im_isneg = (x.imag() < 0); + const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); + + if(x_im_iszero) + { + using std::pow; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE pxa = pow(x.real(), a); + + return complex(pxa, BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0)); + } + else + { + return std::exp(a * std::log(x)); + } + } + + inline complex pow(const complex& x, + const complex& a) + { + const bool x_im_isneg = (x.imag() < 0); + const bool x_im_iszero = ((x_im_isneg || (x.imag() > 0)) == false); + + if(x_im_iszero) + { + using std::pow; + + return pow(x.real(), a); + } + else + { + return std::exp(a * std::log(x)); + } + } + + inline complex pow(const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE& x, + const complex& a) + { + const bool x_isneg = (x < 0); + const bool x_isnan = (x != x); + const bool x_isinf = ((!x_isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + const bool a_re_isneg = (a.real() < 0); + const bool a_re_isnan = (a.real() != a.real()); + const bool a_re_isinf = ((!a_re_isneg) ? bool(+a.real() > (std::numeric_limits::max)()) + : bool(-a.real() > (std::numeric_limits::max)())); + + const bool a_im_isneg = (a.imag() < 0); + const bool a_im_isnan = (a.imag() != a.imag()); + const bool a_im_isinf = ((!a_im_isneg) ? bool(+a.imag() > (std::numeric_limits::max)()) + : bool(-a.imag() > (std::numeric_limits::max)())); + + const bool args_is_nan = (x_isnan || a_re_isnan || a_im_isnan); + const bool a_is_finite = (!(a_re_isnan || a_re_isinf || a_im_isnan || a_im_isinf)); + + complex result; + + if(args_is_nan) + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + else if(x_isinf) + { + if(a_is_finite) + { + result = + complex + ( + std::numeric_limits::infinity(), + std::numeric_limits::infinity() + ); + } + else + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + } + else if(x > 0) + { + result = std::exp(a * std::log(x)); + } + else if(x < 0) + { + using std::acos; + using std::log; + + const complex + cpx_lg_x + ( + log(-x), + acos(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(-1)) + ); + + result = std::exp(a * cpx_lg_x); + } + else + { + if(a_is_finite) + { + result = + complex + ( + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0), + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(0) + ); + } + else + { + result = + complex + ( + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() + ); + } + } + + return result; + } + + inline complex sinh(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; + + return complex(cos_y * sinh_x, cosh_x * sin_y); + } + + inline complex cosh(const complex& x) + { + using std::sin; + using std::cos; + using std::exp; + + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sin_y = sin (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cos_y = cos (x.imag()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xp = exp (x.real()); + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE exp_xm = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / exp_xp; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE sinh_x = (exp_xp - exp_xm) / 2; + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE cosh_x = (exp_xp + exp_xm) / 2; + + return complex(cos_y * cosh_x, sin_y * sinh_x); + } + + inline complex tanh(const complex& x) + { + const complex ex_plus = std::exp(x); + const complex ex_minus = BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) / ex_plus; + + return (ex_plus - ex_minus) / (ex_plus + ex_minus); + } + + inline complex asinh(const complex& x) + { + return std::log(x + std::sqrt((x * x) + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1))); + } + + inline complex acosh(const complex& x) + { + const BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE my_one(1); + + const complex zp(x.real() + my_one, x.imag()); + const complex zm(x.real() - my_one, x.imag()); + + return std::log(x + (zp * std::sqrt(zm / zp))); + } + + inline complex atanh(const complex& x) + { + return (std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) + x) - std::log(BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE(1) - x)) / 2.0; + } + + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const std::complex& x) + { + std::basic_ostringstream ostr; + + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + ostr << char_type('(') + << x.real() + << char_type(',') + << x.imag() + << char_type(')'); + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, std::complex& x) + { + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE rx; + BOOST_CSTDFLOAT_EXTENDED_COMPLEX_FLOAT_TYPE ix; + + char_type the_char; + + static_cast(is >> the_char); + + if(the_char == static_cast('(')) + { + static_cast(is >> rx >> the_char); + + if(the_char == static_cast(',')) + { + static_cast(is >> ix >> the_char); + + if(the_char == static_cast(')')) + { + x = complex(rx, ix); + } + else + { + is.setstate(ios_base::failbit); + } + } + else if(the_char == static_cast(')')) + { + x = rx; + } + else + { + is.setstate(ios_base::failbit); + } + } + else + { + static_cast(is.putback(the_char)); + + static_cast(is >> rx); + + x = rx; + } + + return is; + } + } // namespace std + +#endif // BOOST_MATH_CSTDFLOAT_COMPLEX_STD_2014_02_15_HPP_ diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_iostream.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_iostream.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_iostream.hpp @@ -0,0 +1,775 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement quadruple-precision I/O stream operations. + +#ifndef BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ + #define BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ + + #include + #include + #include + + #if defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH) + #error You can not use with BOOST_CSTDFLOAT_NO_LIBQUADMATH_CMATH defined. + #endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + #include + #include + #include + #include + #include + #include + #include + #include + #include + +// #if (0) + #if defined(__GNUC__) + + // Forward declarations of quadruple-precision string functions. + extern "C" int quadmath_snprintf(char *str, size_t size, const char *format, ...) BOOST_MATH_NOTHROW; + extern "C" boost::math::cstdfloat::detail::float_internal128_t strtoflt128(const char*, char **) BOOST_MATH_NOTHROW; + + namespace std + { + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::basic_ostringstream ostr; + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + char my_buffer[64U]; + + const int my_prec = static_cast(os.precision()); + const int my_digits = ((my_prec == 0) ? 36 : my_prec); + + const std::ios_base::fmtflags my_flags = os.flags(); + + char my_format_string[8U]; + + std::size_t my_format_string_index = 0U; + + my_format_string[my_format_string_index] = '%'; + ++my_format_string_index; + + if(my_flags & std::ios_base::showpos) { my_format_string[my_format_string_index] = '+'; ++my_format_string_index; } + if(my_flags & std::ios_base::showpoint) { my_format_string[my_format_string_index] = '#'; ++my_format_string_index; } + + my_format_string[my_format_string_index + 0U] = '.'; + my_format_string[my_format_string_index + 1U] = '*'; + my_format_string[my_format_string_index + 2U] = 'Q'; + + my_format_string_index += 3U; + + char the_notation_char; + + if (my_flags & std::ios_base::scientific) { the_notation_char = 'e'; } + else if(my_flags & std::ios_base::fixed) { the_notation_char = 'f'; } + else { the_notation_char = 'g'; } + + my_format_string[my_format_string_index + 0U] = the_notation_char; + my_format_string[my_format_string_index + 1U] = 0; + + const int v = ::quadmath_snprintf(my_buffer, + static_cast(sizeof(my_buffer)), + my_format_string, + my_digits, + x); + + if(v < 0) { BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed internally in quadmath_snprintf().")); } + + if(v >= static_cast(sizeof(my_buffer) - 1U)) + { + // Evidently there is a really long floating-point string here, + // such as a small decimal representation in non-scientific notation. + // So we have to use dynamic memory allocation for the output + // string buffer. + + char* my_buffer2 = static_cast(0U); + +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + my_buffer2 = new char[v + 3]; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const std::bad_alloc&) + { + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed while allocating memory.")); + } +#endif + const int v2 = ::quadmath_snprintf(my_buffer2, + v + 3, + my_format_string, + my_digits, + x); + + if(v2 >= v + 3) + { + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Formatting of boost::float128_t failed.")); + } + + static_cast(ostr << my_buffer2); + + delete [] my_buffer2; + } + else + { + static_cast(ostr << my_buffer); + } + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::string str; + + static_cast(is >> str); + + char* p_end; + + x = strtoflt128(str.c_str(), &p_end); + + if(static_cast(p_end - str.c_str()) != static_cast(str.length())) + { + for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) + { + static_cast(is.putback(*it)); + } + + is.setstate(ios_base::failbit); + + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); + } + + return is; + } + } + +// #elif defined(__GNUC__) + #elif defined(__INTEL_COMPILER) + + // The section for I/O stream support for the ICC compiler is particularly + // long, because these functions must be painstakingly synthesized from + // manually-written routines (ICC does not support I/O stream operations + // for its _Quad type). + + // The following string-extraction routines are based on the methodology + // used in Boost.Multiprecision by John Maddock and Christopher Kormanyos. + // This methodology has been slightly modified here for boost::float128_t. + + #include + #include + + namespace boost { namespace math { namespace cstdfloat { namespace detail { + + template + void format_float_string(string_type& str, + int my_exp, + int digits, + const std::ios_base::fmtflags f, + const bool iszero) + { + typedef typename string_type::size_type size_type; + + const bool scientific = ((f & std::ios_base::scientific) == std::ios_base::scientific); + const bool fixed = ((f & std::ios_base::fixed) == std::ios_base::fixed); + const bool showpoint = ((f & std::ios_base::showpoint) == std::ios_base::showpoint); + const bool showpos = ((f & std::ios_base::showpos) == std::ios_base::showpos); + + const bool b_neg = ((str.size() != 0U) && (str[0] == '-')); + + if(b_neg) + { + str.erase(0, 1); + } + + if(digits == 0) + { + digits = static_cast((std::max)(str.size(), size_type(16))); + } + + if(iszero || str.empty() || (str.find_first_not_of('0') == string_type::npos)) + { + // We will be printing zero, even though the value might not + // actually be zero (it just may have been rounded to zero). + str = "0"; + + if(scientific || fixed) + { + str.append(1, '.'); + str.append(size_type(digits), '0'); + + if(scientific) + { + str.append("e+00"); + } + } + else + { + if(showpoint) + { + str.append(1, '.'); + if(digits > 1) + { + str.append(size_type(digits - 1), '0'); + } + } + } + + if(b_neg) + { + str.insert(0U, 1U, '-'); + } + else if(showpos) + { + str.insert(0U, 1U, '+'); + } + + return; + } + + if(!fixed && !scientific && !showpoint) + { + // Suppress trailing zeros. + typename string_type::iterator pos = str.end(); + + while(pos != str.begin() && *--pos == '0') { ; } + + if(pos != str.end()) + { + ++pos; + } + + str.erase(pos, str.end()); + + if(str.empty()) + { + str = '0'; + } + } + else if(!fixed || (my_exp >= 0)) + { + // Pad out the end with zero's if we need to. + + int chars = static_cast(str.size()); + chars = digits - chars; + + if(scientific) + { + ++chars; + } + + if(chars > 0) + { + str.append(static_cast(chars), '0'); + } + } + + if(fixed || (!scientific && (my_exp >= -4) && (my_exp < digits))) + { + if((1 + my_exp) > static_cast(str.size())) + { + // Just pad out the end with zeros. + str.append(static_cast((1 + my_exp) - static_cast(str.size())), '0'); + + if(showpoint || fixed) + { + str.append("."); + } + } + else if(my_exp + 1 < static_cast(str.size())) + { + if(my_exp < 0) + { + str.insert(0U, static_cast(-1 - my_exp), '0'); + str.insert(0U, "0."); + } + else + { + // Insert the decimal point: + str.insert(static_cast(my_exp + 1), 1, '.'); + } + } + else if(showpoint || fixed) // we have exactly the digits we require to left of the point + { + str += "."; + } + + if(fixed) + { + // We may need to add trailing zeros. + int l = static_cast(str.find('.') + 1U); + l = digits - (static_cast(str.size()) - l); + + if(l > 0) + { + str.append(size_type(l), '0'); + } + } + } + else + { + // Scientific format: + if(showpoint || (str.size() > 1)) + { + str.insert(1U, 1U, '.'); + } + + str.append(1U, 'e'); + + string_type e = std::to_string(std::abs(my_exp)); + + if(e.size() < 2U) + { + e.insert(0U, 2U - e.size(), '0'); + } + + if(my_exp < 0) + { + e.insert(0U, 1U, '-'); + } + else + { + e.insert(0U, 1U, '+'); + } + + str.append(e); + } + + if(b_neg) + { + str.insert(0U, 1U, '-'); + } + else if(showpos) + { + str.insert(0U, 1U, '+'); + } + } + + template inline void eval_convert_to(type_a* pa, const float_type& cb) { *pa = static_cast(cb); } + template inline void eval_add (float_type& b, const type_a& a) { b += a; } + template inline void eval_subtract (float_type& b, const type_a& a) { b -= a; } + template inline void eval_multiply (float_type& b, const type_a& a) { b *= a; } + template inline void eval_multiply (float_type& b, const float_type& cb, const float_type& cb2) { b = (cb * cb2); } + template inline void eval_divide (float_type& b, const type_a& a) { b /= a; } + template inline void eval_log10 (float_type& b, const float_type& cb) { b = std::log10(cb); } + template inline void eval_floor (float_type& b, const float_type& cb) { b = std::floor(cb); } + + inline void round_string_up_at(std::string& s, int pos, int& expon) + { + // This subroutine rounds up a string representation of a + // number at the given position pos. + + if(pos < 0) + { + s.insert(0U, 1U, '1'); + s.erase(s.size() - 1U); + ++expon; + } + else if(s[pos] == '9') + { + s[pos] = '0'; + round_string_up_at(s, pos - 1, expon); + } + else + { + if((pos == 0) && (s[pos] == '0') && (s.size() == 1)) + { + ++expon; + } + + ++s[pos]; + } + } + + template + std::string convert_to_string(float_type& x, + std::streamsize digits, + const std::ios_base::fmtflags f) + { + const bool isneg = (x < 0); + const bool iszero = ((!isneg) ? bool(+x < (std::numeric_limits::min)()) + : bool(-x < (std::numeric_limits::min)())); + const bool isnan = (x != x); + const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits::max)()) + : bool(-x > (std::numeric_limits::max)())); + + int expon = 0; + + if(digits <= 0) { digits = std::numeric_limits::max_digits10; } + + const int org_digits = static_cast(digits); + + std::string result; + + if(iszero) + { + result = "0"; + } + else if(isinf) + { + if(x < 0) + { + return "-inf"; + } + else + { + return ((f & std::ios_base::showpos) == std::ios_base::showpos) ? "+inf" : "inf"; + } + } + else if(isnan) + { + return "nan"; + } + else + { + // Start by figuring out the base-10 exponent. + if(isneg) { x = -x; } + + float_type t; + float_type ten = 10; + + eval_log10(t, x); + eval_floor(t, t); + eval_convert_to(&expon, t); + + if(-expon > std::numeric_limits::max_exponent10 - 3) + { + int e = -expon / 2; + + const float_type t2 = boost::math::cstdfloat::detail::pown(ten, e); + + eval_multiply(t, t2, x); + eval_multiply(t, t2); + + if((expon & 1) != 0) + { + eval_multiply(t, ten); + } + } + else + { + t = boost::math::cstdfloat::detail::pown(ten, -expon); + eval_multiply(t, x); + } + + // Make sure that the value lies between [1, 10), and adjust if not. + if(t < 1) + { + eval_multiply(t, 10); + + --expon; + } + else if(t >= 10) + { + eval_divide(t, 10); + + ++expon; + } + + float_type digit; + int cdigit; + + // Adjust the number of digits required based on formatting options. + if(((f & std::ios_base::fixed) == std::ios_base::fixed) && (expon != -1)) + { + digits += (expon + 1); + } + + if((f & std::ios_base::scientific) == std::ios_base::scientific) + { + ++digits; + } + + // Extract the base-10 digits one at a time. + for(int i = 0; i < digits; ++i) + { + eval_floor(digit, t); + eval_convert_to(&cdigit, digit); + + result += static_cast('0' + cdigit); + + eval_subtract(t, digit); + eval_multiply(t, ten); + } + + // Possibly round the result. + if(digits >= 0) + { + eval_floor(digit, t); + eval_convert_to(&cdigit, digit); + eval_subtract(t, digit); + + if((cdigit == 5) && (t == 0)) + { + // Use simple bankers rounding. + + if((static_cast(*result.rbegin() - '0') & 1) != 0) + { + round_string_up_at(result, static_cast(result.size() - 1U), expon); + } + } + else if(cdigit >= 5) + { + round_string_up_at(result, static_cast(result.size() - 1), expon); + } + } + } + + while((result.size() > static_cast(digits)) && result.size()) + { + // We may get here as a result of rounding. + + if(result.size() > 1U) + { + result.erase(result.size() - 1U); + } + else + { + if(expon > 0) + { + --expon; // so we put less padding in the result. + } + else + { + ++expon; + } + + ++digits; + } + } + + if(isneg) + { + result.insert(0U, 1U, '-'); + } + + format_float_string(result, expon, org_digits, f, iszero); + + return result; + } + + template + bool convert_from_string(float_type& value, const char* p) + { + value = 0; + + if((p == static_cast(0U)) || (*p == static_cast(0))) + { + return; + } + + bool is_neg = false; + bool is_neg_expon = false; + + constexpr int ten = 10; + + int expon = 0; + int digits_seen = 0; + + constexpr int max_digits = std::numeric_limits::max_digits10 + 1; + + if(*p == static_cast('+')) + { + ++p; + } + else if(*p == static_cast('-')) + { + is_neg = true; + ++p; + } + + const bool isnan = ((std::strcmp(p, "nan") == 0) || (std::strcmp(p, "NaN") == 0) || (std::strcmp(p, "NAN") == 0)); + + if(isnan) + { + eval_divide(value, 0); + + if(is_neg) + { + value = -value; + } + + return true; + } + + const bool isinf = ((std::strcmp(p, "inf") == 0) || (std::strcmp(p, "Inf") == 0) || (std::strcmp(p, "INF") == 0)); + + if(isinf) + { + value = 1; + eval_divide(value, 0); + + if(is_neg) + { + value = -value; + } + + return true; + } + + // Grab all the leading digits before the decimal point. + while(std::isdigit(*p)) + { + eval_multiply(value, ten); + eval_add(value, static_cast(*p - '0')); + ++p; + ++digits_seen; + } + + if(*p == static_cast('.')) + { + // Grab everything after the point, stop when we've seen + // enough digits, even if there are actually more available. + + ++p; + + while(std::isdigit(*p)) + { + eval_multiply(value, ten); + eval_add(value, static_cast(*p - '0')); + ++p; + --expon; + + if(++digits_seen > max_digits) + { + break; + } + } + + while(std::isdigit(*p)) + { + ++p; + } + } + + // Parse the exponent. + if((*p == static_cast('e')) || (*p == static_cast('E'))) + { + ++p; + + if(*p == static_cast('+')) + { + ++p; + } + else if(*p == static_cast('-')) + { + is_neg_expon = true; + ++p; + } + + int e2 = 0; + + while(std::isdigit(*p)) + { + e2 *= 10; + e2 += (*p - '0'); + ++p; + } + + if(is_neg_expon) + { + e2 = -e2; + } + + expon += e2; + } + + if(expon) + { + // Scale by 10^expon. Note that 10^expon can be outside the range + // of our number type, even though the result is within range. + // If that looks likely, then split the calculation in two parts. + float_type t; + t = ten; + + if(expon > (std::numeric_limits::min_exponent10 + 2)) + { + t = boost::math::cstdfloat::detail::pown(t, expon); + eval_multiply(value, t); + } + else + { + t = boost::math::cstdfloat::detail::pown(t, (expon + digits_seen + 1)); + eval_multiply(value, t); + t = ten; + t = boost::math::cstdfloat::detail::pown(t, (-digits_seen - 1)); + eval_multiply(value, t); + } + } + + if(is_neg) + { + value = -value; + } + + return (*p == static_cast(0)); + } + } } } } // boost::math::cstdfloat::detail + + namespace std + { + template + inline std::basic_ostream& operator<<(std::basic_ostream& os, const boost::math::cstdfloat::detail::float_internal128_t& x) + { + boost::math::cstdfloat::detail::float_internal128_t non_const_x = x; + + const std::string str = boost::math::cstdfloat::detail::convert_to_string(non_const_x, + os.precision(), + os.flags()); + + std::basic_ostringstream ostr; + ostr.flags(os.flags()); + ostr.imbue(os.getloc()); + ostr.precision(os.precision()); + + static_cast(ostr << str); + + return (os << ostr.str()); + } + + template + inline std::basic_istream& operator>>(std::basic_istream& is, boost::math::cstdfloat::detail::float_internal128_t& x) + { + std::string str; + + static_cast(is >> str); + + const bool conversion_is_ok = boost::math::cstdfloat::detail::convert_from_string(x, str.c_str()); + + if(false == conversion_is_ok) + { + for(std::string::const_reverse_iterator it = str.rbegin(); it != str.rend(); ++it) + { + static_cast(is.putback(*it)); + } + + is.setstate(ios_base::failbit); + + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a boost::float128_t")); + } + + return is; + } + } + + #endif // Use __GNUC__ or __INTEL_COMPILER libquadmath + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_IOSTREAM_2014_02_15_HPP_ diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_limits.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_limits.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_limits.hpp @@ -0,0 +1,87 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement quadruple-precision std::numeric_limits<> support. + +#ifndef BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + #define BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + + #include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + #include + #include + + // Define the name of the global quadruple-precision function to be used for + // calculating quiet_NaN() in the specialization of std::numeric_limits<>. + #if defined(__INTEL_COMPILER) + #define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq + #elif defined(__GNUC__) + #define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq + #endif + + // Forward declaration of the quadruple-precision square root function. + extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) BOOST_MATH_NOTHROW; + + namespace std + { + template<> + class numeric_limits + { + public: + static constexpr bool is_specialized = true; + static boost::math::cstdfloat::detail::float_internal128_t (min) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MIN; } + static boost::math::cstdfloat::detail::float_internal128_t (max) () noexcept { return BOOST_CSTDFLOAT_FLOAT128_MAX; } + static boost::math::cstdfloat::detail::float_internal128_t lowest() noexcept { return -(max)(); } + static constexpr int digits = 113; + static constexpr int digits10 = 33; + static constexpr int max_digits10 = 36; + static constexpr bool is_signed = true; + static constexpr bool is_integer = false; + static constexpr bool is_exact = false; + static constexpr int radix = 2; + static boost::math::cstdfloat::detail::float_internal128_t epsilon () { return BOOST_CSTDFLOAT_FLOAT128_EPS; } + static boost::math::cstdfloat::detail::float_internal128_t round_error() { return BOOST_FLOAT128_C(0.5); } + static constexpr int min_exponent = -16381; + static constexpr int min_exponent10 = static_cast((min_exponent * 301L) / 1000L); + static constexpr int max_exponent = +16384; + static constexpr int max_exponent10 = static_cast((max_exponent * 301L) / 1000L); + static constexpr bool has_infinity = true; + static constexpr bool has_quiet_NaN = true; + static constexpr bool has_signaling_NaN = false; + static constexpr float_denorm_style has_denorm = denorm_present; + static constexpr bool has_denorm_loss = false; + static boost::math::cstdfloat::detail::float_internal128_t infinity () { return BOOST_FLOAT128_C(1.0) / BOOST_FLOAT128_C(0.0); } + static boost::math::cstdfloat::detail::float_internal128_t quiet_NaN () { return -(::BOOST_CSTDFLOAT_FLOAT128_SQRT(BOOST_FLOAT128_C(-1.0))); } + static boost::math::cstdfloat::detail::float_internal128_t signaling_NaN() { return BOOST_FLOAT128_C(0.0); } + static boost::math::cstdfloat::detail::float_internal128_t denorm_min () { return BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN; } + static constexpr bool is_iec559 = true; + static constexpr bool is_bounded = true; + static constexpr bool is_modulo = false; + static constexpr bool traps = false; + static constexpr bool tinyness_before = false; + static constexpr float_round_style round_style = round_to_nearest; + }; + } // namespace std + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + +#endif // BOOST_MATH_CSTDFLOAT_LIMITS_2014_01_09_HPP_ + diff --git a/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_types.hpp b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_types.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/cstdfloat/cstdfloat_types.hpp @@ -0,0 +1,441 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2014. +// Copyright John Maddock 2014. +// Copyright Paul Bristow 2014. +// Distributed under 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) +// + +// Implement the types for floating-point typedefs having specified widths. + +#ifndef BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ + #define BOOST_MATH_CSTDFLOAT_TYPES_2014_01_09_HPP_ + + #include + #include + #include + + // This is the beginning of the preamble. + + // In this preamble, the preprocessor is used to query certain + // preprocessor definitions from . Based on the results + // of these queries, an attempt is made to automatically detect + // the presence of built-in floating-point types having specified + // widths. These are *thought* to be conformant with IEEE-754, + // whereby an unequivocal test based on std::numeric_limits<> + // follows below. + + // In addition, various macros that are used for initializing + // floating-point literal values having specified widths and + // some basic min/max values are defined. + + // First, we will pre-load certain preprocessor definitions + // with a dummy value. + + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 0 + + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 + + // Ensure that the compiler has a radix-2 floating-point representation. + #if (!defined(FLT_RADIX) || ((defined(FLT_RADIX) && (FLT_RADIX != 2)))) + #error The compiler does not support any radix-2 floating-point types required for . + #endif + + // Check if built-in float is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(FLT_MANT_DIG) && defined(FLT_MAX_EXP)) + #if ((FLT_MANT_DIG == 11) && (FLT_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX FLT_MAX + #elif((FLT_MANT_DIG == 24) && (FLT_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX FLT_MAX + #elif((FLT_MANT_DIG == 53) && (FLT_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX FLT_MAX + #elif((FLT_MANT_DIG == 64) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX FLT_MAX + #elif((FLT_MANT_DIG == 113) && (FLT_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## F) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN FLT_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX FLT_MAX + #endif + #endif + + // Check if built-in double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(DBL_MANT_DIG) && defined(DBL_MAX_EXP)) + #if ((DBL_MANT_DIG == 11) && (DBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX DBL_MAX + #elif((DBL_MANT_DIG == 24) && (DBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX DBL_MAX + #elif((DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX DBL_MAX + #elif((DBL_MANT_DIG == 64) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX DBL_MAX + #elif((DBL_MANT_DIG == 113) && (DBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN DBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX DBL_MAX + #endif + #endif + + // Disable check long double capability even if supported by compiler since some math runtime + // implementations are broken for long double. + #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + // Check if built-in long double is equivalent to float16_t, float32_t, float64_t, float80_t, or float128_t. + #if(defined(LDBL_MANT_DIG) && defined(LDBL_MAX_EXP)) + #if ((LDBL_MANT_DIG == 11) && (LDBL_MAX_EXP == 16) && (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 16 + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE 1 + #define BOOST_FLOAT16_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_16_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_16_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 24) && (LDBL_MAX_EXP == 128) && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 32 + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE 1 + #define BOOST_FLOAT32_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_32_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_32_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024) && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE 1 + #define BOOST_FLOAT64_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_64_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_64_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 64) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 80 + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 1 + #define BOOST_FLOAT80_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_80_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_80_MAX LDBL_MAX + #elif((LDBL_MANT_DIG == 113) && (LDBL_MAX_EXP == 16384) && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE long double + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## L) + #define BOOST_CSTDFLOAT_FLOAT_128_MIN LDBL_MIN + #define BOOST_CSTDFLOAT_FLOAT_128_MAX LDBL_MAX + #endif + #endif + #endif + + // Check if quadruple-precision is supported. Here, we are checking + // for the presence of __float128 from GCC's quadmath.h or _Quad + // from ICC's /Qlong-double flag). To query these, we use the + // BOOST_MATH_USE_FLOAT128 pre-processor definition from + // . + + #if (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + + // Specify the underlying name of the internal 128-bit floating-point type definition. + namespace boost { namespace math { namespace cstdfloat { namespace detail { + #if defined(__GNUC__) + typedef __float128 float_internal128_t; + #elif defined(__INTEL_COMPILER) + typedef _Quad float_internal128_t; + #else + #error "Sorry, the compiler is neither GCC, nor Intel, I don't know how to configure ." + #endif + } } } } // boost::math::cstdfloat::detail + + #define BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE boost::math::cstdfloat::detail::float_internal128_t + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + #define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 128 + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + #define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 1 + #define BOOST_FLOAT128_C(x) (x ## Q) + #define BOOST_CSTDFLOAT_FLOAT128_MIN 3.36210314311209350626267781732175260e-4932Q + #define BOOST_CSTDFLOAT_FLOAT128_MAX 1.18973149535723176508575932662800702e+4932Q + #define BOOST_CSTDFLOAT_FLOAT128_EPS 1.92592994438723585305597794258492732e-0034Q + #define BOOST_CSTDFLOAT_FLOAT128_DENORM_MIN 6.475175119438025110924438958227646552e-4966Q + + #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support) + + // This is the end of the preamble, and also the end of the + // sections providing support for the C++ standard library + // for quadruple-precision. + + // Now we use the results of the queries that have been obtained + // in the preamble (far above) for the final type definitions in + // the namespace boost. + + // Make sure that the compiler has any floating-point type(s) whatsoever. + #if ( (BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 0) \ + && (BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 0)) + #error The compiler does not support any of the floating-point types required for . + #endif + + // The following section contains the various min/max macros + // for the *leastN and *fastN types. + + #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOAT_LEAST16_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOAT_FAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #define BOOST_FLOAT_LEAST16_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOAT_LEAST32_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOAT_FAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #define BOOST_FLOAT_LEAST32_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOAT_LEAST64_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOAT_FAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #define BOOST_FLOAT_LEAST64_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) + #define BOOST_FLOAT_FAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOAT_LEAST80_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOAT_FAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #define BOOST_FLOAT_LEAST80_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) + #define BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T + + #define BOOST_FLOAT_FAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOAT_LEAST128_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOAT_FAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #define BOOST_FLOAT_LEAST128_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #endif + + // The following section contains the various min/max macros + // for the *floatmax types. + + #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT16_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_16_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_16_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT32_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_32_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_32_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT64_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_64_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_64_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT80_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_80_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_80_MAX + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) + #define BOOST_FLOATMAX_C(x) BOOST_FLOAT128_C(x) + #define BOOST_FLOATMAX_MIN BOOST_CSTDFLOAT_FLOAT_128_MIN + #define BOOST_FLOATMAX_MAX BOOST_CSTDFLOAT_FLOAT_128_MAX + #else + #error The maximum available floating-point width for is undefined. + #endif + + // And finally..., we define the floating-point typedefs having + // specified widths. The types are defined in the namespace boost. + + // For simplicity, the least and fast types are type defined identically + // as the corresponding fixed-width type. This behavior may, however, + // be modified when being optimized for a given compiler implementation. + + // In addition, a clear assessment of IEEE-754 conformance is carried out + // using compile-time assertion. + + namespace boost + { + #if(BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE float16_t; + typedef boost::float16_t float_fast16_t; + typedef boost::float16_t float_least16_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 11, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16, "boost::float16_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_16_MIN + #undef BOOST_CSTDFLOAT_FLOAT_16_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE float32_t; + typedef boost::float32_t float_fast32_t; + typedef boost::float32_t float_least32_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 24, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 128, "boost::float32_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_32_MIN + #undef BOOST_CSTDFLOAT_FLOAT_32_MAX + #endif + +#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && defined(__SUNPRO_CC) +#undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE +#define BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE 0 +#undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE +#define BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE 0 +#undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH +#define BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH 64 +#endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE float64_t; + typedef boost::float64_t float_fast64_t; + typedef boost::float64_t float_least64_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 53, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 1024, "boost::float64_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_64_MIN + #undef BOOST_CSTDFLOAT_FLOAT_64_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE float80_t; + typedef boost::float80_t float_fast80_t; + typedef boost::float80_t float_least80_t; + + static_assert(std::numeric_limits::is_iec559 == true, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 64, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16384, "boost::float80_t has been detected in , but verification with std::numeric_limits fails"); + + #undef BOOST_CSTDFLOAT_FLOAT_80_MIN + #undef BOOST_CSTDFLOAT_FLOAT_80_MAX + #endif + + #if(BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE == 1) + typedef BOOST_CSTDFLOAT_FLOAT128_NATIVE_TYPE float128_t; + typedef boost::float128_t float_fast128_t; + typedef boost::float128_t float_least128_t; + + #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT) + // This configuration does not *yet* support std::numeric_limits. + // Support for std::numeric_limits is added in the detail + // file . + #else + static_assert(std::numeric_limits::is_iec559 == true, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::radix == 2, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::digits == 113, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + static_assert(std::numeric_limits::max_exponent == 16384, "boost::float128_t has been detected in , but verification with std::numeric_limits fails"); + #endif + + #undef BOOST_CSTDFLOAT_FLOAT_128_MIN + #undef BOOST_CSTDFLOAT_FLOAT_128_MAX + #endif + + #if (BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 16) + typedef boost::float16_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 32) + typedef boost::float32_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 64) + typedef boost::float64_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 80) + typedef boost::float80_t floatmax_t; + #elif(BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH == 128) + typedef boost::float128_t floatmax_t; + #else + #error The maximum available floating-point width for is undefined. + #endif + + #undef BOOST_CSTDFLOAT_HAS_FLOAT16_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT32_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT64_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT80_NATIVE_TYPE + #undef BOOST_CSTDFLOAT_HAS_FLOAT128_NATIVE_TYPE + + #undef BOOST_CSTDFLOAT_MAXIMUM_AVAILABLE_WIDTH + } + // namespace boost + +#endif // BOOST_MATH_CSTDFLOAT_BASE_TYPES_2014_01_09_HPP_ + diff --git a/libcxx/src/third-party/boost/math/differentiation/autodiff.hpp b/libcxx/src/third-party/boost/math/differentiation/autodiff.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/differentiation/autodiff.hpp @@ -0,0 +1,2061 @@ +// Copyright Matthew Pulver 2018 - 2019. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP +#define BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace differentiation { +// Automatic Differentiation v1 +inline namespace autodiff_v1 { +namespace detail { + +template +struct promote_args_n { + using type = typename tools::promote_args_2::type>::type; +}; + +template +struct promote_args_n { + using type = typename tools::promote_arg::type; +}; + +} // namespace detail + +template +using promote = typename detail::promote_args_n::type; + +namespace detail { + +template +class fvar; + +template +struct is_fvar_impl : std::false_type {}; + +template +struct is_fvar_impl> : std::true_type {}; + +template +using is_fvar = is_fvar_impl::type>; + +template +struct nest_fvar { + using type = fvar::type, Order>; +}; + +template +struct nest_fvar { + using type = fvar; +}; + +template +struct get_depth_impl : std::integral_constant {}; + +template +struct get_depth_impl> + : std::integral_constant::value + 1> {}; + +template +using get_depth = get_depth_impl::type>; + +template +struct get_order_sum_t : std::integral_constant {}; + +template +struct get_order_sum_t> + : std::integral_constant::value + Order> {}; + +template +using get_order_sum = get_order_sum_t::type>; + +template +struct get_root_type { + using type = RealType; +}; + +template +struct get_root_type> { + using type = typename get_root_type::type; +}; + +template +struct type_at { + using type = RealType; +}; + +template +struct type_at, Depth> { + using type = typename std::conditional, + typename type_at::type>::type; +}; + +template +using get_type_at = typename type_at::type; + +// Satisfies Boost's Conceptual Requirements for Real Number Types. +// https://www.boost.org/libs/math/doc/html/math_toolkit/real_concepts.html +template +class fvar { + protected: + std::array v; + + public: + using root_type = typename get_root_type::type; // RealType in the root fvar. + + fvar() = default; + + // Initialize a variable or constant. + fvar(root_type const&, bool const is_variable); + + // RealType(cr) | RealType | RealType is copy constructible. + fvar(fvar const&) = default; + + // Be aware of implicit casting from one fvar<> type to another by this copy constructor. + template + fvar(fvar const&); + + // RealType(ca) | RealType | RealType is copy constructible from the arithmetic types. + explicit fvar(root_type const&); // Initialize a constant. (No epsilon terms.) + + template + fvar(RealType2 const& ca); // Supports any RealType2 for which static_cast(ca) compiles. + + // r = cr | RealType& | Assignment operator. + fvar& operator=(fvar const&) = default; + + // r = ca | RealType& | Assignment operator from the arithmetic types. + // Handled by constructor that takes a single parameter of generic type. + // fvar& operator=(root_type const&); // Set a constant. + + // r += cr | RealType& | Adds cr to r. + template + fvar& operator+=(fvar const&); + + // r += ca | RealType& | Adds ar to r. + fvar& operator+=(root_type const&); + + // r -= cr | RealType& | Subtracts cr from r. + template + fvar& operator-=(fvar const&); + + // r -= ca | RealType& | Subtracts ca from r. + fvar& operator-=(root_type const&); + + // r *= cr | RealType& | Multiplies r by cr. + template + fvar& operator*=(fvar const&); + + // r *= ca | RealType& | Multiplies r by ca. + fvar& operator*=(root_type const&); + + // r /= cr | RealType& | Divides r by cr. + template + fvar& operator/=(fvar const&); + + // r /= ca | RealType& | Divides r by ca. + fvar& operator/=(root_type const&); + + // -r | RealType | Unary Negation. + fvar operator-() const; + + // +r | RealType& | Identity Operation. + fvar const& operator+() const; + + // cr + cr2 | RealType | Binary Addition + template + promote> operator+(fvar const&) const; + + // cr + ca | RealType | Binary Addition + fvar operator+(root_type const&) const; + + // ca + cr | RealType | Binary Addition + template + friend fvar operator+(typename fvar::root_type const&, + fvar const&); + + // cr - cr2 | RealType | Binary Subtraction + template + promote> operator-(fvar const&) const; + + // cr - ca | RealType | Binary Subtraction + fvar operator-(root_type const&) const; + + // ca - cr | RealType | Binary Subtraction + template + friend fvar operator-(typename fvar::root_type const&, + fvar const&); + + // cr * cr2 | RealType | Binary Multiplication + template + promote> operator*(fvar const&)const; + + // cr * ca | RealType | Binary Multiplication + fvar operator*(root_type const&)const; + + // ca * cr | RealType | Binary Multiplication + template + friend fvar operator*(typename fvar::root_type const&, + fvar const&); + + // cr / cr2 | RealType | Binary Subtraction + template + promote> operator/(fvar const&) const; + + // cr / ca | RealType | Binary Subtraction + fvar operator/(root_type const&) const; + + // ca / cr | RealType | Binary Subtraction + template + friend fvar operator/(typename fvar::root_type const&, + fvar const&); + + // For all comparison overloads, only the root term is compared. + + // cr == cr2 | bool | Equality Comparison + template + bool operator==(fvar const&) const; + + // cr == ca | bool | Equality Comparison + bool operator==(root_type const&) const; + + // ca == cr | bool | Equality Comparison + template + friend bool operator==(typename fvar::root_type const&, fvar const&); + + // cr != cr2 | bool | Inequality Comparison + template + bool operator!=(fvar const&) const; + + // cr != ca | bool | Inequality Comparison + bool operator!=(root_type const&) const; + + // ca != cr | bool | Inequality Comparison + template + friend bool operator!=(typename fvar::root_type const&, fvar const&); + + // cr <= cr2 | bool | Less than equal to. + template + bool operator<=(fvar const&) const; + + // cr <= ca | bool | Less than equal to. + bool operator<=(root_type const&) const; + + // ca <= cr | bool | Less than equal to. + template + friend bool operator<=(typename fvar::root_type const&, fvar const&); + + // cr >= cr2 | bool | Greater than equal to. + template + bool operator>=(fvar const&) const; + + // cr >= ca | bool | Greater than equal to. + bool operator>=(root_type const&) const; + + // ca >= cr | bool | Greater than equal to. + template + friend bool operator>=(typename fvar::root_type const&, fvar const&); + + // cr < cr2 | bool | Less than comparison. + template + bool operator<(fvar const&) const; + + // cr < ca | bool | Less than comparison. + bool operator<(root_type const&) const; + + // ca < cr | bool | Less than comparison. + template + friend bool operator<(typename fvar::root_type const&, fvar const&); + + // cr > cr2 | bool | Greater than comparison. + template + bool operator>(fvar const&) const; + + // cr > ca | bool | Greater than comparison. + bool operator>(root_type const&) const; + + // ca > cr | bool | Greater than comparison. + template + friend bool operator>(typename fvar::root_type const&, fvar const&); + + // Will throw std::out_of_range if Order < order. + template + get_type_at at(size_t order, Orders... orders) const; + + template + get_type_at derivative(Orders... orders) const; + + const RealType& operator[](size_t) const; + + fvar inverse() const; // Multiplicative inverse. + + fvar& negate(); // Negate and return reference to *this. + + static constexpr size_t depth = get_depth::value; // Number of nested std::array. + + static constexpr size_t order_sum = get_order_sum::value; + + explicit operator root_type() const; // Must be explicit, otherwise overloaded operators are ambiguous. + + template ::type>::value>> + explicit operator T() const; // Must be explicit; multiprecision has trouble without the std::enable_if + + fvar& set_root(root_type const&); + + // Apply coefficients using horner method. + template + promote, Fvar, Fvars...> apply_coefficients(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_coefficients(size_t const order, Func const& f) const; + + // Use when function returns derivative(i)/factorial(i) and may have some infinite derivatives. + template + promote, Fvar, Fvars...> apply_coefficients_nonhorner(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_coefficients_nonhorner(size_t const order, Func const& f) const; + + // Apply derivatives using horner method. + template + promote, Fvar, Fvars...> apply_derivatives(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_derivatives(size_t const order, Func const& f) const; + + // Use when function returns derivative(i) and may have some infinite derivatives. + template + promote, Fvar, Fvars...> apply_derivatives_nonhorner(size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const; + + template + fvar apply_derivatives_nonhorner(size_t const order, Func const& f) const; + + private: + RealType epsilon_inner_product(size_t z0, + size_t isum0, + size_t m0, + fvar const& cr, + size_t z1, + size_t isum1, + size_t m1, + size_t j) const; + + fvar epsilon_multiply(size_t z0, size_t isum0, fvar const& cr, size_t z1, size_t isum1) const; + + fvar epsilon_multiply(size_t z0, size_t isum0, root_type const& ca) const; + + fvar inverse_apply() const; + + fvar& multiply_assign_by_root_type(bool is_root, root_type const&); + + template + friend class fvar; + + template + friend std::ostream& operator<<(std::ostream&, fvar const&); + + // C++11 Compatibility +#ifdef BOOST_NO_CXX17_IF_CONSTEXPR + template + void fvar_cpp11(std::true_type, RootType const& ca, bool const is_variable); + + template + void fvar_cpp11(std::false_type, RootType const& ca, bool const is_variable); + + template + get_type_at at_cpp11(std::true_type, size_t order, Orders... orders) const; + + template + get_type_at at_cpp11(std::false_type, size_t order, Orders... orders) const; + + template + fvar epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const; + + template + fvar epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const; + + template + fvar epsilon_multiply_cpp11(std::true_type, SizeType z0, size_t isum0, root_type const& ca) const; + + template + fvar epsilon_multiply_cpp11(std::false_type, SizeType z0, size_t isum0, root_type const& ca) const; + + template + fvar& multiply_assign_by_root_type_cpp11(std::true_type, bool is_root, RootType const& ca); + + template + fvar& multiply_assign_by_root_type_cpp11(std::false_type, bool is_root, RootType const& ca); + + template + fvar& negate_cpp11(std::true_type, RootType const&); + + template + fvar& negate_cpp11(std::false_type, RootType const&); + + template + fvar& set_root_cpp11(std::true_type, RootType const& root); + + template + fvar& set_root_cpp11(std::false_type, RootType const& root); +#endif +}; + +// Standard Library Support Requirements + +// fabs(cr1) | RealType +template +fvar fabs(fvar const&); + +// abs(cr1) | RealType +template +fvar abs(fvar const&); + +// ceil(cr1) | RealType +template +fvar ceil(fvar const&); + +// floor(cr1) | RealType +template +fvar floor(fvar const&); + +// exp(cr1) | RealType +template +fvar exp(fvar const&); + +// pow(cr, ca) | RealType +template +fvar pow(fvar const&, typename fvar::root_type const&); + +// pow(ca, cr) | RealType +template +fvar pow(typename fvar::root_type const&, fvar const&); + +// pow(cr1, cr2) | RealType +template +promote, fvar> pow(fvar const&, + fvar const&); + +// sqrt(cr1) | RealType +template +fvar sqrt(fvar const&); + +// log(cr1) | RealType +template +fvar log(fvar const&); + +// frexp(cr1, &i) | RealType +template +fvar frexp(fvar const&, int*); + +// ldexp(cr1, i) | RealType +template +fvar ldexp(fvar const&, int); + +// cos(cr1) | RealType +template +fvar cos(fvar const&); + +// sin(cr1) | RealType +template +fvar sin(fvar const&); + +// asin(cr1) | RealType +template +fvar asin(fvar const&); + +// tan(cr1) | RealType +template +fvar tan(fvar const&); + +// atan(cr1) | RealType +template +fvar atan(fvar const&); + +// atan2(cr, ca) | RealType +template +fvar atan2(fvar const&, typename fvar::root_type const&); + +// atan2(ca, cr) | RealType +template +fvar atan2(typename fvar::root_type const&, fvar const&); + +// atan2(cr1, cr2) | RealType +template +promote, fvar> atan2(fvar const&, + fvar const&); + +// fmod(cr1,cr2) | RealType +template +promote, fvar> fmod(fvar const&, + fvar const&); + +// round(cr1) | RealType +template +fvar round(fvar const&); + +// iround(cr1) | int +template +int iround(fvar const&); + +template +long lround(fvar const&); + +template +long long llround(fvar const&); + +// trunc(cr1) | RealType +template +fvar trunc(fvar const&); + +template +long double truncl(fvar const&); + +// itrunc(cr1) | int +template +int itrunc(fvar const&); + +template +long long lltrunc(fvar const&); + +// Additional functions +template +fvar acos(fvar const&); + +template +fvar acosh(fvar const&); + +template +fvar asinh(fvar const&); + +template +fvar atanh(fvar const&); + +template +fvar cosh(fvar const&); + +template +fvar digamma(fvar const&); + +template +fvar erf(fvar const&); + +template +fvar erfc(fvar const&); + +template +fvar lambert_w0(fvar const&); + +template +fvar lgamma(fvar const&); + +template +fvar sinc(fvar const&); + +template +fvar sinh(fvar const&); + +template +fvar tanh(fvar const&); + +template +fvar tgamma(fvar const&); + +template +struct zero : std::integral_constant {}; + +} // namespace detail + +template +using autodiff_fvar = typename detail::nest_fvar::type; + +template +autodiff_fvar make_fvar(RealType const& ca) { + return autodiff_fvar(ca, true); +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +namespace detail { + +template +auto make_fvar_for_tuple(std::index_sequence, RealType const& ca) { + return make_fvar::value..., Order>(ca); +} + +template +auto make_ftuple_impl(std::index_sequence, RealTypes const&... ca) { + return std::make_tuple(make_fvar_for_tuple(std::make_index_sequence{}, ca)...); +} + +} // namespace detail + +template +auto make_ftuple(RealTypes const&... ca) { + static_assert(sizeof...(Orders) == sizeof...(RealTypes), + "Number of Orders must match number of function parameters."); + return detail::make_ftuple_impl(std::index_sequence_for{}, ca...); +} +#endif + +namespace detail { + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +template +fvar::fvar(root_type const& ca, bool const is_variable) { + if constexpr (is_fvar::value) { + v.front() = RealType(ca, is_variable); + if constexpr (0 < Order) + std::fill(v.begin() + 1, v.end(), static_cast(0)); + } else { + v.front() = ca; + if constexpr (0 < Order) + v[1] = static_cast(static_cast(is_variable)); + if constexpr (1 < Order) + std::fill(v.begin() + 2, v.end(), static_cast(0)); + } +} +#endif + +template +template +fvar::fvar(fvar const& cr) { + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + v[i] = static_cast(cr.v[i]); + BOOST_IF_CONSTEXPR (Order2 < Order) + std::fill(v.begin() + (Order2 + 1), v.end(), static_cast(0)); +} + +template +fvar::fvar(root_type const& ca) : v{{static_cast(ca)}} {} + +// Can cause compiler error if RealType2 cannot be cast to root_type. +template +template +fvar::fvar(RealType2 const& ca) : v{{static_cast(ca)}} {} + +/* +template +fvar& fvar::operator=(root_type const& ca) +{ + v.front() = static_cast(ca); + if constexpr (0 < Order) + std::fill(v.begin()+1, v.end(), static_cast(0)); + return *this; +} +*/ + +template +template +fvar& fvar::operator+=(fvar const& cr) { + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + v[i] += cr.v[i]; + return *this; +} + +template +fvar& fvar::operator+=(root_type const& ca) { + v.front() += ca; + return *this; +} + +template +template +fvar& fvar::operator-=(fvar const& cr) { + for (size_t i = 0; i <= Order; ++i) + v[i] -= cr.v[i]; + return *this; +} + +template +fvar& fvar::operator-=(root_type const& ca) { + v.front() -= ca; + return *this; +} + +template +template +fvar& fvar::operator*=(fvar const& cr) { + using diff_t = typename std::array::difference_type; + promote const zero(0); + BOOST_IF_CONSTEXPR (Order <= Order2) + for (size_t i = 0, j = Order; i <= Order; ++i, --j) + v[j] = std::inner_product(v.cbegin(), v.cend() - diff_t(i), cr.v.crbegin() + diff_t(i), zero); + else { + for (size_t i = 0, j = Order; i <= Order - Order2; ++i, --j) + v[j] = std::inner_product(cr.v.cbegin(), cr.v.cend(), v.crbegin() + diff_t(i), zero); + for (size_t i = Order - Order2 + 1, j = Order2 - 1; i <= Order; ++i, --j) + v[j] = std::inner_product(cr.v.cbegin(), cr.v.cbegin() + diff_t(j + 1), v.crbegin() + diff_t(i), zero); + } + return *this; +} + +template +fvar& fvar::operator*=(root_type const& ca) { + return multiply_assign_by_root_type(true, ca); +} + +template +template +fvar& fvar::operator/=(fvar const& cr) { + using diff_t = typename std::array::difference_type; + RealType const zero(0); + v.front() /= cr.v.front(); + BOOST_IF_CONSTEXPR (Order < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, --j, --k) + (v[i] -= std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); + else BOOST_IF_CONSTEXPR (0 < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) + (v[i] -= std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero)) /= cr.v.front(); + else + for (size_t i = 1; i <= Order; ++i) + v[i] /= cr.v.front(); + return *this; +} + +template +fvar& fvar::operator/=(root_type const& ca) { + std::for_each(v.begin(), v.end(), [&ca](RealType& x) { x /= ca; }); + return *this; +} + +template +fvar fvar::operator-() const { + fvar retval(*this); + retval.negate(); + return retval; +} + +template +fvar const& fvar::operator+() const { + return *this; +} + +template +template +promote, fvar> fvar::operator+( + fvar const& cr) const { + promote, fvar> retval; + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + retval.v[i] = v[i] + cr.v[i]; + BOOST_IF_CONSTEXPR (Order < Order2) + for (size_t i = Order + 1; i <= Order2; ++i) + retval.v[i] = cr.v[i]; + else BOOST_IF_CONSTEXPR (Order2 < Order) + for (size_t i = Order2 + 1; i <= Order; ++i) + retval.v[i] = v[i]; + return retval; +} + +template +fvar fvar::operator+(root_type const& ca) const { + fvar retval(*this); + retval.v.front() += ca; + return retval; +} + +template +fvar operator+(typename fvar::root_type const& ca, + fvar const& cr) { + return cr + ca; +} + +template +template +promote, fvar> fvar::operator-( + fvar const& cr) const { + promote, fvar> retval; + for (size_t i = 0; i <= (std::min)(Order, Order2); ++i) + retval.v[i] = v[i] - cr.v[i]; + BOOST_IF_CONSTEXPR (Order < Order2) + for (auto i = Order + 1; i <= Order2; ++i) + retval.v[i] = -cr.v[i]; + else BOOST_IF_CONSTEXPR (Order2 < Order) + for (auto i = Order2 + 1; i <= Order; ++i) + retval.v[i] = v[i]; + return retval; +} + +template +fvar fvar::operator-(root_type const& ca) const { + fvar retval(*this); + retval.v.front() -= ca; + return retval; +} + +template +fvar operator-(typename fvar::root_type const& ca, + fvar const& cr) { + fvar mcr = -cr; // Has same address as retval in operator-() due to NRVO. + mcr += ca; + return mcr; // <-- This allows for NRVO. The following does not. --> return mcr += ca; +} + +template +template +promote, fvar> fvar::operator*( + fvar const& cr) const { + using diff_t = typename std::array::difference_type; + promote const zero(0); + promote, fvar> retval; + BOOST_IF_CONSTEXPR (Order < Order2) + for (size_t i = 0, j = Order, k = Order2; i <= Order2; ++i, j && --j, --k) + retval.v[i] = std::inner_product(v.cbegin(), v.cend() - diff_t(j), cr.v.crbegin() + diff_t(k), zero); + else + for (size_t i = 0, j = Order2, k = Order; i <= Order; ++i, j && --j, --k) + retval.v[i] = std::inner_product(cr.v.cbegin(), cr.v.cend() - diff_t(j), v.crbegin() + diff_t(k), zero); + return retval; +} + +template +fvar fvar::operator*(root_type const& ca) const { + fvar retval(*this); + retval *= ca; + return retval; +} + +template +fvar operator*(typename fvar::root_type const& ca, + fvar const& cr) { + return cr * ca; +} + +template +template +promote, fvar> fvar::operator/( + fvar const& cr) const { + using diff_t = typename std::array::difference_type; + promote const zero(0); + promote, fvar> retval; + retval.v.front() = v.front() / cr.v.front(); + BOOST_IF_CONSTEXPR (Order < Order2) { + for (size_t i = 1, j = Order2 - 1; i <= Order; ++i, --j) + retval.v[i] = + (v[i] - std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero)) / + cr.v.front(); + for (size_t i = Order + 1, j = Order2 - Order - 1; i <= Order2; ++i, --j) + retval.v[i] = + -std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero) / + cr.v.front(); + } else BOOST_IF_CONSTEXPR (0 < Order2) + for (size_t i = 1, j = Order2 - 1, k = Order; i <= Order; ++i, j && --j, --k) + retval.v[i] = + (v[i] - std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(k), zero)) / + cr.v.front(); + else + for (size_t i = 1; i <= Order; ++i) + retval.v[i] = v[i] / cr.v.front(); + return retval; +} + +template +fvar fvar::operator/(root_type const& ca) const { + fvar retval(*this); + retval /= ca; + return retval; +} + +template +fvar operator/(typename fvar::root_type const& ca, + fvar const& cr) { + using diff_t = typename std::array::difference_type; + fvar retval; + retval.v.front() = ca / cr.v.front(); + BOOST_IF_CONSTEXPR (0 < Order) { + RealType const zero(0); + for (size_t i = 1, j = Order - 1; i <= Order; ++i, --j) + retval.v[i] = + -std::inner_product( + cr.v.cbegin() + 1, cr.v.cend() - diff_t(j), retval.v.crbegin() + diff_t(j + 1), zero) / + cr.v.front(); + } + return retval; +} + +template +template +bool fvar::operator==(fvar const& cr) const { + return v.front() == cr.v.front(); +} + +template +bool fvar::operator==(root_type const& ca) const { + return v.front() == ca; +} + +template +bool operator==(typename fvar::root_type const& ca, fvar const& cr) { + return ca == cr.v.front(); +} + +template +template +bool fvar::operator!=(fvar const& cr) const { + return v.front() != cr.v.front(); +} + +template +bool fvar::operator!=(root_type const& ca) const { + return v.front() != ca; +} + +template +bool operator!=(typename fvar::root_type const& ca, fvar const& cr) { + return ca != cr.v.front(); +} + +template +template +bool fvar::operator<=(fvar const& cr) const { + return v.front() <= cr.v.front(); +} + +template +bool fvar::operator<=(root_type const& ca) const { + return v.front() <= ca; +} + +template +bool operator<=(typename fvar::root_type const& ca, fvar const& cr) { + return ca <= cr.v.front(); +} + +template +template +bool fvar::operator>=(fvar const& cr) const { + return v.front() >= cr.v.front(); +} + +template +bool fvar::operator>=(root_type const& ca) const { + return v.front() >= ca; +} + +template +bool operator>=(typename fvar::root_type const& ca, fvar const& cr) { + return ca >= cr.v.front(); +} + +template +template +bool fvar::operator<(fvar const& cr) const { + return v.front() < cr.v.front(); +} + +template +bool fvar::operator<(root_type const& ca) const { + return v.front() < ca; +} + +template +bool operator<(typename fvar::root_type const& ca, fvar const& cr) { + return ca < cr.v.front(); +} + +template +template +bool fvar::operator>(fvar const& cr) const { + return v.front() > cr.v.front(); +} + +template +bool fvar::operator>(root_type const& ca) const { + return v.front() > ca; +} + +template +bool operator>(typename fvar::root_type const& ca, fvar const& cr) { + return ca > cr.v.front(); +} + + /*** Other methods and functions ***/ + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order)/factorial(order) +// Use this when you have the polynomial coefficients, rather than just the derivatives. E.g. See atan2(). +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = (std::min)(order, order_sum); + promote, Fvar, Fvars...> accumulator = cr.apply_coefficients( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...); + while (i--) + (accumulator *= epsilon) += cr.apply_coefficients( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...); + return accumulator; +} +#endif + +// f : order -> derivative(order)/factorial(order) +// Use this when you have the polynomial coefficients, rather than just the derivatives. E.g. See atan(). +template +template +fvar fvar::apply_coefficients(size_t const order, Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + size_t i = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t i = order < order_sum ? order : order_sum; +#endif + fvar accumulator = f(i); + while (i--) + (accumulator *= epsilon) += f(i); + return accumulator; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + promote, Fvar, Fvars...> accumulator = cr.apply_coefficients_nonhorner( + order, + [&f](auto... indices) { return f(0, static_cast(indices)...); }, + std::forward(fvars)...); + size_t const i_max = (std::min)(order, order_sum); + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_coefficients_nonhorner( + order - i, + [&f, i](auto... indices) { return f(i, static_cast(indices)...); }, + std::forward(fvars)...), + 0, + 0); + } + return accumulator; +} +#endif + +// f : order -> coefficient(order) +template +template +fvar fvar::apply_coefficients_nonhorner(size_t const order, + Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + fvar accumulator = fvar(f(0u)); +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + size_t const i_max = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t const i_max = order < order_sum ? order : order_sum; +#endif + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply(i, 0, f(i)); + } + return accumulator; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = (std::min)(order, order_sum); + promote, Fvar, Fvars...> accumulator = + cr.apply_derivatives( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...) / + factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += + cr.apply_derivatives( + order - i, [&f, i](auto... indices) { return f(i, indices...); }, std::forward(fvars)...) / + factorial(static_cast(i)); + return accumulator; +} +#endif + +// f : order -> derivative(order) +template +template +fvar fvar::apply_derivatives(size_t const order, Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + size_t i = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t i = order < order_sum ? order : order_sum; +#endif + fvar accumulator = f(i) / factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += f(i) / factorial(static_cast(i)); + return accumulator; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// f : order -> derivative(order) +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + promote, Fvar, Fvars...> accumulator = cr.apply_derivatives_nonhorner( + order, + [&f](auto... indices) { return f(0, static_cast(indices)...); }, + std::forward(fvars)...); + size_t const i_max = (std::min)(order, order_sum); + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_derivatives_nonhorner( + order - i, + [&f, i](auto... indices) { return f(i, static_cast(indices)...); }, + std::forward(fvars)...) / + factorial(static_cast(i)), + 0, + 0); + } + return accumulator; +} +#endif + +// f : order -> derivative(order) +template +template +fvar fvar::apply_derivatives_nonhorner(size_t const order, + Func const& f) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + fvar accumulator = fvar(f(0u)); +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + size_t const i_max = (std::min)(order, order_sum); +#else // ODR-use of static constexpr + size_t const i_max = order < order_sum ? order : order_sum; +#endif + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply(i, 0, f(i) / factorial(static_cast(i))); + } + return accumulator; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at fvar::at(size_t order, Orders... orders) const { + if constexpr (0 < sizeof...(Orders)) + return v.at(order).at(static_cast(orders)...); + else + return v.at(order); +} +#endif + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at, sizeof...(Orders)> fvar::derivative( + Orders... orders) const { + static_assert(sizeof...(Orders) <= depth, + "Number of parameters to derivative(...) cannot exceed fvar::depth."); + return at(static_cast(orders)...) * + (... * factorial(static_cast(orders))); +} +#endif + +template +const RealType& fvar::operator[](size_t i) const { + return v[i]; +} + +template +RealType fvar::epsilon_inner_product(size_t z0, + size_t const isum0, + size_t const m0, + fvar const& cr, + size_t z1, + size_t const isum1, + size_t const m1, + size_t const j) const { + static_assert(is_fvar::value, "epsilon_inner_product() must have 1 < depth."); + RealType accumulator = RealType(); + auto const i0_max = m1 < j ? j - m1 : 0; + for (auto i0 = m0, i1 = j - m0; i0 <= i0_max; ++i0, --i1) + accumulator += v[i0].epsilon_multiply(z0, isum0 + i0, cr.v[i1], z1, isum1 + i1); + return accumulator; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + using diff_t = typename std::array::difference_type; + RealType const zero(0); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + if constexpr (is_fvar::value) + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = epsilon_inner_product(z0, isum0, m0, cr, z1, isum1, m1, j); + else + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = std::inner_product( + v.cbegin() + diff_t(m0), v.cend() - diff_t(i + m1), cr.v.crbegin() + diff_t(i + m0), zero); + return retval; +} +#endif + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +// When called from outside this method, z0 should be non-zero. Otherwise if z0=0 then it will give an +// incorrect result of 0 when the root value is 0 and ca=inf, when instead the correct product is nan. +// If z0=0 then use the regular multiply operator*() instead. +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + if constexpr (is_fvar::value) + for (size_t i = m0; i <= Order; ++i) + retval.v[i] = retval.v[i].epsilon_multiply(z0, isum0 + i, ca); + else + for (size_t i = m0; i <= Order; ++i) + if (retval.v[i] != static_cast(0)) + retval.v[i] *= ca; + return retval; +} +#endif + +template +fvar fvar::inverse() const { + return static_cast(*this) == 0 ? inverse_apply() : 1 / *this; +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::negate() { + if constexpr (is_fvar::value) + std::for_each(v.begin(), v.end(), [](RealType& r) { r.negate(); }); + else + std::for_each(v.begin(), v.end(), [](RealType& a) { a = -a; }); + return *this; +} +#endif + +// This gives log(0.0) = depth(1)(-inf,inf,-inf,inf,-inf,inf) +// 1 / *this: log(0.0) = depth(1)(-inf,inf,-inf,-nan,-nan,-nan) +template +fvar fvar::inverse_apply() const { + root_type derivatives[order_sum + 1]; // LCOV_EXCL_LINE This causes a false negative on lcov coverage test. + root_type const x0 = static_cast(*this); + *derivatives = 1 / x0; + for (size_t i = 1; i <= order_sum; ++i) + derivatives[i] = -derivatives[i - 1] * i / x0; + return apply_derivatives_nonhorner(order_sum, [&derivatives](size_t j) { return derivatives[j]; }); +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::multiply_assign_by_root_type(bool is_root, + root_type const& ca) { + auto itr = v.begin(); + if constexpr (is_fvar::value) { + itr->multiply_assign_by_root_type(is_root, ca); + for (++itr; itr != v.end(); ++itr) + itr->multiply_assign_by_root_type(false, ca); + } else { + if (is_root || *itr != 0) + *itr *= ca; // Skip multiplication of 0 by ca=inf to avoid nan, except when is_root. + for (++itr; itr != v.end(); ++itr) + if (*itr != 0) + *itr *= ca; + } + return *this; +} +#endif + +template +fvar::operator root_type() const { + return static_cast(v.front()); +} + +template +template +fvar::operator T() const { + return static_cast(static_cast(v.front())); +} + +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR +template +fvar& fvar::set_root(root_type const& root) { + if constexpr (is_fvar::value) + v.front().set_root(root); + else + v.front() = root; + return *this; +} +#endif + +// Standard Library Support Requirements + +template +fvar fabs(fvar const& cr) { + typename fvar::root_type const zero(0); + return cr < zero ? -cr + : cr == zero ? fvar() // Canonical fabs'(0) = 0. + : cr; // Propagate NaN. +} + +template +fvar abs(fvar const& cr) { + return fabs(cr); +} + +template +fvar ceil(fvar const& cr) { + using std::ceil; + return fvar(ceil(static_cast::root_type>(cr))); +} + +template +fvar floor(fvar const& cr) { + using std::floor; + return fvar(floor(static_cast::root_type>(cr))); +} + +template +fvar exp(fvar const& cr) { + using std::exp; + constexpr size_t order = fvar::order_sum; + using root_type = typename fvar::root_type; + root_type const d0 = exp(static_cast(cr)); + return cr.apply_derivatives(order, [&d0](size_t) { return d0; }); +} + +template +fvar pow(fvar const& x, + typename fvar::root_type const& y) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x0 = static_cast(x); + root_type derivatives[order + 1]{pow(x0, y)}; + if (fabs(x0) < std::numeric_limits::epsilon()) { + root_type coef = 1; + for (size_t i = 0; i < order && y - i != 0; ++i) { + coef *= y - i; + derivatives[i + 1] = coef * pow(x0, y - (i + 1)); + } + return x.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + } else { + for (size_t i = 0; i < order && y - i != 0; ++i) + derivatives[i + 1] = (y - i) * derivatives[i] / x0; + return x.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i]; }); + } +} + +template +fvar pow(typename fvar::root_type const& x, + fvar const& y) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const y0 = static_cast(y); + root_type derivatives[order + 1]; + *derivatives = pow(x, y0); + root_type const logx = log(x); + for (size_t i = 0; i < order; ++i) + derivatives[i + 1] = derivatives[i] * logx; + return y.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i]; }); +} + +template +promote, fvar> pow(fvar const& x, + fvar const& y) { + BOOST_MATH_STD_USING + using return_type = promote, fvar>; + using root_type = typename return_type::root_type; + constexpr size_t order = return_type::order_sum; + root_type const x0 = static_cast(x); + root_type const y0 = static_cast(y); + root_type dxydx[order + 1]{pow(x0, y0)}; + BOOST_IF_CONSTEXPR (order == 0) + return return_type(*dxydx); + else { + for (size_t i = 0; i < order && y0 - i != 0; ++i) + dxydx[i + 1] = (y0 - i) * dxydx[i] / x0; + std::array, order + 1> lognx; + lognx.front() = fvar(1); +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + lognx[1] = log(make_fvar(x0)); +#else // for compilers that compile this branch when order == 0. + lognx[(std::min)(size_t(1), order)] = log(make_fvar(x0)); +#endif + for (size_t i = 1; i < order; ++i) + lognx[i + 1] = lognx[i] * lognx[1]; + auto const f = [&dxydx, &lognx](size_t i, size_t j) { + size_t binomial = 1; + root_type sum = dxydx[i] * static_cast(lognx[j]); + for (size_t k = 1; k <= i; ++k) { + (binomial *= (i - k + 1)) /= k; // binomial_coefficient(i,k) + sum += binomial * dxydx[i - k] * lognx[j].derivative(k); + } + return sum; + }; + if (fabs(x0) < std::numeric_limits::epsilon()) + return x.apply_derivatives_nonhorner(order, f, y); + return x.apply_derivatives(order, f, y); + } +} + +template +fvar sqrt(fvar const& cr) { + using std::sqrt; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type derivatives[order + 1]; + root_type const x = static_cast(cr); + *derivatives = sqrt(x); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(*derivatives); + else { + root_type numerator = 0.5; + root_type powers = 1; +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + derivatives[1] = numerator / *derivatives; +#else // for compilers that compile this branch when order == 0. + derivatives[(std::min)(size_t(1), order)] = numerator / *derivatives; +#endif + using diff_t = typename std::array::difference_type; + for (size_t i = 2; i <= order; ++i) { + numerator *= static_cast(-0.5) * ((static_cast(i) << 1) - 3); + powers *= x; + derivatives[i] = numerator / (powers * *derivatives); + } + auto const f = [&derivatives](size_t i) { return derivatives[i]; }; + if (cr < std::numeric_limits::epsilon()) + return cr.apply_derivatives_nonhorner(order, f); + return cr.apply_derivatives(order, f); + } +} + +// Natural logarithm. If cr==0 then derivative(i) may have nans due to nans from inverse(). +template +fvar log(fvar const& cr) { + using std::log; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = log(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto const d1 = make_fvar(static_cast(cr)).inverse(); // log'(x) = 1 / x + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar frexp(fvar const& cr, int* exp) { + using std::exp2; + using std::frexp; + using root_type = typename fvar::root_type; + frexp(static_cast(cr), exp); + return cr * static_cast(exp2(-*exp)); +} + +template +fvar ldexp(fvar const& cr, int exp) { + // argument to std::exp2 must be casted to root_type, otherwise std::exp2 returns double (always) + using std::exp2; + return cr * exp2(static_cast::root_type>(exp)); +} + +template +fvar cos(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = cos(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const d1 = -sin(static_cast(cr)); + root_type const derivatives[4]{d0, d1, -d0, -d1}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 3]; }); + } +} + +template +fvar sin(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = sin(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const d1 = cos(static_cast(cr)); + root_type const derivatives[4]{d0, d1, -d0, -d1}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 3]; }); + } +} + +template +fvar asin(fvar const& cr) { + using std::asin; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = asin(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x).negate() += 1).inverse(); // asin'(x) = 1 / sqrt(1-x*x). + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar tan(fvar const& cr) { + using std::tan; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = tan(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto c = cos(make_fvar(static_cast(cr))); + auto const d1 = (c *= c).inverse(); // tan'(x) = 1 / cos(x)^2 + return cr.apply_coefficients_nonhorner(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan(fvar const& cr) { + using std::atan; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = ((x *= x) += 1).inverse(); // atan'(x) = 1 / (x*x+1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan2(fvar const& cr, + typename fvar::root_type const& ca) { + using std::atan2; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan2(static_cast(cr), ca); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto y = make_fvar(static_cast(cr)); + auto const d1 = ca / ((y *= y) += (ca * ca)); // (d/dy)atan2(y,x) = x / (y*y+x*x) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atan2(typename fvar::root_type const& ca, + fvar const& cr) { + using std::atan2; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atan2(ca, static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = -ca / ((x *= x) += (ca * ca)); // (d/dx)atan2(y,x) = -y / (x*x+y*y) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +promote, fvar> atan2(fvar const& cr1, + fvar const& cr2) { + using std::atan2; + using return_type = promote, fvar>; + using root_type = typename return_type::root_type; + constexpr size_t order = return_type::order_sum; + root_type const y = static_cast(cr1); + root_type const x = static_cast(cr2); + root_type const d00 = atan2(y, x); + BOOST_IF_CONSTEXPR (order == 0) + return return_type(d00); + else { + constexpr size_t order1 = fvar::order_sum; + constexpr size_t order2 = fvar::order_sum; + auto x01 = make_fvar::root_type, order2 - 1>(x); + auto const d01 = -y / ((x01 *= x01) += (y * y)); + auto y10 = make_fvar::root_type, order1 - 1>(y); + auto x10 = make_fvar::root_type, 0, order2>(x); + auto const d10 = x10 / ((x10 * x10) + (y10 *= y10)); + auto const f = [&d00, &d01, &d10](size_t i, size_t j) { + return i ? d10[i - 1][j] / i : j ? d01[j - 1] / j : d00; + }; + return cr1.apply_coefficients(order, f, cr2); + } +} + +template +promote, fvar> fmod(fvar const& cr1, + fvar const& cr2) { + using boost::math::trunc; + auto const numer = static_cast::root_type>(cr1); + auto const denom = static_cast::root_type>(cr2); + return cr1 - cr2 * trunc(numer / denom); +} + +template +fvar round(fvar const& cr) { + using boost::math::round; + return fvar(round(static_cast::root_type>(cr))); +} + +template +int iround(fvar const& cr) { + using boost::math::iround; + return iround(static_cast::root_type>(cr)); +} + +template +long lround(fvar const& cr) { + using boost::math::lround; + return lround(static_cast::root_type>(cr)); +} + +template +long long llround(fvar const& cr) { + using boost::math::llround; + return llround(static_cast::root_type>(cr)); +} + +template +fvar trunc(fvar const& cr) { + using boost::math::trunc; + return fvar(trunc(static_cast::root_type>(cr))); +} + +template +long double truncl(fvar const& cr) { + using std::truncl; + return truncl(static_cast::root_type>(cr)); +} + +template +int itrunc(fvar const& cr) { + using boost::math::itrunc; + return itrunc(static_cast::root_type>(cr)); +} + +template +long long lltrunc(fvar const& cr) { + using boost::math::lltrunc; + return lltrunc(static_cast::root_type>(cr)); +} + +template +std::ostream& operator<<(std::ostream& out, fvar const& cr) { + out << "depth(" << cr.depth << ")(" << cr.v.front(); + for (size_t i = 1; i <= Order; ++i) + out << ',' << cr.v[i]; + return out << ')'; +} + +// Additional functions + +template +fvar acos(fvar const& cr) { + using std::acos; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = acos(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x).negate() += 1).inverse().negate(); // acos'(x) = -1 / sqrt(1-x*x). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar acosh(fvar const& cr) { + using boost::math::acosh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = acosh(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x) -= 1).inverse(); // acosh'(x) = 1 / sqrt(x*x-1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar asinh(fvar const& cr) { + using boost::math::asinh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = asinh(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = sqrt((x *= x) += 1).inverse(); // asinh'(x) = 1 / sqrt(x*x+1). + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar atanh(fvar const& cr) { + using boost::math::atanh; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = atanh(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); + auto const d1 = ((x *= x).negate() += 1).inverse(); // atanh'(x) = 1 / (1-x*x) + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar cosh(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = cosh(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + root_type const derivatives[2]{d0, sinh(static_cast(cr))}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 1]; }); + } +} + +template +fvar digamma(fvar const& cr) { + using boost::math::digamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x = static_cast(cr); + root_type const d0 = digamma(x); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + static_assert(order <= static_cast((std::numeric_limits::max)()), + "order exceeds maximum derivative for boost::math::polygamma()."); + return cr.apply_derivatives( + order, [&x, &d0](size_t i) { return i ? boost::math::polygamma(static_cast(i), x) : d0; }); + } +} + +template +fvar erf(fvar const& cr) { + using boost::math::erf; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = erf(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); // d1 = 2/sqrt(pi)*exp(-x*x) + auto const d1 = 2 * constants::one_div_root_pi() * exp((x *= x).negate()); + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar erfc(fvar const& cr) { + using boost::math::erfc; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = erfc(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + auto x = make_fvar(static_cast(cr)); // erfc'(x) = -erf'(x) + auto const d1 = -2 * constants::one_div_root_pi() * exp((x *= x).negate()); + return cr.apply_coefficients(order, [&d0, &d1](size_t i) { return i ? d1[i - 1] / i : d0; }); + } +} + +template +fvar lambert_w0(fvar const& cr) { + using std::exp; + using boost::math::lambert_w0; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type derivatives[order + 1]; + *derivatives = lambert_w0(static_cast(cr)); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(*derivatives); + else { + root_type const expw = exp(*derivatives); + derivatives[1] = 1 / (static_cast(cr) + expw); + BOOST_IF_CONSTEXPR (order == 1) + return cr.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + else { + using diff_t = typename std::array::difference_type; + root_type d1powers = derivatives[1] * derivatives[1]; + root_type const x = derivatives[1] * expw; + derivatives[2] = d1powers * (-1 - x); + std::array coef{{-1, -1}}; // as in derivatives[2]. + for (size_t n = 3; n <= order; ++n) { + coef[n - 1] = coef[n - 2] * -static_cast(2 * n - 3); + for (size_t j = n - 2; j != 0; --j) + (coef[j] *= -static_cast(n - 1)) -= (n + j - 2) * coef[j - 1]; + coef[0] *= -static_cast(n - 1); + d1powers *= derivatives[1]; + derivatives[n] = + d1powers * std::accumulate(coef.crend() - diff_t(n - 1), + coef.crend(), + coef[n - 1], + [&x](root_type const& a, root_type const& b) { return a * x + b; }); + } + return cr.apply_derivatives_nonhorner(order, [&derivatives](size_t i) { return derivatives[i]; }); + } + } +} + +template +fvar lgamma(fvar const& cr) { + using std::lgamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const x = static_cast(cr); + root_type const d0 = lgamma(x); + BOOST_IF_CONSTEXPR (order == 0) + return fvar(d0); + else { + static_assert(order <= static_cast((std::numeric_limits::max)()) + 1, + "order exceeds maximum derivative for boost::math::polygamma()."); + return cr.apply_derivatives( + order, [&x, &d0](size_t i) { return i ? boost::math::polygamma(static_cast(i - 1), x) : d0; }); + } +} + +template +fvar sinc(fvar const& cr) { + if (cr != 0) + return sin(cr) / cr; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type taylor[order + 1]{1}; // sinc(0) = 1 + BOOST_IF_CONSTEXPR (order == 0) + return fvar(*taylor); + else { + for (size_t n = 2; n <= order; n += 2) + taylor[n] = (1 - static_cast(n & 2)) / factorial(static_cast(n + 1)); + return cr.apply_coefficients_nonhorner(order, [&taylor](size_t i) { return taylor[i]; }); + } +} + +template +fvar sinh(fvar const& cr) { + BOOST_MATH_STD_USING + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + root_type const d0 = sinh(static_cast(cr)); + BOOST_IF_CONSTEXPR (fvar::order_sum == 0) + return fvar(d0); + else { + root_type const derivatives[2]{d0, cosh(static_cast(cr))}; + return cr.apply_derivatives(order, [&derivatives](size_t i) { return derivatives[i & 1]; }); + } +} + +template +fvar tanh(fvar const& cr) { + fvar retval = exp(cr * 2); + fvar const denom = retval + 1; + (retval -= 1) /= denom; + return retval; +} + +template +fvar tgamma(fvar const& cr) { + using std::tgamma; + using root_type = typename fvar::root_type; + constexpr size_t order = fvar::order_sum; + BOOST_IF_CONSTEXPR (order == 0) + return fvar(tgamma(static_cast(cr))); + else { + if (cr < 0) + return constants::pi() / (sin(constants::pi() * cr) * tgamma(1 - cr)); + return exp(lgamma(cr)).set_root(tgamma(static_cast(cr))); + } +} + +} // namespace detail +} // namespace autodiff_v1 +} // namespace differentiation +} // namespace math +} // namespace boost + +namespace std { + +// boost::math::tools::digits() is handled by this std::numeric_limits<> specialization, +// and similarly for max_value, min_value, log_max_value, log_min_value, and epsilon. +template +class numeric_limits> + : public numeric_limits::root_type> { +}; + +} // namespace std + +namespace boost { +namespace math { +namespace tools { +namespace detail { + +template +using autodiff_fvar_type = differentiation::detail::fvar; + +template +using autodiff_root_type = typename autodiff_fvar_type::root_type; +} // namespace detail + +// See boost/math/tools/promotion.hpp +template +struct promote_args_2, + detail::autodiff_fvar_type> { + using type = detail::autodiff_fvar_type::type, +#ifndef BOOST_NO_CXX14_CONSTEXPR + (std::max)(Order0, Order1)>; +#else + Order0; +#endif +}; + +template +struct promote_args> { + using type = detail::autodiff_fvar_type::type, Order>; +}; + +template +struct promote_args_2, RealType1> { + using type = detail::autodiff_fvar_type::type, Order0>; +}; + +template +struct promote_args_2> { + using type = detail::autodiff_fvar_type::type, Order1>; +}; + +template +inline constexpr destination_t real_cast(detail::autodiff_fvar_type const& from_v) + noexcept(BOOST_MATH_IS_FLOAT(destination_t) && BOOST_MATH_IS_FLOAT(RealType)) { + return real_cast(static_cast>(from_v)); +} + +} // namespace tools + +namespace policies { + +template +using fvar_t = differentiation::detail::fvar; +template +struct evaluation, Policy> { + using type = fvar_t::type, Order>; +}; + +template +struct evaluation, Policy> { + using type = + fvar_t::type, Order>; +}; + +} // namespace policies +} // namespace math +} // namespace boost + +#ifdef BOOST_NO_CXX17_IF_CONSTEXPR +#include "autodiff_cpp11.hpp" +#endif + +#endif // BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP diff --git a/libcxx/src/third-party/boost/math/differentiation/autodiff_cpp11.hpp b/libcxx/src/third-party/boost/math/differentiation/autodiff_cpp11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/differentiation/autodiff_cpp11.hpp @@ -0,0 +1,387 @@ +// Copyright Matthew Pulver 2018 - 2019. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// Contributors: +// * Kedar R. Bhat - C++11 compatibility. + +// Notes: +// * Any changes to this file should always be downstream from autodiff.cpp. +// C++17 is a higher-level language and is easier to maintain. For example, a number of functions which are +// lucidly read in autodiff.cpp are forced to be split into multiple structs/functions in this file for +// C++11. +// * Use of typename RootType and SizeType is a hack to prevent Visual Studio 2015 from compiling functions +// that are never called, that would otherwise produce compiler errors. Also forces functions to be inline. + +#ifndef BOOST_MATH_DIFFERENTIATION_AUTODIFF_HPP +#error \ + "Do not #include this file directly. This should only be #included by autodiff.hpp for C++11 compatibility." +#endif + +#include +#include + +namespace boost { +namespace math { + +namespace mp = tools::meta_programming; + +namespace differentiation { +inline namespace autodiff_v1 { +namespace detail { + +template +fvar::fvar(root_type const& ca, bool const is_variable) { + fvar_cpp11(is_fvar{}, ca, is_variable); +} + +template +template +void fvar::fvar_cpp11(std::true_type, RootType const& ca, bool const is_variable) { + v.front() = RealType(ca, is_variable); + if (0 < Order) + std::fill(v.begin() + 1, v.end(), static_cast(0)); +} + +template +template +void fvar::fvar_cpp11(std::false_type, RootType const& ca, bool const is_variable) { + v.front() = ca; + if (0 < Order) { + v[1] = static_cast(static_cast(is_variable)); + if (1 < Order) + std::fill(v.begin() + 2, v.end(), static_cast(0)); + } +} + +template +template +get_type_at fvar::at_cpp11(std::true_type, + size_t order, + Orders...) const { + return v.at(order); +} + +template +template +get_type_at fvar::at_cpp11(std::false_type, + size_t order, + Orders... orders) const { + return v.at(order).at(orders...); +} + +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at fvar::at(size_t order, Orders... orders) const { + return at_cpp11(std::integral_constant{}, order, orders...); +} + +template +constexpr T product(Ts...) { + return static_cast(1); +} + +template +constexpr T product(T factor, Ts... factors) { + return factor * product(factors...); +} + +// Can throw "std::out_of_range: array::at: __n (which is 7) >= _Nm (which is 7)" +template +template +get_type_at, sizeof...(Orders)> fvar::derivative( + Orders... orders) const { + static_assert(sizeof...(Orders) <= depth, + "Number of parameters to derivative(...) cannot exceed fvar::depth."); + return at(static_cast(orders)...) * + product(boost::math::factorial(static_cast(orders))...); +} + +template +class Curry { + Func const& f_; + size_t const i_; + + public: + template // typename SizeType to force inline constructor. + Curry(Func const& f, SizeType i) : f_(f), i_(static_cast(i)) {} + template + RootType operator()(Indices... indices) const { + using unsigned_t = typename std::make_unsigned::type...>::type; + return f_(i_, static_cast(indices)...); + } +}; + +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = order < order_sum ? order : order_sum; + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_coefficients( + order - i, Curry(f, i), std::forward(fvars)...); + while (i--) + (accumulator *= epsilon) += cr.apply_coefficients( + order - i, Curry(f, i), std::forward(fvars)...); + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_coefficients_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_coefficients_nonhorner( + order, Curry(f, 0), std::forward(fvars)...); + size_t const i_max = order < order_sum ? order : order_sum; + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_coefficients_nonhorner( + order - i, Curry(f, i), std::forward(fvars)...), + 0, + 0); + } + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + size_t i = order < order_sum ? order : order_sum; + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = + cr.apply_derivatives( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)); + while (i--) + (accumulator *= epsilon) += + cr.apply_derivatives( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)); + return accumulator; +} + +template +template +promote, Fvar, Fvars...> fvar::apply_derivatives_nonhorner( + size_t const order, + Func const& f, + Fvar const& cr, + Fvars&&... fvars) const { + fvar const epsilon = fvar(*this).set_root(0); + fvar epsilon_i = fvar(1); // epsilon to the power of i + using return_type = promote, Fvar, Fvars...>; + return_type accumulator = cr.apply_derivatives_nonhorner( + order, Curry(f, 0), std::forward(fvars)...); + size_t const i_max = order < order_sum ? order : order_sum; + for (size_t i = 1; i <= i_max; ++i) { + epsilon_i = epsilon_i.epsilon_multiply(i - 1, 0, epsilon, 1, 0); + accumulator += epsilon_i.epsilon_multiply( + i, + 0, + cr.apply_derivatives_nonhorner( + order - i, Curry(f, i), std::forward(fvars)...) / + factorial(static_cast(i)), + 0, + 0); + } + return accumulator; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = epsilon_inner_product(z0, isum0, m0, cr, z1, isum1, m1, j); + return retval; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + using ssize_t = typename std::make_signed::type; + RealType const zero(0); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + size_t const m1 = order_sum + isum1 < Order + z1 ? Order + z1 - (order_sum + isum1) : 0; + size_t const i_max = m0 + m1 < Order ? Order - (m0 + m1) : 0; + fvar retval = fvar(); + for (size_t i = 0, j = Order; i <= i_max; ++i, --j) + retval.v[j] = std::inner_product( + v.cbegin() + ssize_t(m0), v.cend() - ssize_t(i + m1), cr.v.crbegin() + ssize_t(i + m0), zero); + return retval; +} + +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + fvar const& cr, + size_t z1, + size_t isum1) const { + return epsilon_multiply_cpp11(is_fvar{}, z0, isum0, cr, z1, isum1); +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::true_type, + SizeType z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + for (size_t i = m0; i <= Order; ++i) + retval.v[i] = retval.v[i].epsilon_multiply(z0, isum0 + i, ca); + return retval; +} + +template +template +fvar fvar::epsilon_multiply_cpp11(std::false_type, + SizeType z0, + size_t isum0, + root_type const& ca) const { + fvar retval(*this); + size_t const m0 = order_sum + isum0 < Order + z0 ? Order + z0 - (order_sum + isum0) : 0; + for (size_t i = m0; i <= Order; ++i) + if (retval.v[i] != static_cast(0)) + retval.v[i] *= ca; + return retval; +} + +template +fvar fvar::epsilon_multiply(size_t z0, + size_t isum0, + root_type const& ca) const { + return epsilon_multiply_cpp11(is_fvar{}, z0, isum0, ca); +} + +template +template +fvar& fvar::multiply_assign_by_root_type_cpp11(std::true_type, + bool is_root, + RootType const& ca) { + auto itr = v.begin(); + itr->multiply_assign_by_root_type(is_root, ca); + for (++itr; itr != v.end(); ++itr) + itr->multiply_assign_by_root_type(false, ca); + return *this; +} + +template +template +fvar& fvar::multiply_assign_by_root_type_cpp11(std::false_type, + bool is_root, + RootType const& ca) { + auto itr = v.begin(); + if (is_root || *itr != 0) + *itr *= ca; // Skip multiplication of 0 by ca=inf to avoid nan, except when is_root. + for (++itr; itr != v.end(); ++itr) + if (*itr != 0) + *itr *= ca; + return *this; +} + +template +fvar& fvar::multiply_assign_by_root_type(bool is_root, + root_type const& ca) { + return multiply_assign_by_root_type_cpp11(is_fvar{}, is_root, ca); +} + +template +template +fvar& fvar::negate_cpp11(std::true_type, RootType const&) { + std::for_each(v.begin(), v.end(), [](RealType& r) { r.negate(); }); + return *this; +} + +template +template +fvar& fvar::negate_cpp11(std::false_type, RootType const&) { + std::for_each(v.begin(), v.end(), [](RealType& a) { a = -a; }); + return *this; +} + +template +fvar& fvar::negate() { + return negate_cpp11(is_fvar{}, static_cast(*this)); +} + +template +template +fvar& fvar::set_root_cpp11(std::true_type, RootType const& root) { + v.front().set_root(root); + return *this; +} + +template +template +fvar& fvar::set_root_cpp11(std::false_type, RootType const& root) { + v.front() = root; + return *this; +} + +template +fvar& fvar::set_root(root_type const& root) { + return set_root_cpp11(is_fvar{}, root); +} + +template +auto make_fvar_for_tuple(mp::index_sequence, RealType const& ca) + -> decltype(make_fvar::value..., Order>(ca)) { + return make_fvar::value..., Order>(ca); +} + +template +auto make_ftuple_impl(mp::index_sequence, RealTypes const&... ca) + -> decltype(std::make_tuple(make_fvar_for_tuple(mp::make_index_sequence{}, + ca)...)) { + return std::make_tuple(make_fvar_for_tuple(mp::make_index_sequence{}, ca)...); +} + +} // namespace detail + +template +auto make_ftuple(RealTypes const&... ca) + -> decltype(detail::make_ftuple_impl(mp::index_sequence_for{}, + ca...)) { + static_assert(sizeof...(Orders) == sizeof...(RealTypes), + "Number of Orders must match number of function parameters."); + return detail::make_ftuple_impl(mp::index_sequence_for{}, ca...); +} + +} // namespace autodiff_v1 +} // namespace differentiation +} // namespace math +} // namespace boost diff --git a/libcxx/src/third-party/boost/math/differentiation/finite_difference.hpp b/libcxx/src/third-party/boost/math/differentiation/finite_difference.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/differentiation/finite_difference.hpp @@ -0,0 +1,266 @@ +// (C) Copyright Nick Thompson 2018. +// 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_DIFFERENTIATION_FINITE_DIFFERENCE_HPP +#define BOOST_MATH_DIFFERENTIATION_FINITE_DIFFERENCE_HPP + +/* + * Performs numerical differentiation by finite-differences. + * + * All numerical differentiation using finite-differences are ill-conditioned, and these routines are no exception. + * A simple argument demonstrates that the error is unbounded as h->0. + * Take the one sides finite difference formula f'(x) = (f(x+h)-f(x))/h. + * The evaluation of f induces an error as well as the error from the finite-difference approximation, giving + * |f'(x) - (f(x+h) -f(x))/h| < h|f''(x)|/2 + (|f(x)|+|f(x+h)|)eps/h =: g(h), where eps is the unit roundoff for the type. + * It is reasonable to choose h in a way that minimizes the maximum error bound g(h). + * The value of h that minimizes g is h = sqrt(2eps(|f(x)| + |f(x+h)|)/|f''(x)|), and for this value of h the error bound is + * sqrt(2eps(|f(x+h) +f(x)||f''(x)|)). + * In fact it is not necessary to compute the ratio (|f(x+h)| + |f(x)|)/|f''(x)|; the error bound of ~\sqrt{\epsilon} still holds if we set it to one. + * + * + * For more details on this method of analysis, see + * + * http://www.uio.no/studier/emner/matnat/math/MAT-INF1100/h08/kompendiet/diffint.pdf + * http://web.archive.org/web/20150420195907/http://www.uio.no/studier/emner/matnat/math/MAT-INF1100/h08/kompendiet/diffint.pdf + * + * + * It can be shown on general grounds that when choosing the optimal h, the maximum error in f'(x) is ~(|f(x)|eps)^k/k+1|f^(k-1)(x)|^1/k+1. + * From this we can see that full precision can be recovered in the limit k->infinity. + * + * References: + * + * 1) Fornberg, Bengt. "Generation of finite difference formulas on arbitrarily spaced grids." Mathematics of computation 51.184 (1988): 699-706. + * + * + * The second algorithm, the complex step derivative, is not ill-conditioned. + * However, it requires that your function can be evaluated at complex arguments. + * The idea is that f(x+ih) = f(x) +ihf'(x) - h^2f''(x) + ... so f'(x) \approx Im[f(x+ih)]/h. + * No subtractive cancellation occurs. The error is ~ eps|f'(x)| + eps^2|f'''(x)|/6; hard to beat that. + * + * References: + * + * 1) Squire, William, and George Trapp. "Using complex variables to estimate derivatives of real functions." Siam Review 40.1 (1998): 110-112. + */ + +#include +#include + +namespace boost{ namespace math{ namespace differentiation { + +namespace detail { + template + Real make_xph_representable(Real x, Real h) + { + using std::numeric_limits; + // Redefine h so that x + h is representable. Not using this trick leads to large error. + // The compiler flag -ffast-math evaporates these operations . . . + Real temp = x + h; + h = temp - x; + // Handle the case x + h == x: + if (h == 0) + { + h = boost::math::nextafter(x, (numeric_limits::max)()) - x; + } + return h; + } +} + +template +Real complex_step_derivative(const F f, Real x) +{ + // Is it really this easy? Yes. + // Note that some authors recommend taking the stepsize h to be smaller than epsilon(), some recommending use of the min(). + // This idea was tested over a few billion test cases and found the make the error *much* worse. + // Even 2eps and eps/2 made the error worse, which was surprising. + using std::complex; + using std::numeric_limits; + constexpr const Real step = (numeric_limits::epsilon)(); + constexpr const Real inv_step = 1/(numeric_limits::epsilon)(); + return f(complex(x, step)).imag()*inv_step; +} + +namespace detail { + + template + struct fd_tag {}; + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<1>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^1/2 + // Note that this estimate of h differs from the best estimate by a factor of sqrt((|f(x)| + |f(x+h)|)/|f''(x)|). + // Since this factor is invariant under the scaling f -> kf, then we are somewhat justified in approximating it by 1. + // This approximation will get better as we move to higher orders of accuracy. + Real h = 2 * sqrt(eps); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real y0 = f(x); + Real diff = yh - y0; + if (error) + { + Real ym = f(x - h); + Real ypph = abs(yh - 2 * y0 + ym) / h; + // h*|f''(x)|*0.5 + (|f(x+h)+|f(x)|)*eps/h + *error = ypph / 2 + (abs(yh) + abs(y0))*eps / h; + } + return diff / h; + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<2>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^2/3 + // See the previous discussion to understand determination of h and the error bound. + // Series[(f[x+h] - f[x-h])/(2*h), {h, 0, 4}] + Real h = pow(3 * eps, static_cast(1) / static_cast(3)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real diff = yh - ymh; + if (error) + { + Real yth = f(x + 2 * h); + Real ymth = f(x - 2 * h); + *error = eps * (abs(yh) + abs(ymh)) / (2 * h) + abs((yth - ymth) / 2 - diff) / (6 * h); + } + + return diff / (2 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<4>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^4/5 + Real h = pow(11.25*eps, static_cast(1) / static_cast(5)); + h = detail::make_xph_representable(x, h); + Real ymth = f(x - 2 * h); + Real yth = f(x + 2 * h); + Real yh = f(x + h); + Real ymh = f(x - h); + Real y2 = ymth - yth; + Real y1 = yh - ymh; + if (error) + { + // Mathematica code to extract the remainder: + // Series[(f[x-2*h]+ 8*f[x+h] - 8*f[x-h] - f[x+2*h])/(12*h), {h, 0, 7}] + Real y_three_h = f(x + 3 * h); + Real y_m_three_h = f(x - 3 * h); + // Error from fifth derivative: + *error = abs((y_three_h - y_m_three_h) / 2 + 2 * (ymth - yth) + 5 * (yh - ymh) / 2) / (30 * h); + // Error from function evaluation: + *error += eps * (abs(yth) + abs(ymth) + 8 * (abs(ymh) + abs(yh))) / (12 * h); + } + return (y2 + 8 * y1) / (12 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<6>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^6/7 + // Error: h^6f^(7)(x)/140 + 5|f(x)|eps/h + Real h = pow(eps / 168, static_cast(1) / static_cast(7)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real y1 = yh - ymh; + Real y2 = f(x - 2 * h) - f(x + 2 * h); + Real y3 = f(x + 3 * h) - f(x - 3 * h); + + if (error) + { + // Mathematica code to generate fd scheme for 7th derivative: + // Sum[(-1)^i*Binomial[7, i]*(f[x+(3-i)*h] + f[x+(4-i)*h])/2, {i, 0, 7}] + // Mathematica to demonstrate that this is a finite difference formula for 7th derivative: + // Series[(f[x+4*h]-f[x-4*h] + 6*(f[x-3*h] - f[x+3*h]) + 14*(f[x-h] - f[x+h] + f[x+2*h] - f[x-2*h]))/2, {h, 0, 15}] + Real y7 = (f(x + 4 * h) - f(x - 4 * h) - 6 * y3 - 14 * y1 - 14 * y2) / 2; + *error = abs(y7) / (140 * h) + 5 * (abs(yh) + abs(ymh))*eps / h; + } + return (y3 + 9 * y2 + 45 * y1) / (60 * h); + } + + template + Real finite_difference_derivative(const F f, Real x, Real* error, const fd_tag<8>&) + { + using std::sqrt; + using std::pow; + using std::abs; + using std::numeric_limits; + + const Real eps = (numeric_limits::epsilon)(); + // Error bound ~eps^8/9. + // In double precision, we only expect to lose two digits of precision while using this formula, at the cost of 8 function evaluations. + // Error: h^8|f^(9)(x)|/630 + 7|f(x)|eps/h assuming 7 unstabilized additions. + // Mathematica code to get the error: + // Series[(f[x+h]-f[x-h])*(4/5) + (1/5)*(f[x-2*h] - f[x+2*h]) + (4/105)*(f[x+3*h] - f[x-3*h]) + (1/280)*(f[x-4*h] - f[x+4*h]), {h, 0, 9}] + // If we used Kahan summation, we could get the max error down to h^8|f^(9)(x)|/630 + |f(x)|eps/h. + Real h = pow(551.25*eps, static_cast(1) / static_cast(9)); + h = detail::make_xph_representable(x, h); + + Real yh = f(x + h); + Real ymh = f(x - h); + Real y1 = yh - ymh; + Real y2 = f(x - 2 * h) - f(x + 2 * h); + Real y3 = f(x + 3 * h) - f(x - 3 * h); + Real y4 = f(x - 4 * h) - f(x + 4 * h); + + Real tmp1 = 3 * y4 / 8 + 4 * y3; + Real tmp2 = 21 * y2 + 84 * y1; + + if (error) + { + // Mathematica code to generate fd scheme for 7th derivative: + // Sum[(-1)^i*Binomial[9, i]*(f[x+(4-i)*h] + f[x+(5-i)*h])/2, {i, 0, 9}] + // Mathematica to demonstrate that this is a finite difference formula for 7th derivative: + // Series[(f[x+5*h]-f[x- 5*h])/2 + 4*(f[x-4*h] - f[x+4*h]) + 27*(f[x+3*h] - f[x-3*h])/2 + 24*(f[x-2*h] - f[x+2*h]) + 21*(f[x+h] - f[x-h]), {h, 0, 15}] + Real f9 = (f(x + 5 * h) - f(x - 5 * h)) / 2 + 4 * y4 + 27 * y3 / 2 + 24 * y2 + 21 * y1; + *error = abs(f9) / (630 * h) + 7 * (abs(yh) + abs(ymh))*eps / h; + } + return (tmp1 + tmp2) / (105 * h); + } + + template + Real finite_difference_derivative(const F, Real, Real*, const tag&) + { + // Always fails, but condition is template-arg-dependent so only evaluated if we get instantiated. + static_assert(sizeof(Real) == 0, "Finite difference not implemented for this order: try 1, 2, 4, 6 or 8"); + } + +} + +template +inline Real finite_difference_derivative(const F f, Real x, Real* error = nullptr) +{ + return detail::finite_difference_derivative(f, x, error, detail::fd_tag()); +} + +}}} // namespaces +#endif diff --git a/libcxx/src/third-party/boost/math/differentiation/lanczos_smoothing.hpp b/libcxx/src/third-party/boost/math/differentiation/lanczos_smoothing.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/differentiation/lanczos_smoothing.hpp @@ -0,0 +1,582 @@ +// (C) Copyright Nick Thompson 2019. +// 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_DIFFERENTIATION_LANCZOS_SMOOTHING_HPP +#define BOOST_MATH_DIFFERENTIATION_LANCZOS_SMOOTHING_HPP +#include // for std::abs +#include +#include // to nan initialize +#include +#include +#include +#include +#include + +namespace boost::math::differentiation { + +namespace detail { +template +class discrete_legendre { + public: + explicit discrete_legendre(std::size_t n, Real x) : m_n{n}, m_r{2}, m_x{x}, + m_qrm2{1}, m_qrm1{x}, + m_qrm2p{0}, m_qrm1p{1}, + m_qrm2pp{0}, m_qrm1pp{0} + { + using std::abs; + BOOST_MATH_ASSERT_MSG(abs(m_x) <= 1, "Three term recurrence is stable only for |x| <=1."); + // The integer n indexes a family of discrete Legendre polynomials indexed by k <= 2*n + } + + Real norm_sq(int r) const + { + Real prod = Real(2) / Real(2 * r + 1); + for (int k = -r; k <= r; ++k) { + prod *= Real(2 * m_n + 1 + k) / Real(2 * m_n); + } + return prod; + } + + Real next() + { + Real N = 2 * m_n + 1; + Real num = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) * m_qrm2; + Real tmp = (2 * m_r - 1) * m_x * m_qrm1 - num / Real(4 * m_n * m_n); + m_qrm2 = m_qrm1; + m_qrm1 = tmp / m_r; + ++m_r; + return m_qrm1; + } + + Real next_prime() + { + Real N = 2 * m_n + 1; + Real s = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) / Real(4 * m_n * m_n); + Real tmp1 = ((2 * m_r - 1) * m_x * m_qrm1 - s * m_qrm2) / m_r; + Real tmp2 = ((2 * m_r - 1) * (m_qrm1 + m_x * m_qrm1p) - s * m_qrm2p) / m_r; + m_qrm2 = m_qrm1; + m_qrm1 = tmp1; + m_qrm2p = m_qrm1p; + m_qrm1p = tmp2; + ++m_r; + return m_qrm1p; + } + + Real next_dbl_prime() + { + Real N = 2*m_n + 1; + Real trm1 = 2*m_r - 1; + Real s = (m_r - 1) * (N * N - (m_r - 1) * (m_r - 1)) / Real(4 * m_n * m_n); + Real rqrpp = 2*trm1*m_qrm1p + trm1*m_x*m_qrm1pp - s*m_qrm2pp; + Real tmp1 = ((2 * m_r - 1) * m_x * m_qrm1 - s * m_qrm2) / m_r; + Real tmp2 = ((2 * m_r - 1) * (m_qrm1 + m_x * m_qrm1p) - s * m_qrm2p) / m_r; + m_qrm2 = m_qrm1; + m_qrm1 = tmp1; + m_qrm2p = m_qrm1p; + m_qrm1p = tmp2; + m_qrm2pp = m_qrm1pp; + m_qrm1pp = rqrpp/m_r; + ++m_r; + return m_qrm1pp; + } + + Real operator()(Real x, std::size_t k) + { + BOOST_MATH_ASSERT_MSG(k <= 2 * m_n, "r <= 2n is required."); + if (k == 0) + { + return 1; + } + if (k == 1) + { + return x; + } + Real qrm2 = 1; + Real qrm1 = x; + Real N = 2 * m_n + 1; + for (std::size_t r = 2; r <= k; ++r) { + Real num = (r - 1) * (N * N - (r - 1) * (r - 1)) * qrm2; + Real tmp = (2 * r - 1) * x * qrm1 - num / Real(4 * m_n * m_n); + qrm2 = qrm1; + qrm1 = tmp / r; + } + return qrm1; + } + + Real prime(Real x, std::size_t k) { + BOOST_MATH_ASSERT_MSG(k <= 2 * m_n, "r <= 2n is required."); + if (k == 0) { + return 0; + } + if (k == 1) { + return 1; + } + Real qrm2 = 1; + Real qrm1 = x; + Real qrm2p = 0; + Real qrm1p = 1; + Real N = 2 * m_n + 1; + for (std::size_t r = 2; r <= k; ++r) { + Real s = + (r - 1) * (N * N - (r - 1) * (r - 1)) / Real(4 * m_n * m_n); + Real tmp1 = ((2 * r - 1) * x * qrm1 - s * qrm2) / r; + Real tmp2 = ((2 * r - 1) * (qrm1 + x * qrm1p) - s * qrm2p) / r; + qrm2 = qrm1; + qrm1 = tmp1; + qrm2p = qrm1p; + qrm1p = tmp2; + } + return qrm1p; + } + + private: + std::size_t m_n; + std::size_t m_r; + Real m_x; + Real m_qrm2; + Real m_qrm1; + Real m_qrm2p; + Real m_qrm1p; + Real m_qrm2pp; + Real m_qrm1pp; +}; + +template +std::vector interior_velocity_filter(std::size_t n, std::size_t p) { + auto dlp = discrete_legendre(n, 0); + std::vector coeffs(p+1); + coeffs[1] = 1/dlp.norm_sq(1); + for (std::size_t l = 3; l < p + 1; l += 2) + { + dlp.next_prime(); + coeffs[l] = dlp.next_prime()/ dlp.norm_sq(l); + } + + // We could make the filter length n, as f[0] = 0, + // but that'd make the indexing awkward when applying the filter. + std::vector f(n + 1); + // This value should never be read, but this is the correct value *if it is read*. + // Hmm, should it be a nan then? I'm not gonna agonize. + f[0] = 0; + for (std::size_t j = 1; j < f.size(); ++j) + { + Real arg = Real(j) / Real(n); + dlp = discrete_legendre(n, arg); + f[j] = coeffs[1]*arg; + for (std::size_t l = 3; l <= p; l += 2) + { + dlp.next(); + f[j] += coeffs[l]*dlp.next(); + } + f[j] /= (n * n); + } + return f; +} + +template +std::vector boundary_velocity_filter(std::size_t n, std::size_t p, int64_t s) +{ + std::vector coeffs(p+1, std::numeric_limits::quiet_NaN()); + Real sn = Real(s) / Real(n); + auto dlp = discrete_legendre(n, sn); + coeffs[0] = 0; + coeffs[1] = 1/dlp.norm_sq(1); + for (std::size_t l = 2; l < p + 1; ++l) + { + // Calculation of the norms is common to all filters, + // so it seems like an obvious optimization target. + // I tried this: The spent in computing the norms time is not negligible, + // but still a small fraction of the total compute time. + // Hence I'm not refactoring out these norm calculations. + coeffs[l] = dlp.next_prime()/ dlp.norm_sq(l); + } + + std::vector f(2*n + 1); + for (std::size_t k = 0; k < f.size(); ++k) + { + Real j = Real(k) - Real(n); + Real arg = j/Real(n); + dlp = discrete_legendre(n, arg); + f[k] = coeffs[1]*arg; + for (std::size_t l = 2; l <= p; ++l) + { + f[k] += coeffs[l]*dlp.next(); + } + f[k] /= (n * n); + } + return f; +} + +template +std::vector acceleration_filter(std::size_t n, std::size_t p, int64_t s) +{ + BOOST_MATH_ASSERT_MSG(p <= 2*n, "Approximation order must be <= 2*n"); + BOOST_MATH_ASSERT_MSG(p > 2, "Approximation order must be > 2"); + + std::vector coeffs(p+1, std::numeric_limits::quiet_NaN()); + Real sn = Real(s) / Real(n); + auto dlp = discrete_legendre(n, sn); + coeffs[0] = 0; + coeffs[1] = 0; + for (std::size_t l = 2; l < p + 1; ++l) + { + coeffs[l] = dlp.next_dbl_prime()/ dlp.norm_sq(l); + } + + std::vector f(2*n + 1, 0); + for (std::size_t k = 0; k < f.size(); ++k) + { + Real j = Real(k) - Real(n); + Real arg = j/Real(n); + dlp = discrete_legendre(n, arg); + for (std::size_t l = 2; l <= p; ++l) + { + f[k] += coeffs[l]*dlp.next(); + } + f[k] /= (n * n * n); + } + return f; +} + + +} // namespace detail + +template +class discrete_lanczos_derivative { +public: + discrete_lanczos_derivative(Real const & spacing, + std::size_t n = 18, + std::size_t approximation_order = 3) + : m_dt{spacing} + { + static_assert(!std::is_integral_v, + "Spacing must be a floating point type."); + BOOST_MATH_ASSERT_MSG(spacing > 0, + "Spacing between samples must be > 0."); + + if constexpr (order == 1) + { + BOOST_MATH_ASSERT_MSG(approximation_order <= 2 * n, + "The approximation order must be <= 2n"); + BOOST_MATH_ASSERT_MSG(approximation_order >= 2, + "The approximation order must be >= 2"); + + if constexpr (std::is_same_v || std::is_same_v) + { + auto interior = detail::interior_velocity_filter(n, approximation_order); + m_f.resize(interior.size()); + for (std::size_t j = 0; j < interior.size(); ++j) + { + m_f[j] = static_cast(interior[j])/m_dt; + } + } + else + { + m_f = detail::interior_velocity_filter(n, approximation_order); + for (auto & x : m_f) + { + x /= m_dt; + } + } + + m_boundary_filters.resize(n); + // This for loop is a natural candidate for parallelization. + // But does it matter? Probably not. + for (std::size_t i = 0; i < n; ++i) + { + if constexpr (std::is_same_v || std::is_same_v) + { + int64_t s = static_cast(i) - static_cast(n); + auto bf = detail::boundary_velocity_filter(n, approximation_order, s); + m_boundary_filters[i].resize(bf.size()); + for (std::size_t j = 0; j < bf.size(); ++j) + { + m_boundary_filters[i][j] = static_cast(bf[j])/m_dt; + } + } + else + { + int64_t s = static_cast(i) - static_cast(n); + m_boundary_filters[i] = detail::boundary_velocity_filter(n, approximation_order, s); + for (auto & bf : m_boundary_filters[i]) + { + bf /= m_dt; + } + } + } + } + else if constexpr (order == 2) + { + // High precision isn't warranted for small p; only for large p. + // (The computation appears stable for large n.) + // But given that the filters are reusable for many vectors, + // it's better to do a high precision computation and then cast back, + // since the resulting cost is a factor of 2, and the cost of the filters not working is hours of debugging. + if constexpr (std::is_same_v || std::is_same_v) + { + auto f = detail::acceleration_filter(n, approximation_order, 0); + m_f.resize(n+1); + for (std::size_t i = 0; i < m_f.size(); ++i) + { + m_f[i] = static_cast(f[i+n])/(m_dt*m_dt); + } + m_boundary_filters.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + int64_t s = static_cast(i) - static_cast(n); + auto bf = detail::acceleration_filter(n, approximation_order, s); + m_boundary_filters[i].resize(bf.size()); + for (std::size_t j = 0; j < bf.size(); ++j) + { + m_boundary_filters[i][j] = static_cast(bf[j])/(m_dt*m_dt); + } + } + } + else + { + // Given that the purpose is denoising, for higher precision calculations, + // the default precision should be fine. + auto f = detail::acceleration_filter(n, approximation_order, 0); + m_f.resize(n+1); + for (std::size_t i = 0; i < m_f.size(); ++i) + { + m_f[i] = f[i+n]/(m_dt*m_dt); + } + m_boundary_filters.resize(n); + for (std::size_t i = 0; i < n; ++i) + { + int64_t s = static_cast(i) - static_cast(n); + m_boundary_filters[i] = detail::acceleration_filter(n, approximation_order, s); + for (auto & bf : m_boundary_filters[i]) + { + bf /= (m_dt*m_dt); + } + } + } + } + else + { + BOOST_MATH_ASSERT_MSG(false, "Derivatives of order 3 and higher are not implemented."); + } + } + + Real get_spacing() const + { + return m_dt; + } + + template + Real operator()(RandomAccessContainer const & v, std::size_t i) const + { + static_assert(std::is_same_v, + "The type of the values in the vector provided does not match the type in the filters."); + + BOOST_MATH_ASSERT_MSG(std::size(v) >= m_boundary_filters[0].size(), + "Vector must be at least as long as the filter length"); + + if constexpr (order==1) + { + if (i >= m_f.size() - 1 && i <= std::size(v) - m_f.size()) + { + // The filter has length >= 1: + Real dvdt = m_f[1] * (v[i + 1] - v[i - 1]); + for (std::size_t j = 2; j < m_f.size(); ++j) + { + dvdt += m_f[j] * (v[i + j] - v[i - j]); + } + return dvdt; + } + + // m_f.size() = N+1 + if (i < m_f.size() - 1) + { + auto &bf = m_boundary_filters[i]; + Real dvdt = bf[0]*v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[j]; + } + return dvdt; + } + + if (i > std::size(v) - m_f.size() && i < std::size(v)) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real dvdt = bf[0]*v[std::size(v)-1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[std::size(v) - 1 - j]; + } + return -dvdt; + } + } + else if constexpr (order==2) + { + if (i >= m_f.size() - 1 && i <= std::size(v) - m_f.size()) + { + Real d2vdt2 = m_f[0]*v[i]; + for (std::size_t j = 1; j < m_f.size(); ++j) + { + d2vdt2 += m_f[j] * (v[i + j] + v[i - j]); + } + return d2vdt2; + } + + // m_f.size() = N+1 + if (i < m_f.size() - 1) + { + auto &bf = m_boundary_filters[i]; + Real d2vdt2 = bf[0]*v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[j]; + } + return d2vdt2; + } + + if (i > std::size(v) - m_f.size() && i < std::size(v)) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real d2vdt2 = bf[0] * v[std::size(v) - 1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[std::size(v) - 1 - j]; + } + return d2vdt2; + } + } + + // OOB access: + std::string msg = "Out of bounds access in Lanczos derivative."; + msg += "Input vector has length " + std::to_string(std::size(v)) + ", but user requested access at index " + std::to_string(i) + "."; + throw std::out_of_range(msg); + return std::numeric_limits::quiet_NaN(); + } + + template + void operator()(RandomAccessContainer const & v, RandomAccessContainer & w) const + { + static_assert(std::is_same_v, + "The type of the values in the vector provided does not match the type in the filters."); + if (&w[0] == &v[0]) + { + throw std::logic_error("This transform cannot be performed in-place."); + } + + if (std::size(v) < m_boundary_filters[0].size()) + { + std::string msg = "The input vector must be at least as long as the filter length. "; + msg += "The input vector has length = " + std::to_string(std::size(v)) + ", the filter has length " + std::to_string(m_boundary_filters[0].size()); + throw std::length_error(msg); + } + + if (std::size(w) < std::size(v)) + { + std::string msg = "The output vector (containing the derivative) must be at least as long as the input vector."; + msg += "The output vector has length = " + std::to_string(std::size(w)) + ", the input vector has length " + std::to_string(std::size(v)); + throw std::length_error(msg); + } + + if constexpr (order==1) + { + for (std::size_t i = 0; i < m_f.size() - 1; ++i) + { + auto &bf = m_boundary_filters[i]; + Real dvdt = bf[0] * v[0]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + dvdt += bf[j] * v[j]; + } + w[i] = dvdt; + } + + for(std::size_t i = m_f.size() - 1; i <= std::size(v) - m_f.size(); ++i) + { + Real dvdt = m_f[1] * (v[i + 1] - v[i - 1]); + for (std::size_t j = 2; j < m_f.size(); ++j) + { + dvdt += m_f[j] *(v[i + j] - v[i - j]); + } + w[i] = dvdt; + } + + + for(std::size_t i = std::size(v) - m_f.size() + 1; i < std::size(v); ++i) + { + int k = std::size(v) - 1 - i; + auto &f = m_boundary_filters[k]; + Real dvdt = f[0] * v[std::size(v) - 1];; + for (std::size_t j = 1; j < f.size(); ++j) + { + dvdt += f[j] * v[std::size(v) - 1 - j]; + } + w[i] = -dvdt; + } + } + else if constexpr (order==2) + { + // m_f.size() = N+1 + for (std::size_t i = 0; i < m_f.size() - 1; ++i) + { + auto &bf = m_boundary_filters[i]; + Real d2vdt2 = 0; + for (std::size_t j = 0; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[j]; + } + w[i] = d2vdt2; + } + + for (std::size_t i = m_f.size() - 1; i <= std::size(v) - m_f.size(); ++i) + { + Real d2vdt2 = m_f[0]*v[i]; + for (std::size_t j = 1; j < m_f.size(); ++j) + { + d2vdt2 += m_f[j] * (v[i + j] + v[i - j]); + } + w[i] = d2vdt2; + } + + for (std::size_t i = std::size(v) - m_f.size() + 1; i < std::size(v); ++i) + { + int k = std::size(v) - 1 - i; + auto &bf = m_boundary_filters[k]; + Real d2vdt2 = bf[0] * v[std::size(v) - 1]; + for (std::size_t j = 1; j < bf.size(); ++j) + { + d2vdt2 += bf[j] * v[std::size(v) - 1 - j]; + } + w[i] = d2vdt2; + } + } + } + + template + RandomAccessContainer operator()(RandomAccessContainer const & v) const + { + RandomAccessContainer w(std::size(v)); + this->operator()(v, w); + return w; + } + + + // Don't copy; too big. + discrete_lanczos_derivative( const discrete_lanczos_derivative & ) = delete; + discrete_lanczos_derivative& operator=(const discrete_lanczos_derivative&) = delete; + + // Allow moves: + discrete_lanczos_derivative(discrete_lanczos_derivative&&) noexcept = default; + discrete_lanczos_derivative& operator=(discrete_lanczos_derivative&&) noexcept = default; + +private: + std::vector m_f; + std::vector> m_boundary_filters; + Real m_dt; +}; + +} // namespaces +#endif diff --git a/libcxx/src/third-party/boost/math/distributions.hpp b/libcxx/src/third-party/boost/math/distributions.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions.hpp @@ -0,0 +1,54 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007, 2009, 2010. + +// 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) + +// This file includes *all* the distributions. +// this *may* be convenient if many are used +// - to avoid including each distribution individually. + +#ifndef BOOST_MATH_DISTRIBUTIONS_HPP +#define BOOST_MATH_DISTRIBUTIONS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/arcsine.hpp b/libcxx/src/third-party/boost/math/distributions/arcsine.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/arcsine.hpp @@ -0,0 +1,541 @@ +// boost/math/distributions/arcsine.hpp + +// Copyright John Maddock 2014. +// Copyright Paul A. Bristow 2014. + +// 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) + +// http://en.wikipedia.org/wiki/arcsine_distribution + +// The arcsine Distribution is a continuous probability distribution. +// http://en.wikipedia.org/wiki/Arcsine_distribution +// http://www.wolframalpha.com/input/?i=ArcSinDistribution + +// Standard arcsine distribution is a special case of beta distribution with both a & b = one half, +// and 0 <= x <= 1. + +// It is generalized to include any bounded support a <= x <= b from 0 <= x <= 1 +// by Wolfram and Wikipedia, +// but using location and scale parameters by +// Virtual Laboratories in Probability and Statistics http://www.math.uah.edu/stat/index.html +// http://www.math.uah.edu/stat/special/Arcsine.html +// The end-point version is simpler and more obvious, so we implement that. +// TODO Perhaps provide location and scale functions? + + +#ifndef BOOST_MATH_DIST_ARCSINE_HPP +#define BOOST_MATH_DIST_ARCSINE_HPP + +#include +#include +#include // complements. +#include // error checks. +#include + +#include // isnan. + +#if defined (BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4702) // Unreachable code, +// in domain_error_imp in error_handling. +#endif + +#include +#include // For std::domain_error. + +namespace boost +{ + namespace math + { + namespace arcsine_detail + { + // Common error checking routines for arcsine distribution functions: + // Duplicating for x_min and x_max provides specific error messages. + template + inline bool check_x_min(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x_min argument is %1%, but must be finite !", x, pol); + return false; + } + return true; + } // bool check_x_min + + template + inline bool check_x_max(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x_max argument is %1%, but must be finite !", x, pol); + return false; + } + return true; + } // bool check_x_max + + + template + inline bool check_x_minmax(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol) + { // Check x_min < x_max + if (x_min >= x_max) + { + std::string msg = "x_max argument is %1%, but must be > x_min"; + *result = policies::raise_domain_error( + function, + msg.c_str(), x_max, pol); + // "x_max argument is %1%, but must be > x_min !", x_max, pol); + // "x_max argument is %1%, but must be > x_min %2!", x_max, x_min, pol); would be better. + // But would require replication of all helpers functions in /policies/error_handling.hpp for two values, + // as well as two value versions of raise_error, raise_domain_error and do_format + return false; + } + return true; + } // bool check_x_minmax + + template + inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if ((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + inline bool check_x(const char* function, const RealType& x_min, const RealType& x_max, const RealType& x, RealType* result, const Policy& pol) + { // Check x finite and x_min < x < x_max. + if (!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be finite !", x, pol); + return false; + } + if ((x < x_min) || (x > x_max)) + { + // std::cout << x_min << ' ' << x << x_max << std::endl; + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be x_min < x < x_max !", x, pol); + // For example: + // Error in function boost::math::pdf(arcsine_distribution const&, double) : x argument is -1.01, but must be x_min < x < x_max ! + // TODO Perhaps show values of x_min and x_max? + return false; + } + return true; + } // bool check_x + + template + inline bool check_dist(const char* function, const RealType& x_min, const RealType& x_max, RealType* result, const Policy& pol) + { // Check both x_min and x_max finite, and x_min < x_max. + return check_x_min(function, x_min, result, pol) + && check_x_max(function, x_max, result, pol) + && check_x_minmax(function, x_min, x_max, result, pol); + } // bool check_dist + + template + inline bool check_dist_and_x(const char* function, const RealType& x_min, const RealType& x_max, RealType x, RealType* result, const Policy& pol) + { + return check_dist(function, x_min, x_max, result, pol) + && arcsine_detail::check_x(function, x_min, x_max, x, result, pol); + } // bool check_dist_and_x + + template + inline bool check_dist_and_prob(const char* function, const RealType& x_min, const RealType& x_max, RealType p, RealType* result, const Policy& pol) + { + return check_dist(function, x_min, x_max, result, pol) + && check_prob(function, p, result, pol); + } // bool check_dist_and_prob + + } // namespace arcsine_detail + + template > + class arcsine_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + arcsine_distribution(RealType x_min = 0, RealType x_max = 1) : m_x_min(x_min), m_x_max(x_max) + { // Default beta (alpha = beta = 0.5) is standard arcsine with x_min = 0, x_max = 1. + // Generalized to allow x_min and x_max to be specified. + RealType result; + arcsine_detail::check_dist( + "boost::math::arcsine_distribution<%1%>::arcsine_distribution", + m_x_min, + m_x_max, + &result, Policy()); + } // arcsine_distribution constructor. + // Accessor functions: + RealType x_min() const + { + return m_x_min; + } + RealType x_max() const + { + return m_x_max; + } + + private: + RealType m_x_min; // Two x min and x max parameters of the arcsine distribution. + RealType m_x_max; + }; // template class arcsine_distribution + + // Convenient typedef to construct double version. + typedef arcsine_distribution arcsine; + + #ifdef __cpp_deduction_guides + template + arcsine_distribution(RealType)->arcsine_distribution::type>; + template + arcsine_distribution(RealType, RealType)->arcsine_distribution::type>; + #endif + + template + inline const std::pair range(const arcsine_distribution& dist) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(dist.x_min()), static_cast(dist.x_max())); + } + + template + inline const std::pair support(const arcsine_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(dist.x_min()), static_cast(dist.x_max())); + } + + template + inline RealType mean(const arcsine_distribution& dist) + { // Mean of arcsine distribution . + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::mean(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; + } // mean + + template + inline RealType variance(const arcsine_distribution& dist) + { // Variance of standard arcsine distribution = (1-0)/8 = 0.125. + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist( + "boost::math::variance(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_max - x_min) * (x_max - x_min) / 8; + } // variance + + template + inline RealType mode(const arcsine_distribution& /* dist */) + { //There are always [*two] values for the mode, at ['x_min] and at ['x_max], default 0 and 1, + // so instead we raise the exception domain_error. + return policies::raise_domain_error( + "boost::math::mode(arcsine_distribution<%1%>&)", + "The arcsine distribution has two modes at x_min and x_max: " + "so the return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); + } // mode + + template + inline RealType median(const arcsine_distribution& dist) + { // Median of arcsine distribution (a + b) / 2 == mean. + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + RealType result; + if (false == arcsine_detail::check_dist( + "boost::math::median(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return (x_min + x_max) / 2; + } + + template + inline RealType skewness(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::skewness(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + return 0; + } // skewness + + template + inline RealType kurtosis_excess(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis_excess(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + result = -3; + return result / 2; + } // kurtosis_excess + + template + inline RealType kurtosis(const arcsine_distribution& dist) + { + RealType result; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + if (false == arcsine_detail::check_dist( + "boost::math::kurtosis(arcsine_distribution<%1%> const&, %1% )", + x_min, + x_max, + &result, Policy()) + ) + { + return result; + } + + return 3 + kurtosis_excess(dist); + } // kurtosis + + template + inline RealType pdf(const arcsine_distribution& dist, const RealType& xx) + { // Probability Density/Mass Function arcsine. + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // For ADL of std functions. + + static const char* function = "boost::math::pdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType lo = dist.x_min(); + RealType hi = dist.x_max(); + RealType x = xx; + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + lo, hi, x, + &result, Policy())) + { + return result; + } + using boost::math::constants::pi; + result = static_cast(1) / (pi() * sqrt((x - lo) * (hi - x))); + return result; + } // pdf + + template + inline RealType cdf(const arcsine_distribution& dist, const RealType& x) + { // Cumulative Distribution Function arcsine. + BOOST_MATH_STD_USING // For ADL of std functions. + + static const char* function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + x_min, x_max, x, + &result, Policy())) + { + return result; + } + // Special cases: + if (x == x_min) + { + return 0; + } + else if (x == x_max) + { + return 1; + } + using boost::math::constants::pi; + result = static_cast(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi(); + return result; + } // arcsine cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function arcsine. + BOOST_MATH_STD_USING // For ADL of std functions. + static const char* function = "boost::math::cdf(arcsine_distribution<%1%> const&, %1%)"; + + RealType x = c.param; + arcsine_distribution const& dist = c.dist; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + + // Argument checks: + RealType result = 0; + if (false == arcsine_detail::check_dist_and_x( + function, + x_min, x_max, x, + &result, Policy())) + { + return result; + } + if (x == x_min) + { + return 0; + } + else if (x == x_max) + { + return 1; + } + using boost::math::constants::pi; + // Naive version x = 1 - x; + // result = static_cast(2) * asin(sqrt((x - x_min) / (x_max - x_min))) / pi(); + // is less accurate, so use acos instead of asin for complement. + result = static_cast(2) * acos(sqrt((x - x_min) / (x_max - x_min))) / pi(); + return result; + } // arcsine ccdf + + template + inline RealType quantile(const arcsine_distribution& dist, const RealType& p) + { + // Quantile or Percent Point arcsine function or + // Inverse Cumulative probability distribution function CDF. + // Return x (0 <= x <= 1), + // for a given probability p (0 <= p <= 1). + // These functions take a probability as an argument + // and return a value such that the probability that a random variable x + // will be less than or equal to that value + // is whatever probability you supplied as an argument. + BOOST_MATH_STD_USING // For ADL of std functions. + + using boost::math::constants::half_pi; + + static const char* function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)"; + + RealType result = 0; // of argument checks: + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist_and_prob( + function, + x_min, x_max, p, + &result, Policy())) + { + return result; + } + // Special cases: + if (p == 0) + { + return 0; + } + if (p == 1) + { + return 1; + } + + RealType sin2hpip = sin(half_pi() * p); + RealType sin2hpip2 = sin2hpip * sin2hpip; + result = -x_min * sin2hpip2 + x_min + x_max * sin2hpip2; + + return result; + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + // Complement Quantile or Percent Point arcsine function. + // Return the number of expected x for a given + // complement of the probability q. + BOOST_MATH_STD_USING // For ADL of std functions. + + using boost::math::constants::half_pi; + static const char* function = "boost::math::quantile(arcsine_distribution<%1%> const&, %1%)"; + + // Error checks: + RealType q = c.param; + const arcsine_distribution& dist = c.dist; + RealType result = 0; + RealType x_min = dist.x_min(); + RealType x_max = dist.x_max(); + if (false == arcsine_detail::check_dist_and_prob( + function, + x_min, + x_max, + q, + &result, Policy())) + { + return result; + } + // Special cases: + if (q == 1) + { + return 0; + } + if (q == 0) + { + return 1; + } + // Naive RealType p = 1 - q; result = sin(half_pi() * p); loses accuracy, so use a cos alternative instead. + //result = cos(half_pi() * q); // for arcsine(0,1) + //result = result * result; + // For generalized arcsine: + RealType cos2hpip = cos(half_pi() * q); + RealType cos2hpip2 = cos2hpip * cos2hpip; + result = -x_min * cos2hpip2 + x_min + x_max * cos2hpip2; + + return result; + } // Quantile Complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DIST_ARCSINE_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/bernoulli.hpp b/libcxx/src/third-party/boost/math/distributions/bernoulli.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/bernoulli.hpp @@ -0,0 +1,341 @@ +// boost\math\distributions\bernoulli.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. + +// 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) + +// http://en.wikipedia.org/wiki/bernoulli_distribution +// http://mathworld.wolfram.com/BernoulliDistribution.html + +// bernoulli distribution is the discrete probability distribution of +// the number (k) of successes, in a single Bernoulli trials. +// It is a version of the binomial distribution when n = 1. + +// But note that the bernoulli distribution +// (like others including the poisson, binomial & negative binomial) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +#ifndef BOOST_MATH_SPECIAL_BERNOULLI_HPP +#define BOOST_MATH_SPECIAL_BERNOULLI_HPP + +#include +#include +#include // complements +#include // error checks +#include // isnan. + +#include + +namespace boost +{ + namespace math + { + namespace bernoulli_detail + { + // Common error checking routines for bernoulli distribution functions: + template + inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& /* pol */) + { + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, Policy()); + return false; + } + return true; + } + template + inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */, const std::true_type&) + { + return check_success_fraction(function, p, result, Policy()); + } + template + inline bool check_dist(const char* , const RealType& , RealType* , const Policy& /* pol */, const std::false_type&) + { + return true; + } + template + inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& /* pol */) + { + return check_dist(function, p, result, Policy(), typename policies::constructor_error_check::type()); + } + + template + inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, p, result, Policy(), typename policies::method_error_check::type()) == false) + { + return false; + } + if(!(boost::math::isfinite)(k) || !((k == 0) || (k == 1))) + { + *result = policies::raise_domain_error( + function, + "Number of successes argument is %1%, but must be 0 or 1 !", k, pol); + return false; + } + return true; + } + template + inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& /* pol */) + { + if((check_dist(function, p, result, Policy(), typename policies::method_error_check::type()) && detail::check_probability(function, prob, result, Policy())) == false) + { + return false; + } + return true; + } + } // namespace bernoulli_detail + + + template > + class bernoulli_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + bernoulli_distribution(RealType p = 0.5) : m_p(p) + { // Default probability = half suits 'fair' coin tossing + // where probability of heads == probability of tails. + RealType result; // of checks. + bernoulli_detail::check_dist( + "boost::math::bernoulli_distribution<%1%>::bernoulli_distribution", + m_p, + &result, Policy()); + } // bernoulli_distribution constructor. + + RealType success_fraction() const + { // Probability. + return m_p; + } + + private: + RealType m_p; // success_fraction + }; // template class bernoulli_distribution + + typedef bernoulli_distribution bernoulli; + + #ifdef __cpp_deduction_guides + template + bernoulli_distribution(RealType)->bernoulli_distribution::type>; + #endif + + template + inline const std::pair range(const bernoulli_distribution& /* dist */) + { // Range of permissible values for random variable k = {0, 1}. + using boost::math::tools::max_value; + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline const std::pair support(const bernoulli_distribution& /* dist */) + { // Range of supported values for random variable k = {0, 1}. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline RealType mean(const bernoulli_distribution& dist) + { // Mean of bernoulli distribution = p (n = 1). + return dist.success_fraction(); + } // mean + + // Rely on dereived_accessors quantile(half) + //template + //inline RealType median(const bernoulli_distribution& dist) + //{ // Median of bernoulli distribution is not defined. + // return tools::domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + + template + inline RealType variance(const bernoulli_distribution& dist) + { // Variance of bernoulli distribution =p * q. + return dist.success_fraction() * (1 - dist.success_fraction()); + } // variance + + template + RealType pdf(const bernoulli_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + // Error check: + RealType result = 0; // of checks. + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::pdf(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), // 0 to 1 + k, // 0 or 1 + &result, Policy())) + { + return result; + } + // Assume k is integral. + if (k == 0) + { + return 1 - dist.success_fraction(); // 1 - p + } + else // k == 1 + { + return dist.success_fraction(); // p + } + } // pdf + + template + inline RealType cdf(const bernoulli_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Bernoulli. + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::cdf(bernoulli_distribution<%1%>, %1%)", + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return 1 - p; + } + else + { // k == 1 + return 1; + } + } // bernoulli cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function bernoulli. + RealType const& k = c.param; + bernoulli_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + // Error checks: + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_k( + "boost::math::cdf(bernoulli_distribution<%1%>, %1%)", + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return p; + } + else + { // k == 1 + return 0; + } + } // bernoulli cdf complement + + template + inline RealType quantile(const bernoulli_distribution& dist, const RealType& p) + { // Quantile or Percent Point Bernoulli function. + // Return the number of expected successes k either 0 or 1. + // for a given probability p. + + RealType result = 0; // of error checks: + if(false == bernoulli_detail::check_dist_and_prob( + "boost::math::quantile(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), + p, + &result, Policy())) + { + return result; + } + if (p <= (1 - dist.success_fraction())) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + else + { + return 1; + } + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point bernoulli function. + // Return the number of expected successes k for a given + // complement of the probability q. + // + // Error checks: + RealType q = c.param; + const bernoulli_distribution& dist = c.dist; + RealType result = 0; + if(false == bernoulli_detail::check_dist_and_prob( + "boost::math::quantile(bernoulli_distribution<%1%>, %1%)", + dist.success_fraction(), + q, + &result, Policy())) + { + return result; + } + + if (q <= 1 - dist.success_fraction()) + { // // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 1; + } + else + { + return 0; + } + } // quantile complemented. + + template + inline RealType mode(const bernoulli_distribution& dist) + { + return static_cast((dist.success_fraction() <= 0.5) ? 0 : 1); // p = 0.5 can be 0 or 1 + } + + template + inline RealType skewness(const bernoulli_distribution& dist) + { + BOOST_MATH_STD_USING; // Aid ADL for sqrt. + RealType p = dist.success_fraction(); + return (1 - 2 * p) / sqrt(p * (1 - p)); + } + + template + inline RealType kurtosis_excess(const bernoulli_distribution& dist) + { + RealType p = dist.success_fraction(); + // Note Wolfram says this is kurtosis in text, but gamma2 is the kurtosis excess, + // and Wikipedia also says this is the kurtosis excess formula. + // return (6 * p * p - 6 * p + 1) / (p * (1 - p)); + // But Wolfram kurtosis article gives this simpler formula for kurtosis excess: + return 1 / (1 - p) + 1/p -6; + } + + template + inline RealType kurtosis(const bernoulli_distribution& dist) + { + RealType p = dist.success_fraction(); + return 1 / (1 - p) + 1/p -6 + 3; + // Simpler than: + // return (6 * p * p - 6 * p + 1) / (p * (1 - p)) + 3; + } + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_BERNOULLI_HPP + + + diff --git a/libcxx/src/third-party/boost/math/distributions/beta.hpp b/libcxx/src/third-party/boost/math/distributions/beta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/beta.hpp @@ -0,0 +1,555 @@ +// boost\math\distributions\beta.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 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) + +// http://en.wikipedia.org/wiki/Beta_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm +// http://mathworld.wolfram.com/BetaDistribution.html + +// The Beta Distribution is a continuous probability distribution. +// The beta distribution is used to model events which are constrained to take place +// within an interval defined by maxima and minima, +// so is used extensively in PERT and other project management systems +// to describe the time to completion. +// The cdf of the beta distribution is used as a convenient way +// of obtaining the sum over a set of binomial outcomes. +// The beta distribution is also used in Bayesian statistics. + +#ifndef BOOST_MATH_DIST_BETA_HPP +#define BOOST_MATH_DIST_BETA_HPP + +#include +#include // for beta. +#include // complements. +#include // error checks +#include // isnan. +#include // for root finding. + +#if defined (BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code +// in domain_error_imp in error_handling +#endif + +#include + +namespace boost +{ + namespace math + { + namespace beta_detail + { + // Common error checking routines for beta distribution functions: + template + inline bool check_alpha(const char* function, const RealType& alpha, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(alpha) || (alpha <= 0)) + { + *result = policies::raise_domain_error( + function, + "Alpha argument is %1%, but must be > 0 !", alpha, pol); + return false; + } + return true; + } // bool check_alpha + + template + inline bool check_beta(const char* function, const RealType& beta, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(beta) || (beta <= 0)) + { + *result = policies::raise_domain_error( + function, + "Beta argument is %1%, but must be > 0 !", beta, pol); + return false; + } + return true; + } // bool check_beta + + template + inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + inline bool check_x(const char* function, const RealType& x, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(x) || (x < 0) || (x > 1)) + { + *result = policies::raise_domain_error( + function, + "x argument is %1%, but must be >= 0 and <= 1 !", x, pol); + return false; + } + return true; + } // bool check_x + + template + inline bool check_dist(const char* function, const RealType& alpha, const RealType& beta, RealType* result, const Policy& pol) + { // Check both alpha and beta. + return check_alpha(function, alpha, result, pol) + && check_beta(function, beta, result, pol); + } // bool check_dist + + template + inline bool check_dist_and_x(const char* function, const RealType& alpha, const RealType& beta, RealType x, RealType* result, const Policy& pol) + { + return check_dist(function, alpha, beta, result, pol) + && beta_detail::check_x(function, x, result, pol); + } // bool check_dist_and_x + + template + inline bool check_dist_and_prob(const char* function, const RealType& alpha, const RealType& beta, RealType p, RealType* result, const Policy& pol) + { + return check_dist(function, alpha, beta, result, pol) + && check_prob(function, p, result, pol); + } // bool check_dist_and_prob + + template + inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(mean) || (mean <= 0)) + { + *result = policies::raise_domain_error( + function, + "mean argument is %1%, but must be > 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean + template + inline bool check_variance(const char* function, const RealType& variance, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(variance) || (variance <= 0)) + { + *result = policies::raise_domain_error( + function, + "variance argument is %1%, but must be > 0 !", variance, pol); + return false; + } + return true; + } // bool check_variance + } // namespace beta_detail + + // typedef beta_distribution beta; + // is deliberately NOT included to avoid a name clash with the beta function. + // Use beta_distribution<> mybeta(...) to construct type double. + + template > + class beta_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + beta_distribution(RealType l_alpha = 1, RealType l_beta = 1) : m_alpha(l_alpha), m_beta(l_beta) + { + RealType result; + beta_detail::check_dist( + "boost::math::beta_distribution<%1%>::beta_distribution", + m_alpha, + m_beta, + &result, Policy()); + } // beta_distribution constructor. + // Accessor functions: + RealType alpha() const + { + return m_alpha; + } + RealType beta() const + { // . + return m_beta; + } + + // Estimation of the alpha & beta parameters. + // http://en.wikipedia.org/wiki/Beta_distribution + // gives formulae in section on parameter estimation. + // Also NIST EDA page 3 & 4 give the same. + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm + // http://www.epi.ucdavis.edu/diagnostictests/betabuster.html + + static RealType find_alpha( + RealType mean, // Expected value of mean. + RealType variance) // Expected value of variance. + { + static const char* function = "boost::math::beta_distribution<%1%>::find_alpha"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_mean(function, mean, &result, Policy()) + && beta_detail::check_variance(function, variance, &result, Policy()) + ) + ) + { + return result; + } + return mean * (( (mean * (1 - mean)) / variance)- 1); + } // RealType find_alpha + + static RealType find_beta( + RealType mean, // Expected value of mean. + RealType variance) // Expected value of variance. + { + static const char* function = "boost::math::beta_distribution<%1%>::find_beta"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_mean(function, mean, &result, Policy()) + && + beta_detail::check_variance(function, variance, &result, Policy()) + ) + ) + { + return result; + } + return (1 - mean) * (((mean * (1 - mean)) /variance)-1); + } // RealType find_beta + + // Estimate alpha & beta from either alpha or beta, and x and probability. + // Uses for these parameter estimators are unclear. + + static RealType find_alpha( + RealType beta, // from beta. + RealType x, // x. + RealType probability) // cdf + { + static const char* function = "boost::math::beta_distribution<%1%>::find_alpha"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_prob(function, probability, &result, Policy()) + && + beta_detail::check_beta(function, beta, &result, Policy()) + && + beta_detail::check_x(function, x, &result, Policy()) + ) + ) + { + return result; + } + return ibeta_inva(beta, x, probability, Policy()); + } // RealType find_alpha(beta, a, probability) + + static RealType find_beta( + // ibeta_invb(T b, T x, T p); (alpha, x, cdf,) + RealType alpha, // alpha. + RealType x, // probability x. + RealType probability) // probability cdf. + { + static const char* function = "boost::math::beta_distribution<%1%>::find_beta"; + RealType result = 0; // of error checks. + if(false == + ( + beta_detail::check_prob(function, probability, &result, Policy()) + && + beta_detail::check_alpha(function, alpha, &result, Policy()) + && + beta_detail::check_x(function, x, &result, Policy()) + ) + ) + { + return result; + } + return ibeta_invb(alpha, x, probability, Policy()); + } // RealType find_beta(alpha, x, probability) + + private: + RealType m_alpha; // Two parameters of the beta distribution. + RealType m_beta; + }; // template class beta_distribution + + #ifdef __cpp_deduction_guides + template + beta_distribution(RealType)->beta_distribution::type>; + template + beta_distribution(RealType, RealType)->beta_distribution::type>; + #endif + + template + inline const std::pair range(const beta_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline const std::pair support(const beta_distribution& /* dist */) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline RealType mean(const beta_distribution& dist) + { // Mean of beta distribution = np. + return dist.alpha() / (dist.alpha() + dist.beta()); + } // mean + + template + inline RealType variance(const beta_distribution& dist) + { // Variance of beta distribution = np(1-p). + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (a * b) / ((a + b ) * (a + b) * (a + b + 1)); + } // variance + + template + inline RealType mode(const beta_distribution& dist) + { + static const char* function = "boost::math::mode(beta_distribution<%1%> const&)"; + + RealType result; + if ((dist.alpha() <= 1)) + { + result = policies::raise_domain_error( + function, + "mode undefined for alpha = %1%, must be > 1!", dist.alpha(), Policy()); + return result; + } + + if ((dist.beta() <= 1)) + { + result = policies::raise_domain_error( + function, + "mode undefined for beta = %1%, must be > 1!", dist.beta(), Policy()); + return result; + } + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (a-1) / (a + b - 2); + } // mode + + //template + //inline RealType median(const beta_distribution& dist) + //{ // Median of beta distribution is not defined. + // return tools::domain_error(function, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + + //But WILL be provided by the derived accessor as quantile(0.5). + + template + inline RealType skewness(const beta_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType a = dist.alpha(); + RealType b = dist.beta(); + return (2 * (b-a) * sqrt(a + b + 1)) / ((a + b + 2) * sqrt(a * b)); + } // skewness + + template + inline RealType kurtosis_excess(const beta_distribution& dist) + { + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType a_2 = a * a; + RealType n = 6 * (a_2 * a - a_2 * (2 * b - 1) + b * b * (b + 1) - 2 * a * b * (b + 2)); + RealType d = a * b * (a + b + 2) * (a + b + 3); + return n / d; + } // kurtosis_excess + + template + inline RealType kurtosis(const beta_distribution& dist) + { + return 3 + kurtosis_excess(dist); + } // kurtosis + + template + inline RealType pdf(const beta_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + static const char* function = "boost::math::pdf(beta_distribution<%1%> const&, %1%)"; + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + using boost::math::beta; + + // Corner case: check_x ensures x element of [0, 1], but PDF is 0 for x = 0 and x = 1. PDF EQN: + // https://wikimedia.org/api/rest_v1/media/math/render/svg/125fdaa41844a8703d1a8610ac00fbf3edacc8e7 + if(x == 0 || x == 1) + { + return RealType(0); + } + return ibeta_derivative(a, b, x, Policy()); + } // pdf + + template + inline RealType cdf(const beta_distribution& dist, const RealType& x) + { // Cumulative Distribution Function beta. + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)"; + + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + // Special cases: + if (x == 0) + { + return 0; + } + else if (x == 1) + { + return 1; + } + return ibeta(a, b, x, Policy()); + } // beta cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function beta. + + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(beta_distribution<%1%> const&, %1%)"; + + RealType const& x = c.param; + beta_distribution const& dist = c.dist; + RealType a = dist.alpha(); + RealType b = dist.beta(); + + // Argument checks: + RealType result = 0; + if(false == beta_detail::check_dist_and_x( + function, + a, b, x, + &result, Policy())) + { + return result; + } + if (x == 0) + { + return 1; + } + else if (x == 1) + { + return 0; + } + // Calculate cdf beta using the incomplete beta function. + // Use of ibeta here prevents cancellation errors in calculating + // 1 - x if x is very small, perhaps smaller than machine epsilon. + return ibetac(a, b, x, Policy()); + } // beta cdf + + template + inline RealType quantile(const beta_distribution& dist, const RealType& p) + { // Quantile or Percent Point beta function or + // Inverse Cumulative probability distribution function CDF. + // Return x (0 <= x <= 1), + // for a given probability p (0 <= p <= 1). + // These functions take a probability as an argument + // and return a value such that the probability that a random variable x + // will be less than or equal to that value + // is whatever probability you supplied as an argument. + + static const char* function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)"; + + RealType result = 0; // of argument checks: + RealType a = dist.alpha(); + RealType b = dist.beta(); + if(false == beta_detail::check_dist_and_prob( + function, + a, b, p, + &result, Policy())) + { + return result; + } + // Special cases: + if (p == 0) + { + return 0; + } + if (p == 1) + { + return 1; + } + return ibeta_inv(a, b, p, static_cast(nullptr), Policy()); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Complement Quantile or Percent Point beta function . + // Return the number of expected x for a given + // complement of the probability q. + + static const char* function = "boost::math::quantile(beta_distribution<%1%> const&, %1%)"; + + // + // Error checks: + RealType q = c.param; + const beta_distribution& dist = c.dist; + RealType result = 0; + RealType a = dist.alpha(); + RealType b = dist.beta(); + if(false == beta_detail::check_dist_and_prob( + function, + a, + b, + q, + &result, Policy())) + { + return result; + } + // Special cases: + if(q == 1) + { + return 0; + } + if(q == 0) + { + return 1; + } + + return ibetac_inv(a, b, q, static_cast(nullptr), Policy()); + } // Quantile Complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DIST_BETA_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/binomial.hpp b/libcxx/src/third-party/boost/math/distributions/binomial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/binomial.hpp @@ -0,0 +1,730 @@ +// boost\math\distributions\binomial.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. + +// 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) + +// http://en.wikipedia.org/wiki/binomial_distribution + +// Binomial distribution is the discrete probability distribution of +// the number (k) of successes, in a sequence of +// n independent (yes or no, success or failure) Bernoulli trials. + +// It expresses the probability of a number of events occurring in a fixed time +// if these events occur with a known average rate (probability of success), +// and are independent of the time since the last event. + +// The number of cars that pass through a certain point on a road during a given period of time. +// The number of spelling mistakes a secretary makes while typing a single page. +// The number of phone calls at a call center per minute. +// The number of times a web server is accessed per minute. +// The number of light bulbs that burn out in a certain amount of time. +// The number of roadkill found per unit length of road + +// http://en.wikipedia.org/wiki/binomial_distribution + +// Given a sample of N measured values k[i], +// we wish to estimate the value of the parameter x (mean) +// of the binomial population from which the sample was drawn. +// To calculate the maximum likelihood value = 1/N sum i = 1 to N of k[i] + +// Also may want a function for EXACTLY k. + +// And probability that there are EXACTLY k occurrences is +// exp(-x) * pow(x, k) / factorial(k) +// where x is expected occurrences (mean) during the given interval. +// For example, if events occur, on average, every 4 min, +// and we are interested in number of events occurring in 10 min, +// then x = 10/4 = 2.5 + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366i.htm + +// The binomial distribution is used when there are +// exactly two mutually exclusive outcomes of a trial. +// These outcomes are appropriately labeled "success" and "failure". +// The binomial distribution is used to obtain +// the probability of observing x successes in N trials, +// with the probability of success on a single trial denoted by p. +// The binomial distribution assumes that p is fixed for all trials. + +// P(x, p, n) = n!/(x! * (n-x)!) * p^x * (1-p)^(n-x) + +// http://mathworld.wolfram.com/BinomialCoefficient.html + +// The binomial coefficient (n; k) is the number of ways of picking +// k unordered outcomes from n possibilities, +// also known as a combination or combinatorial number. +// The symbols _nC_k and (n; k) are used to denote a binomial coefficient, +// and are sometimes read as "n choose k." +// (n; k) therefore gives the number of k-subsets possible out of a set of n distinct items. + +// For example: +// The 2-subsets of {1,2,3,4} are the six pairs {1,2}, {1,3}, {1,4}, {2,3}, {2,4}, and {3,4}, so (4; 2)==6. + +// http://functions.wolfram.com/GammaBetaErf/Binomial/ for evaluation. + +// But note that the binomial distribution +// (like others including the poisson, negative binomial & Bernoulli) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +#ifndef BOOST_MATH_SPECIAL_BINOMIAL_HPP +#define BOOST_MATH_SPECIAL_BINOMIAL_HPP + +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include // error checks +#include // isnan. +#include // for root finding. + +#include + +namespace boost +{ + namespace math + { + + template + class binomial_distribution; + + namespace binomial_detail{ + // common error checking routines for binomial distribution functions: + template + inline bool check_N(const char* function, const RealType& N, RealType* result, const Policy& pol) + { + if((N < 0) || !(boost::math::isfinite)(N)) + { + *result = policies::raise_domain_error( + function, + "Number of Trials argument is %1%, but must be >= 0 !", N, pol); + return false; + } + return true; + } + template + inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if((p < 0) || (p > 1) || !(boost::math::isfinite)(p)) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + template + inline bool check_dist(const char* function, const RealType& N, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction( + function, p, result, pol) + && check_N( + function, N, result, pol); + } + template + inline bool check_dist_and_k(const char* function, const RealType& N, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, N, p, result, pol) == false) + return false; + if((k < 0) || !(boost::math::isfinite)(k)) + { + *result = policies::raise_domain_error( + function, + "Number of Successes argument is %1%, but must be >= 0 !", k, pol); + return false; + } + if(k > N) + { + *result = policies::raise_domain_error( + function, + "Number of Successes argument is %1%, but must be <= Number of Trials !", k, pol); + return false; + } + return true; + } + template + inline bool check_dist_and_prob(const char* function, const RealType& N, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, N, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + return false; + return true; + } + + template + T inverse_binomial_cornish_fisher(T n, T sf, T p, T q, const Policy& pol) + { + BOOST_MATH_STD_USING + // mean: + T m = n * sf; + // standard deviation: + T sigma = sqrt(n * sf * (1 - sf)); + // skewness + T sk = (1 - 2 * sf) / sigma; + // kurtosis: + // T k = (1 - 6 * sf * (1 - sf) ) / (n * sf * (1 - sf)); + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + /* + // Add on correction due to kurtosis. + // Disabled for now, seems to make things worse? + // + if(n >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + */ + w = m + sigma * w; + if(w < tools::min_value()) + return sqrt(tools::min_value()); + if(w > n) + return n; + return w; + } + + template + RealType quantile_imp(const binomial_distribution& dist, const RealType& p, const RealType& q, bool comp) + { // Quantile or Percent Point Binomial function. + // Return the number of expected successes k, + // for a given probability p. + // + // Error checks: + BOOST_MATH_STD_USING // ADL of std names + RealType result = 0; + RealType trials = dist.trials(); + RealType success_fraction = dist.success_fraction(); + if(false == binomial_detail::check_dist_and_prob( + "boost::math::quantile(binomial_distribution<%1%> const&, %1%)", + trials, + success_fraction, + p, + &result, Policy())) + { + return result; + } + + // Special cases: + // + if(p == 0) + { // There may actually be no answer to this question, + // since the probability of zero successes may be non-zero, + // but zero is the best we can do: + return 0; + } + if(p == 1) + { // Probability of n or fewer successes is always one, + // so n is the most sensible answer here: + return trials; + } + if (p <= pow(1 - success_fraction, trials)) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; // So the only reasonable result is zero. + } // And root finder would fail otherwise. + if(success_fraction == 1) + { // our formulae break down in this case: + return p > 0.5f ? trials : 0; + } + + // Solve for quantile numerically: + // + RealType guess = binomial_detail::inverse_binomial_cornish_fisher(trials, success_fraction, p, q, Policy()); + RealType factor = 8; + if(trials > 100) + factor = 1.01f; // guess is pretty accurate + else if((trials > 10) && (trials - 1 > guess) && (guess > 3)) + factor = 1.15f; // less accurate but OK. + else if(trials < 10) + { + // pretty inaccurate guess in this area: + if(guess > trials / 64) + { + guess = trials / 4; + factor = 2; + } + else + guess = trials / 1024; + } + else + factor = 2; // trials largish, but in far tails. + + typedef typename Policy::discrete_quantile_type discrete_quantile_type; + std::uintmax_t max_iter = policies::get_max_root_iterations(); + return detail::inverse_discrete_quantile( + dist, + comp ? q : p, + comp, + guess, + factor, + RealType(1), + discrete_quantile_type(), + max_iter); + } // quantile + + } + + template > + class binomial_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + binomial_distribution(RealType n = 1, RealType p = 0.5) : m_n(n), m_p(p) + { // Default n = 1 is the Bernoulli distribution + // with equal probability of 'heads' or 'tails. + RealType r; + binomial_detail::check_dist( + "boost::math::binomial_distribution<%1%>::binomial_distribution", + m_n, + m_p, + &r, Policy()); + } // binomial_distribution constructor. + + RealType success_fraction() const + { // Probability. + return m_p; + } + RealType trials() const + { // Total number of trials. + return m_n; + } + + enum interval_type{ + clopper_pearson_exact_interval, + jeffreys_prior_interval + }; + + // + // Estimation of the success fraction parameter. + // The best estimate is actually simply successes/trials, + // these functions are used + // to obtain confidence intervals for the success fraction. + // + static RealType find_lower_bound_on_p( + RealType trials, + RealType successes, + RealType probability, + interval_type t = clopper_pearson_exact_interval) + { + static const char* function = "boost::math::binomial_distribution<%1%>::find_lower_bound_on_p"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, trials, RealType(0), successes, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, trials, RealType(0), probability, &result, Policy())) + { return result; } + + if(successes == 0) + return 0; + + // NOTE!!! The Clopper Pearson formula uses "successes" not + // "successes+1" as usual to get the lower bound, + // see http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + return (t == clopper_pearson_exact_interval) ? ibeta_inv(successes, trials - successes + 1, probability, static_cast(nullptr), Policy()) + : ibeta_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast(nullptr), Policy()); + } + static RealType find_upper_bound_on_p( + RealType trials, + RealType successes, + RealType probability, + interval_type t = clopper_pearson_exact_interval) + { + static const char* function = "boost::math::binomial_distribution<%1%>::find_upper_bound_on_p"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, trials, RealType(0), successes, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, trials, RealType(0), probability, &result, Policy())) + { return result; } + + if(trials == successes) + return 1; + + return (t == clopper_pearson_exact_interval) ? ibetac_inv(successes + 1, trials - successes, probability, static_cast(nullptr), Policy()) + : ibetac_inv(successes + 0.5f, trials - successes + 0.5f, probability, static_cast(nullptr), Policy()); + } + // Estimate number of trials parameter: + // + // "How many trials do I need to be P% sure of seeing k events?" + // or + // "How many trials can I have to be P% sure of seeing fewer than k events?" + // + static RealType find_minimum_number_of_trials( + RealType k, // number of events + RealType p, // success fraction + RealType alpha) // risk level + { + static const char* function = "boost::math::binomial_distribution<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, k, p, k, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, k, p, alpha, &result, Policy())) + { return result; } + + result = ibetac_invb(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } + + static RealType find_maximum_number_of_trials( + RealType k, // number of events + RealType p, // success fraction + RealType alpha) // risk level + { + static const char* function = "boost::math::binomial_distribution<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + function, k, p, k, &result, Policy()) + && + binomial_detail::check_dist_and_prob( + function, k, p, alpha, &result, Policy())) + { return result; } + + result = ibeta_invb(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } + + private: + RealType m_n; // Not sure if this shouldn't be an int? + RealType m_p; // success_fraction + }; // template class binomial_distribution + + typedef binomial_distribution<> binomial; + // typedef binomial_distribution binomial; + // IS now included since no longer a name clash with function binomial. + //typedef binomial_distribution binomial; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + binomial_distribution(RealType)->binomial_distribution::type>; + template + binomial_distribution(RealType,RealType)->binomial_distribution::type>; + #endif + + template + const std::pair range(const binomial_distribution& dist) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), dist.trials()); + } + + template + const std::pair support(const binomial_distribution& dist) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(0), dist.trials()); + } + + template + inline RealType mean(const binomial_distribution& dist) + { // Mean of Binomial distribution = np. + return dist.trials() * dist.success_fraction(); + } // mean + + template + inline RealType variance(const binomial_distribution& dist) + { // Variance of Binomial distribution = np(1-p). + return dist.trials() * dist.success_fraction() * (1 - dist.success_fraction()); + } // variance + + template + RealType pdf(const binomial_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType n = dist.trials(); + + // Error check: + RealType result = 0; // initialization silences some compiler warnings + if(false == binomial_detail::check_dist_and_k( + "boost::math::pdf(binomial_distribution<%1%> const&, %1%)", + n, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + // Special cases of success_fraction, regardless of k successes and regardless of n trials. + if (dist.success_fraction() == 0) + { // probability of zero successes is 1: + return static_cast(k == 0 ? 1 : 0); + } + if (dist.success_fraction() == 1) + { // probability of n successes is 1: + return static_cast(k == n ? 1 : 0); + } + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + if (n == 0) + { + return 1; // Probability = 1 = certainty. + } + if (k == n) + { // binomial coeffic (n n) = 1, + // n ^ 0 = 1 + return pow(dist.success_fraction(), k); // * pow((1 - dist.success_fraction()), (n - k)) = 1 + } + + // Probability of getting exactly k successes + // if C(n, k) is the binomial coefficient then: + // + // f(k; n,p) = C(n, k) * p^k * (1-p)^(n-k) + // = (n!/(k!(n-k)!)) * p^k * (1-p)^(n-k) + // = (tgamma(n+1) / (tgamma(k+1)*tgamma(n-k+1))) * p^k * (1-p)^(n-k) + // = p^k (1-p)^(n-k) / (beta(k+1, n-k+1) * (n+1)) + // = ibeta_derivative(k+1, n-k+1, p) / (n+1) + // + using boost::math::ibeta_derivative; // a, b, x + return ibeta_derivative(k+1, n-k+1, dist.success_fraction(), Policy()) / (n+1); + + } // pdf + + template + inline RealType cdf(const binomial_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Binomial. + // The random variate k is the number of successes in n trials. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + + // Returns the sum of the terms 0 through k of the Binomial Probability Density/Mass: + // + // i=k + // -- ( n ) i n-i + // > | | p (1-p) + // -- ( i ) + // i=0 + + // The terms are not summed directly instead + // the incomplete beta integral is employed, + // according to the formula: + // P = I[1-p]( n-k, k+1). + // = 1 - I[p](k + 1, n - k) + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType n = dist.trials(); + RealType p = dist.success_fraction(); + + // Error check: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + "boost::math::cdf(binomial_distribution<%1%> const&, %1%)", + n, + p, + k, + &result, Policy())) + { + return result; + } + if (k == n) + { + return 1; + } + + // Special cases, regardless of k. + if (p == 0) + { // This need explanation: + // the pdf is zero for all cases except when k == 0. + // For zero p the probability of zero successes is one. + // Therefore the cdf is always 1: + // the probability of k or *fewer* successes is always 1 + // if there are never any successes! + return 1; + } + if (p == 1) + { // This is correct but needs explanation: + // when k = 1 + // all the cdf and pdf values are zero *except* when k == n, + // and that case has been handled above already. + return 0; + } + // + // P = I[1-p](n - k, k + 1) + // = 1 - I[p](k + 1, n - k) + // Use of ibetac here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // + // Note that we do not use a finite sum here, since the incomplete + // beta uses a finite sum internally for integer arguments, so + // we'll just let it take care of the necessary logic. + // + return ibetac(k + 1, n - k, p, Policy()); + } // binomial cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Binomial. + // The random variate k is the number of successes in n trials. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + + // Returns the sum of the terms k+1 through n of the Binomial Probability Density/Mass: + // + // i=n + // -- ( n ) i n-i + // > | | p (1-p) + // -- ( i ) + // i=k+1 + + // The terms are not summed directly instead + // the incomplete beta integral is employed, + // according to the formula: + // Q = 1 -I[1-p]( n-k, k+1). + // = I[p](k + 1, n - k) + + BOOST_MATH_STD_USING // for ADL of std functions + + RealType const& k = c.param; + binomial_distribution const& dist = c.dist; + RealType n = dist.trials(); + RealType p = dist.success_fraction(); + + // Error checks: + RealType result = 0; + if(false == binomial_detail::check_dist_and_k( + "boost::math::cdf(binomial_distribution<%1%> const&, %1%)", + n, + p, + k, + &result, Policy())) + { + return result; + } + + if (k == n) + { // Probability of greater than n successes is necessarily zero: + return 0; + } + + // Special cases, regardless of k. + if (p == 0) + { + // This need explanation: the pdf is zero for all + // cases except when k == 0. For zero p the probability + // of zero successes is one. Therefore the cdf is always + // 1: the probability of *more than* k successes is always 0 + // if there are never any successes! + return 0; + } + if (p == 1) + { + // This needs explanation, when p = 1 + // we always have n successes, so the probability + // of more than k successes is 1 as long as k < n. + // The k == n case has already been handled above. + return 1; + } + // + // Calculate cdf binomial using the incomplete beta function. + // Q = 1 -I[1-p](n - k, k + 1) + // = I[p](k + 1, n - k) + // Use of ibeta here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // + // Note that we do not use a finite sum here, since the incomplete + // beta uses a finite sum internally for integer arguments, so + // we'll just let it take care of the necessary logic. + // + return ibeta(k + 1, n - k, p, Policy()); + } // binomial cdf + + template + inline RealType quantile(const binomial_distribution& dist, const RealType& p) + { + return binomial_detail::quantile_imp(dist, p, RealType(1-p), false); + } // quantile + + template + RealType quantile(const complemented2_type, RealType>& c) + { + return binomial_detail::quantile_imp(c.dist, RealType(1-c.param), c.param, true); + } // quantile + + template + inline RealType mode(const binomial_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return floor(p * (n + 1)); + } + + template + inline RealType median(const binomial_distribution& dist) + { // Bounds for the median of the negative binomial distribution + // VAN DE VEN R. ; WEBER N. C. ; + // Univ. Sydney, school mathematics statistics, Sydney N.S.W. 2006, AUSTRALIE + // Metrika (Metrika) ISSN 0026-1335 CODEN MTRKA8 + // 1993, vol. 40, no3-4, pp. 185-189 (4 ref.) + + // Bounds for median and 50 percentage point of binomial and negative binomial distribution + // Metrika, ISSN 0026-1335 (Print) 1435-926X (Online) + // Volume 41, Number 1 / December, 1994, DOI 10.1007/BF01895303 + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + // Wikipedia says one of floor(np) -1, floor (np), floor(np) +1 + return floor(p * n); // Chose the middle value. + } + + template + inline RealType skewness(const binomial_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return (1 - 2 * p) / sqrt(n * p * (1 - p)); + } + + template + inline RealType kurtosis(const binomial_distribution& dist) + { + RealType p = dist.success_fraction(); + RealType n = dist.trials(); + return 3 - 6 / n + 1 / (n * p * (1 - p)); + } + + template + inline RealType kurtosis_excess(const binomial_distribution& dist) + { + RealType p = dist.success_fraction(); + RealType q = 1 - p; + RealType n = dist.trials(); + return (1 - 6 * p * q) / (n * p * q); + } + + } // namespace math + } // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_BINOMIAL_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/cauchy.hpp b/libcxx/src/third-party/boost/math/distributions/cauchy.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/cauchy.hpp @@ -0,0 +1,375 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2007. + +// 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_STATS_CAUCHY_HPP +#define BOOST_STATS_CAUCHY_HPP + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math +{ + +template +class cauchy_distribution; + +namespace detail +{ + +template +RealType cdf_imp(const cauchy_distribution& dist, const RealType& x, bool complement) +{ + // + // This calculates the cdf of the Cauchy distribution and/or its complement. + // + // The usual formula for the Cauchy cdf is: + // + // cdf = 0.5 + atan(x)/pi + // + // But that suffers from cancellation error as x -> -INF. + // + // Recall that for x < 0: + // + // atan(x) = -pi/2 - atan(1/x) + // + // Substituting into the above we get: + // + // CDF = -atan(1/x) ; x < 0 + // + // So the procedure is to calculate the cdf for -fabs(x) + // using the above formula, and then subtract from 1 when required + // to get the result. + // + BOOST_MATH_STD_USING // for ADL of std functions + static const char* function = "boost::math::cdf(cauchy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(std::numeric_limits::has_infinity && x == std::numeric_limits::infinity()) + { // cdf +infinity is unity. + return static_cast((complement) ? 0 : 1); + } + if(std::numeric_limits::has_infinity && x == -std::numeric_limits::infinity()) + { // cdf -infinity is zero. + return static_cast((complement) ? 1 : 0); + } + if(false == detail::check_x(function, x, &result, Policy())) + { // Catches x == NaN + return result; + } + RealType mx = -fabs((x - location) / scale); // scale is > 0 + if(mx > -tools::epsilon() / 8) + { // special case first: x extremely close to location. + return 0.5; + } + result = -atan(1 / mx) / constants::pi(); + return (((x > location) != complement) ? 1 - result : result); +} // cdf + +template +RealType quantile_imp( + const cauchy_distribution& dist, + const RealType& p, + bool complement) +{ + // This routine implements the quantile for the Cauchy distribution, + // the value p may be the probability, or its complement if complement=true. + // + // The procedure first performs argument reduction on p to avoid error + // when calculating the tangent, then calculates the distance from the + // mid-point of the distribution. This is either added or subtracted + // from the location parameter depending on whether `complement` is true. + // + static const char* function = "boost::math::quantile(cauchy<%1%>&, %1%)"; + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + // Special cases: + if(p == 1) + { + return (complement ? -1 : 1) * policies::raise_overflow_error(function, 0, Policy()); + } + if(p == 0) + { + return (complement ? 1 : -1) * policies::raise_overflow_error(function, 0, Policy()); + } + + RealType P = p - floor(p); // argument reduction of p: + if(P > 0.5) + { + P = P - 1; + } + if(P == 0.5) // special case: + { + return location; + } + result = -scale / tan(constants::pi() * P); + return complement ? RealType(location - result) : RealType(location + result); +} // quantile + +} // namespace detail + +template > +class cauchy_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + cauchy_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_a(l_location), m_hg(l_scale) + { + static const char* function = "boost::math::cauchy_distribution<%1%>::cauchy_distribution"; + RealType result; + detail::check_location(function, l_location, &result, Policy()); + detail::check_scale(function, l_scale, &result, Policy()); + } // cauchy_distribution + + RealType location()const + { + return m_a; + } + RealType scale()const + { + return m_hg; + } + +private: + RealType m_a; // The location, this is the median of the distribution. + RealType m_hg; // The scale )or shape), this is the half width at half height. +}; + +typedef cauchy_distribution cauchy; + +#ifdef __cpp_deduction_guides +template +cauchy_distribution(RealType)->cauchy_distribution::type>; +template +cauchy_distribution(RealType,RealType)->cauchy_distribution::type>; +#endif + +template +inline const std::pair range(const cauchy_distribution&) +{ // Range of permissible values for random variable x. + if (std::numeric_limits::has_infinity) + { + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max. + } +} + +template +inline const std::pair support(const cauchy_distribution& ) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + if (std::numeric_limits::has_infinity) + { + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-tools::max_value(), max_value()); // - to + max. + } +} + +template +inline RealType pdf(const cauchy_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(cauchy<%1%>&, %1%)"; + RealType result = 0; + RealType location = dist.location(); + RealType scale = dist.scale(); + if(false == detail::check_scale("boost::math::pdf(cauchy<%1%>&, %1%)", scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location("boost::math::pdf(cauchy<%1%>&, %1%)", location, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && abs(x) == std::numeric_limits::infinity()) + //{ // pdf + and - infinity is zero. + // return 0; + //} + + if(false == detail::check_x(function, x, &result, Policy())) + { // Catches x = NaN + return result; + } + + RealType xs = (x - location) / scale; + result = 1 / (constants::pi() * scale * (1 + xs * xs)); + return result; +} // pdf + +template +inline RealType cdf(const cauchy_distribution& dist, const RealType& x) +{ + return detail::cdf_imp(dist, x, false); +} // cdf + +template +inline RealType quantile(const cauchy_distribution& dist, const RealType& p) +{ + return detail::quantile_imp(dist, p, false); +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + return detail::cdf_imp(c.dist, c.param, true); +} // cdf complement + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + return detail::quantile_imp(c.dist, c.param, true); +} // quantile complement + +template +inline RealType mean(const cauchy_distribution&) +{ // There is no mean: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "assert type is undefined"); + + return policies::raise_domain_error( + "boost::math::mean(cauchy<%1%>&)", + "The Cauchy distribution does not have a mean: " + "the only possible return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); +} + +template +inline RealType variance(const cauchy_distribution& /*dist*/) +{ + // There is no variance: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "assert type is undefined"); + + return policies::raise_domain_error( + "boost::math::variance(cauchy<%1%>&)", + "The Cauchy distribution does not have a variance: " + "the only possible return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); +} + +template +inline RealType mode(const cauchy_distribution& dist) +{ + return dist.location(); +} + +template +inline RealType median(const cauchy_distribution& dist) +{ + return dist.location(); +} +template +inline RealType skewness(const cauchy_distribution& /*dist*/) +{ + // There is no skewness: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "assert type is undefined"); + + return policies::raise_domain_error( + "boost::math::skewness(cauchy<%1%>&)", + "The Cauchy distribution does not have a skewness: " + "the only possible return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); // infinity? +} + +template +inline RealType kurtosis(const cauchy_distribution& /*dist*/) +{ + // There is no kurtosis: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "assert type is undefined"); + + return policies::raise_domain_error( + "boost::math::kurtosis(cauchy<%1%>&)", + "The Cauchy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); +} + +template +inline RealType kurtosis_excess(const cauchy_distribution& /*dist*/) +{ + // There is no kurtosis excess: + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "assert type is undefined"); + + return policies::raise_domain_error( + "boost::math::kurtosis_excess(cauchy<%1%>&)", + "The Cauchy distribution does not have a kurtosis: " + "the only possible return value is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); +} + +template +inline RealType entropy(const cauchy_distribution & dist) +{ + using std::log; + return log(2*constants::two_pi()*dist.scale()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_CAUCHY_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/chi_squared.hpp b/libcxx/src/third-party/boost/math/distributions/chi_squared.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/chi_squared.hpp @@ -0,0 +1,345 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2008, 2010. + +// 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_DISTRIBUTIONS_CHI_SQUARED_HPP +#define BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP + +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include + +#include + +namespace boost{ namespace math{ + +template > +class chi_squared_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit chi_squared_distribution(RealType i) : m_df(i) + { + RealType result; + detail::check_df( + "boost::math::chi_squared_distribution<%1%>::chi_squared_distribution", m_df, &result, Policy()); + } // chi_squared_distribution + + RealType degrees_of_freedom()const + { + return m_df; + } + + // Parameter estimation: + static RealType find_degrees_of_freedom( + RealType difference_from_variance, + RealType alpha, + RealType beta, + RealType variance, + RealType hint = 100); + +private: + // + // Data member: + // + RealType m_df; // degrees of freedom is a positive real number. +}; // class chi_squared_distribution + +using chi_squared = chi_squared_distribution; + +#ifdef __cpp_deduction_guides +template +chi_squared_distribution(RealType)->chi_squared_distribution::type>; +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +inline std::pair range(const chi_squared_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + if (std::numeric_limits::has_infinity) + { + return std::pair(static_cast(0), std::numeric_limits::infinity()); // 0 to + infinity. + } + else + { + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // 0 to + max. + } +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +inline std::pair support(const chi_squared_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(0), tools::max_value()); // 0 to + infinity. +} + +template +RealType pdf(const chi_squared_distribution& dist, const RealType& chi_square) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType degrees_of_freedom = dist.degrees_of_freedom(); + // Error check: + RealType error_result; + + static const char* function = "boost::math::pdf(const chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + if(chi_square == 0) + { + // Handle special cases: + if(degrees_of_freedom < 2) + { + return policies::raise_overflow_error( + function, 0, Policy()); + } + else if(degrees_of_freedom == 2) + { + return 0.5f; + } + else + { + return 0; + } + } + + return gamma_p_derivative(degrees_of_freedom / 2, chi_square / 2, Policy()) / 2; +} // pdf + +template +inline RealType cdf(const chi_squared_distribution& dist, const RealType& chi_square) +{ + RealType degrees_of_freedom = dist.degrees_of_freedom(); + // Error check: + RealType error_result; + static const char* function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + return boost::math::gamma_p(degrees_of_freedom / 2, chi_square / 2, Policy()); +} // cdf + +template +inline RealType quantile(const chi_squared_distribution& dist, const RealType& p) +{ + RealType degrees_of_freedom = dist.degrees_of_freedom(); + static const char* function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == + ( + detail::check_df(function, degrees_of_freedom, &error_result, Policy()) + && detail::check_probability(function, p, &error_result, Policy())) + ) + return error_result; + + return 2 * boost::math::gamma_p_inv(degrees_of_freedom / 2, p, Policy()); +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + RealType const& degrees_of_freedom = c.dist.degrees_of_freedom(); + RealType const& chi_square = c.param; + static const char* function = "boost::math::cdf(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, degrees_of_freedom, &error_result, Policy())) + return error_result; + + if((chi_square < 0) || !(boost::math::isfinite)(chi_square)) + { + return policies::raise_domain_error( + function, "Chi Square parameter was %1%, but must be > 0 !", chi_square, Policy()); + } + + return boost::math::gamma_q(degrees_of_freedom / 2, chi_square / 2, Policy()); +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + RealType const& degrees_of_freedom = c.dist.degrees_of_freedom(); + RealType const& q = c.param; + static const char* function = "boost::math::quantile(const chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == ( + detail::check_df(function, degrees_of_freedom, &error_result, Policy()) + && detail::check_probability(function, q, &error_result, Policy())) + ) + return error_result; + + return 2 * boost::math::gamma_q_inv(degrees_of_freedom / 2, q, Policy()); +} + +template +inline RealType mean(const chi_squared_distribution& dist) +{ // Mean of Chi-Squared distribution = v. + return dist.degrees_of_freedom(); +} // mean + +template +inline RealType variance(const chi_squared_distribution& dist) +{ // Variance of Chi-Squared distribution = 2v. + return 2 * dist.degrees_of_freedom(); +} // variance + +template +inline RealType mode(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + static const char* function = "boost::math::mode(const chi_squared_distribution<%1%>&)"; + + if(df < 2) + return policies::raise_domain_error( + function, + "Chi-Squared distribution only has a mode for degrees of freedom >= 2, but got degrees of freedom = %1%.", + df, Policy()); + return df - 2; +} + +template +inline RealType skewness(const chi_squared_distribution& dist) +{ + BOOST_MATH_STD_USING // For ADL + RealType df = dist.degrees_of_freedom(); + return sqrt (8 / df); +} + +template +inline RealType kurtosis(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + return 3 + 12 / df; +} + +template +inline RealType kurtosis_excess(const chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + return 12 / df; +} + +// +// Parameter estimation comes last: +// +namespace detail +{ + +template +struct df_estimator +{ + df_estimator(RealType a, RealType b, RealType variance, RealType delta) + : alpha(a), beta(b), ratio(delta/variance) + { // Constructor + } + + RealType operator()(const RealType& df) + { + if(df <= tools::min_value()) + return 1; + chi_squared_distribution cs(df); + + RealType result; + if(ratio > 0) + { + RealType r = 1 + ratio; + result = cdf(cs, quantile(complement(cs, alpha)) / r) - beta; + } + else + { // ratio <= 0 + RealType r = 1 + ratio; + result = cdf(complement(cs, quantile(cs, alpha) / r)) - beta; + } + return result; + } +private: + RealType alpha; + RealType beta; + RealType ratio; // Difference from variance / variance, so fractional. +}; + +} // namespace detail + +template +RealType chi_squared_distribution::find_degrees_of_freedom( + RealType difference_from_variance, + RealType alpha, + RealType beta, + RealType variance, + RealType hint) +{ + static const char* function = "boost::math::chi_squared_distribution<%1%>::find_degrees_of_freedom(%1%,%1%,%1%,%1%,%1%)"; + // Check for domain errors: + RealType error_result; + if(false == + detail::check_probability(function, alpha, &error_result, Policy()) + && detail::check_probability(function, beta, &error_result, Policy())) + { // Either probability is outside 0 to 1. + return error_result; + } + + if(hint <= 0) + { // No hint given, so guess df = 1. + hint = 1; + } + + detail::df_estimator f(alpha, beta, variance, difference_from_variance); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + std::pair r = + tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy()); + RealType result = r.first + (r.second - r.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " either there is no answer to how many degrees of freedom are required" + " or the answer is infinite. Current best guess is %1%", result, Policy()); + } + return result; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_CHI_SQUARED_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/complement.hpp b/libcxx/src/third-party/boost/math/distributions/complement.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/complement.hpp @@ -0,0 +1,195 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Paul A. Bristow 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_STATS_COMPLEMENT_HPP +#define BOOST_STATS_COMPLEMENT_HPP + +// +// This code really defines our own tuple type. +// It would be nice to reuse boost::math::tuple +// while retaining our own type safety, but it's +// not clear if that's possible. In any case this +// code is *very* lightweight. +// +namespace boost{ namespace math{ + +template +struct complemented2_type +{ + complemented2_type( + const Dist& d, + const RealType& p1) + : dist(d), + param(p1) {} + + const Dist& dist; + const RealType& param; + +private: + complemented2_type& operator=(const complemented2_type&) = delete; +}; + +template +struct complemented3_type +{ + complemented3_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2) + : dist(d), + param1(p1), + param2(p2) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; +private: + complemented3_type& operator=(const complemented3_type&) = delete; +}; + +template +struct complemented4_type +{ + complemented4_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3) + : dist(d), + param1(p1), + param2(p2), + param3(p3) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; +private: + complemented4_type& operator=(const complemented4_type&) = delete; +}; + +template +struct complemented5_type +{ + complemented5_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; +private: + complemented5_type& operator=(const complemented5_type&) = delete; +}; + +template +struct complemented6_type +{ + complemented6_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4, + const RealType5& p5) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4), + param5(p5) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; + const RealType5& param5; +private: + complemented6_type& operator=(const complemented6_type&) = delete; +}; + +template +struct complemented7_type +{ + complemented7_type( + const Dist& d, + const RealType1& p1, + const RealType2& p2, + const RealType3& p3, + const RealType4& p4, + const RealType5& p5, + const RealType6& p6) + : dist(d), + param1(p1), + param2(p2), + param3(p3), + param4(p4), + param5(p5), + param6(p6) {} + + const Dist& dist; + const RealType1& param1; + const RealType2& param2; + const RealType3& param3; + const RealType4& param4; + const RealType5& param5; + const RealType6& param6; +private: + complemented7_type& operator=(const complemented7_type&) = delete; +}; + +template +inline complemented2_type complement(const Dist& d, const RealType& r) +{ + return complemented2_type(d, r); +} + +template +inline complemented3_type complement(const Dist& d, const RealType1& r1, const RealType2& r2) +{ + return complemented3_type(d, r1, r2); +} + +template +inline complemented4_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3) +{ + return complemented4_type(d, r1, r2, r3); +} + +template +inline complemented5_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4) +{ + return complemented5_type(d, r1, r2, r3, r4); +} + +template +inline complemented6_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5) +{ + return complemented6_type(d, r1, r2, r3, r4, r5); +} + +template +inline complemented7_type complement(const Dist& d, const RealType1& r1, const RealType2& r2, const RealType3& r3, const RealType4& r4, const RealType5& r5, const RealType6& r6) +{ + return complemented7_type(d, r1, r2, r3, r4, r5, r6); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_STATS_COMPLEMENT_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/detail/common_error_handling.hpp b/libcxx/src/third-party/boost/math/distributions/detail/common_error_handling.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/common_error_handling.hpp @@ -0,0 +1,223 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007, 2012. + +// 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_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP +#define BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP + +#include +#include +// using boost::math::isfinite; +// using boost::math::isnan; + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost{ namespace math{ namespace detail +{ + +template +inline bool check_probability(const char* function, RealType const& prob, RealType* result, const Policy& pol) +{ + if((prob < 0) || (prob > 1) || !(boost::math::isfinite)(prob)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", prob, pol); + return false; + } + return true; +} + +template +inline bool check_df(const char* function, RealType const& df, RealType* result, const Policy& pol) +{ // df > 0 but NOT +infinity allowed. + if((df <= 0) || !(boost::math::isfinite)(df)) + { + *result = policies::raise_domain_error( + function, + "Degrees of freedom argument is %1%, but must be > 0 !", df, pol); + return false; + } + return true; +} + +template +inline bool check_df_gt0_to_inf(const char* function, RealType const& df, RealType* result, const Policy& pol) +{ // df > 0 or +infinity are allowed. + if( (df <= 0) || (boost::math::isnan)(df) ) + { // is bad df <= 0 or NaN or -infinity. + *result = policies::raise_domain_error( + function, + "Degrees of freedom argument is %1%, but must be > 0 !", df, pol); + return false; + } + return true; +} // check_df_gt0_to_inf + + +template +inline bool check_scale( + const char* function, + RealType scale, + RealType* result, + const Policy& pol) +{ + if((scale <= 0) || !(boost::math::isfinite)(scale)) + { // Assume scale == 0 is NOT valid for any distribution. + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be > 0 !", scale, pol); + return false; + } + return true; +} + +template +inline bool check_location( + const char* function, + RealType location, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(location)) + { + *result = policies::raise_domain_error( + function, + "Location parameter is %1%, but must be finite!", location, pol); + return false; + } + return true; +} + +template +inline bool check_x( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + // Note that this test catches both infinity and NaN. + // Some distributions permit x to be infinite, so these must be tested 1st and return, + // leaving this test to catch any NaNs. + // See Normal, Logistic, Laplace and Cauchy for example. + if(!(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite!", x, pol); + return false; + } + return true; +} // bool check_x + +template +inline bool check_x_not_NaN( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + // Note that this test catches only NaN. + // Some distributions permit x to be infinite, leaving this test to catch any NaNs. + // See Normal, Logistic, Laplace and Cauchy for example. + if ((boost::math::isnan)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite or + or - infinity!", x, pol); + return false; + } + return true; +} // bool check_x_not_NaN + +template +inline bool check_x_gt0( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(x <= 0) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be > 0!", x, pol); + return false; + } + + return true; + // Note that this test catches both infinity and NaN. + // Some special cases permit x to be infinite, so these must be tested 1st, + // leaving this test to catch any NaNs. See Normal and cauchy for example. +} // bool check_x_gt0 + +template +inline bool check_positive_x( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(x) || (x < 0)) + { + *result = policies::raise_domain_error( + function, + "Random variate x is %1%, but must be finite and >= 0!", x, pol); + return false; + } + return true; + // Note that this test catches both infinity and NaN. + // Some special cases permit x to be infinite, so these must be tested 1st, + // leaving this test to catch any NaNs. see Normal and cauchy for example. +} + +template +inline bool check_non_centrality( + const char* function, + RealType ncp, + RealType* result, + const Policy& pol) +{ + if((ncp < 0) || !(boost::math::isfinite)(ncp)) + { // Assume scale == 0 is NOT valid for any distribution. + *result = policies::raise_domain_error( + function, + "Non centrality parameter is %1%, but must be > 0 !", ncp, pol); + return false; + } + return true; +} + +template +inline bool check_finite( + const char* function, + RealType x, + RealType* result, + const Policy& pol) +{ + if(!(boost::math::isfinite)(x)) + { // Assume scale == 0 is NOT valid for any distribution. + *result = policies::raise_domain_error( + function, + "Parameter is %1%, but must be finite !", x, pol); + return false; + } + return true; +} + +} // namespace detail +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/detail/derived_accessors.hpp b/libcxx/src/third-party/boost/math/distributions/detail/derived_accessors.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/derived_accessors.hpp @@ -0,0 +1,170 @@ +// 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_STATS_DERIVED_HPP +#define BOOST_STATS_DERIVED_HPP + +// This file implements various common properties of distributions +// that can be implemented in terms of other properties: +// variance OR standard deviation (see note below), +// hazard, cumulative hazard (chf), coefficient_of_variation. +// +// Note that while both variance and standard_deviation are provided +// here, each distribution MUST SPECIALIZE AT LEAST ONE OF THESE +// otherwise these two versions will just call each other over and over +// until stack space runs out ... + +// Of course there may be more efficient means of implementing these +// that are specific to a particular distribution, but these generic +// versions give these properties "for free" with most distributions. +// +// In order to make use of this header, it must be included AT THE END +// of the distribution header, AFTER the distribution and its core +// property accessors have been defined: this is so that compilers +// that implement 2-phase lookup and early-type-checking of templates +// can find the definitions referred to herein. +// + +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4723) // potential divide by 0 +// Suppressing spurious warning in coefficient_of_variation +#endif + +namespace boost{ namespace math{ + +template +typename Distribution::value_type variance(const Distribution& dist); + +template +inline typename Distribution::value_type standard_deviation(const Distribution& dist) +{ + BOOST_MATH_STD_USING // ADL of sqrt. + return sqrt(variance(dist)); +} + +template +inline typename Distribution::value_type variance(const Distribution& dist) +{ + typename Distribution::value_type result = standard_deviation(dist); + return result * result; +} + +template +inline typename Distribution::value_type hazard(const Distribution& dist, const RealType& x) +{ // hazard function + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ + typedef typename Distribution::value_type value_type; + typedef typename Distribution::policy_type policy_type; + value_type p = cdf(complement(dist, x)); + value_type d = pdf(dist, x); + if(d > p * tools::max_value()) + return policies::raise_overflow_error( + "boost::math::hazard(const Distribution&, %1%)", nullptr, policy_type()); + if(d == 0) + { + // This protects against 0/0, but is it the right thing to do? + return 0; + } + return d / p; +} + +template +inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x) +{ // cumulative hazard function. + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda362.htm#HAZ + BOOST_MATH_STD_USING + return -log(cdf(complement(dist, x))); +} + +template +inline typename Distribution::value_type coefficient_of_variation(const Distribution& dist) +{ + typedef typename Distribution::value_type value_type; + typedef typename Distribution::policy_type policy_type; + + using std::abs; + + value_type m = mean(dist); + value_type d = standard_deviation(dist); + if((abs(m) < 1) && (d > abs(m) * tools::max_value())) + { // Checks too that m is not zero, + return policies::raise_overflow_error("boost::math::coefficient_of_variation(const Distribution&, %1%)", nullptr, policy_type()); + } + return d / m; // so MSVC warning on zerodivide is spurious, and suppressed. +} +// +// Next follow overloads of some of the standard accessors with mixed +// argument types. We just use a typecast to forward on to the "real" +// implementation with all arguments of the same type: +// +template +inline typename Distribution::value_type pdf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return pdf(dist, static_cast(x)); +} +template +inline typename Distribution::value_type logpdf(const Distribution& dist, const RealType& x) +{ + using std::log; + typedef typename Distribution::value_type value_type; + return log(pdf(dist, static_cast(x))); +} +template +inline typename Distribution::value_type cdf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return cdf(dist, static_cast(x)); +} +template +inline typename Distribution::value_type quantile(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return quantile(dist, static_cast(x)); +} +/* +template +inline typename Distribution::value_type chf(const Distribution& dist, const RealType& x) +{ + typedef typename Distribution::value_type value_type; + return chf(dist, static_cast(x)); +} +*/ +template +inline typename Distribution::value_type cdf(const complemented2_type& c) +{ + typedef typename Distribution::value_type value_type; + return cdf(complement(c.dist, static_cast(c.param))); +} + +template +inline typename Distribution::value_type quantile(const complemented2_type& c) +{ + typedef typename Distribution::value_type value_type; + return quantile(complement(c.dist, static_cast(c.param))); +} + +template +inline typename Dist::value_type median(const Dist& d) +{ // median - default definition for those distributions for which a + // simple closed form is not known, + // and for which a domain_error and/or NaN generating function is NOT defined. + typedef typename Dist::value_type value_type; + return quantile(d, static_cast(0.5f)); +} + +} // namespace math +} // namespace boost + + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_STATS_DERIVED_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/detail/generic_mode.hpp b/libcxx/src/third-party/boost/math/distributions/detail/generic_mode.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/generic_mode.hpp @@ -0,0 +1,149 @@ +// Copyright John Maddock 2008. + +// 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_DISTRIBUTIONS_DETAIL_MODE_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP + +#include // function minimization for mode +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct pdf_minimizer +{ + pdf_minimizer(const Dist& d) + : dist(d) {} + + typename Dist::value_type operator()(const typename Dist::value_type& x) + { + return -pdf(dist, x); + } +private: + Dist dist; +}; + +template +typename Dist::value_type generic_find_mode(const Dist& dist, typename Dist::value_type guess, const char* function, typename Dist::value_type step = 0) +{ + BOOST_MATH_STD_USING + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + // + // Need to begin by bracketing the maxima of the PDF: + // + value_type maxval; + value_type upper_bound = guess; + value_type lower_bound; + value_type v = pdf(dist, guess); + if(v == 0) + { + // + // Oops we don't know how to handle this, or even in which + // direction we should move in, treat as an evaluation error: + // + return policies::raise_evaluation_error( + function, + "Could not locate a starting location for the search for the mode, original guess was %1%", guess, policy_type()); + } + do + { + maxval = v; + if(step != 0) + upper_bound += step; + else + upper_bound *= 2; + v = pdf(dist, upper_bound); + }while(maxval < v); + + lower_bound = upper_bound; + do + { + maxval = v; + if(step != 0) + lower_bound -= step; + else + lower_bound /= 2; + v = pdf(dist, lower_bound); + }while(maxval < v); + + std::uintmax_t max_iter = policies::get_max_root_iterations(); + + value_type result = tools::brent_find_minima( + pdf_minimizer(dist), + lower_bound, + upper_bound, + policies::digits(), + max_iter).first; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error( + function, + "Unable to locate solution in a reasonable time:" + " either there is no answer to the mode of the distribution" + " or the answer is infinite. Current best guess is %1%", result, policy_type()); + } + return result; +} +// +// As above,but confined to the interval [0,1]: +// +template +typename Dist::value_type generic_find_mode_01(const Dist& dist, typename Dist::value_type guess, const char* function) +{ + BOOST_MATH_STD_USING + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + // + // Need to begin by bracketing the maxima of the PDF: + // + value_type maxval; + value_type upper_bound = guess; + value_type lower_bound; + value_type v = pdf(dist, guess); + do + { + maxval = v; + upper_bound = 1 - (1 - upper_bound) / 2; + if(upper_bound == 1) + return 1; + v = pdf(dist, upper_bound); + }while(maxval < v); + + lower_bound = upper_bound; + do + { + maxval = v; + lower_bound /= 2; + if(lower_bound < tools::min_value()) + return 0; + v = pdf(dist, lower_bound); + }while(maxval < v); + + std::uintmax_t max_iter = policies::get_max_root_iterations(); + + value_type result = tools::brent_find_minima( + pdf_minimizer(dist), + lower_bound, + upper_bound, + policies::digits(), + max_iter).first; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error( + function, + "Unable to locate solution in a reasonable time:" + " either there is no answer to the mode of the distribution" + " or the answer is infinite. Current best guess is %1%", result, policy_type()); + } + return result; +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_MODE_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/detail/generic_quantile.hpp b/libcxx/src/third-party/boost/math/distributions/detail/generic_quantile.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/generic_quantile.hpp @@ -0,0 +1,97 @@ +// Copyright John Maddock 2008. +// 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_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP +#define BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP + +namespace boost{ namespace math{ namespace detail{ + +template +struct generic_quantile_finder +{ + using value_type = typename Dist::value_type; + using policy_type = typename Dist::policy_type; + + generic_quantile_finder(const Dist& d, value_type t, bool c) + : dist(d), target(t), comp(c) {} + + value_type operator()(const value_type& x) + { + return comp ? + value_type(target - cdf(complement(dist, x))) + : value_type(cdf(dist, x) - target); + } + +private: + Dist dist; + value_type target; + bool comp; +}; + +template +inline T check_range_result(const T& x, const Policy& pol, const char* function) +{ + if((x >= 0) && (x < tools::min_value())) + { + return policies::raise_underflow_error(function, nullptr, pol); + } + if(x <= -tools::max_value()) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + if(x >= tools::max_value()) + { + return policies::raise_overflow_error(function, nullptr, pol); + } + return x; +} + +template +typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function) +{ + using value_type = typename Dist::value_type; + using policy_type = typename Dist::policy_type; + using forwarding_policy = typename policies::normalise< + policy_type, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + // + // Special cases first: + // + if(p == 0) + { + return comp + ? check_range_result(range(dist).second, forwarding_policy(), function) + : check_range_result(range(dist).first, forwarding_policy(), function); + } + if(p == 1) + { + return !comp + ? check_range_result(range(dist).second, forwarding_policy(), function) + : check_range_result(range(dist).first, forwarding_policy(), function); + } + + generic_quantile_finder f(dist, p, comp); + tools::eps_tolerance tol(policies::digits() - 3); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + std::pair ir = tools::bracket_and_solve_root( + f, guess, value_type(2), true, tol, max_iter, forwarding_policy()); + value_type result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " either there is no answer to quantile" + " or the answer is infinite. Current best guess is %1%", result, forwarding_policy()); + } + return result; +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTIBUTIONS_DETAIL_GENERIC_QUANTILE_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_cdf.hpp b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_cdf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_cdf.hpp @@ -0,0 +1,100 @@ +// Copyright 2008 John Maddock +// +// 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_DISTRIBUTIONS_DETAIL_HG_CDF_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_CDF_HPP + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + + template + T hypergeometric_cdf_imp(unsigned x, unsigned r, unsigned n, unsigned N, bool invert, const Policy& pol) + { +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + BOOST_MATH_STD_USING + T result = 0; + T mode = floor(T(r + 1) * T(n + 1) / (N + 2)); + if(x < mode) + { + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + unsigned lower_limit = static_cast((std::max)(0, static_cast(n + r) - static_cast(N))); + while(diff > (invert ? T(1) : result) * tools::epsilon()) + { + diff = T(x) * T((N + x) - n - r) * diff / (T(1 + n - x) * T(1 + r - x)); + result += diff; + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(x == lower_limit) + break; + --x; + } + } + else + { + invert = !invert; + unsigned upper_limit = (std::min)(r, n); + if(x != upper_limit) + { + ++x; + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + while((x <= upper_limit) && (diff > (invert ? T(1) : result) * tools::epsilon())) + { + diff = T(n - x) * T(r - x) * diff / (T(x + 1) * T((N + x + 1) - n - r)); + result += diff; + ++x; + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + if(invert) + result = 1 - result; + return result; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } + + template + inline T hypergeometric_cdf(unsigned x, unsigned r, unsigned n, unsigned N, bool invert, const Policy&) + { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type result; + result = detail::hypergeometric_cdf_imp(x, r, n, N, invert, forwarding_policy()); + if(result > 1) + { + result = 1; + } + if(result < 0) + { + result = 0; + } + return policies::checked_narrowing_cast(result, "boost::math::hypergeometric_cdf<%1%>(%1%,%1%,%1%,%1%)"); + } + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_pdf.hpp b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_pdf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_pdf.hpp @@ -0,0 +1,488 @@ +// Copyright 2008 Gautam Sewani +// Copyright 2008 John Maddock +// +// 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_DISTRIBUTIONS_DETAIL_HG_PDF_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_PDF_HPP + +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_INSTRUMENT +#include +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +void bubble_down_one(T* first, T* last, Func f) +{ + using std::swap; + T* next = first; + ++next; + while((next != last) && (!f(*first, *next))) + { + swap(*first, *next); + ++first; + ++next; + } +} + +template +struct sort_functor +{ + sort_functor(const T* exponents) : m_exponents(exponents){} + bool operator()(int i, int j) + { + return m_exponents[i] > m_exponents[j]; + } +private: + const T* m_exponents; +}; + +template +T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const Lanczos&, const Policy&) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_FPU + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(N); + BOOST_MATH_INSTRUMENT_VARIABLE(typeid(Lanczos).name()); + + T bases[9] = { + T(n) + static_cast(Lanczos::g()) + 0.5f, + T(r) + static_cast(Lanczos::g()) + 0.5f, + T(N - n) + static_cast(Lanczos::g()) + 0.5f, + T(N - r) + static_cast(Lanczos::g()) + 0.5f, + 1 / (T(N) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(n - x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(r - x) + static_cast(Lanczos::g()) + 0.5f), + 1 / (T(N - n - r + x) + static_cast(Lanczos::g()) + 0.5f) + }; + T exponents[9] = { + n + T(0.5f), + r + T(0.5f), + N - n + T(0.5f), + N - r + T(0.5f), + N + T(0.5f), + x + T(0.5f), + n - x + T(0.5f), + r - x + T(0.5f), + N - n - r + x + T(0.5f) + }; + int base_e_factors[9] = { + -1, -1, -1, -1, 1, 1, 1, 1, 1 + }; + int sorted_indexes[9] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8 + }; +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + std::sort(sorted_indexes, sorted_indexes + 9, sort_functor(exponents)); +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + + do{ + exponents[sorted_indexes[0]] -= exponents[sorted_indexes[1]]; + bases[sorted_indexes[1]] *= bases[sorted_indexes[0]]; + if((bases[sorted_indexes[1]] < tools::min_value()) && (exponents[sorted_indexes[1]] != 0)) + { + return 0; + } + base_e_factors[sorted_indexes[1]] += base_e_factors[sorted_indexes[0]]; + bubble_down_one(sorted_indexes, sorted_indexes + 9, sort_functor(exponents)); + +#ifdef BOOST_MATH_INSTRUMENT + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + }while(exponents[sorted_indexes[1]] > 1); + + // + // Combine equal powers: + // + int j = 8; + while(exponents[sorted_indexes[j]] == 0) --j; + while(j) + { + while(j && (exponents[sorted_indexes[j-1]] == exponents[sorted_indexes[j]])) + { + bases[sorted_indexes[j-1]] *= bases[sorted_indexes[j]]; + exponents[sorted_indexes[j]] = 0; + base_e_factors[sorted_indexes[j-1]] += base_e_factors[sorted_indexes[j]]; + bubble_down_one(sorted_indexes + j, sorted_indexes + 9, sort_functor(exponents)); + --j; + } + --j; + +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_VARIABLE(j); + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + } + +#ifdef BOOST_MATH_INSTRUMENT + BOOST_MATH_INSTRUMENT_FPU + for(unsigned i = 0; i < 9; ++i) + { + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(bases[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(base_e_factors[i]); + BOOST_MATH_INSTRUMENT_VARIABLE(sorted_indexes[i]); + } +#endif + + T result; + BOOST_MATH_INSTRUMENT_VARIABLE(bases[sorted_indexes[0]] * exp(static_cast(base_e_factors[sorted_indexes[0]]))); + BOOST_MATH_INSTRUMENT_VARIABLE(exponents[sorted_indexes[0]]); + { + BOOST_FPU_EXCEPTION_GUARD + result = pow(bases[sorted_indexes[0]] * exp(static_cast(base_e_factors[sorted_indexes[0]])), exponents[sorted_indexes[0]]); + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + for(unsigned i = 1; (i < 9) && (exponents[sorted_indexes[i]] > 0); ++i) + { + BOOST_FPU_EXCEPTION_GUARD + if(result < tools::min_value()) + return 0; // short circuit further evaluation + if(exponents[sorted_indexes[i]] == 1) + result *= bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]])); + else if(exponents[sorted_indexes[i]] == 0.5f) + result *= sqrt(bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]]))); + else + result *= pow(bases[sorted_indexes[i]] * exp(static_cast(base_e_factors[sorted_indexes[i]])), exponents[sorted_indexes[i]]); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + + result *= Lanczos::lanczos_sum_expG_scaled(static_cast(n + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(r + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - n + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - r + 1)) + / + ( Lanczos::lanczos_sum_expG_scaled(static_cast(N + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(n - x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(r - x + 1)) + * Lanczos::lanczos_sum_expG_scaled(static_cast(N - n - r + x + 1))); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result; +} + +template +T hypergeometric_pdf_lanczos_imp(T /*dummy*/, unsigned x, unsigned r, unsigned n, unsigned N, const boost::math::lanczos::undefined_lanczos&, const Policy& pol) +{ + BOOST_MATH_STD_USING + return exp( + boost::math::lgamma(T(n + 1), pol) + + boost::math::lgamma(T(r + 1), pol) + + boost::math::lgamma(T(N - n + 1), pol) + + boost::math::lgamma(T(N - r + 1), pol) + - boost::math::lgamma(T(N + 1), pol) + - boost::math::lgamma(T(x + 1), pol) + - boost::math::lgamma(T(n - x + 1), pol) + - boost::math::lgamma(T(r - x + 1), pol) + - boost::math::lgamma(T(N - n - r + x + 1), pol)); +} + +template +inline T integer_power(const T& x, int ex) +{ + if(ex < 0) + return 1 / integer_power(x, -ex); + switch(ex) + { + case 0: + return 1; + case 1: + return x; + case 2: + return x * x; + case 3: + return x * x * x; + case 4: + return boost::math::pow<4>(x); + case 5: + return boost::math::pow<5>(x); + case 6: + return boost::math::pow<6>(x); + case 7: + return boost::math::pow<7>(x); + case 8: + return boost::math::pow<8>(x); + } + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + return pow(x, T(ex)); +#else + return pow(x, ex); +#endif +} +template +struct hypergeometric_pdf_prime_loop_result_entry +{ + T value; + const hypergeometric_pdf_prime_loop_result_entry* next; +}; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4510 4512 4610) +#endif + +struct hypergeometric_pdf_prime_loop_data +{ + const unsigned x; + const unsigned r; + const unsigned n; + const unsigned N; + unsigned prime_index; + unsigned current_prime; +}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +T hypergeometric_pdf_prime_loop_imp(hypergeometric_pdf_prime_loop_data& data, hypergeometric_pdf_prime_loop_result_entry& result) +{ + while(data.current_prime <= data.N) + { + unsigned base = data.current_prime; + int prime_powers = 0; + while(base <= data.N) + { + prime_powers += data.n / base; + prime_powers += data.r / base; + prime_powers += (data.N - data.n) / base; + prime_powers += (data.N - data.r) / base; + prime_powers -= data.N / base; + prime_powers -= data.x / base; + prime_powers -= (data.n - data.x) / base; + prime_powers -= (data.r - data.x) / base; + prime_powers -= (data.N - data.n - data.r + data.x) / base; + base *= data.current_prime; + } + if(prime_powers) + { + T p = integer_power(static_cast(data.current_prime), prime_powers); + if((p > 1) && (tools::max_value() / p < result.value)) + { + // + // The next calculation would overflow, use recursion + // to sidestep the issue: + // + hypergeometric_pdf_prime_loop_result_entry t = { p, &result }; + data.current_prime = prime(++data.prime_index); + return hypergeometric_pdf_prime_loop_imp(data, t); + } + if((p < 1) && (tools::min_value() / p > result.value)) + { + // + // The next calculation would underflow, use recursion + // to sidestep the issue: + // + hypergeometric_pdf_prime_loop_result_entry t = { p, &result }; + data.current_prime = prime(++data.prime_index); + return hypergeometric_pdf_prime_loop_imp(data, t); + } + result.value *= p; + } + data.current_prime = prime(++data.prime_index); + } + // + // When we get to here we have run out of prime factors, + // the overall result is the product of all the partial + // results we have accumulated on the stack so far, these + // are in a linked list starting with "data.head" and ending + // with "result". + // + // All that remains is to multiply them together, taking + // care not to overflow or underflow. + // + // Enumerate partial results >= 1 in variable i + // and partial results < 1 in variable j: + // + hypergeometric_pdf_prime_loop_result_entry const *i, *j; + i = &result; + while(i && i->value < 1) + i = i->next; + j = &result; + while(j && j->value >= 1) + j = j->next; + + T prod = 1; + + while(i || j) + { + while(i && ((prod <= 1) || (j == 0))) + { + prod *= i->value; + i = i->next; + while(i && i->value < 1) + i = i->next; + } + while(j && ((prod >= 1) || (i == 0))) + { + prod *= j->value; + j = j->next; + while(j && j->value >= 1) + j = j->next; + } + } + + return prod; +} + +template +inline T hypergeometric_pdf_prime_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&) +{ + hypergeometric_pdf_prime_loop_result_entry result = { 1, 0 }; + hypergeometric_pdf_prime_loop_data data = { x, r, n, N, 0, prime(0) }; + return hypergeometric_pdf_prime_loop_imp(data, result); +} + +template +T hypergeometric_pdf_factorial_imp(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&) +{ + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(N <= boost::math::max_factorial::value); + T result = boost::math::unchecked_factorial(n); + T num[3] = { + boost::math::unchecked_factorial(r), + boost::math::unchecked_factorial(N - n), + boost::math::unchecked_factorial(N - r) + }; + T denom[5] = { + boost::math::unchecked_factorial(N), + boost::math::unchecked_factorial(x), + boost::math::unchecked_factorial(n - x), + boost::math::unchecked_factorial(r - x), + boost::math::unchecked_factorial(N - n - r + x) + }; + int i = 0; + int j = 0; + while((i < 3) || (j < 5)) + { + while((j < 5) && ((result >= 1) || (i >= 3))) + { + result /= denom[j]; + ++j; + } + while((i < 3) && ((result <= 1) || (j >= 5))) + { + result *= num[i]; + ++i; + } + } + return result; +} + + +template +inline typename tools::promote_args::type + hypergeometric_pdf(unsigned x, unsigned r, unsigned n, unsigned N, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type result; + if(N <= boost::math::max_factorial::value) + { + // + // If N is small enough then we can evaluate the PDF via the factorials + // directly: table lookup of the factorials gives the best performance + // of the methods available: + // + result = detail::hypergeometric_pdf_factorial_imp(x, r, n, N, forwarding_policy()); + } + else if(N <= boost::math::prime(boost::math::max_prime - 1)) + { + // + // If N is no larger than the largest prime number in our lookup table + // (104729) then we can use prime factorisation to evaluate the PDF, + // this is slow but accurate: + // + result = detail::hypergeometric_pdf_prime_imp(x, r, n, N, forwarding_policy()); + } + else + { + // + // Catch all case - use the lanczos approximation - where available - + // to evaluate the ratio of factorials. This is reasonably fast + // (almost as quick as using logarithmic evaluation in terms of lgamma) + // but only a few digits better in accuracy than using lgamma: + // + result = detail::hypergeometric_pdf_lanczos_imp(value_type(), x, r, n, N, evaluation_type(), forwarding_policy()); + } + + if(result > 1) + { + result = 1; + } + if(result < 0) + { + result = 0; + } + + return policies::checked_narrowing_cast(result, "boost::math::hypergeometric_pdf<%1%>(%1%,%1%,%1%,%1%)"); +} + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_quantile.hpp b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_quantile.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/hypergeometric_quantile.hpp @@ -0,0 +1,245 @@ +// Copyright 2008 John Maddock +// +// 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_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_HG_QUANTILE_HPP + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile&) +{ + if((p < cum * fudge_factor) && (x != lbound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x-1); + return --x; + } + return x; +} + +template +inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile&) +{ + if((cum < p * fudge_factor) && (x != ubound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x+1); + return ++x; + } + return x; +} + +template +inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile&) +{ + if(p >= 0.5) + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline unsigned round_x_from_p(unsigned x, T p, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile&) +{ + if(p >= 0.5) + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_p(x, p, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline unsigned round_x_from_p(unsigned x, T /*p*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile&) +{ + return x; +} + +template +inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned /*ubound*/, const policies::discrete_quantile&) +{ + if((q * fudge_factor > cum) && (x != lbound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x-1); + return --x; + } + return x; +} + +template +inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned /*lbound*/, unsigned ubound, const policies::discrete_quantile&) +{ + if((q < cum * fudge_factor) && (x != ubound)) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x+1); + return ++x; + } + return x; +} + +template +inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile&) +{ + if(q < 0.5) + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline unsigned round_x_from_q(unsigned x, T q, T cum, T fudge_factor, unsigned lbound, unsigned ubound, const policies::discrete_quantile&) +{ + if(q >= 0.5) + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); + return round_x_from_q(x, q, cum, fudge_factor, lbound, ubound, policies::discrete_quantile()); +} + +template +inline unsigned round_x_from_q(unsigned x, T /*q*/, T /*cum*/, T /*fudge_factor*/, unsigned /*lbound*/, unsigned /*ubound*/, const policies::discrete_quantile&) +{ + return x; +} + +template +unsigned hypergeometric_quantile_imp(T p, T q, unsigned r, unsigned n, unsigned N, const Policy& pol) +{ +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + typedef typename Policy::discrete_quantile_type discrete_quantile_type; + BOOST_MATH_STD_USING + BOOST_FPU_EXCEPTION_GUARD + T result; + T fudge_factor = 1 + tools::epsilon() * ((N <= boost::math::prime(boost::math::max_prime - 1)) ? 50 : 2 * N); + unsigned base = static_cast((std::max)(0, static_cast(n + r) - static_cast(N))); + unsigned lim = (std::min)(r, n); + + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(N); + BOOST_MATH_INSTRUMENT_VARIABLE(fudge_factor); + BOOST_MATH_INSTRUMENT_VARIABLE(base); + BOOST_MATH_INSTRUMENT_VARIABLE(lim); + + if(p <= 0.5) + { + unsigned x = base; + result = hypergeometric_pdf(x, r, n, N, pol); + T diff = result; + if (diff == 0) + { + ++x; + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + T log_pdf = boost::math::lgamma(static_cast(n + 1), pol) + + boost::math::lgamma(static_cast(r + 1), pol) + + boost::math::lgamma(static_cast(N - n + 1), pol) + + boost::math::lgamma(static_cast(N - r + 1), pol) + - boost::math::lgamma(static_cast(N + 1), pol) + - boost::math::lgamma(static_cast(x + 1), pol) + - boost::math::lgamma(static_cast(n - x + 1), pol) + - boost::math::lgamma(static_cast(r - x + 1), pol) + - boost::math::lgamma(static_cast(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value()) + { + log_pdf += -log(static_cast(x + 1)) + log(static_cast(n - x)) + log(static_cast(r - x)) - log(static_cast(N - n - r + x + 1)); + ++x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceeding: + diff = hypergeometric_pdf(x, r, n, N, pol); + } + while(result < p) + { + diff = (diff > tools::min_value() * 8) + ? T(n - x) * T(r - x) * diff / (T(x + 1) * T(N + x + 1 - n - r)) + : hypergeometric_pdf(x + 1, r, n, N, pol); + if(result + diff / 2 > p) + break; + ++x; + result += diff; +#ifdef BOOST_MATH_INSTRUMENT + if(diff != 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } +#endif + } + return round_x_from_p(x, p, result, fudge_factor, base, lim, discrete_quantile_type()); + } + else + { + unsigned x = lim; + result = 0; + T diff = hypergeometric_pdf(x, r, n, N, pol); + if (diff == 0) + { + // We want to skip through x values as fast as we can until we start getting non-zero values, + // otherwise we're just making lots of expensive PDF calls: + --x; + T log_pdf = boost::math::lgamma(static_cast(n + 1), pol) + + boost::math::lgamma(static_cast(r + 1), pol) + + boost::math::lgamma(static_cast(N - n + 1), pol) + + boost::math::lgamma(static_cast(N - r + 1), pol) + - boost::math::lgamma(static_cast(N + 1), pol) + - boost::math::lgamma(static_cast(x + 1), pol) + - boost::math::lgamma(static_cast(n - x + 1), pol) + - boost::math::lgamma(static_cast(r - x + 1), pol) + - boost::math::lgamma(static_cast(N - n - r + x + 1), pol); + while (log_pdf < tools::log_min_value()) + { + log_pdf += log(static_cast(x)) - log(static_cast(n - x + 1)) - log(static_cast(r - x + 1)) + log(static_cast(N - n - r + x)); + --x; + } + // By the time we get here, log_pdf may be fairly inaccurate due to + // roundoff errors, get a fresh PDF calculation before proceeding: + diff = hypergeometric_pdf(x, r, n, N, pol); + } + while(result + diff / 2 < q) + { + result += diff; + diff = (diff > tools::min_value() * 8) + ? x * T(N + x - n - r) * diff / (T(1 + n - x) * T(1 + r - x)) + : hypergeometric_pdf(x - 1, r, n, N, pol); + --x; +#ifdef BOOST_MATH_INSTRUMENT + if(diff != 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(diff); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } +#endif + } + return round_x_from_q(x, q, result, fudge_factor, base, lim, discrete_quantile_type()); + } +#ifdef _MSC_VER +# pragma warning(pop) +#endif +} + +template +inline unsigned hypergeometric_quantile(T p, T q, unsigned r, unsigned n, unsigned N, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::assert_undefined<> >::type forwarding_policy; + + return detail::hypergeometric_quantile_imp(p, q, r, n, N, forwarding_policy()); +} + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/distributions/detail/inv_discrete_quantile.hpp b/libcxx/src/third-party/boost/math/distributions/detail/inv_discrete_quantile.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/detail/inv_discrete_quantile.hpp @@ -0,0 +1,571 @@ +// Copyright John Maddock 2007. +// 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_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE +#define BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE + +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// Functor for root finding algorithm: +// +template +struct distribution_quantile_finder +{ + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + + distribution_quantile_finder(const Dist d, value_type p, bool c) + : dist(d), target(p), comp(c) {} + + value_type operator()(value_type const& x) + { + return comp ? value_type(target - cdf(complement(dist, x))) : value_type(cdf(dist, x) - target); + } + +private: + Dist dist; + value_type target; + bool comp; +}; +// +// The purpose of adjust_bounds, is to toggle the last bit of the +// range so that both ends round to the same integer, if possible. +// If they do both round the same then we terminate the search +// for the root *very* quickly when finding an integer result. +// At the point that this function is called we know that "a" is +// below the root and "b" above it, so this change can not result +// in the root no longer being bracketed. +// +template +void adjust_bounds(Real& /* a */, Real& /* b */, Tol const& /* tol */){} + +template +void adjust_bounds(Real& /* a */, Real& b, tools::equal_floor const& /* tol */) +{ + BOOST_MATH_STD_USING + b -= tools::epsilon() * b; +} + +template +void adjust_bounds(Real& a, Real& /* b */, tools::equal_ceil const& /* tol */) +{ + BOOST_MATH_STD_USING + a += tools::epsilon() * a; +} + +template +void adjust_bounds(Real& a, Real& b, tools::equal_nearest_integer const& /* tol */) +{ + BOOST_MATH_STD_USING + a += tools::epsilon() * a; + b -= tools::epsilon() * b; +} +// +// This is where all the work is done: +// +template +typename Dist::value_type + do_inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool comp, + typename Dist::value_type guess, + const typename Dist::value_type& multiplier, + typename Dist::value_type adder, + const Tolerance& tol, + std::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + typedef typename Dist::policy_type policy_type; + + static const char* function = "boost::math::do_inverse_discrete_quantile<%1%>"; + + BOOST_MATH_STD_USING + + distribution_quantile_finder f(dist, p, comp); + // + // Max bounds of the distribution: + // + value_type min_bound, max_bound; + boost::math::tie(min_bound, max_bound) = support(dist); + + if(guess > max_bound) + guess = max_bound; + if(guess < min_bound) + guess = min_bound; + + value_type fa = f(guess); + std::uintmax_t count = max_iter - 1; + value_type fb(fa), a(guess), b =0; // Compiler warning C4701: potentially uninitialized local variable 'b' used + + if(fa == 0) + return guess; + + // + // For small expected results, just use a linear search: + // + if(guess < 10) + { + b = a; + while((a < 10) && (fa * fb >= 0)) + { + if(fb <= 0) + { + a = b; + b = a + 1; + if(b > max_bound) + b = max_bound; + fb = f(b); + --count; + if(fb == 0) + return b; + if(a == b) + return b; // can't go any higher! + } + else + { + b = a; + a = (std::max)(value_type(b - 1), value_type(0)); + if(a < min_bound) + a = min_bound; + fa = f(a); + --count; + if(fa == 0) + return a; + if(a == b) + return a; // We can't go any lower than this! + } + } + } + // + // Try and bracket using a couple of additions first, + // we're assuming that "guess" is likely to be accurate + // to the nearest int or so: + // + else if(adder != 0) + { + // + // If we're looking for a large result, then bump "adder" up + // by a bit to increase our chances of bracketing the root: + // + //adder = (std::max)(adder, 0.001f * guess); + if(fa < 0) + { + b = a + adder; + if(b > max_bound) + b = max_bound; + } + else + { + b = (std::max)(value_type(a - adder), value_type(0)); + if(b < min_bound) + b = min_bound; + } + fb = f(b); + --count; + if(fb == 0) + return b; + if(count && (fa * fb >= 0)) + { + // + // We didn't bracket the root, try + // once more: + // + a = b; + fa = fb; + if(fa < 0) + { + b = a + adder; + if(b > max_bound) + b = max_bound; + } + else + { + b = (std::max)(value_type(a - adder), value_type(0)); + if(b < min_bound) + b = min_bound; + } + fb = f(b); + --count; + } + if(a > b) + { + using std::swap; + swap(a, b); + swap(fa, fb); + } + } + // + // If the root hasn't been bracketed yet, try again + // using the multiplier this time: + // + if((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fa < 0) + { + // + // Zero is to the right of x2, so walk upwards + // until we find it: + // + while(((boost::math::sign)(fb) == (boost::math::sign)(fa)) && (a != b)) + { + if(count == 0) + return policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, policy_type()); + a = b; + fa = fb; + b *= multiplier; + if(b > max_bound) + b = max_bound; + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while(((boost::math::sign)(fb) == (boost::math::sign)(fa)) && (a != b)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return 0; + } + if(count == 0) + return policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, policy_type()); + b = a; + fb = fa; + a /= multiplier; + if(a < min_bound) + a = min_bound; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + } + max_iter -= count; + if(fa == 0) + return a; + if(fb == 0) + return b; + if(a == b) + return b; // Ran out of bounds trying to bracket - there is no answer! + // + // Adjust bounds so that if we're looking for an integer + // result, then both ends round the same way: + // + adjust_bounds(a, b, tol); + // + // We don't want zero or denorm lower bounds: + // + if(a < tools::min_value()) + a = tools::min_value(); + // + // Go ahead and find the root: + // + std::pair r = toms748_solve(f, a, b, fa, fb, tol, count, policy_type()); + max_iter += count; + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + return (r.first + r.second) / 2; +} +// +// Some special routine for rounding up and down: +// We want to check and see if we are very close to an integer, and if so test to see if +// that integer is an exact root of the cdf. We do this because our root finder only +// guarantees to find *a root*, and there can sometimes be many consecutive floating +// point values which are all roots. This is especially true if the target probability +// is very close 1. +// +template +inline typename Dist::value_type round_to_floor(const Dist& d, typename Dist::value_type result, typename Dist::value_type p, bool c) +{ + BOOST_MATH_STD_USING + typename Dist::value_type cc = ceil(result); + typename Dist::value_type pp = cc <= support(d).second ? c ? cdf(complement(d, cc)) : cdf(d, cc) : 1; + if(pp == p) + result = cc; + else + result = floor(result); + // + // Now find the smallest integer <= result for which we get an exact root: + // + while(result != 0) + { + cc = result - 1; + if(cc < support(d).first) + break; + pp = c ? cdf(complement(d, cc)) : cdf(d, cc); + if(pp == p) + result = cc; + else if(c ? pp > p : pp < p) + break; + result -= 1; + } + + return result; +} + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +inline typename Dist::value_type round_to_ceil(const Dist& d, typename Dist::value_type result, typename Dist::value_type p, bool c) +{ + BOOST_MATH_STD_USING + typename Dist::value_type cc = floor(result); + typename Dist::value_type pp = cc >= support(d).first ? c ? cdf(complement(d, cc)) : cdf(d, cc) : 0; + if(pp == p) + result = cc; + else + result = ceil(result); + // + // Now find the largest integer >= result for which we get an exact root: + // + while(true) + { + cc = result + 1; + if(cc > support(d).second) + break; + pp = c ? cdf(complement(d, cc)) : cdf(d, cc); + if(pp == p) + result = cc; + else if(c ? pp < p : pp > p) + break; + result += 1; + } + + return result; +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif +// +// Now finally are the public API functions. +// There is one overload for each policy, +// each one is responsible for selecting the correct +// termination condition, and rounding the result +// to an int where required. +// +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + typename Dist::value_type p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + if(p > 0.5) + { + p = 1 - p; + c = !c; + } + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return do_inverse_discrete_quantile( + dist, + p, + c, + guess, + multiplier, + adder, + tools::eps_tolerance(policies::digits()), + max_iter); +} + +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // What happens next depends on whether we're looking for an + // upper or lower quantile: + // + if(pp < 0.5f) + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : (value_type)floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); + // else: + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (value_type)ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); +} + +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // What happens next depends on whether we're looking for an + // upper or lower quantile: + // + if(pp < 0.5f) + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); + // else: + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); +} + +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 1 ? value_type(1) : floor(guess)), + multiplier, + adder, + tools::equal_floor(), + max_iter), p, c); +} + +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + return round_to_ceil(dist, do_inverse_discrete_quantile( + dist, + p, + c, + ceil(guess), + multiplier, + adder, + tools::equal_ceil(), + max_iter), p, c); +} + +template +inline typename Dist::value_type + inverse_discrete_quantile( + const Dist& dist, + const typename Dist::value_type& p, + bool c, + const typename Dist::value_type& guess, + const typename Dist::value_type& multiplier, + const typename Dist::value_type& adder, + const policies::discrete_quantile&, + std::uintmax_t& max_iter) +{ + typedef typename Dist::value_type value_type; + BOOST_MATH_STD_USING + typename Dist::value_type pp = c ? 1 - p : p; + if(pp <= pdf(dist, 0)) + return 0; + // + // Note that we adjust the guess to the nearest half-integer: + // this increase the chances that we will bracket the root + // with two results that both round to the same integer quickly. + // + return round_to_floor(dist, do_inverse_discrete_quantile( + dist, + p, + c, + (guess < 0.5f ? value_type(1.5f) : floor(guess + 0.5f) + 0.5f), + multiplier, + adder, + tools::equal_nearest_integer(), + max_iter) + 0.5f, p, c); +} + +}}} // namespaces + +#endif // BOOST_MATH_DISTRIBUTIONS_DETAIL_INV_DISCRETE_QUANTILE + diff --git a/libcxx/src/third-party/boost/math/distributions/empirical_cumulative_distribution_function.hpp b/libcxx/src/third-party/boost/math/distributions/empirical_cumulative_distribution_function.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/empirical_cumulative_distribution_function.hpp @@ -0,0 +1,65 @@ +// Copyright Nick Thompson 2019. +// 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_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP +#define BOOST_MATH_DISTRIBUTIONS_EMPIRICAL_CUMULATIVE_DISTRIBUTION_FUNCTION_HPP +#include +#include +#include +#include +#include + +namespace boost { namespace math{ + +template +class empirical_cumulative_distribution_function { + using Real = typename RandomAccessContainer::value_type; +public: + empirical_cumulative_distribution_function(RandomAccessContainer && v, bool sorted = false) + { + if (v.size() == 0) { + throw std::domain_error("At least one sample is required to compute an empirical CDF."); + } + m_v = std::move(v); + if (!sorted) { + std::sort(m_v.begin(), m_v.end()); + } + } + + auto operator()(Real x) const { + if constexpr (std::is_integral_v) + { + if (x < m_v[0]) { + return static_cast(0); + } + if (x >= m_v[m_v.size()-1]) { + return static_cast(1); + } + auto it = std::upper_bound(m_v.begin(), m_v.end(), x); + return static_cast(std::distance(m_v.begin(), it))/static_cast(m_v.size()); + } + else + { + if (x < m_v[0]) { + return Real(0); + } + if (x >= m_v[m_v.size()-1]) { + return Real(1); + } + auto it = std::upper_bound(m_v.begin(), m_v.end(), x); + return static_cast(std::distance(m_v.begin(), it))/static_cast(m_v.size()); + } + } + + RandomAccessContainer&& return_data() { + return std::move(m_v); + } + +private: + RandomAccessContainer m_v; +}; + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/distributions/exponential.hpp b/libcxx/src/third-party/boost/math/distributions/exponential.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/exponential.hpp @@ -0,0 +1,305 @@ +// 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_STATS_EXPONENTIAL_HPP +#define BOOST_STATS_EXPONENTIAL_HPP + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ +// +// Error check: +// +template +inline bool verify_lambda(const char* function, RealType l, RealType* presult, const Policy& pol) +{ + if((l <= 0) || !(boost::math::isfinite)(l)) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"lambda\" must be > 0, but was: %1%.", l, pol); + return false; + } + return true; +} + +template +inline bool verify_exp_x(const char* function, RealType x, RealType* presult, const Policy& pol) +{ + if((x < 0) || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error( + function, + "The random variable must be >= 0, but was: %1%.", x, pol); + return false; + } + return true; +} + +} // namespace detail + +template > +class exponential_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit exponential_distribution(RealType l_lambda = 1) + : m_lambda(l_lambda) + { + RealType err; + detail::verify_lambda("boost::math::exponential_distribution<%1%>::exponential_distribution", l_lambda, &err, Policy()); + } // exponential_distribution + + RealType lambda()const { return m_lambda; } + +private: + RealType m_lambda; +}; + +using exponential = exponential_distribution; + +#ifdef __cpp_deduction_guides +template +exponential_distribution(RealType)->exponential_distribution::type>; +#endif + +template +inline std::pair range(const exponential_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + if (std::numeric_limits::has_infinity) + { + return std::pair(static_cast(0), std::numeric_limits::infinity()); // 0 to + infinity. + } + else + { + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // 0 to + max + } +} + +template +inline std::pair support(const exponential_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return std::pair(min_value(), max_value()); + // min_value() to avoid a discontinuity at x = 0. +} + +template +inline RealType pdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(const exponential_distribution<%1%>&, %1%)"; + + RealType lambda = dist.lambda(); + RealType result = 0; + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + // Workaround for VC11/12 bug: + if ((boost::math::isinf)(x)) + return 0; + result = lambda * exp(-lambda * x); + return result; +} // pdf + +template +inline RealType logpdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::logpdf(const exponential_distribution<%1%>&, %1%)"; + + RealType lambda = dist.lambda(); + RealType result = -std::numeric_limits::infinity(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + + result = log(lambda) - lambda * x; + return result; +} // logpdf + +template +inline RealType cdf(const exponential_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, x, &result, Policy())) + return result; + result = -boost::math::expm1(-x * lambda, Policy()); + + return result; +} // cdf + +template +inline RealType quantile(const exponential_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return 0; + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = -boost::math::log1p(-p, Policy()) / lambda; + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = c.dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + if(0 == detail::verify_exp_x(function, c.param, &result, Policy())) + return result; + // Workaround for VC11/12 bug: + if (c.param >= tools::max_value()) + return 0; + result = exp(-c.param * lambda); + + return result; +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const exponential_distribution<%1%>&, %1%)"; + + RealType result = 0; + RealType lambda = c.dist.lambda(); + if(0 == detail::verify_lambda(function, lambda, &result, Policy())) + return result; + + RealType q = c.param; + if(0 == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 1) + return 0; + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = -log(q) / lambda; + return result; +} + +template +inline RealType mean(const exponential_distribution& dist) +{ + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda("boost::math::mean(const exponential_distribution<%1%>&)", lambda, &result, Policy())) + return result; + return 1 / lambda; +} + +template +inline RealType standard_deviation(const exponential_distribution& dist) +{ + RealType result = 0; + RealType lambda = dist.lambda(); + if(0 == detail::verify_lambda("boost::math::standard_deviation(const exponential_distribution<%1%>&)", lambda, &result, Policy())) + return result; + return 1 / lambda; +} + +template +inline RealType mode(const exponential_distribution& /*dist*/) +{ + return 0; +} + +template +inline RealType median(const exponential_distribution& dist) +{ + using boost::math::constants::ln_two; + return ln_two() / dist.lambda(); // ln(2) / lambda +} + +template +inline RealType skewness(const exponential_distribution& /*dist*/) +{ + return 2; +} + +template +inline RealType kurtosis(const exponential_distribution& /*dist*/) +{ + return 9; +} + +template +inline RealType kurtosis_excess(const exponential_distribution& /*dist*/) +{ + return 6; +} + +template +inline RealType entropy(const exponential_distribution& dist) +{ + using std::log; + return 1 - log(dist.lambda()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_EXPONENTIAL_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/extreme_value.hpp b/libcxx/src/third-party/boost/math/distributions/extreme_value.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/extreme_value.hpp @@ -0,0 +1,333 @@ +// 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_STATS_EXTREME_VALUE_HPP +#define BOOST_STATS_EXTREME_VALUE_HPP + +#include +#include +#include +#include +#include +#include + +// +// This is the maximum extreme value distribution, see +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366g.htm +// and http://mathworld.wolfram.com/ExtremeValueDistribution.html +// Also known as a Fisher-Tippett distribution, a log-Weibull +// distribution or a Gumbel distribution. + +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost{ namespace math{ + +namespace detail{ +// +// Error check: +// +template +inline bool verify_scale_b(const char* function, RealType b, RealType* presult, const Policy& pol) +{ + if((b <= 0) || !(boost::math::isfinite)(b)) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"b\" must be finite and > 0, but was: %1%.", b, pol); + return false; + } + return true; +} + +} // namespace detail + +template > +class extreme_value_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit extreme_value_distribution(RealType a = 0, RealType b = 1) + : m_a(a), m_b(b) + { + RealType err; + detail::verify_scale_b("boost::math::extreme_value_distribution<%1%>::extreme_value_distribution", b, &err, Policy()); + detail::check_finite("boost::math::extreme_value_distribution<%1%>::extreme_value_distribution", a, &err, Policy()); + } // extreme_value_distribution + + RealType location()const { return m_a; } + RealType scale()const { return m_b; } + +private: + RealType m_a; + RealType m_b; +}; + +using extreme_value = extreme_value_distribution; + +#ifdef __cpp_deduction_guides +template +extreme_value_distribution(RealType)->extreme_value_distribution::type>; +template +extreme_value_distribution(RealType,RealType)->extreme_value_distribution::type>; +#endif + +template +inline std::pair range(const extreme_value_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair( + std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -max_value(), + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : max_value()); +} + +template +inline std::pair support(const extreme_value_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); +} + +template +inline RealType pdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + return 0.0f; + if(0 == detail::check_x(function, x, &result, Policy())) + return result; + RealType e = (a - x) / b; + if(e < tools::log_max_value()) + result = exp(e) * exp(-exp(e)) / b; + // else.... result *must* be zero since exp(e) is infinite... + return result; +} // pdf + +template +inline RealType logpdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::logpdf(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = -std::numeric_limits::infinity(); + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + return 0.0f; + if(0 == detail::check_x(function, x, &result, Policy())) + return result; + RealType e = (a - x) / b; + if(e < tools::log_max_value()) + result = log(1/b) + e - exp(e); + // else.... result *must* be zero since exp(e) is infinite... + return result; +} // logpdf + +template +inline RealType cdf(const extreme_value_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(x)) + return x < 0 ? 0.0f : 1.0f; + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x("boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)", x, &result, Policy())) + return result; + + result = exp(-exp((a-x)/b)); + + return result; +} // cdf + +template +RealType quantile(const extreme_value_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return -policies::raise_overflow_error(function, 0, Policy()); + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = a - log(-log(p)) * b; + + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const extreme_value_distribution<%1%>&, %1%)"; + + if((boost::math::isinf)(c.param)) + return c.param < 0 ? 1.0f : 0.0f; + RealType a = c.dist.location(); + RealType b = c.dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_x(function, c.param, &result, Policy())) + return result; + + result = -boost::math::expm1(-exp((a-c.param)/b), Policy()); + + return result; +} + +template +RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const extreme_value_distribution<%1%>&, %1%)"; + + RealType a = c.dist.location(); + RealType b = c.dist.scale(); + RealType q = c.param; + RealType result = 0; + if(0 == detail::verify_scale_b(function, b, &result, Policy())) + return result; + if(0 == detail::check_finite(function, a, &result, Policy())) + return result; + if(0 == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + if(q == 1) + return -policies::raise_overflow_error(function, 0, Policy()); + + result = a - log(-boost::math::log1p(-q, Policy())) * b; + + return result; +} + +template +inline RealType mean(const extreme_value_distribution& dist) +{ + RealType a = dist.location(); + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b("boost::math::mean(const extreme_value_distribution<%1%>&)", b, &result, Policy())) + return result; + if (0 == detail::check_finite("boost::math::mean(const extreme_value_distribution<%1%>&)", a, &result, Policy())) + return result; + return a + constants::euler() * b; +} + +template +inline RealType standard_deviation(const extreme_value_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType b = dist.scale(); + RealType result = 0; + if(0 == detail::verify_scale_b("boost::math::standard_deviation(const extreme_value_distribution<%1%>&)", b, &result, Policy())) + return result; + if(0 == detail::check_finite("boost::math::standard_deviation(const extreme_value_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + return constants::pi() * b / sqrt(static_cast(6)); +} + +template +inline RealType mode(const extreme_value_distribution& dist) +{ + return dist.location(); +} + +template +inline RealType median(const extreme_value_distribution& dist) +{ + using constants::ln_ln_two; + return dist.location() - dist.scale() * ln_ln_two(); +} + +template +inline RealType skewness(const extreme_value_distribution& /*dist*/) +{ + // + // This is 12 * sqrt(6) * zeta(3) / pi^3: + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + // + return static_cast(1.1395470994046486574927930193898461120875997958366L); +} + +template +inline RealType kurtosis(const extreme_value_distribution& /*dist*/) +{ + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + return RealType(27) / 5; +} + +template +inline RealType kurtosis_excess(const extreme_value_distribution& /*dist*/) +{ + // See http://mathworld.wolfram.com/ExtremeValueDistribution.html + return RealType(12) / 5; +} + + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_EXTREME_VALUE_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/find_location.hpp b/libcxx/src/third-party/boost/math/distributions/find_location.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/find_location.hpp @@ -0,0 +1,140 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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_STATS_FIND_LOCATION_HPP +#define BOOST_STATS_FIND_LOCATION_HPP + +#include // for all distribution signatures. +#include +#include +#include +#include +#include +// using boost::math::policies::policy; +// using boost::math::complement; // will be needed by users who want complement, +// but NOT placed here to avoid putting it in global scope. + +namespace boost +{ + namespace math + { + // Function to find location of random variable z + // to give probability p (given scale) + // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular), + // enforced by static_assert below. + + template + inline + typename Dist::value_type find_location( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type scale, // scale parameter, for example, normal standard deviation. + const Policy& pol + ) + { + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_location&, %1%)"; + + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol); + } + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, pol); + } + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, pol); + } + + //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) " + // << quantile(Dist(), p) << ", quan * scale " << quantile(Dist(), p) * scale << endl; + return z - (quantile(Dist(), p) * scale); + } // find_location + + template + inline // with default policy. + typename Dist::value_type find_location( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type scale) // scale parameter, for example, normal standard deviation. + { // Forward to find_location with default policy. + return (find_location(z, p, scale, policies::policy<>())); + } // find_location + + // So the user can start from the complement q = (1 - p) of the probability p, + // for example, l = find_location(complement(z, q, sd)); + + template + inline typename Dist::value_type find_location( // Default policy. + complemented3_type const& c) + { + static const char* function = "boost::math::find_location&, %1%)"; + + typename Dist::value_type p = c.param1; + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, policies::policy<>()); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, policies::policy<>()); + } + typename Dist::value_type scale = c.param2; + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, policies::policy<>()); + } + // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; + return z - quantile(Dist(), p) * scale; + } // find_location complement + + + template + inline typename Dist::value_type find_location( // Explicit policy. + complemented4_type const& c) + { + static const char* function = "boost::math::find_location&, %1%)"; + + typename Dist::value_type p = c.param1; + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, c.param3); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "z parameter was %1%, but must be finite!", z, c.param3); + } + typename Dist::value_type scale = c.param2; + if(!(boost::math::isfinite)(scale)) + { + return policies::raise_domain_error( + function, "scale parameter was %1%, but must be finite!", scale, c.param3); + } + // cout << "z " << c.dist << ", quantile (Dist(), " << c.param1 << ") * scale " << c.param2 << endl; + return z - quantile(Dist(), p) * scale; + } // find_location complement + + } // namespace boost +} // namespace math + +#endif // BOOST_STATS_FIND_LOCATION_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/find_scale.hpp b/libcxx/src/third-party/boost/math/distributions/find_scale.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/find_scale.hpp @@ -0,0 +1,205 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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_STATS_FIND_SCALE_HPP +#define BOOST_STATS_FIND_SCALE_HPP + +#include // for all distribution signatures. +#include +#include +// using boost::math::policies::policy; +#include +#include +#include +#include +// using boost::math::complement; // will be needed by users who want complement, +// but NOT placed here to avoid putting it in global scope. + +namespace boost +{ + namespace math + { + // Function to find location of random variable z + // to give probability p (given scale) + // Applies to normal, lognormal, extreme value, Cauchy, (and symmetrical triangular), + // distributions that have scale. + // BOOST_STATIC_ASSERTs, see below, are used to enforce this. + + template + inline + typename Dist::value_type find_scale( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable weight z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type location, // location parameter, for example, normal distribution mean. + const Policy& pol + ) + { + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(%1%, %1%, %1%, Policy)"; + + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", p, pol); + } + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, pol); + } + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, pol); + } + + //cout << "z " << z << ", p " << p << ", quantile(Dist(), p) " + //<< quantile(Dist(), p) << ", z - mean " << z - location + //<<", sd " << (z - location) / quantile(Dist(), p) << endl; + + //quantile(N01, 0.001) -3.09023 + //quantile(N01, 0.01) -2.32635 + //quantile(N01, 0.05) -1.64485 + //quantile(N01, 0.333333) -0.430728 + //quantile(N01, 0.5) 0 + //quantile(N01, 0.666667) 0.430728 + //quantile(N01, 0.9) 1.28155 + //quantile(N01, 0.95) 1.64485 + //quantile(N01, 0.99) 2.32635 + //quantile(N01, 0.999) 3.09023 + + typename Dist::value_type result = + (z - location) // difference between desired x and current location. + / quantile(Dist(), p); // standard distribution. + + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, + "Computed scale (%1%) is <= 0!" " Was the complement intended?", + result, Policy()); + } + return result; + } // template find_scale + + template + inline // with default policy. + typename Dist::value_type find_scale( // For example, normal mean. + typename Dist::value_type z, // location of random variable z to give probability, P(X > z) == p. + // For example, a nominal minimum acceptable z, so that p * 100 % are > z + typename Dist::value_type p, // probability value desired at x, say 0.95 for 95% > z. + typename Dist::value_type location) // location parameter, for example, mean. + { // Forward to find_scale using the default policy. + return (find_scale(z, p, location, policies::policy<>())); + } // find_scale + + template + inline typename Dist::value_type find_scale( + complemented4_type const& c) + { + //cout << "cparam1 q " << c.param1 // q + // << ", c.dist z " << c.dist // z + // << ", c.param2 l " << c.param2 // l + // << ", quantile (Dist(), c.param1 = q) " + // << quantile(Dist(), c.param1) //q + // << endl; + + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(complement(%1%, %1%, %1%, Policy))"; + + // Checks on arguments, as not complemented version, + // Explicit policy. + typename Dist::value_type q = c.param1; + if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, c.param3); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, c.param3); + } + typename Dist::value_type location = c.param2; + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, c.param3); + } + + typename Dist::value_type result = + (c.dist - c.param2) // difference between desired x and current location. + / quantile(complement(Dist(), c.param1)); + // ( z - location) / (quantile(complement(Dist(), q)) + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, + "Computed scale (%1%) is <= 0!" " Was the complement intended?", + result, Policy()); + } + return result; + } // template typename Dist::value_type find_scale + + // So the user can start from the complement q = (1 - p) of the probability p, + // for example, s = find_scale(complement(z, q, l)); + + template + inline typename Dist::value_type find_scale( + complemented3_type const& c) + { + //cout << "cparam1 q " << c.param1 // q + // << ", c.dist z " << c.dist // z + // << ", c.param2 l " << c.param2 // l + // << ", quantile (Dist(), c.param1 = q) " + // << quantile(Dist(), c.param1) //q + // << endl; + + static_assert(::boost::math::tools::is_distribution::value, "The provided distribution does not meet the conceptual requirements of a distribution."); + static_assert(::boost::math::tools::is_scaled_distribution::value, "The provided distribution does not meet the conceptual requirements of a scaled distribution."); + static const char* function = "boost::math::find_scale(complement(%1%, %1%, %1%, Policy))"; + + // Checks on arguments, as not complemented version, + // default policy policies::policy<>(). + typename Dist::value_type q = c.param1; + if(!(boost::math::isfinite)(q) || (q < 0) || (q > 1)) + { + return policies::raise_domain_error( + function, "Probability parameter was %1%, but must be >= 0 and <= 1!", q, policies::policy<>()); + } + typename Dist::value_type z = c.dist; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error( + function, "find_scale z parameter was %1%, but must be finite!", z, policies::policy<>()); + } + typename Dist::value_type location = c.param2; + if(!(boost::math::isfinite)(location)) + { + return policies::raise_domain_error( + function, "find_scale location parameter was %1%, but must be finite!", location, policies::policy<>()); + } + + typename Dist::value_type result = + (z - location) // difference between desired x and current location. + / quantile(complement(Dist(), q)); + // ( z - location) / (quantile(complement(Dist(), q)) + if (result <= 0) + { // If policy isn't to throw, return the scale <= 0. + policies::raise_evaluation_error(function, + "Computed scale (%1%) is <= 0!" " Was the complement intended?", + result, policies::policy<>()); // This is only the default policy - also Want a version with Policy here. + } + return result; + } // template typename Dist::value_type find_scale + + } // namespace boost +} // namespace math + +#endif // BOOST_STATS_FIND_SCALE_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/fisher_f.hpp b/libcxx/src/third-party/boost/math/distributions/fisher_f.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/fisher_f.hpp @@ -0,0 +1,392 @@ +// 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_DISTRIBUTIONS_FISHER_F_HPP +#define BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP + +#include +#include // for incomplete beta. +#include // complements +#include // error checks +#include + +#include + +namespace boost{ namespace math{ + +template > +class fisher_f_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + fisher_f_distribution(const RealType& i, const RealType& j) : m_df1(i), m_df2(j) + { + static const char* function = "fisher_f_distribution<%1%>::fisher_f_distribution"; + RealType result; + detail::check_df( + function, m_df1, &result, Policy()); + detail::check_df( + function, m_df2, &result, Policy()); + } // fisher_f_distribution + + RealType degrees_of_freedom1()const + { + return m_df1; + } + RealType degrees_of_freedom2()const + { + return m_df2; + } + +private: + // + // Data members: + // + RealType m_df1; // degrees of freedom are a real number. + RealType m_df2; // degrees of freedom are a real number. +}; + +typedef fisher_f_distribution fisher_f; + +#ifdef __cpp_deduction_guides +template +fisher_f_distribution(RealType,RealType)->fisher_f_distribution::type>; +#endif + +template +inline const std::pair range(const fisher_f_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline const std::pair support(const fisher_f_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +RealType pdf(const fisher_f_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + static const char* function = "boost::math::pdf(fisher_f_distribution<%1%> const&, %1%)"; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()))) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + if(x == 0) + { + // special cases: + if(df1 < 2) + return policies::raise_overflow_error( + function, 0, Policy()); + else if(df1 == 2) + return 1; + else + return 0; + } + + // + // You reach this formula by direct differentiation of the + // cdf expressed in terms of the incomplete beta. + // + // There are two versions so we don't pass a value of z + // that is very close to 1 to ibeta_derivative: for some values + // of df1 and df2, all the change takes place in this area. + // + RealType v1x = df1 * x; + RealType result; + if(v1x > df2) + { + result = (df2 * df1) / ((df2 + v1x) * (df2 + v1x)); + result *= ibeta_derivative(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()); + } + else + { + result = df2 + df1 * x; + result = (result * df1 - x * df1 * df1) / (result * result); + result *= ibeta_derivative(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); + } + return result; +} // pdf + +template +inline RealType cdf(const fisher_f_distribution& dist, const RealType& x) +{ + static const char* function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType v1x = df1 * x; + // + // There are two equivalent formulas used here, the aim is + // to prevent the final argument to the incomplete beta + // from being too close to 1: for some values of df1 and df2 + // the rate of change can be arbitrarily large in this area, + // whilst the value we're passing will have lost information + // content as a result of being 0.999999something. Better + // to switch things around so we're passing 1-z instead. + // + return v1x > df2 + ? boost::math::ibetac(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()) + : boost::math::ibeta(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); +} // cdf + +template +inline RealType quantile(const fisher_f_distribution& dist, const RealType& p) +{ + static const char* function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy()))) + return error_result; + + // With optimizations turned on, gcc wrongly warns about y being used + // uninitialized unless we initialize it to something: + RealType x, y(0); + + x = boost::math::ibeta_inv(df1 / 2, df2 / 2, p, &y, Policy()); + + return df2 * x / (df1 * y); +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + static const char* function = "boost::math::cdf(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = c.dist.degrees_of_freedom1(); + RealType df2 = c.dist.degrees_of_freedom2(); + RealType x = c.param; + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType v1x = df1 * x; + // + // There are two equivalent formulas used here, the aim is + // to prevent the final argument to the incomplete beta + // from being too close to 1: for some values of df1 and df2 + // the rate of change can be arbitrarily large in this area, + // whilst the value we're passing will have lost information + // content as a result of being 0.999999something. Better + // to switch things around so we're passing 1-z instead. + // + return v1x > df2 + ? boost::math::ibeta(df2 / 2, df1 / 2, df2 / (df2 + v1x), Policy()) + : boost::math::ibetac(df1 / 2, df2 / 2, v1x / (df2 + v1x), Policy()); +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + static const char* function = "boost::math::quantile(fisher_f_distribution<%1%> const&, %1%)"; + RealType df1 = c.dist.degrees_of_freedom1(); + RealType df2 = c.dist.degrees_of_freedom2(); + RealType p = c.param; + // Error check: + RealType error_result = 0; + if(false == (detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy()))) + return error_result; + + RealType x, y; + + x = boost::math::ibetac_inv(df1 / 2, df2 / 2, p, &y, Policy()); + + return df2 * x / (df1 * y); +} + +template +inline RealType mean(const fisher_f_distribution& dist) +{ // Mean of F distribution = v. + static const char* function = "boost::math::mean(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 2) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 2 in order for the distribution to have a mean.", df2, Policy()); + } + return df2 / (df2 - 2); +} // mean + +template +inline RealType variance(const fisher_f_distribution& dist) +{ // Variance of F distribution. + static const char* function = "boost::math::variance(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 4) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 4 in order for the distribution to have a valid variance.", df2, Policy()); + } + return 2 * df2 * df2 * (df1 + df2 - 2) / (df1 * (df2 - 2) * (df2 - 2) * (df2 - 4)); +} // variance + +template +inline RealType mode(const fisher_f_distribution& dist) +{ + static const char* function = "boost::math::mode(fisher_f_distribution<%1%> const&)"; + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 2) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 2 in order for the distribution to have a mode.", df2, Policy()); + } + return df2 * (df1 - 2) / (df1 * (df2 + 2)); +} + +//template +//inline RealType median(const fisher_f_distribution& dist) +//{ // Median of Fisher F distribution is not defined. +// return tools::domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); +// } // median + +// Now implemented via quantile(half) in derived accessors. + +template +inline RealType skewness(const fisher_f_distribution& dist) +{ + static const char* function = "boost::math::skewness(fisher_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING // ADL of std names + // See http://mathworld.wolfram.com/F-Distribution.html + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 6) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 6 in order for the distribution to have a skewness.", df2, Policy()); + } + return 2 * (df2 + 2 * df1 - 2) * sqrt((2 * df2 - 8) / (df1 * (df2 + df1 - 2))) / (df2 - 6); +} + +template +RealType kurtosis_excess(const fisher_f_distribution& dist); + +template +inline RealType kurtosis(const fisher_f_distribution& dist) +{ + return 3 + kurtosis_excess(dist); +} + +template +inline RealType kurtosis_excess(const fisher_f_distribution& dist) +{ + static const char* function = "boost::math::kurtosis_excess(fisher_f_distribution<%1%> const&)"; + // See http://mathworld.wolfram.com/F-Distribution.html + RealType df1 = dist.degrees_of_freedom1(); + RealType df2 = dist.degrees_of_freedom2(); + // Error check: + RealType error_result = 0; + if(false == detail::check_df( + function, df1, &error_result, Policy()) + && detail::check_df( + function, df2, &error_result, Policy())) + return error_result; + if(df2 <= 8) + { + return policies::raise_domain_error( + function, "Second degree of freedom was %1% but must be > 8 in order for the distribution to have a kurtosis.", df2, Policy()); + } + RealType df2_2 = df2 * df2; + RealType df1_2 = df1 * df1; + RealType n = -16 + 20 * df2 - 8 * df2_2 + df2_2 * df2 + 44 * df1 - 32 * df2 * df1 + 5 * df2_2 * df1 - 22 * df1_2 + 5 * df2 * df1_2; + n *= 12; + RealType d = df1 * (df2 - 6) * (df2 - 8) * (df1 + df2 - 2); + return n / d; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_FISHER_F_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/fwd.hpp b/libcxx/src/third-party/boost/math/distributions/fwd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/fwd.hpp @@ -0,0 +1,157 @@ +// fwd.hpp Forward declarations of Boost.Math distributions. + +// Copyright Paul A. Bristow 2007, 2010, 2012, 2014. +// Copyright John Maddock 2007. + +// 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_DISTRIBUTIONS_FWD_HPP +#define BOOST_MATH_DISTRIBUTIONS_FWD_HPP + +// 33 distributions at Boost 1.9.1 after adding hyperexpon and arcsine + +namespace boost{ namespace math{ + +template +class arcsine_distribution; + +template +class bernoulli_distribution; + +template +class beta_distribution; + +template +class binomial_distribution; + +template +class cauchy_distribution; + +template +class chi_squared_distribution; + +template +class exponential_distribution; + +template +class extreme_value_distribution; + +template +class fisher_f_distribution; + +template +class gamma_distribution; + +template +class geometric_distribution; + +template +class hyperexponential_distribution; + +template +class hypergeometric_distribution; + +template +class inverse_chi_squared_distribution; + +template +class inverse_gamma_distribution; + +template +class inverse_gaussian_distribution; + +template +class kolmogorov_smirnov_distribution; + +template +class laplace_distribution; + +template +class logistic_distribution; + +template +class lognormal_distribution; + +template +class negative_binomial_distribution; + +template +class non_central_beta_distribution; + +template +class non_central_chi_squared_distribution; + +template +class non_central_f_distribution; + +template +class non_central_t_distribution; + +template +class normal_distribution; + +template +class pareto_distribution; + +template +class poisson_distribution; + +template +class rayleigh_distribution; + +template +class skew_normal_distribution; + +template +class students_t_distribution; + +template +class triangular_distribution; + +template +class uniform_distribution; + +template +class weibull_distribution; + +}} // namespaces + +#define BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)\ + typedef boost::math::arcsine_distribution arcsine;\ + typedef boost::math::bernoulli_distribution bernoulli;\ + typedef boost::math::beta_distribution beta;\ + typedef boost::math::binomial_distribution binomial;\ + typedef boost::math::cauchy_distribution cauchy;\ + typedef boost::math::chi_squared_distribution chi_squared;\ + typedef boost::math::exponential_distribution exponential;\ + typedef boost::math::extreme_value_distribution extreme_value;\ + typedef boost::math::fisher_f_distribution fisher_f;\ + typedef boost::math::gamma_distribution gamma;\ + typedef boost::math::geometric_distribution geometric;\ + typedef boost::math::hypergeometric_distribution hypergeometric;\ + typedef boost::math::kolmogorov_smirnov_distribution kolmogorov_smirnov;\ + typedef boost::math::inverse_chi_squared_distribution inverse_chi_squared;\ + typedef boost::math::inverse_gaussian_distribution inverse_gaussian;\ + typedef boost::math::inverse_gamma_distribution inverse_gamma;\ + typedef boost::math::laplace_distribution laplace;\ + typedef boost::math::logistic_distribution logistic;\ + typedef boost::math::lognormal_distribution lognormal;\ + typedef boost::math::negative_binomial_distribution negative_binomial;\ + typedef boost::math::non_central_beta_distribution non_central_beta;\ + typedef boost::math::non_central_chi_squared_distribution non_central_chi_squared;\ + typedef boost::math::non_central_f_distribution non_central_f;\ + typedef boost::math::non_central_t_distribution non_central_t;\ + typedef boost::math::normal_distribution normal;\ + typedef boost::math::pareto_distribution pareto;\ + typedef boost::math::poisson_distribution poisson;\ + typedef boost::math::rayleigh_distribution rayleigh;\ + typedef boost::math::skew_normal_distribution skew_normal;\ + typedef boost::math::students_t_distribution students_t;\ + typedef boost::math::triangular_distribution triangular;\ + typedef boost::math::uniform_distribution uniform;\ + typedef boost::math::weibull_distribution weibull; + +#endif // BOOST_MATH_DISTRIBUTIONS_FWD_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/gamma.hpp b/libcxx/src/third-party/boost/math/distributions/gamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/gamma.hpp @@ -0,0 +1,394 @@ +// 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_STATS_GAMMA_HPP +#define BOOST_STATS_GAMMA_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm +// http://mathworld.wolfram.com/GammaDistribution.html +// http://en.wikipedia.org/wiki/Gamma_distribution + +#include +#include +#include +#include +#include + +#include +#include + +namespace boost{ namespace math +{ +namespace detail +{ + +template +inline bool check_gamma_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) +{ + if((shape <= 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0 !", shape, pol); + return false; + } + return true; +} + +template +inline bool check_gamma_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +inline bool check_gamma( + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) && check_gamma_shape(function, shape, result, pol); +} + +} // namespace detail + +template > +class gamma_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit gamma_distribution(RealType l_shape, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_gamma("boost::math::gamma_distribution<%1%>::gamma_distribution", l_scale, l_shape, &result, Policy()); + } + + RealType shape()const + { + return m_shape; + } + + RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +// NO typedef because of clash with name of gamma function. + +#ifdef __cpp_deduction_guides +template +gamma_distribution(RealType)->gamma_distribution::type>; +template +gamma_distribution(RealType,RealType)->gamma_distribution::type>; +#endif + +template +inline std::pair range(const gamma_distribution& /* dist */) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline std::pair support(const gamma_distribution& /* dist */) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return std::pair(min_value(), max_value()); +} + +template +inline RealType pdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + return 0; + } + result = gamma_p_derivative(shape, x / scale, Policy()) / scale; + return result; +} // pdf + +template +inline RealType logpdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::lgamma; + + static const char* function = "boost::math::logpdf(const gamma_distribution<%1%>&, %1%)"; + + RealType k = dist.shape(); + RealType theta = dist.scale(); + + RealType result = -std::numeric_limits::infinity(); + if(false == detail::check_gamma(function, theta, k, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + return std::numeric_limits::quiet_NaN(); + } + + result = -k*log(theta) + (k-1)*log(x) - lgamma(k) - (x/theta); + + return result; +} // logpdf + +template +inline RealType cdf(const gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, x, &result, Policy())) + return result; + + result = boost::math::gamma_p(shape, x / scale, Policy()); + return result; +} // cdf + +template +inline RealType quantile(const gamma_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = gamma_p_inv(shape, p, Policy()) * scale; + + return result; +} + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_gamma_x(function, c.param, &result, Policy())) + return result; + + result = gamma_q(shape, c.param / scale, Policy()); + + return result; +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = gamma_q_inv(shape, q, Policy()) * scale; + + return result; +} + +template +inline RealType mean(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::mean(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = shape * scale; + return result; +} + +template +inline RealType variance(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::variance(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = shape * scale * scale; + return result; +} + +template +inline RealType mode(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::mode(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + if(shape < 1) + return policies::raise_domain_error( + function, + "The mode of the gamma distribution is only defined for values of the shape parameter >= 1, but got %1%.", + shape, Policy()); + + result = (shape - 1) * scale; + return result; +} + +//template +//inline RealType median(const gamma_distribution& dist) +//{ // Rely on default definition in derived accessors. +//} + +template +inline RealType skewness(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::skewness(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = 2 / sqrt(shape); + return result; +} + +template +inline RealType kurtosis_excess(const gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::kurtosis_excess(const gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_gamma(function, scale, shape, &result, Policy())) + return result; + + result = 6 / shape; + return result; +} + +template +inline RealType kurtosis(const gamma_distribution& dist) +{ + return kurtosis_excess(dist) + 3; +} + +template +inline RealType entropy(const gamma_distribution& dist) +{ + RealType k = dist.shape(); + RealType theta = dist.scale(); + using std::log; + return k + log(theta) + lgamma(k) + (1-k)*digamma(k); +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_GAMMA_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/geometric.hpp b/libcxx/src/third-party/boost/math/distributions/geometric.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/geometric.hpp @@ -0,0 +1,516 @@ +// boost\math\distributions\geometric.hpp + +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. + +// 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) + +// geometric distribution is a discrete probability distribution. +// It expresses the probability distribution of the number (k) of +// events, occurrences, failures or arrivals before the first success. +// supported on the set {0, 1, 2, 3...} + +// Note that the set includes zero (unlike some definitions that start at one). + +// The random variate k is the number of events, occurrences or arrivals. +// k argument may be integral, signed, or unsigned, or floating point. +// If necessary, it has already been promoted from an integral type. + +// Note that the geometric distribution +// (like others including the binomial, geometric & Bernoulli) +// is strictly defined as a discrete function: +// only integral values of k are envisaged. +// However because the method of calculation uses a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +// See http://en.wikipedia.org/wiki/geometric_distribution +// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html +// http://mathworld.wolfram.com/GeometricDistribution.html + +#ifndef BOOST_MATH_SPECIAL_GEOMETRIC_HPP +#define BOOST_MATH_SPECIAL_GEOMETRIC_HPP + +#include +#include // for ibeta(a, b, x) == Ix(a, b). +#include // complement. +#include // error checks domain_error & logic_error. +#include // isnan. +#include // for root finding. +#include + +#include // using std::numeric_limits; +#include + +#if defined (BOOST_MSVC) +# pragma warning(push) +// This believed not now necessary, so commented out. +//# pragma warning(disable: 4702) // unreachable code. +// in domain_error_imp in error_handling. +#endif + +namespace boost +{ + namespace math + { + namespace geometric_detail + { + // Common error checking routines for geometric distribution function: + template + inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) ) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + + template + inline bool check_dist(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction(function, p, result, pol); + } + + template + inline bool check_dist_and_k(const char* function, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, p, result, pol) == false) + { + return false; + } + if( !(boost::math::isfinite)(k) || (k < 0) ) + { // Check k failures. + *result = policies::raise_domain_error( + function, + "Number of failures argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // Check_dist_and_k + + template + inline bool check_dist_and_prob(const char* function, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + { + return false; + } + return true; + } // check_dist_and_prob + } // namespace geometric_detail + + template > + class geometric_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + geometric_distribution(RealType p) : m_p(p) + { // Constructor stores success_fraction p. + RealType result; + geometric_detail::check_dist( + "geometric_distribution<%1%>::geometric_distribution", + m_p, // Check success_fraction 0 <= p <= 1. + &result, Policy()); + } // geometric_distribution constructor. + + // Private data getter class member functions. + RealType success_fraction() const + { // Probability of success as fraction in range 0 to 1. + return m_p; + } + RealType successes() const + { // Total number of successes r = 1 (for compatibility with negative binomial?). + return 1; + } + + // Parameter estimation. + // (These are copies of negative_binomial distribution with successes = 1). + static RealType find_lower_bound_on_p( + RealType trials, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + static const char* function = "boost::math::geometric<%1%>::find_lower_bound_on_p"; + RealType result = 0; // of error checks. + RealType successes = 1; + RealType failures = trials - successes; + if(false == detail::check_probability(function, alpha, &result, Policy()) + && geometric_detail::check_dist_and_k( + function, RealType(0), failures, &result, Policy())) + { + return result; + } + // Use complement ibeta_inv function for lower bound. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibeta_inv(successes, failures + 1, alpha, static_cast(nullptr), Policy()); + } // find_lower_bound_on_p + + static RealType find_upper_bound_on_p( + RealType trials, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + static const char* function = "boost::math::geometric<%1%>::find_upper_bound_on_p"; + RealType result = 0; // of error checks. + RealType successes = 1; + RealType failures = trials - successes; + if(false == geometric_detail::check_dist_and_k( + function, RealType(0), failures, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + if(failures == 0) + { + return 1; + }// Use complement ibetac_inv function for upper bound. + // Note adjusted failures value: *not* failures+1 as usual. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. Krishnamoorthy + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibetac_inv(successes, failures, alpha, static_cast(nullptr), Policy()); + } // find_upper_bound_on_p + + // Estimate number of trials : + // "How many trials do I need to be P% sure of seeing k or fewer failures?" + + static RealType find_minimum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + static const char* function = "boost::math::geometric<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_failures + + static RealType find_maximum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + static const char* function = "boost::math::geometric<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_trials complemented + + private: + //RealType m_r; // successes fixed at unity. + RealType m_p; // success_fraction + }; // template class geometric_distribution + + typedef geometric_distribution geometric; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + geometric_distribution(RealType)->geometric_distribution::type>; + #endif + + template + inline const std::pair range(const geometric_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // max_integer? + } + + template + inline const std::pair support(const geometric_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // max_integer? + } + + template + inline RealType mean(const geometric_distribution& dist) + { // Mean of geometric distribution = (1-p)/p. + return (1 - dist.success_fraction() ) / dist.success_fraction(); + } // mean + + // median implemented via quantile(half) in derived accessors. + + template + inline RealType mode(const geometric_distribution&) + { // Mode of geometric distribution = zero. + BOOST_MATH_STD_USING // ADL of std functions. + return 0; + } // mode + + template + inline RealType variance(const geometric_distribution& dist) + { // Variance of Binomial distribution = (1-p) / p^2. + return (1 - dist.success_fraction()) + / (dist.success_fraction() * dist.success_fraction()); + } // variance + + template + inline RealType skewness(const geometric_distribution& dist) + { // skewness of geometric distribution = 2-p / (sqrt(r(1-p)) + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + return (2 - p) / sqrt(1 - p); + } // skewness + + template + inline RealType kurtosis(const geometric_distribution& dist) + { // kurtosis of geometric distribution + // http://en.wikipedia.org/wiki/geometric is kurtosis_excess so add 3 + RealType p = dist.success_fraction(); + return 3 + (p*p - 6*p + 6) / (1 - p); + } // kurtosis + + template + inline RealType kurtosis_excess(const geometric_distribution& dist) + { // kurtosis excess of geometric distribution + // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess + RealType p = dist.success_fraction(); + return (p*p - 6*p + 6) / (1 - p); + } // kurtosis_excess + + // RealType standard_deviation(const geometric_distribution& dist) + // standard_deviation provided by derived accessors. + // RealType hazard(const geometric_distribution& dist) + // hazard of geometric distribution provided by derived accessors. + // RealType chf(const geometric_distribution& dist) + // chf of geometric distribution provided by derived accessors. + + template + inline RealType pdf(const geometric_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // For ADL of math functions. + static const char* function = "boost::math::pdf(const geometric_distribution<%1%>&, %1%)"; + + RealType p = dist.success_fraction(); + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + if (k == 0) + { + return p; // success_fraction + } + RealType q = 1 - p; // Inaccurate for small p? + // So try to avoid inaccuracy for large or small p. + // but has little effect > last significant bit. + //cout << "p * pow(q, k) " << result << endl; // seems best whatever p + //cout << "exp(p * k * log1p(-p)) " << p * exp(k * log1p(-p)) << endl; + //if (p < 0.5) + //{ + // result = p * pow(q, k); + //} + //else + //{ + // result = p * exp(k * log1p(-p)); + //} + result = p * pow(q, k); + return result; + } // geometric_pdf + + template + inline RealType cdf(const geometric_distribution& dist, const RealType& k) + { // Cumulative Distribution Function of geometric. + static const char* function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)"; + + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + if(k == 0) + { + return p; // success_fraction + } + //RealType q = 1 - p; // Bad for small p + //RealType probability = 1 - std::pow(q, k+1); + + RealType z = boost::math::log1p(-p, Policy()) * (k + 1); + RealType probability = -boost::math::expm1(z, Policy()); + + return probability; + } // cdf Cumulative Distribution Function geometric. + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function geometric. + BOOST_MATH_STD_USING + static const char* function = "boost::math::cdf(const geometric_distribution<%1%>&, %1%)"; + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType const& k = c.param; + geometric_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + // Error check: + RealType result = 0; + if(false == geometric_detail::check_dist_and_k( + function, + p, + k, + &result, Policy())) + { + return result; + } + RealType z = boost::math::log1p(-p, Policy()) * (k+1); + RealType probability = exp(z); + return probability; + } // cdf Complemented Cumulative Distribution Function geometric. + + template + inline RealType quantile(const geometric_distribution& dist, const RealType& x) + { // Quantile, percentile/100 or Percent Point geometric function. + // Return the number of expected failures k for a given probability p. + + // Inverse cumulative Distribution Function or Quantile (percentile / 100) of geometric Probability. + // k argument may be integral, signed, or unsigned, or floating point. + + static const char* function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING // ADL of std functions. + + RealType success_fraction = dist.success_fraction(); + // Check dist and x. + RealType result = 0; + if(false == geometric_detail::check_dist_and_prob + (function, success_fraction, x, &result, Policy())) + { + return result; + } + + // Special cases. + if (x == 1) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument is 1, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (x == 0) + { // No failures are expected if P = 0. + return 0; // Total trials will be just dist.successes. + } + // if (P <= pow(dist.success_fraction(), 1)) + if (x <= success_fraction) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + if (x == 1) + { + return 0; + } + + // log(1-x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small + result = boost::math::log1p(-x, Policy()) / boost::math::log1p(-success_fraction, Policy()) - 1; + // Subtract a few epsilons here too? + // to make sure it doesn't slip over, so ceil would be one too many. + return result; + } // RealType quantile(const geometric_distribution dist, p) + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point Binomial function. + // Return the number of expected failures k for a given + // complement of the probability Q = 1 - P. + static const char* function = "boost::math::quantile(const geometric_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING + // Error checks: + RealType x = c.param; + const geometric_distribution& dist = c.dist; + RealType success_fraction = dist.success_fraction(); + RealType result = 0; + if(false == geometric_detail::check_dist_and_prob( + function, + success_fraction, + x, + &result, Policy())) + { + return result; + } + + // Special cases: + if(x == 1) + { // There may actually be no answer to this question, + // since the probability of zero failures may be non-zero, + return 0; // but zero is the best we can do: + } + if (-x <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy())) + { // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 0; // + } + if(x == 0) + { // Probability 1 - Q == 1 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument complement is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + // log(x) /log(1-success_fraction) -1; but use log1p in case success_fraction is small + result = log(x) / boost::math::log1p(-success_fraction, Policy()) - 1; + return result; + + } // quantile complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_SPECIAL_GEOMETRIC_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/hyperexponential.hpp b/libcxx/src/third-party/boost/math/distributions/hyperexponential.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/hyperexponential.hpp @@ -0,0 +1,641 @@ +// Copyright 2014 Marco Guazzone (marco.guazzone@gmail.com) +// +// 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) +// +// This module implements the Hyper-Exponential distribution. +// +// References: +// - "Queueing Theory in Manufacturing Systems Analysis and Design" by H.T. Papadopolous, C. Heavey and J. Browne (Chapman & Hall/CRC, 1993) +// - http://reference.wolfram.com/language/ref/HyperexponentialDistribution.html +// - http://en.wikipedia.org/wiki/Hyperexponential_distribution +// + +#ifndef BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP +#define BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _MSC_VER +# pragma warning (push) +# pragma warning(disable:4127) // conditional expression is constant +# pragma warning(disable:4389) // '==' : signed/unsigned mismatch in test_tools +#endif // _MSC_VER + +namespace boost { namespace math { + +namespace detail { + +template +typename Dist::value_type generic_quantile(const Dist& dist, const typename Dist::value_type& p, const typename Dist::value_type& guess, bool comp, const char* function); + +} // Namespace detail + + +template +class hyperexponential_distribution; + + +namespace /**/ { namespace hyperexp_detail { + +template +void normalize(std::vector& v) +{ + if(!v.size()) + return; // Our error handlers will get this later + const T sum = std::accumulate(v.begin(), v.end(), static_cast(0)); + T final_sum = 0; + const typename std::vector::iterator end = --v.end(); + for (typename std::vector::iterator it = v.begin(); + it != end; + ++it) + { + *it /= sum; + final_sum += *it; + } + *end = 1 - final_sum; // avoids round off errors, ensures the probs really do sum to 1. +} + +template +bool check_probabilities(char const* function, std::vector const& probabilities, RealT* presult, PolicyT const& pol) +{ + BOOST_MATH_STD_USING + const std::size_t n = probabilities.size(); + RealT sum = 0; + for (std::size_t i = 0; i < n; ++i) + { + if (probabilities[i] < 0 + || probabilities[i] > 1 + || !(boost::math::isfinite)(probabilities[i])) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"probabilities\" must be >= 0 and <= 1, but at least one of them was: %1%.", + probabilities[i], + pol); + return false; + } + sum += probabilities[i]; + } + + // + // We try to keep phase probabilities correctly normalized in the distribution constructors, + // however in practice we have to allow for a very slight divergence from a sum of exactly 1: + // + if (fabs(sum - 1) > tools::epsilon() * 2) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"probabilities\" must sum to 1, but their sum is: %1%.", + sum, + pol); + return false; + } + + return true; +} + +template +bool check_rates(char const* function, std::vector const& rates, RealT* presult, PolicyT const& pol) +{ + const std::size_t n = rates.size(); + for (std::size_t i = 0; i < n; ++i) + { + if (rates[i] <= 0 + || !(boost::math::isfinite)(rates[i])) + { + *presult = policies::raise_domain_error(function, + "The elements of parameter \"rates\" must be > 0, but at least one of them is: %1%.", + rates[i], + pol); + return false; + } + } + return true; +} + +template +bool check_dist(char const* function, std::vector const& probabilities, std::vector const& rates, RealT* presult, PolicyT const& pol) +{ + BOOST_MATH_STD_USING + if (probabilities.size() != rates.size()) + { + *presult = policies::raise_domain_error(function, + R"(The parameters "probabilities" and "rates" must have the same length, but their size differ by: %1%.)", + fabs(static_cast(probabilities.size())-static_cast(rates.size())), + pol); + return false; + } + + return check_probabilities(function, probabilities, presult, pol) + && check_rates(function, rates, presult, pol); +} + +template +bool check_x(char const* function, RealT x, RealT* presult, PolicyT const& pol) +{ + if (x < 0 || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error(function, "The random variable must be >= 0, but is: %1%.", x, pol); + return false; + } + return true; +} + +template +bool check_probability(char const* function, RealT p, RealT* presult, PolicyT const& pol) +{ + if (p < 0 || p > 1 || (boost::math::isnan)(p)) + { + *presult = policies::raise_domain_error(function, "The probability be >= 0 and <= 1, but is: %1%.", p, pol); + return false; + } + return true; +} + +template +RealT quantile_impl(hyperexponential_distribution const& dist, RealT const& p, bool comp) +{ + // Don't have a closed form so try to numerically solve the inverse CDF... + + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = comp ? "boost::math::quantile(const boost::math::complemented2_type, %1%>&)" + : "boost::math::quantile(const boost::math::hyperexponential_distribution<%1%>&, %1%)"; + + RealT result = 0; + + if (!check_probability(function, p, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + // A possible (but inaccurate) approximation is given below, where the + // quantile is given by the weighted sum of exponential quantiles: + RealT guess = 0; + if (comp) + { + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + guess += probs[i]*quantile(complement(exp, p)); + } + } + else + { + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + guess += probs[i]*quantile(exp, p); + } + } + + // Fast return in case the Hyper-Exponential is essentially an Exponential + if (n == 1) + { + return guess; + } + + value_type q; + q = detail::generic_quantile(hyperexponential_distribution(probs, rates), + p, + guess, + comp, + function); + + result = policies::checked_narrowing_cast(q, function); + + return result; +} + +}} // Namespace ::hyperexp_detail + + +template > +class hyperexponential_distribution +{ + public: typedef RealT value_type; + public: typedef PolicyT policy_type; + + + public: hyperexponential_distribution() + : probs_(1, 1), + rates_(1, 1) + { + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Four arg constructor: no ambiguity here, the arguments must be two pairs of iterators: + public: template + hyperexponential_distribution(ProbIterT prob_first, ProbIterT prob_last, + RateIterT rate_first, RateIterT rate_last) + : probs_(prob_first, prob_last), + rates_(rate_first, rate_last) + { + hyperexp_detail::normalize(probs_); + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + private: template + struct is_iterator + { + static constexpr bool value = false; + }; + + template + struct is_iterator::difference_type>> + { + // std::iterator_traits::difference_type returns void for invalid types + static constexpr bool value = !std::is_same::difference_type, void>::value; + }; + + // Two arg constructor from 2 ranges, we SFINAE this out of existence if + // either argument type is incrementable as in that case the type is + // probably an iterator: + public: template ::value && + !is_iterator::value, bool>::type = true> + hyperexponential_distribution(ProbRangeT const& prob_range, + RateRangeT const& rate_range) + : probs_(std::begin(prob_range), std::end(prob_range)), + rates_(std::begin(rate_range), std::end(rate_range)) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Two arg constructor for a pair of iterators: we SFINAE this out of + // existence if neither argument types are incrementable. + // Note that we allow different argument types here to allow for + // construction from an array plus a pointer into that array. + public: template ::value || + is_iterator::value, bool>::type = true> + hyperexponential_distribution(RateIterT const& rate_first, + RateIterT2 const& rate_last) + : probs_(std::distance(rate_first, rate_last), 1), // will be normalized below + rates_(rate_first, rate_last) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Initializer list constructor: allows for construction from array literals: +public: hyperexponential_distribution(std::initializer_list l1, std::initializer_list l2) + : probs_(l1.begin(), l1.end()), + rates_(l2.begin(), l2.end()) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + +public: hyperexponential_distribution(std::initializer_list l1) + : probs_(l1.size(), 1), + rates_(l1.begin(), l1.end()) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + // Single argument constructor: argument must be a range. + public: template + hyperexponential_distribution(RateRangeT const& rate_range) + : probs_(std::distance(std::begin(rate_range), std::end(rate_range)), 1), // will be normalized below + rates_(std::begin(rate_range), std::end(rate_range)) + { + hyperexp_detail::normalize(probs_); + + RealT err; + hyperexp_detail::check_dist("boost::math::hyperexponential_distribution<%1%>::hyperexponential_distribution", + probs_, + rates_, + &err, + PolicyT()); + } + + public: std::vector probabilities() const + { + return probs_; + } + + public: std::vector rates() const + { + return rates_; + } + + public: std::size_t num_phases() const + { + return rates_.size(); + } + + + private: std::vector probs_; + private: std::vector rates_; +}; // class hyperexponential_distribution + + +// Convenient type synonym for double. +typedef hyperexponential_distribution hyperexponential; + + +// Range of permissible values for random variable x +template +std::pair range(hyperexponential_distribution const&) +{ + if (std::numeric_limits::has_infinity) + { + return std::make_pair(static_cast(0), std::numeric_limits::infinity()); // 0 to +inf. + } + + return std::make_pair(static_cast(0), tools::max_value()); // 0 to + +} + +// Range of supported values for random variable x. +// This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. +template +std::pair support(hyperexponential_distribution const&) +{ + return std::make_pair(tools::min_value(), tools::max_value()); // to +. +} + +template +RealT pdf(hyperexponential_distribution const& dist, RealT const& x) +{ + BOOST_MATH_STD_USING + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::pdf(const boost::math::hyperexponential_distribution<%1%>&, %1%)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*pdf(exp, x); + //result += probs[i]*rates[i]*exp(-rates[i]*x); + } + + return result; +} + +template +RealT cdf(hyperexponential_distribution const& dist, RealT const& x) +{ + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::cdf(const boost::math::hyperexponential_distribution<%1%>&, %1%)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*cdf(exp, x); + } + + return result; +} + +template +RealT quantile(hyperexponential_distribution const& dist, RealT const& p) +{ + return hyperexp_detail::quantile_impl(dist, p , false); +} + +template +RealT cdf(complemented2_type, RealT> const& c) +{ + RealT const& x = c.param; + hyperexponential_distribution const& dist = c.dist; + + RealT result = 0; + + if (!hyperexp_detail::check_x("boost::math::cdf(boost::math::complemented2_type&, %1%>)", x, &result, PolicyT())) + { + return result; + } + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*cdf(complement(exp, x)); + } + + return result; +} + + +template +RealT quantile(complemented2_type, RealT> const& c) +{ + RealT const& p = c.param; + hyperexponential_distribution const& dist = c.dist; + + return hyperexp_detail::quantile_impl(dist, p , true); +} + +template +RealT mean(hyperexponential_distribution const& dist) +{ + RealT result = 0; + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + const exponential_distribution exp(rates[i]); + + result += probs[i]*mean(exp); + } + + return result; +} + +template +RealT variance(hyperexponential_distribution const& dist) +{ + RealT result = 0; + + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + for (std::size_t i = 0; i < n; ++i) + { + result += probs[i]/(rates[i]*rates[i]); + } + + const RealT mean = boost::math::mean(dist); + + result = 2*result-mean*mean; + + return result; +} + +template +RealT skewness(hyperexponential_distribution const& dist) +{ + BOOST_MATH_STD_USING + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + RealT s1 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i} + RealT s2 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^2} + RealT s3 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^3} + for (std::size_t i = 0; i < n; ++i) + { + const RealT p = probs[i]; + const RealT r = rates[i]; + const RealT r2 = r*r; + const RealT r3 = r2*r; + + s1 += p/r; + s2 += p/r2; + s3 += p/r3; + } + + const RealT s1s1 = s1*s1; + + const RealT num = (6*s3 - (3*(2*s2 - s1s1) + s1s1)*s1); + const RealT den = (2*s2 - s1s1); + + return num / pow(den, static_cast(1.5)); +} + +template +RealT kurtosis(hyperexponential_distribution const& dist) +{ + const std::size_t n = dist.num_phases(); + const std::vector probs = dist.probabilities(); + const std::vector rates = dist.rates(); + + RealT s1 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i} + RealT s2 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^2} + RealT s3 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^3} + RealT s4 = 0; // \sum_{i=1}^n \frac{p_i}{\lambda_i^4} + for (std::size_t i = 0; i < n; ++i) + { + const RealT p = probs[i]; + const RealT r = rates[i]; + const RealT r2 = r*r; + const RealT r3 = r2*r; + const RealT r4 = r3*r; + + s1 += p/r; + s2 += p/r2; + s3 += p/r3; + s4 += p/r4; + } + + const RealT s1s1 = s1*s1; + + const RealT num = (24*s4 - 24*s3*s1 + 3*(2*(2*s2 - s1s1) + s1s1)*s1s1); + const RealT den = (2*s2 - s1s1); + + return num/(den*den); +} + +template +RealT kurtosis_excess(hyperexponential_distribution const& dist) +{ + return kurtosis(dist) - 3; +} + +template +RealT mode(hyperexponential_distribution const& /*dist*/) +{ + return 0; +} + +}} // namespace boost::math + +#ifdef _MSC_VER +#pragma warning (pop) +#endif +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_HYPEREXPONENTIAL diff --git a/libcxx/src/third-party/boost/math/distributions/hypergeometric.hpp b/libcxx/src/third-party/boost/math/distributions/hypergeometric.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/hypergeometric.hpp @@ -0,0 +1,305 @@ +// Copyright 2008 Gautam Sewani +// Copyright 2008 John Maddock +// Copyright 2021 Paul A. Bristow +// +// 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_DISTRIBUTIONS_HYPERGEOMETRIC_HPP +#define BOOST_MATH_DISTRIBUTIONS_HYPERGEOMETRIC_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + + template > + class hypergeometric_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + hypergeometric_distribution(unsigned r, unsigned n, unsigned N) // Constructor. r=defective/failures/success, n=trials/draws, N=total population. + : m_n(n), m_N(N), m_r(r) + { + static const char* function = "boost::math::hypergeometric_distribution<%1%>::hypergeometric_distribution"; + RealType ret; + check_params(function, &ret); + } + // Accessor functions. + unsigned total()const + { + return m_N; + } + + unsigned defective()const // successes/failures/events + { + return m_r; + } + + unsigned sample_count()const + { + return m_n; + } + + bool check_params(const char* function, RealType* result)const + { + if(m_r > m_N) + { + *result = boost::math::policies::raise_domain_error( + function, "Parameter r out of range: must be <= N but got %1%", static_cast(m_r), Policy()); + return false; + } + if(m_n > m_N) + { + *result = boost::math::policies::raise_domain_error( + function, "Parameter n out of range: must be <= N but got %1%", static_cast(m_n), Policy()); + return false; + } + return true; + } + bool check_x(unsigned x, const char* function, RealType* result)const + { + if(x < static_cast((std::max)(0, static_cast(m_n + m_r) - static_cast(m_N)))) + { + *result = boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be > 0 and > m + r - N but got %1%", static_cast(x), Policy()); + return false; + } + if(x > (std::min)(m_r, m_n)) + { + *result = boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be less than both n and r but got %1%", static_cast(x), Policy()); + return false; + } + return true; + } + + private: + // Data members: + unsigned m_n; // number of items picked or drawn. + unsigned m_N; // number of "total" items. + unsigned m_r; // number of "defective/successes/failures/events items. + + }; // class hypergeometric_distribution + + typedef hypergeometric_distribution hypergeometric; + + template + inline const std::pair range(const hypergeometric_distribution& dist) + { // Range of permissible values for random variable x. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4267) +#endif + unsigned r = dist.defective(); + unsigned n = dist.sample_count(); + unsigned N = dist.total(); + unsigned l = static_cast((std::max)(0, static_cast(n + r) - static_cast(N))); + unsigned u = (std::min)(r, n); + return std::pair(l, u); +#ifdef _MSC_VER +# pragma warning(pop) +#endif + } + + template + inline const std::pair support(const hypergeometric_distribution& d) + { + return range(d); + } + + template + inline RealType pdf(const hypergeometric_distribution& dist, const unsigned& x) + { + static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!dist.check_params(function, &result)) + return result; + if(!dist.check_x(x, function, &result)) + return result; + + return boost::math::detail::hypergeometric_pdf( + x, dist.defective(), dist.sample_count(), dist.total(), Policy()); + } + + template + inline RealType pdf(const hypergeometric_distribution& dist, const U& x) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::pdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(x); + unsigned u = itrunc(r, typename policies::normalise >::type()); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return pdf(dist, u); + } + + template + inline RealType cdf(const hypergeometric_distribution& dist, const unsigned& x) + { + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!dist.check_params(function, &result)) + return result; + if(!dist.check_x(x, function, &result)) + return result; + + return boost::math::detail::hypergeometric_cdf( + x, dist.defective(), dist.sample_count(), dist.total(), false, Policy()); + } + + template + inline RealType cdf(const hypergeometric_distribution& dist, const U& x) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(x); + unsigned u = itrunc(r, typename policies::normalise >::type()); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return cdf(dist, u); + } + + template + inline RealType cdf(const complemented2_type, unsigned>& c) + { + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType result = 0; + if(!c.dist.check_params(function, &result)) + return result; + if(!c.dist.check_x(c.param, function, &result)) + return result; + + return boost::math::detail::hypergeometric_cdf( + c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), true, Policy()); + } + + template + inline RealType cdf(const complemented2_type, U>& c) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::cdf(const hypergeometric_distribution<%1%>&, const %1%&)"; + RealType r = static_cast(c.param); + unsigned u = itrunc(r, typename policies::normalise >::type()); + if(u != r) + { + return boost::math::policies::raise_domain_error( + function, "Random variable out of range: must be an integer but got %1%", r, Policy()); + } + return cdf(complement(c.dist, u)); + } + + template + inline RealType quantile(const hypergeometric_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + const char* function = "boost::math::quantile(const hypergeometric_distribution<%1%>&, %1%)"; + if (false == dist.check_params(function, &result)) return result; + if(false == detail::check_probability(function, p, &result, Policy())) return result; + + return static_cast(detail::hypergeometric_quantile(p, RealType(1 - p), dist.defective(), dist.sample_count(), dist.total(), Policy())); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + const char* function = "quantile(const complemented2_type, %1%>&)"; + if (false == c.dist.check_params(function, &result)) return result; + if(false == detail::check_probability(function, c.param, &result, Policy())) return result; + + return static_cast(detail::hypergeometric_quantile(RealType(1 - c.param), c.param, c.dist.defective(), c.dist.sample_count(), c.dist.total(), Policy())); + } // quantile + + // https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution + + template + inline RealType mean(const hypergeometric_distribution& dist) + { + return static_cast(dist.defective() * dist.sample_count()) / dist.total(); + } // RealType mean(const hypergeometric_distribution& dist) + + template + inline RealType variance(const hypergeometric_distribution& dist) + { + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return n * r * (N - r) * (N - n) / (N * N * (N - 1)); + } // RealType variance(const hypergeometric_distribution& dist) + + template + inline RealType mode(const hypergeometric_distribution& dist) + { + BOOST_MATH_STD_USING + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return floor((r + 1) * (n + 1) / (N + 2)); + } + + template + inline RealType skewness(const hypergeometric_distribution& dist) + { + BOOST_MATH_STD_USING + RealType r = static_cast(dist.defective()); + RealType n = static_cast(dist.sample_count()); + RealType N = static_cast(dist.total()); + return (N - 2 * r) * sqrt(N - 1) * (N - 2 * n) / (sqrt(n * r * (N - r) * (N - n)) * (N - 2)); + } // RealType skewness(const hypergeometric_distribution& dist) + + template + inline RealType kurtosis_excess(const hypergeometric_distribution& dist) + { + // https://www.wolframalpha.com/input/?i=kurtosis+hypergeometric+distribution shown as plain text: + // mean | (m n)/N + // standard deviation | sqrt((m n(N - m) (N - n))/(N - 1))/N + // variance | (m n(1 - m/N) (N - n))/((N - 1) N) + // skewness | (sqrt(N - 1) (N - 2 m) (N - 2 n))/((N - 2) sqrt(m n(N - m) (N - n))) + // kurtosis | ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n)) + // Kurtosis[HypergeometricDistribution[n, m, N]] + RealType m = static_cast(dist.defective()); // Failures or success events. (Also symbols K or M are used). + RealType n = static_cast(dist.sample_count()); // draws or trials. + RealType n2 = n * n; // n^2 + RealType N = static_cast(dist.total()); // Total population from which n draws or trials are made. + RealType N2 = N * N; // N^2 + // result = ((N - 1) N^2 ((3 m(N - m) (n^2 (-N) + (n - 2) N^2 + 6 n(N - n)))/N^2 - 6 n(N - n) + N(N + 1)))/(m n(N - 3) (N - 2) (N - m) (N - n)); + RealType result = ((N-1)*N2*((3*m*(N-m)*(n2*(-N)+(n-2)*N2+6*n*(N-n)))/N2-6*n*(N-n)+N*(N+1)))/(m*n*(N-3)*(N-2)*(N-m)*(N-n)); + // Agrees with kurtosis hypergeometric distribution(50,200,500) kurtosis = 2.96917 + // N[kurtosis[hypergeometricdistribution(50,200,500)], 55] 2.969174035736058474901169623721804275002985337280263464 + return result; + } // RealType kurtosis_excess(const hypergeometric_distribution& dist) + + template + inline RealType kurtosis(const hypergeometric_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } // RealType kurtosis_excess(const hypergeometric_distribution& dist) +}} // namespaces + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // include guard diff --git a/libcxx/src/third-party/boost/math/distributions/inverse_chi_squared.hpp b/libcxx/src/third-party/boost/math/distributions/inverse_chi_squared.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/inverse_chi_squared.hpp @@ -0,0 +1,398 @@ +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. + +// 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_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP +#define BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP + +#include +#include // for incomplete beta. +#include // for complements. +#include // for error checks. +#include // for isfinite + +// See http://en.wikipedia.org/wiki/Scaled-inverse-chi-square_distribution +// for definitions of this scaled version. +// See http://en.wikipedia.org/wiki/Inverse-chi-square_distribution +// for unscaled version. + +// http://reference.wolfram.com/mathematica/ref/InverseChiSquareDistribution.html +// Weisstein, Eric W. "Inverse Chi-Squared Distribution." From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/InverseChi-SquaredDistribution.html + +#include + +namespace boost{ namespace math{ + +namespace detail +{ + template + inline bool check_inverse_chi_squared( // Check both distribution parameters. + const char* function, + RealType degrees_of_freedom, // degrees_of_freedom (aka nu). + RealType scale, // scale (aka sigma^2) + RealType* result, + const Policy& pol) + { + return check_scale(function, scale, result, pol) + && check_df(function, degrees_of_freedom, + result, pol); + } // bool check_inverse_chi_squared +} // namespace detail + +template > +class inverse_chi_squared_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + inverse_chi_squared_distribution(RealType df, RealType l_scale) : m_df(df), m_scale (l_scale) + { + RealType result; + detail::check_df( + "boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_df, &result, Policy()) + && detail::check_scale( +"boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_scale, &result, Policy()); + } // inverse_chi_squared_distribution constructor + + inverse_chi_squared_distribution(RealType df = 1) : m_df(df) + { + RealType result; + m_scale = 1 / m_df ; // Default scale = 1 / degrees of freedom (Wikipedia definition 1). + detail::check_df( + "boost::math::inverse_chi_squared_distribution<%1%>::inverse_chi_squared_distribution", + m_df, &result, Policy()); + } // inverse_chi_squared_distribution + + RealType degrees_of_freedom()const + { + return m_df; // aka nu + } + RealType scale()const + { + return m_scale; // aka xi + } + + // Parameter estimation: NOT implemented yet. + //static RealType find_degrees_of_freedom( + // RealType difference_from_variance, + // RealType alpha, + // RealType beta, + // RealType variance, + // RealType hint = 100); + +private: + // Data members: + RealType m_df; // degrees of freedom are treated as a real number. + RealType m_scale; // distribution scale. + +}; // class chi_squared_distribution + +typedef inverse_chi_squared_distribution inverse_chi_squared; + +#ifdef __cpp_deduction_guides +template +inverse_chi_squared_distribution(RealType)->inverse_chi_squared_distribution::type>; +template +inverse_chi_squared_distribution(RealType,RealType)->inverse_chi_squared_distribution::type>; +#endif + +template +inline const std::pair range(const inverse_chi_squared_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // 0 to + infinity. +} + +template +inline const std::pair support(const inverse_chi_squared_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(static_cast(0), tools::max_value()); // 0 to + infinity. +} + +template +RealType pdf(const inverse_chi_squared_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + RealType error_result; + + static const char* function = "boost::math::pdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + + if(false == detail::check_inverse_chi_squared + (function, df, scale, &error_result, Policy()) + ) + { // Bad distribution. + return error_result; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { // Bad x. + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); + } + + if(x == 0) + { // Treat as special case. + return 0; + } + // Wikipedia scaled inverse chi sq (df, scale) related to inv gamma (df/2, df * scale /2) + // so use inverse gamma pdf with shape = df/2, scale df * scale /2 + // RealType shape = df /2; // inv_gamma shape + // RealType scale = df * scale/2; // inv_gamma scale + // RealType result = gamma_p_derivative(shape, scale / x, Policy()) * scale / (x * x); + RealType result = df * scale/2 / x; + if(result < tools::min_value()) + return 0; // Random variable is near enough infinite. + result = gamma_p_derivative(df/2, result, Policy()) * df * scale/2; + if(result != 0) // prevent 0 / 0, gamma_p_derivative -> 0 faster than x^2 + result /= (x * x); + return result; +} // pdf + +template +inline RealType cdf(const inverse_chi_squared_distribution& dist, const RealType& x) +{ + static const char* function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + RealType error_result; + + if(false == + detail::check_inverse_chi_squared(function, df, scale, &error_result, Policy()) + ) + { // Bad distribution. + return error_result; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { // Bad x. + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); + } + if (x == 0) + { // Treat zero as a special case. + return 0; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = boost::math::gamma_q(shape, scale / x, Policy()); // inverse_gamma code. + return boost::math::gamma_q(df / 2, (df * (scale / 2)) / x, Policy()); +} // cdf + +template +inline RealType quantile(const inverse_chi_squared_distribution& dist, const RealType& p) +{ + using boost::math::gamma_q_inv; + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + + static const char* function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, df, &error_result, Policy()) + && detail::check_probability( + function, p, &error_result, Policy())) + { + return error_result; + } + if(false == detail::check_probability( + function, p, &error_result, Policy())) + { + return error_result; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = scale / gamma_q_inv(shape, p, Policy()); + RealType result = gamma_q_inv(df /2, p, Policy()); + if(result == 0) + return policies::raise_overflow_error(function, "Random variable is infinite.", Policy()); + result = df * (scale / 2) / result; + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + using boost::math::gamma_q_inv; + RealType const& df = c.dist.degrees_of_freedom(); + RealType const& scale = c.dist.scale(); + RealType const& x = c.param; + static const char* function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df( + function, df, &error_result, Policy())) + { + return error_result; + } + if (x == 0) + { // Treat zero as a special case. + return 1; + } + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "inverse Chi Square parameter was %1%, but must be > 0 !", x, Policy()); + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = gamma_p(shape, scale/c.param, Policy()); use inv_gamma. + + return gamma_p(df / 2, (df * scale/2) / x, Policy()); // OK +} // cdf(complemented + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + using boost::math::gamma_q_inv; + + RealType const& df = c.dist.degrees_of_freedom(); + RealType const& scale = c.dist.scale(); + RealType const& q = c.param; + static const char* function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + if(false == detail::check_df(function, df, &error_result, Policy())) + { + return error_result; + } + if(false == detail::check_probability(function, q, &error_result, Policy())) + { + return error_result; + } + // RealType shape = df /2; // inv_gamma shape, + // RealType scale = df * scale/2; // inv_gamma scale, + // result = scale / gamma_p_inv(shape, q, Policy()); // using inv_gamma. + RealType result = gamma_p_inv(df/2, q, Policy()); + if(result == 0) + return policies::raise_overflow_error(function, "Random variable is infinite.", Policy()); + result = (df * scale / 2) / result; + return result; +} // quantile(const complement + +template +inline RealType mean(const inverse_chi_squared_distribution& dist) +{ // Mean of inverse Chi-Squared distribution. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + + static const char* function = "boost::math::mean(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 2) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a mode for degrees of freedom > 2, but got degrees of freedom = %1%.", + df, Policy()); + return (df * scale) / (df - 2); +} // mean + +template +inline RealType variance(const inverse_chi_squared_distribution& dist) +{ // Variance of inverse Chi-Squared distribution. + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + static const char* function = "boost::math::variance(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 4) + { + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a variance for degrees of freedom > 4, but got degrees of freedom = %1%.", + df, Policy()); + } + return 2 * df * df * scale * scale / ((df - 2)*(df - 2) * (df - 4)); +} // variance + +template +inline RealType mode(const inverse_chi_squared_distribution& dist) +{ // mode is not defined in Mathematica. + // See Discussion section http://en.wikipedia.org/wiki/Talk:Scaled-inverse-chi-square_distribution + // for origin of the formula used below. + + RealType df = dist.degrees_of_freedom(); + RealType scale = dist.scale(); + static const char* function = "boost::math::mode(const inverse_chi_squared_distribution<%1%>&)"; + if(df < 0) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.", + df, Policy()); + return (df * scale) / (df + 2); +} + +//template +//inline RealType median(const inverse_chi_squared_distribution& dist) +//{ // Median is given by Quantile[dist, 1/2] +// RealType df = dist.degrees_of_freedom(); +// if(df <= 1) +// return tools::domain_error( +// BOOST_CURRENT_FUNCTION, +// "The inverse_Chi-Squared distribution only has a median for degrees of freedom >= 0, but got degrees of freedom = %1%.", +// df); +// return df; +//} +// Now implemented via quantile(half) in derived accessors. + +template +inline RealType skewness(const inverse_chi_squared_distribution& dist) +{ + BOOST_MATH_STD_USING // For ADL + RealType df = dist.degrees_of_freedom(); + static const char* function = "boost::math::skewness(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 6) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a skewness for degrees of freedom > 6, but got degrees of freedom = %1%.", + df, Policy()); + + return 4 * sqrt (2 * (df - 4)) / (df - 6); // Not a function of scale. +} + +template +inline RealType kurtosis(const inverse_chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + static const char* function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 8) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a kurtosis for degrees of freedom > 8, but got degrees of freedom = %1%.", + df, Policy()); + + return kurtosis_excess(dist) + 3; +} + +template +inline RealType kurtosis_excess(const inverse_chi_squared_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + static const char* function = "boost::math::kurtosis(const inverse_chi_squared_distribution<%1%>&)"; + if(df <= 8) + return policies::raise_domain_error( + function, + "inverse Chi-Squared distribution only has a kurtosis excess for degrees of freedom > 8, but got degrees of freedom = %1%.", + df, Policy()); + + return 12 * (5 * df - 22) / ((df - 6 )*(df - 8)); // Not a function of scale. +} + +// +// Parameter estimation comes last: +// + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_INVERSE_CHI_SQUARED_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/inverse_gamma.hpp b/libcxx/src/third-party/boost/math/distributions/inverse_gamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/inverse_gamma.hpp @@ -0,0 +1,503 @@ +// inverse_gamma.hpp + +// Copyright Paul A. Bristow 2010. +// Copyright John Maddock 2010. +// 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_STATS_INVERSE_GAMMA_HPP +#define BOOST_STATS_INVERSE_GAMMA_HPP + +// Inverse Gamma Distribution is a two-parameter family +// of continuous probability distributions +// on the positive real line, which is the distribution of +// the reciprocal of a variable distributed according to the gamma distribution. + +// http://en.wikipedia.org/wiki/Inverse-gamma_distribution +// http://rss.acs.unt.edu/Rdoc/library/pscl/html/igamma.html + +// See also gamma distribution at gamma.hpp: +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda366b.htm +// http://mathworld.wolfram.com/GammaDistribution.html +// http://en.wikipedia.org/wiki/Gamma_distribution + +#include +#include +#include +#include + +#include +#include + +namespace boost{ namespace math +{ +namespace detail +{ + +template +inline bool check_inverse_gamma_shape( + const char* function, // inverse_gamma + RealType shape, // shape aka alpha + RealType* result, // to update, perhaps with NaN + const Policy& pol) +{ // Sources say shape argument must be > 0 + // but seems logical to allow shape zero as special case, + // returning pdf and cdf zero (but not < 0). + // (Functions like mean, variance with other limits on shape are checked + // in version including an operator & limit below). + if((shape < 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be >= 0 !", shape, pol); + return false; + } + return true; +} //bool check_inverse_gamma_shape + +template +inline bool check_inverse_gamma_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +inline bool check_inverse_gamma( + const char* function, // TODO swap these over, so shape is first. + RealType scale, // scale aka beta + RealType shape, // shape aka alpha + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) + && check_inverse_gamma_shape(function, shape, result, pol); +} // bool check_inverse_gamma + +} // namespace detail + +template > +class inverse_gamma_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit inverse_gamma_distribution(RealType l_shape = 1, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_inverse_gamma( + "boost::math::inverse_gamma_distribution<%1%>::inverse_gamma_distribution", + l_scale, l_shape, &result, Policy()); + } + + RealType shape()const + { + return m_shape; + } + + RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +using inverse_gamma = inverse_gamma_distribution; +// typedef - but potential clash with name of inverse gamma *function*. +// but there is a typedef for the gamma distribution (gamma) + +#ifdef __cpp_deduction_guides +template +inverse_gamma_distribution(RealType)->inverse_gamma_distribution::type>; +template +inverse_gamma_distribution(RealType,RealType)->inverse_gamma_distribution::type>; +#endif + +// Allow random variable x to be zero, treated as a special case (unlike some definitions). + +template +inline std::pair range(const inverse_gamma_distribution& /* dist */) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline std::pair support(const inverse_gamma_distribution& /* dist */) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline RealType pdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if(x == 0) + { // Treat random variate zero as a special case. + return 0; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad. + return result; + } + result = scale / x; + if(result < tools::min_value()) + return 0; // random variable is infinite or so close as to make no difference. + result = gamma_p_derivative(shape, result, Policy()) * scale; + if(0 != result) + { + if(x < 0) + { + // x * x may under or overflow, likewise our result, + // so be extra careful about the arithmetic: + RealType lim = tools::max_value() * x; + if(lim < result) + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + result /= x; + if(lim < result) + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + result /= x; + } + result /= (x * x); + } + + return result; +} // pdf + +template +inline RealType logpdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::lgamma; + + static const char* function = "boost::math::logpdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = -std::numeric_limits::infinity(); + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if(x == 0) + { // Treat random variate zero as a special case. + return result; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad. + return result; + } + result = scale / x; + if(result < tools::min_value()) + return result; // random variable is infinite or so close as to make no difference. + + // x * x may under or overflow, likewise our result + if (!(boost::math::isfinite)(x*x)) + { + return policies::raise_overflow_error(function, "PDF is infinite.", Policy()); + } + + return shape * log(scale) + (-shape-1)*log(x) - lgamma(shape) - (scale/x); +} // pdf + +template +inline RealType cdf(const inverse_gamma_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { // distribution parameters bad. + return result; + } + if (x == 0) + { // Treat zero as a special case. + return 0; + } + else if(false == detail::check_inverse_gamma_x(function, x, &result, Policy())) + { // x bad + return result; + } + result = boost::math::gamma_q(shape, scale / x, Policy()); + // result = tgamma(shape, scale / x) / tgamma(shape); // naive using tgamma + return result; +} // cdf + +template +inline RealType quantile(const inverse_gamma_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + using boost::math::gamma_q_inv; + + static const char* function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = gamma_q_inv(shape, p, Policy()); + if((result < 1) && (result * tools::max_value() < scale)) + return policies::raise_overflow_error(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy()); + result = scale / result; + return result; +} + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_inverse_gamma_x(function, c.param, &result, Policy())) + return result; + + if(c.param == 0) + return 1; // Avoid division by zero + + result = gamma_p(shape, scale/c.param, Policy()); + return result; +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const inverse_gamma_distribution<%1%>&, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = gamma_p_inv(shape, q, Policy()); + if((result < 1) && (result * tools::max_value() < scale)) + return policies::raise_overflow_error(function, "Value of random variable in inverse gamma distribution quantile is infinite.", Policy()); + result = scale / result; + return result; +} + +template +inline RealType mean(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::mean(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 1) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined mean it must be > 1", shape, Policy()); + return result; + } + result = scale / (shape - 1); + return result; +} // mean + +template +inline RealType variance(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::variance(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 2) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined variance it must be > 2", shape, Policy()); + return result; + } + result = (scale * scale) / ((shape - 1) * (shape -1) * (shape -2)); + return result; +} + +template +inline RealType mode(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::mode(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_inverse_gamma(function, scale, shape, &result, Policy())) + { + return result; + } + // Only defined for shape >= 0, but is checked by check_inverse_gamma. + result = scale / (shape + 1); + return result; +} + +//template +//inline RealType median(const gamma_distribution& dist) +//{ // Wikipedia does not define median, + // so rely on default definition quantile(0.5) in derived accessors. +// return result. +//} + +template +inline RealType skewness(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::skewness(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 3) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined skewness it must be > 3", shape, Policy()); + return result; + } + result = (4 * sqrt(shape - 2) ) / (shape - 3); + return result; +} + +template +inline RealType kurtosis_excess(const inverse_gamma_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::kurtosis_excess(const inverse_gamma_distribution<%1%>&)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 4) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined kurtosis excess it must be > 4", shape, Policy()); + return result; + } + result = (30 * shape - 66) / ((shape - 3) * (shape - 4)); + return result; +} + +template +inline RealType kurtosis(const inverse_gamma_distribution& dist) +{ + static const char* function = "boost::math::kurtosis(const inverse_gamma_distribution<%1%>&)"; + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if((shape <= 4) || !(boost::math::isfinite)(shape)) + { + result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but for a defined kurtosis it must be > 4", shape, Policy()); + return result; + } + return kurtosis_excess(dist) + 3; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_INVERSE_GAMMA_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/inverse_gaussian.hpp b/libcxx/src/third-party/boost/math/distributions/inverse_gaussian.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/inverse_gaussian.hpp @@ -0,0 +1,546 @@ +// Copyright John Maddock 2010. +// Copyright Paul A. Bristow 2010. + +// 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_STATS_INVERSE_GAUSSIAN_HPP +#define BOOST_STATS_INVERSE_GAUSSIAN_HPP + +#ifdef _MSC_VER +#pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +// http://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution +// http://mathworld.wolfram.com/InverseGaussianDistribution.html + +// The normal-inverse Gaussian distribution +// also called the Wald distribution (some sources limit this to when mean = 1). + +// It is the continuous probability distribution +// that is defined as the normal variance-mean mixture where the mixing density is the +// inverse Gaussian distribution. The tails of the distribution decrease more slowly +// than the normal distribution. It is therefore suitable to model phenomena +// where numerically large values are more probable than is the case for the normal distribution. + +// The Inverse Gaussian distribution was first studied in relationship to Brownian motion. +// In 1956 M.C.K. Tweedie used the name 'Inverse Gaussian' because there is an inverse +// relationship between the time to cover a unit distance and distance covered in unit time. + +// Examples are returns from financial assets and turbulent wind speeds. +// The normal-inverse Gaussian distributions form +// a subclass of the generalised hyperbolic distributions. + +// See also + +// http://en.wikipedia.org/wiki/Normal_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Normal Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/NormalDistribution.html + +// http://www.jstatsoft.org/v26/i04/paper General class of inverse Gaussian distributions. +// ig package - withdrawn but at http://cran.r-project.org/src/contrib/Archive/ig/ + +// http://www.stat.ucl.ac.be/ISdidactique/Rhelp/library/SuppDists/html/inverse_gaussian.html +// R package for dinverse_gaussian, ... + +// http://www.statsci.org/s/inverse_gaussian.s and http://www.statsci.org/s/inverse_gaussian.html + +//#include +#include // for erf/erfc. +#include +#include +#include +#include // for gamma function + +#include +#include + +#include + +namespace boost{ namespace math{ + +template > +class inverse_gaussian_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit inverse_gaussian_distribution(RealType l_mean = 1, RealType l_scale = 1) + : m_mean(l_mean), m_scale(l_scale) + { // Default is a 1,1 inverse_gaussian distribution. + static const char* function = "boost::math::inverse_gaussian_distribution<%1%>::inverse_gaussian_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_mean, &result, Policy()); + detail::check_x_gt0(function, l_mean, &result, Policy()); + } + + RealType mean()const + { // alias for location. + return m_mean; // aka mu + } + + // Synonyms, provided to allow generic use of find_location and find_scale. + RealType location()const + { // location, aka mu. + return m_mean; + } + RealType scale()const + { // scale, aka lambda. + return m_scale; + } + + RealType shape()const + { // shape, aka phi = lambda/mu. + return m_scale / m_mean; + } + +private: + // + // Data members: + // + RealType m_mean; // distribution mean or location, aka mu. + RealType m_scale; // distribution standard deviation or scale, aka lambda. +}; // class normal_distribution + +using inverse_gaussian = inverse_gaussian_distribution; + +#ifdef __cpp_deduction_guides +template +inverse_gaussian_distribution(RealType)->inverse_gaussian_distribution::type>; +template +inverse_gaussian_distribution(RealType,RealType)->inverse_gaussian_distribution::type>; +#endif + +template +inline std::pair range(const inverse_gaussian_distribution& /*dist*/) +{ // Range of permissible values for random variable x, zero to max. + using boost::math::tools::max_value; + return std::pair(static_cast(0.), max_value()); // - to + max value. +} + +template +inline std::pair support(const inverse_gaussian_distribution& /*dist*/) +{ // Range of supported values for random variable x, zero to max. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0.), max_value()); // - to + max value. +} + +template +inline RealType pdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Probability Density Function + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 0; + static const char* function = "boost::math::pdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + + if (x == 0) + { + return 0; // Convenient, even if not defined mathematically. + } + + result = + sqrt(scale / (constants::two_pi() * x * x * x)) + * exp(-scale * (x - mean) * (x - mean) / (2 * x * mean * mean)); + return result; +} // pdf + +template +inline RealType logpdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Probability Density Function + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = -std::numeric_limits::infinity(); + static const char* function = "boost::math::logpdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + + if (x == 0) + { + return std::numeric_limits::quiet_NaN(); // Convenient, even if not defined mathematically. log(0) + } + + const RealType two_pi = boost::math::constants::two_pi(); + + result = (-scale*pow(mean - x, RealType(2))/(mean*mean*x) + log(scale) - 3*log(x) - log(two_pi)) / 2; + return result; +} // pdf + +template +inline RealType cdf(const inverse_gaussian_distribution& dist, const RealType& x) +{ // Cumulative Density Function. + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType scale = dist.scale(); + RealType mean = dist.mean(); + static const char* function = "boost::math::cdf(const inverse_gaussian_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + { + return result; + } + if(false == detail::check_positive_x(function, x, &result, Policy())) + { + return result; + } + if (x == 0) + { + return 0; // Convenient, even if not defined mathematically. + } + // Problem with this formula for large scale > 1000 or small x + // so use normal distribution version: + // Wikipedia CDF equation http://en.wikipedia.org/wiki/Inverse_Gaussian_distribution. + + normal_distribution n01; + + RealType n0 = sqrt(scale / x); + n0 *= ((x / mean) -1); + RealType n1 = cdf(n01, n0); + RealType expfactor = exp(2 * scale / mean); + RealType n3 = - sqrt(scale / x); + n3 *= (x / mean) + 1; + RealType n4 = cdf(n01, n3); + result = n1 + expfactor * n4; + return result; +} // cdf + +template +struct inverse_gaussian_quantile_functor +{ + + inverse_gaussian_quantile_functor(const boost::math::inverse_gaussian_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + boost::math::tuple operator()(RealType const& x) + { + RealType c = cdf(distribution, x); + RealType fx = c - prob; // Difference cdf - value - to minimize. + RealType dx = pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } + private: + const boost::math::inverse_gaussian_distribution distribution; + RealType prob; +}; + +template +struct inverse_gaussian_quantile_complement_functor +{ + inverse_gaussian_quantile_complement_functor(const boost::math::inverse_gaussian_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + boost::math::tuple operator()(RealType const& x) + { + RealType c = cdf(complement(distribution, x)); + RealType fx = c - prob; // Difference cdf - value - to minimize. + RealType dx = -pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + //return std::tr1::make_tuple(fx, dx); if available. + return boost::math::make_tuple(fx, dx); + } + private: + const boost::math::inverse_gaussian_distribution distribution; + RealType prob; +}; + +namespace detail +{ + template + inline RealType guess_ig(RealType p, RealType mu = 1, RealType lambda = 1) + { // guess at random variate value x for inverse gaussian quantile. + BOOST_MATH_STD_USING + using boost::math::policies::policy; + // Error type. + using boost::math::policies::overflow_error; + // Action. + using boost::math::policies::ignore_error; + + using no_overthrow_policy = policy>; + + RealType x; // result is guess at random variate value x. + RealType phi = lambda / mu; + if (phi > 2.) + { // Big phi, so starting to look like normal Gaussian distribution. + // + // Whitmore, G.A. and Yalovsky, M. + // A normalising logarithmic transformation for inverse Gaussian random variables, + // Technometrics 20-2, 207-208 (1978), but using expression from + // V Seshadri, Inverse Gaussian distribution (1998) ISBN 0387 98618 9, page 6. + + normal_distribution n01; + x = mu * exp(quantile(n01, p) / sqrt(phi) - 1/(2 * phi)); + } + else + { // phi < 2 so much less symmetrical with long tail, + // so use gamma distribution as an approximation. + using boost::math::gamma_distribution; + + // Define the distribution, using gamma_nooverflow: + using gamma_nooverflow = gamma_distribution; + + gamma_nooverflow g(static_cast(0.5), static_cast(1.)); + + // R qgamma(0.2, 0.5, 1) = 0.0320923 + RealType qg = quantile(complement(g, p)); + x = lambda / (qg * 2); + // + if (x > mu/2) // x > mu /2? + { // x too large for the gamma approximation to work well. + //x = qgamma(p, 0.5, 1.0); // qgamma(0.270614, 0.5, 1) = 0.05983807 + RealType q = quantile(g, p); + // x = mu * exp(q * static_cast(0.1)); // Said to improve at high p + // x = mu * x; // Improves at high p? + x = mu * exp(q / sqrt(phi) - 1/(2 * phi)); + } + } + return x; + } // guess_ig +} // namespace detail + +template +inline RealType quantile(const inverse_gaussian_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + // No closed form exists so guess and use Newton Raphson iteration. + + RealType mean = dist.mean(); + RealType scale = dist.scale(); + static const char* function = "boost::math::quantile(const inverse_gaussian_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + if (p == 0) + { + return 0; // Convenient, even if not defined mathematically? + } + if (p == 1) + { // overflow + result = policies::raise_overflow_error(function, + "probability parameter is 1, but must be < 1!", Policy()); + return result; // infinity; + } + + RealType guess = detail::guess_ig(p, dist.mean(), dist.scale()); + using boost::math::tools::max_value; + + RealType min = 0.; // Minimum possible value is bottom of range of distribution. + RealType max = max_value();// Maximum possible value is top of range. + // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. + // digits used to control how accurate to try to make the result. + // To allow user to control accuracy versus speed, + int get_digits = policies::digits();// get digits from policy, + std::uintmax_t m = policies::get_max_root_iterations(); // and max iterations. + using boost::math::tools::newton_raphson_iterate; + result = + newton_raphson_iterate(inverse_gaussian_quantile_functor(dist, p), guess, min, max, get_digits, m); + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType scale = c.dist.scale(); + RealType mean = c.dist.mean(); + RealType x = c.param; + static const char* function = "boost::math::cdf(const complement(inverse_gaussian_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + if(false == detail::check_positive_x(function, x, &result, Policy())) + return result; + + normal_distribution n01; + RealType n0 = sqrt(scale / x); + n0 *= ((x / mean) -1); + RealType cdf_1 = cdf(complement(n01, n0)); + + RealType expfactor = exp(2 * scale / mean); + RealType n3 = - sqrt(scale / x); + n3 *= (x / mean) + 1; + + //RealType n5 = +sqrt(scale/x) * ((x /mean) + 1); // note now positive sign. + RealType n6 = cdf(complement(n01, +sqrt(scale/x) * ((x /mean) + 1))); + // RealType n4 = cdf(n01, n3); // = + result = cdf_1 - expfactor * n6; + return result; +} // cdf complement + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = c.dist.scale(); + RealType mean = c.dist.mean(); + static const char* function = "boost::math::quantile(const complement(inverse_gaussian_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if (false == detail::check_x_gt0(function, mean, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + RealType guess = detail::guess_ig(q, mean, scale); + // Complement. + using boost::math::tools::max_value; + + RealType min = 0.; // Minimum possible value is bottom of range of distribution. + RealType max = max_value();// Maximum possible value is top of range. + // int digits = std::numeric_limits::digits; // Maximum possible binary digits accuracy for type T. + // digits used to control how accurate to try to make the result. + int get_digits = policies::digits(); + std::uintmax_t m = policies::get_max_root_iterations(); + using boost::math::tools::newton_raphson_iterate; + result = + newton_raphson_iterate(inverse_gaussian_quantile_complement_functor(c.dist, q), guess, min, max, get_digits, m); + return result; +} // quantile + +template +inline RealType mean(const inverse_gaussian_distribution& dist) +{ // aka mu + return dist.mean(); +} + +template +inline RealType scale(const inverse_gaussian_distribution& dist) +{ // aka lambda + return dist.scale(); +} + +template +inline RealType shape(const inverse_gaussian_distribution& dist) +{ // aka phi + return dist.shape(); +} + +template +inline RealType standard_deviation(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = sqrt(mean * mean * mean / scale); + return result; +} + +template +inline RealType mode(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = mean * (sqrt(1 + (9 * mean * mean)/(4 * scale * scale)) + - 3 * mean / (2 * scale)); + return result; +} + +template +inline RealType skewness(const inverse_gaussian_distribution& dist) +{ + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 3 * sqrt(mean/scale); + return result; +} + +template +inline RealType kurtosis(const inverse_gaussian_distribution& dist) +{ + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 15 * mean / scale -3; + return result; +} + +template +inline RealType kurtosis_excess(const inverse_gaussian_distribution& dist) +{ + RealType scale = dist.scale(); + RealType mean = dist.mean(); + RealType result = 15 * mean / scale; + return result; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_INVERSE_GAUSSIAN_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/kolmogorov_smirnov.hpp b/libcxx/src/third-party/boost/math/distributions/kolmogorov_smirnov.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/kolmogorov_smirnov.hpp @@ -0,0 +1,499 @@ +// Kolmogorov-Smirnov 1st order asymptotic distribution +// Copyright Evan Miller 2020 +// +// 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) +// +// The Kolmogorov-Smirnov test in statistics compares two empirical distributions, +// or an empirical distribution against any theoretical distribution. It makes +// use of a specific distribution which doesn't have a formal name, but which +// is often called the Kolmogorv-Smirnov distribution for lack of anything +// better. This file implements the limiting form of this distribution, first +// identified by Andrey Kolmogorov in +// +// Kolmogorov, A. (1933) "Sulla Determinazione Empirica di una Legge di +// Distribuzione." Giornale dell' Istituto Italiano degli Attuari +// +// This limiting form of the CDF is a first-order Taylor expansion that is +// easily implemented by the fourth Jacobi Theta function (setting z=0). The +// PDF is then implemented here as a derivative of the Theta function. Note +// that this derivative is with respect to x, which enters into \tau, and not +// with respect to the z argument, which is always zero, and so the derivative +// identities in DLMF 20.4 do not apply here. +// +// A higher order order expansion is possible, and was first outlined by +// +// Pelz W, Good IJ (1976). "Approximating the Lower Tail-Areas of the +// Kolmogorov-Smirnov One-sample Statistic." Journal of the Royal Statistical +// Society B. +// +// The terms in this expansion get fairly complicated, and as far as I know the +// Pelz-Good expansion is not used in any statistics software. Someone could +// consider updating this implementation to use the Pelz-Good expansion in the +// future, but the math gets considerably hairier with each additional term. +// +// A formula for an exact version of the Kolmogorov-Smirnov test is laid out in +// Equation 2.4.4 of +// +// Durbin J (1973). "Distribution Theory for Tests Based on the Sample +// Distribution Func- tion." In SIAM CBMS-NSF Regional Conference Series in +// Applied Mathematics. SIAM, Philadelphia, PA. +// +// which is available in book form from Amazon and others. This exact version +// involves taking powers of large matrices. To do that right you need to +// compute eigenvalues and eigenvectors, which are beyond the scope of Boost. +// (Some recent work indicates the exact form can also be computed via FFT, see +// https://cran.r-project.org/web/packages/KSgeneral/KSgeneral.pdf). +// +// Even if the CDF of the exact distribution could be computed using Boost +// libraries (which would be cumbersome), the PDF would present another +// difficulty. Therefore I am limiting this implementation to the asymptotic +// form, even though the exact form has trivial values for certain specific +// values of x and n. For more on trivial values see +// +// Ruben H, Gambino J (1982). "The Exact Distribution of Kolmogorov's Statistic +// Dn for n <= 10." Annals of the Institute of Statistical Mathematics. +// +// For a good bibliography and overview of the various algorithms, including +// both exact and asymptotic forms, see +// https://www.jstatsoft.org/article/view/v039i11 +// +// As for this implementation: the distribution is parameterized by n (number +// of observations) in the spirit of chi-squared's degrees of freedom. It then +// takes a single argument x. In terms of the Kolmogorov-Smirnov statistical +// test, x represents the distribution of D_n, where D_n is the maximum +// difference between the CDFs being compared, that is, +// +// D_n = sup|F_n(x) - G(x)| +// +// In the exact distribution, x is confined to the support [0, 1], but in this +// limiting approximation, we allow x to exceed unity (similar to how a normal +// approximation always spills over any boundaries). +// +// As mentioned previously, the CDF is implemented using the \tau +// parameterization of the fourth Jacobi Theta function as +// +// CDF=theta_4(0|2*x*x*n/pi) +// +// The PDF is a hand-coded derivative of that function. Actually, there are two +// (independent) derivatives, as separate code paths are used for "small x" +// (2*x*x*n < pi) and "large x", mirroring the separate code paths in the +// Jacobi Theta implementation to achieve fast convergence. Quantiles are +// computed using a Newton-Raphson iteration from an initial guess that I +// arrived at by trial and error. +// +// The mean and variance are implemented using simple closed-form expressions. +// Skewness and kurtosis use slightly more complicated closed-form expressions +// that involve the zeta function. The mode is calculated at run-time by +// maximizing the PDF. If you have an analytical solution for the mode, feel +// free to plop it in. +// +// The CDF and PDF could almost certainly be re-implemented and sped up using a +// polynomial or rational approximation, since the only meaningful argument is +// x * sqrt(n). But that is left as an exercise for the next maintainer. +// +// In the future, the Pelz-Good approximation could be added. I suggest adding +// a second parameter representing the order, e.g. +// +// kolmogorov_smirnov_dist<>(100) // N=100, order=1 +// kolmogorov_smirnov_dist<>(100, 1) // N=100, order=1, i.e. Kolmogorov's formula +// kolmogorov_smirnov_dist<>(100, 4) // N=100, order=4, i.e. Pelz-Good formula +// +// The exact distribution could be added to the API with a special order +// parameter (e.g. 0 or infinity), or a separate distribution type altogether +// (e.g. kolmogorov_smirnov_exact_distribution). +// +#ifndef BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP +#define BOOST_MATH_DISTRIBUTIONS_KOLMOGOROV_SMIRNOV_HPP + +#include +#include +#include +#include +#include +#include // Newton-Raphson +#include // For the mode + +namespace boost { namespace math { + +namespace detail { +template +inline RealType kolmogorov_smirnov_quantile_guess(RealType p) { + // Choose a starting point for the Newton-Raphson iteration + if (p > 0.9) + return RealType(1.8) - 5 * (1 - p); + if (p < 0.3) + return p + RealType(0.45); + return p + RealType(0.3); +} + +// d/dk (theta2(0, 1/(2*k*k/M_PI))/sqrt(2*k*k*M_PI)) +template +RealType kolmogorov_smirnov_pdf_small_x(RealType x, RealType n, const Policy&) { + BOOST_MATH_STD_USING + RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0); + RealType eps = policies::get_epsilon(); + int i = 0; + RealType pi2 = constants::pi_sqr(); + RealType x2n = x*x*n; + if (x2n*x2n == 0.0) { + return static_cast(0); + } + while (true) { + delta = exp(-RealType(i+0.5)*RealType(i+0.5)*pi2/(2*x2n)) * (RealType(i+0.5)*RealType(i+0.5)*pi2 - x2n); + + if (delta == 0.0) + break; + + if (last_delta != 0.0 && fabs(delta/last_delta) < eps) + break; + + value += delta + delta; + last_delta = delta; + i++; + } + + return value * sqrt(n) * constants::root_half_pi() / (x2n*x2n); +} + +// d/dx (theta4(0, 2*x*x*n/M_PI)) +template +inline RealType kolmogorov_smirnov_pdf_large_x(RealType x, RealType n, const Policy&) { + BOOST_MATH_STD_USING + RealType value = RealType(0), delta = RealType(0), last_delta = RealType(0); + RealType eps = policies::get_epsilon(); + int i = 1; + while (true) { + delta = 8*x*i*i*exp(-2*i*i*x*x*n); + + if (delta == 0.0) + break; + + if (last_delta != 0.0 && fabs(delta / last_delta) < eps) + break; + + if (i%2 == 0) + delta = -delta; + + value += delta; + last_delta = delta; + i++; + } + + return value * n; +} + +} // detail + +template > + class kolmogorov_smirnov_distribution +{ + public: + typedef RealType value_type; + typedef Policy policy_type; + + // Constructor + kolmogorov_smirnov_distribution( RealType n ) : n_obs_(n) + { + RealType result; + detail::check_df( + "boost::math::kolmogorov_smirnov_distribution<%1%>::kolmogorov_smirnov_distribution", n_obs_, &result, Policy()); + } + + RealType number_of_observations()const + { + return n_obs_; + } + + private: + + RealType n_obs_; // positive integer +}; + +typedef kolmogorov_smirnov_distribution kolmogorov_k; // Convenience typedef for double version. + +#ifdef __cpp_deduction_guides +template +kolmogorov_smirnov_distribution(RealType)->kolmogorov_smirnov_distribution::type>; +#endif + +namespace detail { +template +struct kolmogorov_smirnov_quantile_functor +{ + kolmogorov_smirnov_quantile_functor(const boost::math::kolmogorov_smirnov_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + + boost::math::tuple operator()(RealType const& x) + { + RealType fx = cdf(distribution, x) - prob; // Difference cdf - value - to minimize. + RealType dx = pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } +private: + const boost::math::kolmogorov_smirnov_distribution distribution; + RealType prob; +}; + +template +struct kolmogorov_smirnov_complementary_quantile_functor +{ + kolmogorov_smirnov_complementary_quantile_functor(const boost::math::kolmogorov_smirnov_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + + boost::math::tuple operator()(RealType const& x) + { + RealType fx = cdf(complement(distribution, x)) - prob; // Difference cdf - value - to minimize. + RealType dx = -pdf(distribution, x); // pdf is the negative of the derivative of (1-CDF) + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } +private: + const boost::math::kolmogorov_smirnov_distribution distribution; + RealType prob; +}; + +template +struct kolmogorov_smirnov_negative_pdf_functor +{ + RealType operator()(RealType const& x) { + if (2*x*x < constants::pi()) { + return -kolmogorov_smirnov_pdf_small_x(x, static_cast(1), Policy()); + } + return -kolmogorov_smirnov_pdf_large_x(x, static_cast(1), Policy()); + } +}; +} // namespace detail + +template +inline const std::pair range(const kolmogorov_smirnov_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline const std::pair support(const kolmogorov_smirnov_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + // In the exact distribution, the upper limit would be 1. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline RealType pdf(const kolmogorov_smirnov_distribution& dist, const RealType& x) +{ + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType n = dist.number_of_observations(); + RealType error_result; + static const char* function = "boost::math::pdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + if (x < 0 || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Kolmogorov-Smirnov parameter was %1%, but must be > 0 !", x, Policy()); + } + + if (2*x*x*n < constants::pi()) { + return detail::kolmogorov_smirnov_pdf_small_x(x, n, Policy()); + } + + return detail::kolmogorov_smirnov_pdf_large_x(x, n, Policy()); +} // pdf + +template +inline RealType cdf(const kolmogorov_smirnov_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + static const char* function = "boost::math::cdf(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + RealType error_result; + RealType n = dist.number_of_observations(); + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + if((x < 0) || !(boost::math::isfinite)(x)) { + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be between > 0 !", x, Policy()); + } + + if (x*x*n == 0) + return 0; + + return jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); +} // cdf + +template +inline RealType cdf(const complemented2_type, RealType>& c) { + BOOST_MATH_STD_USING // for ADL of std function exp. + RealType x = c.param; + static const char* function = "boost::math::cdf(const complemented2_type&, %1%>)"; + RealType error_result; + kolmogorov_smirnov_distribution const& dist = c.dist; + RealType n = dist.number_of_observations(); + + if(false == detail::check_x_not_NaN(function, x, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + if((x < 0) || !(boost::math::isfinite)(x)) + return policies::raise_domain_error( + function, "Random variable parameter was %1%, but must be between > 0 !", x, Policy()); + + if (x*x*n == 0) + return 1; + + if (2*x*x*n > constants::pi()) + return -jacobi_theta4m1tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); + + return RealType(1) - jacobi_theta4tau(RealType(0), 2*x*x*n/constants::pi(), Policy()); +} // cdf (complemented) + +template +inline RealType quantile(const kolmogorov_smirnov_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + // Error check: + RealType error_result; + RealType n = dist.number_of_observations(); + if(false == detail::check_probability(function, p, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + RealType k = detail::kolmogorov_smirnov_quantile_guess(p) / sqrt(n); + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t m = policies::get_max_root_iterations(); // and max iterations. + + return tools::newton_raphson_iterate(detail::kolmogorov_smirnov_quantile_functor(dist, p), + k, RealType(0), boost::math::tools::max_value(), get_digits, m); +} // quantile + +template +inline RealType quantile(const complemented2_type, RealType>& c) { + BOOST_MATH_STD_USING + static const char* function = "boost::math::quantile(const kolmogorov_smirnov_distribution<%1%>&, %1%)"; + kolmogorov_smirnov_distribution const& dist = c.dist; + RealType n = dist.number_of_observations(); + // Error check: + RealType error_result; + RealType p = c.param; + + if(false == detail::check_probability(function, p, &error_result, Policy())) + return error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + RealType k = detail::kolmogorov_smirnov_quantile_guess(RealType(1-p)) / sqrt(n); + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t m = policies::get_max_root_iterations(); // and max iterations. + + return tools::newton_raphson_iterate( + detail::kolmogorov_smirnov_complementary_quantile_functor(dist, p), + k, RealType(0), boost::math::tools::max_value(), get_digits, m); +} // quantile (complemented) + +template +inline RealType mode(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::mode(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + + std::pair r = boost::math::tools::brent_find_minima( + detail::kolmogorov_smirnov_negative_pdf_functor(), + static_cast(0), static_cast(1), policies::digits()); + return r.first / sqrt(n); +} + +// Mean and variance come directly from +// https://www.jstatsoft.org/article/view/v008i18 Section 3 +template +inline RealType mean(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::mean(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return constants::root_half_pi() * constants::ln_two() / sqrt(n); +} + +template +inline RealType variance(const kolmogorov_smirnov_distribution& dist) +{ + static const char* function = "boost::math::variance(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return (constants::pi_sqr_div_six() + - constants::pi() * constants::ln_two() * constants::ln_two()) / (2*n); +} + +// Skewness and kurtosis come from integrating the PDF +// The alternating series pops out a Dirichlet eta function which is related to the zeta function +template +inline RealType skewness(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::skewness(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + RealType ex3 = RealType(0.5625) * constants::root_half_pi() * constants::zeta_three() / n / sqrt(n); + RealType mean = boost::math::mean(dist); + RealType var = boost::math::variance(dist); + return (ex3 - 3 * mean * var - mean * mean * mean) / var / sqrt(var); +} + +template +inline RealType kurtosis(const kolmogorov_smirnov_distribution& dist) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::kurtosis(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + RealType ex4 = 7 * constants::pi_sqr_div_six() * constants::pi_sqr_div_six() / 20 / n / n; + RealType mean = boost::math::mean(dist); + RealType var = boost::math::variance(dist); + RealType skew = boost::math::skewness(dist); + return (ex4 - 4 * mean * skew * var * sqrt(var) - 6 * mean * mean * var - mean * mean * mean * mean) / var / var; +} + +template +inline RealType kurtosis_excess(const kolmogorov_smirnov_distribution& dist) +{ + static const char* function = "boost::math::kurtosis_excess(const kolmogorov_smirnov_distribution<%1%>&)"; + RealType n = dist.number_of_observations(); + RealType error_result; + if(false == detail::check_df(function, n, &error_result, Policy())) + return error_result; + return kurtosis(dist) - 3; +} +}} +#endif diff --git a/libcxx/src/third-party/boost/math/distributions/laplace.hpp b/libcxx/src/third-party/boost/math/distributions/laplace.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/laplace.hpp @@ -0,0 +1,404 @@ +// Copyright Thijs van den Berg, 2008. +// Copyright John Maddock 2008. +// Copyright Paul A. Bristow 2008, 2014. + +// 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) + +// This module implements the Laplace distribution. +// Weisstein, Eric W. "Laplace Distribution." From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/LaplaceDistribution.html +// http://en.wikipedia.org/wiki/Laplace_distribution +// +// Abramowitz and Stegun 1972, p 930 +// http://www.math.sfu.ca/~cbm/aands/page_930.htm + +#ifndef BOOST_STATS_LAPLACE_HPP +#define BOOST_STATS_LAPLACE_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) // conditional expression is constant +#endif + +template > +class laplace_distribution +{ +public: + // ---------------------------------- + // public Types + // ---------------------------------- + using value_type = RealType; + using policy_type = Policy; + + // ---------------------------------- + // Constructor(s) + // ---------------------------------- + explicit laplace_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_location(l_location), m_scale(l_scale) + { + RealType result; + check_parameters("boost::math::laplace_distribution<%1%>::laplace_distribution()", &result); + } + + + // ---------------------------------- + // Public functions + // ---------------------------------- + + RealType location() const + { + return m_location; + } + + RealType scale() const + { + return m_scale; + } + + bool check_parameters(const char* function, RealType* result) const + { + if(false == detail::check_scale(function, m_scale, result, Policy())) return false; + if(false == detail::check_location(function, m_location, result, Policy())) return false; + return true; + } + +private: + RealType m_location; + RealType m_scale; +}; // class laplace_distribution + +// +// Convenient type synonym for double. +using laplace = laplace_distribution; + +#ifdef __cpp_deduction_guides +template +laplace_distribution(RealType)->laplace_distribution::type>; +template +laplace_distribution(RealType,RealType)->laplace_distribution::type>; +#endif + +// +// Non-member functions. +template +inline std::pair range(const laplace_distribution&) +{ + if (std::numeric_limits::has_infinity) + { // Can use infinity. + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } + +} + +template +inline std::pair support(const laplace_distribution&) +{ + if (std::numeric_limits::has_infinity) + { // Can Use infinity. + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } +} + +template +inline RealType pdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = 0; + const char* function = "boost::math::pdf(const laplace_distribution<%1%>&, %1%))"; + + // Check scale and location. + if (false == dist.check_parameters(function, &result)) return result; + // Special pdf values. + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + if (false == detail::check_x(function, x, &result, Policy())) return result; + + // General case + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + RealType exponent = x - location; + if (exponent>0) exponent = -exponent; + exponent /= scale; + + result = exp(exponent); + result /= 2 * scale; + + return result; +} // pdf + +template +inline RealType logpdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // Checking function argument + RealType result = -std::numeric_limits::infinity(); + const char* function = "boost::math::logpdf(const laplace_distribution<%1%>&, %1%))"; + + // Check scale and location. + if (false == dist.check_parameters(function, &result)) + { + return result; + } + // Special pdf values. + if((boost::math::isinf)(x)) + { + return result; // pdf + and - infinity is zero so logpdf is -INF + } + if (false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType mu = dist.scale(); + const RealType b = dist.location(); + + // if b is 0 avoid divde by 0 error + if(abs(b) < std::numeric_limits::epsilon()) + { + result = log(pdf(dist, x)); + } + else + { + // General case + const RealType log2 = boost::math::constants::ln_two(); + result = -abs(x-mu)/b - log(b) - log2; + } + + return result; +} // logpdf + +template +inline RealType cdf(const laplace_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // For ADL of std functions. + + RealType result = 0; + // Checking function argument. + const char* function = "boost::math::cdf(const laplace_distribution<%1%>&, %1%)"; + // Check scale and location. + if (false == dist.check_parameters(function, &result)) return result; + + // Special cdf values: + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity. + return 1; // + infinity. + } + if (false == detail::check_x(function, x, &result, Policy())) return result; + + // General cdf values + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + if (x < location) + { + result = exp( (x-location)/scale )/2; + } + else + { + result = 1 - exp( (location-x)/scale )/2; + } + return result; +} // cdf + + +template +inline RealType quantile(const laplace_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + // Checking function argument + RealType result = 0; + const char* function = "boost::math::quantile(const laplace_distribution<%1%>&, %1%)"; + if (false == dist.check_parameters(function, &result)) return result; + if(false == detail::check_probability(function, p, &result, Policy())) return result; + + // Extreme values of p: + if(p == 0) + { + result = policies::raise_overflow_error(function, + "probability parameter is 0, but must be > 0!", Policy()); + return -result; // -inf + } + + if(p == 1) + { + result = policies::raise_overflow_error(function, + "probability parameter is 1, but must be < 1!", Policy()); + return result; // inf + } + // Calculate Quantile + RealType scale( dist.scale() ); + RealType location( dist.location() ); + + if (p - 0.5 < 0.0) + result = location + scale*log( static_cast(p*2) ); + else + result = location - scale*log( static_cast(-p*2 + 2) ); + + return result; +} // quantile + + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + // Calculate complement of cdf. + BOOST_MATH_STD_USING // for ADL of std functions + + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + RealType x = c.param; + RealType result = 0; + + // Checking function argument. + const char* function = "boost::math::cdf(const complemented2_type, %1%>&)"; + + // Check scale and location. + if (false == c.dist.check_parameters(function, &result)) return result; + + // Special cdf values. + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy()))return result; + + // Cdf interval value. + if (-x < -location) + { + result = exp( (-x+location)/scale )/2; + } + else + { + result = 1 - exp( (-location+x)/scale )/2; + } + return result; +} // cdf complement + + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions. + + // Calculate quantile. + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + RealType q = c.param; + RealType result = 0; + + // Checking function argument. + const char* function = "quantile(const complemented2_type, %1%>&)"; + if (false == c.dist.check_parameters(function, &result)) return result; + + // Extreme values. + if(q == 0) + { + return std::numeric_limits::infinity(); + } + if(q == 1) + { + return -std::numeric_limits::infinity(); + } + if(false == detail::check_probability(function, q, &result, Policy())) return result; + + if (0.5 - q < 0.0) + result = location + scale*log( static_cast(-q*2 + 2) ); + else + result = location - scale*log( static_cast(q*2) ); + + + return result; +} // quantile + +template +inline RealType mean(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +inline RealType standard_deviation(const laplace_distribution& dist) +{ + return constants::root_two() * dist.scale(); +} + +template +inline RealType mode(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +inline RealType median(const laplace_distribution& dist) +{ + return dist.location(); +} + +template +inline RealType skewness(const laplace_distribution& /*dist*/) +{ + return 0; +} + +template +inline RealType kurtosis(const laplace_distribution& /*dist*/) +{ + return 6; +} + +template +inline RealType kurtosis_excess(const laplace_distribution& /*dist*/) +{ + return 3; +} + +template +inline RealType entropy(const laplace_distribution & dist) +{ + using std::log; + return log(2*dist.scale()*constants::e()); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_LAPLACE_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/logistic.hpp b/libcxx/src/third-party/boost/math/distributions/logistic.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/logistic.hpp @@ -0,0 +1,313 @@ +// Copyright 2008 Gautam Sewani +// +// 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_DISTRIBUTIONS_LOGISTIC +#define BOOST_MATH_DISTRIBUTIONS_LOGISTIC + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + + template > + class logistic_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + logistic_distribution(RealType l_location=0, RealType l_scale=1) // Constructor. + : m_location(l_location), m_scale(l_scale) + { + static const char* function = "boost::math::logistic_distribution<%1%>::logistic_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_location, &result, Policy()); + } + // Accessor functions. + RealType scale()const + { + return m_scale; + } + + RealType location()const + { + return m_location; + } + private: + // Data members: + RealType m_location; // distribution location aka mu. + RealType m_scale; // distribution scale aka s. + }; // class logistic_distribution + + + typedef logistic_distribution logistic; + + #ifdef __cpp_deduction_guides + template + logistic_distribution(RealType)->logistic_distribution::type>; + template + logistic_distribution(RealType,RealType)->logistic_distribution::type>; + #endif + + template + inline const std::pair range(const logistic_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair( + std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -max_value(), + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : max_value()); + } + + template + inline const std::pair support(const logistic_distribution& /* dist */) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + infinity + } + + template + inline RealType pdf(const logistic_distribution& dist, const RealType& x) + { + static const char* function = "boost::math::pdf(const logistic_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType result = 0; + + if(false == detail::check_scale(function, scale , &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + BOOST_MATH_STD_USING + RealType exp_term = (location - x) / scale; + if(fabs(exp_term) > tools::log_max_value()) + return 0; + exp_term = exp(exp_term); + if((exp_term * scale > 1) && (exp_term > tools::max_value() / (scale * exp_term))) + return 1 / (scale * exp_term); + return (exp_term) / (scale * (1 + exp_term) * (1 + exp_term)); + } + + template + inline RealType cdf(const logistic_distribution& dist, const RealType& x) + { + RealType scale = dist.scale(); + RealType location = dist.location(); + RealType result = 0; // of checks. + static const char* function = "boost::math::cdf(const logistic_distribution<%1%>&, %1%)"; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + BOOST_MATH_STD_USING + RealType power = (location - x) / scale; + if(power > tools::log_max_value()) + return 0; + if(power < -tools::log_max_value()) + return 1; + return 1 / (1 + exp(power)); + } + + template + inline RealType quantile(const logistic_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING + RealType location = dist.location(); + RealType scale = dist.scale(); + + static const char* function = "boost::math::quantile(const logistic_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + { + return -policies::raise_overflow_error(function,"probability argument is 0, must be >0 and <1",Policy()); + } + if(p == 1) + { + return policies::raise_overflow_error(function,"probability argument is 1, must be >0 and <1",Policy()); + } + //Expressions to try + //return location+scale*log(p/(1-p)); + //return location+scale*log1p((2*p-1)/(1-p)); + + //return location - scale*log( (1-p)/p); + //return location - scale*log1p((1-2*p)/p); + + //return -scale*log(1/p-1) + location; + return location - scale * log((1 - p) / p); + } // RealType quantile(const logistic_distribution& dist, const RealType& p) + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING + RealType location = c.dist.location(); + RealType scale = c.dist.scale(); + RealType x = c.param; + static const char* function = "boost::math::cdf(const complement(logistic_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + RealType power = (x - location) / scale; + if(power > tools::log_max_value()) + return 0; + if(power < -tools::log_max_value()) + return 1; + return 1 / (1 + exp(power)); + } + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING + RealType scale = c.dist.scale(); + RealType location = c.dist.location(); + static const char* function = "boost::math::quantile(const complement(logistic_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + using boost::math::tools::max_value; + + if(q == 1) + { + return -policies::raise_overflow_error(function,"probability argument is 1, but must be >0 and <1",Policy()); + } + if(q == 0) + { + return policies::raise_overflow_error(function,"probability argument is 0, but must be >0 and <1",Policy()); + } + //Expressions to try + //return location+scale*log((1-q)/q); + return location + scale * log((1 - q) / q); + + //return location-scale*log(q/(1-q)); + //return location-scale*log1p((2*q-1)/(1-q)); + + //return location+scale*log(1/q-1); + //return location+scale*log1p(1/q-2); + } + + template + inline RealType mean(const logistic_distribution& dist) + { + return dist.location(); + } // RealType mean(const logistic_distribution& dist) + + template + inline RealType variance(const logistic_distribution& dist) + { + BOOST_MATH_STD_USING + RealType scale = dist.scale(); + return boost::math::constants::pi()*boost::math::constants::pi()*scale*scale/3; + } // RealType variance(const logistic_distribution& dist) + + template + inline RealType mode(const logistic_distribution& dist) + { + return dist.location(); + } + + template + inline RealType median(const logistic_distribution& dist) + { + return dist.location(); + } + template + inline RealType skewness(const logistic_distribution& /*dist*/) + { + return 0; + } // RealType skewness(const logistic_distribution& dist) + + template + inline RealType kurtosis_excess(const logistic_distribution& /*dist*/) + { + return static_cast(6)/5; + } // RealType kurtosis_excess(const logistic_distribution& dist) + + template + inline RealType kurtosis(const logistic_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } // RealType kurtosis_excess(const logistic_distribution& dist) + + template + inline RealType entropy(const logistic_distribution& dist) + { + using std::log; + return 2 + log(dist.scale()); + } + }} + + +// Must come at the end: +#include + +#endif // BOOST_MATH_DISTRIBUTIONS_LOGISTIC diff --git a/libcxx/src/third-party/boost/math/distributions/lognormal.hpp b/libcxx/src/third-party/boost/math/distributions/lognormal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/lognormal.hpp @@ -0,0 +1,357 @@ +// 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_STATS_LOGNORMAL_HPP +#define BOOST_STATS_LOGNORMAL_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3669.htm +// http://mathworld.wolfram.com/LogNormalDistribution.html +// http://en.wikipedia.org/wiki/Lognormal_distribution + +#include +#include +#include +#include + +#include + +namespace boost{ namespace math +{ +namespace detail +{ + + template + inline bool check_lognormal_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; + } + +} // namespace detail + + +template > +class lognormal_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + lognormal_distribution(RealType l_location = 0, RealType l_scale = 1) + : m_location(l_location), m_scale(l_scale) + { + RealType result; + detail::check_scale("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_scale, &result, Policy()); + detail::check_location("boost::math::lognormal_distribution<%1%>::lognormal_distribution", l_location, &result, Policy()); + } + + RealType location()const + { + return m_location; + } + + RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_location; // distribution location. + RealType m_scale; // distribution scale. +}; + +typedef lognormal_distribution lognormal; + +#ifdef __cpp_deduction_guides +template +lognormal_distribution(RealType)->lognormal_distribution::type>; +template +lognormal_distribution(RealType,RealType)->lognormal_distribution::type>; +#endif + +template +inline const std::pair range(const lognormal_distribution& /*dist*/) +{ // Range of permissible values for random variable x is >0 to +infinity. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline const std::pair support(const lognormal_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +RealType pdf(const lognormal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + static const char* function = "boost::math::pdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, sigma, &result, Policy())) + return result; + if(0 == detail::check_location(function, mu, &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, x, &result, Policy())) + return result; + + if(x == 0) + return 0; + + RealType exponent = log(x) - mu; + exponent *= -exponent; + exponent /= 2 * sigma * sigma; + + result = exp(exponent); + result /= sigma * sqrt(2 * constants::pi()) * x; + + return result; +} + +template +inline RealType cdf(const lognormal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, dist.location(), &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, x, &result, Policy())) + return result; + + if(x == 0) + return 0; + + normal_distribution norm(dist.location(), dist.scale()); + return cdf(norm, log(x)); +} + +template +inline RealType quantile(const lognormal_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, dist.location(), &result, Policy())) + return result; + if(0 == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + return 0; + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + normal_distribution norm(dist.location(), dist.scale()); + return exp(quantile(norm, p)); +} + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, c.dist.location(), &result, Policy())) + return result; + if(0 == detail::check_lognormal_x(function, c.param, &result, Policy())) + return result; + + if(c.param == 0) + return 1; + + normal_distribution norm(c.dist.location(), c.dist.scale()); + return cdf(complement(norm, log(c.param))); +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const lognormal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(0 == detail::check_scale(function, c.dist.scale(), &result, Policy())) + return result; + if(0 == detail::check_location(function, c.dist.location(), &result, Policy())) + return result; + if(0 == detail::check_probability(function, c.param, &result, Policy())) + return result; + + if(c.param == 1) + return 0; + if(c.param == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + normal_distribution norm(c.dist.location(), c.dist.scale()); + return exp(quantile(complement(norm, c.param))); +} + +template +inline RealType mean(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::mean(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::mean(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return exp(mu + sigma * sigma / 2); +} + +template +inline RealType variance(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::variance(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::variance(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return boost::math::expm1(sigma * sigma, Policy()) * exp(2 * mu + sigma * sigma); +} + +template +inline RealType mode(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::mode(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::mode(const lognormal_distribution<%1%>&)", mu, &result, Policy())) + return result; + + return exp(mu - sigma * sigma); +} + +template +inline RealType median(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + RealType mu = dist.location(); + return exp(mu); // e^mu +} + +template +inline RealType skewness(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + //RealType mu = dist.location(); + RealType sigma = dist.scale(); + + RealType ss = sigma * sigma; + RealType ess = exp(ss); + + RealType result = 0; + if(0 == detail::check_scale("boost::math::skewness(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::skewness(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return (ess + 2) * sqrt(boost::math::expm1(ss, Policy())); +} + +template +inline RealType kurtosis(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + //RealType mu = dist.location(); + RealType sigma = dist.scale(); + RealType ss = sigma * sigma; + + RealType result = 0; + if(0 == detail::check_scale("boost::math::kurtosis(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::kurtosis(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 3; +} + +template +inline RealType kurtosis_excess(const lognormal_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + // RealType mu = dist.location(); + RealType sigma = dist.scale(); + RealType ss = sigma * sigma; + + RealType result = 0; + if(0 == detail::check_scale("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", sigma, &result, Policy())) + return result; + if(0 == detail::check_location("boost::math::kurtosis_excess(const lognormal_distribution<%1%>&)", dist.location(), &result, Policy())) + return result; + + return exp(4 * ss) + 2 * exp(3 * ss) + 3 * exp(2 * ss) - 6; +} + +template +inline RealType entropy(const lognormal_distribution& dist) +{ + using std::log; + RealType mu = dist.location(); + RealType sigma = dist.scale(); + return mu + log(constants::two_pi()*constants::e()*sigma*sigma)/2; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_STUDENTS_T_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/negative_binomial.hpp b/libcxx/src/third-party/boost/math/distributions/negative_binomial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/negative_binomial.hpp @@ -0,0 +1,607 @@ +// boost\math\special_functions\negative_binomial.hpp + +// Copyright Paul A. Bristow 2007. +// Copyright John Maddock 2007. + +// 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) + +// http://en.wikipedia.org/wiki/negative_binomial_distribution +// http://mathworld.wolfram.com/NegativeBinomialDistribution.html +// http://documents.wolfram.com/teachersedition/Teacher/Statistics/DiscreteDistributions.html + +// The negative binomial distribution NegativeBinomialDistribution[n, p] +// is the distribution of the number (k) of failures that occur in a sequence of trials before +// r successes have occurred, where the probability of success in each trial is p. + +// In a sequence of Bernoulli trials or events +// (independent, yes or no, succeed or fail) with success_fraction probability p, +// negative_binomial is the probability that k or fewer failures +// precede the r th trial's success. +// random variable k is the number of failures (NOT the probability). + +// Negative_binomial distribution is a discrete probability distribution. +// But note that the negative binomial distribution +// (like others including the binomial, Poisson & Bernoulli) +// is strictly defined as a discrete function: only integral values of k are envisaged. +// However because of the method of calculation using a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. + +// However, by default the policy is to use discrete_quantile_policy. + +// To enforce the strict mathematical model, users should use conversion +// on k outside this function to ensure that k is integral. + +// MATHCAD cumulative negative binomial pnbinom(k, n, p) + +// Implementation note: much greater speed, and perhaps greater accuracy, +// might be achieved for extreme values by using a normal approximation. +// This is NOT been tested or implemented. + +#ifndef BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP +#define BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP + +#include +#include // for ibeta(a, b, x) == Ix(a, b). +#include // complement. +#include // error checks domain_error & logic_error. +#include // isnan. +#include // for root finding. +#include + +#include // using std::numeric_limits; +#include + +#if defined (BOOST_MSVC) +# pragma warning(push) +// This believed not now necessary, so commented out. +//# pragma warning(disable: 4702) // unreachable code. +// in domain_error_imp in error_handling. +#endif + +namespace boost +{ + namespace math + { + namespace negative_binomial_detail + { + // Common error checking routines for negative binomial distribution functions: + template + inline bool check_successes(const char* function, const RealType& r, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(r) || (r <= 0) ) + { + *result = policies::raise_domain_error( + function, + "Number of successes argument is %1%, but must be > 0 !", r, pol); + return false; + } + return true; + } + template + inline bool check_success_fraction(const char* function, const RealType& p, RealType* result, const Policy& pol) + { + if( !(boost::math::isfinite)(p) || (p < 0) || (p > 1) ) + { + *result = policies::raise_domain_error( + function, + "Success fraction argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } + template + inline bool check_dist(const char* function, const RealType& r, const RealType& p, RealType* result, const Policy& pol) + { + return check_success_fraction(function, p, result, pol) + && check_successes(function, r, result, pol); + } + template + inline bool check_dist_and_k(const char* function, const RealType& r, const RealType& p, RealType k, RealType* result, const Policy& pol) + { + if(check_dist(function, r, p, result, pol) == false) + { + return false; + } + if( !(boost::math::isfinite)(k) || (k < 0) ) + { // Check k failures. + *result = policies::raise_domain_error( + function, + "Number of failures argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // Check_dist_and_k + + template + inline bool check_dist_and_prob(const char* function, const RealType& r, RealType p, RealType prob, RealType* result, const Policy& pol) + { + if((check_dist(function, r, p, result, pol) && detail::check_probability(function, prob, result, pol)) == false) + { + return false; + } + return true; + } // check_dist_and_prob + } // namespace negative_binomial_detail + + template > + class negative_binomial_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + negative_binomial_distribution(RealType r, RealType p) : m_r(r), m_p(p) + { // Constructor. + RealType result; + negative_binomial_detail::check_dist( + "negative_binomial_distribution<%1%>::negative_binomial_distribution", + m_r, // Check successes r > 0. + m_p, // Check success_fraction 0 <= p <= 1. + &result, Policy()); + } // negative_binomial_distribution constructor. + + // Private data getter class member functions. + RealType success_fraction() const + { // Probability of success as fraction in range 0 to 1. + return m_p; + } + RealType successes() const + { // Total number of successes r. + return m_r; + } + + static RealType find_lower_bound_on_p( + RealType trials, + RealType successes, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + static const char* function = "boost::math::negative_binomial<%1%>::find_lower_bound_on_p"; + RealType result = 0; // of error checks. + RealType failures = trials - successes; + if(false == detail::check_probability(function, alpha, &result, Policy()) + && negative_binomial_detail::check_dist_and_k( + function, successes, RealType(0), failures, &result, Policy())) + { + return result; + } + // Use complement ibeta_inv function for lower bound. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibeta_inv(successes, failures + 1, alpha, static_cast(nullptr), Policy()); + } // find_lower_bound_on_p + + static RealType find_upper_bound_on_p( + RealType trials, + RealType successes, + RealType alpha) // alpha 0.05 equivalent to 95% for one-sided test. + { + static const char* function = "boost::math::negative_binomial<%1%>::find_upper_bound_on_p"; + RealType result = 0; // of error checks. + RealType failures = trials - successes; + if(false == negative_binomial_detail::check_dist_and_k( + function, successes, RealType(0), failures, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { + return result; + } + if(failures == 0) + return 1; + // Use complement ibetac_inv function for upper bound. + // Note adjusted failures value: *not* failures+1 as usual. + // This is adapted from the corresponding binomial formula + // here: http://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm + // This is a Clopper-Pearson interval, and may be overly conservative, + // see also "A Simple Improved Inferential Method for Some + // Discrete Distributions" Yong CAI and K. KRISHNAMOORTHY + // http://www.ucs.louisiana.edu/~kxk4695/Discrete_new.pdf + // + return ibetac_inv(successes, failures, alpha, static_cast(nullptr), Policy()); + } // find_upper_bound_on_p + + // Estimate number of trials : + // "How many trials do I need to be P% sure of seeing k or fewer failures?" + + static RealType find_minimum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + static const char* function = "boost::math::negative_binomial<%1%>::find_minimum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, RealType(1), p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { return result; } + + result = ibeta_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_failures + + static RealType find_maximum_number_of_trials( + RealType k, // number of failures (k >= 0). + RealType p, // success fraction 0 <= p <= 1. + RealType alpha) // risk level threshold 0 <= alpha <= 1. + { + static const char* function = "boost::math::negative_binomial<%1%>::find_maximum_number_of_trials"; + // Error checks: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, RealType(1), p, k, &result, Policy()) + && detail::check_probability(function, alpha, &result, Policy())) + { return result; } + + result = ibetac_inva(k + 1, p, alpha, Policy()); // returns n - k + return result + k; + } // RealType find_number_of_trials complemented + + private: + RealType m_r; // successes. + RealType m_p; // success_fraction + }; // template class negative_binomial_distribution + + typedef negative_binomial_distribution negative_binomial; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + negative_binomial_distribution(RealType,RealType)->negative_binomial_distribution::type>; + #endif + + template + inline const std::pair range(const negative_binomial_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // max_integer? + } + + template + inline const std::pair support(const negative_binomial_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // max_integer? + } + + template + inline RealType mean(const negative_binomial_distribution& dist) + { // Mean of Negative Binomial distribution = r(1-p)/p. + return dist.successes() * (1 - dist.success_fraction() ) / dist.success_fraction(); + } // mean + + //template + //inline RealType median(const negative_binomial_distribution& dist) + //{ // Median of negative_binomial_distribution is not defined. + // return policies::raise_domain_error(BOOST_CURRENT_FUNCTION, "Median is not implemented, result is %1%!", std::numeric_limits::quiet_NaN()); + //} // median + // Now implemented via quantile(half) in derived accessors. + + template + inline RealType mode(const negative_binomial_distribution& dist) + { // Mode of Negative Binomial distribution = floor[(r-1) * (1 - p)/p] + BOOST_MATH_STD_USING // ADL of std functions. + return floor((dist.successes() -1) * (1 - dist.success_fraction()) / dist.success_fraction()); + } // mode + + template + inline RealType skewness(const negative_binomial_distribution& dist) + { // skewness of Negative Binomial distribution = 2-p / (sqrt(r(1-p)) + BOOST_MATH_STD_USING // ADL of std functions. + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + + return (2 - p) / + sqrt(r * (1 - p)); + } // skewness + + template + inline RealType kurtosis(const negative_binomial_distribution& dist) + { // kurtosis of Negative Binomial distribution + // http://en.wikipedia.org/wiki/Negative_binomial is kurtosis_excess so add 3 + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + return 3 + (6 / r) + ((p * p) / (r * (1 - p))); + } // kurtosis + + template + inline RealType kurtosis_excess(const negative_binomial_distribution& dist) + { // kurtosis excess of Negative Binomial distribution + // http://mathworld.wolfram.com/Kurtosis.html table of kurtosis_excess + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + return (6 - p * (6-p)) / (r * (1-p)); + } // kurtosis_excess + + template + inline RealType variance(const negative_binomial_distribution& dist) + { // Variance of Binomial distribution = r (1-p) / p^2. + return dist.successes() * (1 - dist.success_fraction()) + / (dist.success_fraction() * dist.success_fraction()); + } // variance + + // RealType standard_deviation(const negative_binomial_distribution& dist) + // standard_deviation provided by derived accessors. + // RealType hazard(const negative_binomial_distribution& dist) + // hazard of Negative Binomial distribution provided by derived accessors. + // RealType chf(const negative_binomial_distribution& dist) + // chf of Negative Binomial distribution provided by derived accessors. + + template + inline RealType pdf(const negative_binomial_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + BOOST_FPU_EXCEPTION_GUARD + + static const char* function = "boost::math::pdf(const negative_binomial_distribution<%1%>&, %1%)"; + + RealType r = dist.successes(); + RealType p = dist.success_fraction(); + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + result = (p/(r + k)) * ibeta_derivative(r, static_cast(k+1), p, Policy()); + // Equivalent to: + // return exp(lgamma(r + k) - lgamma(r) - lgamma(k+1)) * pow(p, r) * pow((1-p), k); + return result; + } // negative_binomial_pdf + + template + inline RealType cdf(const negative_binomial_distribution& dist, const RealType& k) + { // Cumulative Distribution Function of Negative Binomial. + static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)"; + using boost::math::ibeta; // Regularized incomplete beta function. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Error check: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + dist.success_fraction(), + k, + &result, Policy())) + { + return result; + } + + RealType probability = ibeta(r, static_cast(k+1), p, Policy()); + // Ip(r, k+1) = ibeta(r, k+1, p) + return probability; + } // cdf Cumulative Distribution Function Negative Binomial. + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Negative Binomial. + + static const char* function = "boost::math::cdf(const negative_binomial_distribution<%1%>&, %1%)"; + using boost::math::ibetac; // Regularized incomplete beta function complement. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + RealType const& k = c.param; + negative_binomial_distribution const& dist = c.dist; + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Error check: + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_k( + function, + r, + p, + k, + &result, Policy())) + { + return result; + } + // Calculate cdf negative binomial using the incomplete beta function. + // Use of ibeta here prevents cancellation errors in calculating + // 1-p if p is very small, perhaps smaller than machine epsilon. + // Ip(k+1, r) = ibetac(r, k+1, p) + // constrain_probability here? + RealType probability = ibetac(r, static_cast(k+1), p, Policy()); + // Numerical errors might cause probability to be slightly outside the range < 0 or > 1. + // This might cause trouble downstream, so warn, possibly throw exception, but constrain to the limits. + return probability; + } // cdf Cumulative Distribution Function Negative Binomial. + + template + inline RealType quantile(const negative_binomial_distribution& dist, const RealType& P) + { // Quantile, percentile/100 or Percent Point Negative Binomial function. + // Return the number of expected failures k for a given probability p. + + // Inverse cumulative Distribution Function or Quantile (percentile / 100) of negative_binomial Probability. + // MAthCAD pnbinom return smallest k such that negative_binomial(k, n, p) >= probability. + // k argument may be integral, signed, or unsigned, or floating point. + // BUT Cephes/CodeCogs says: finds argument p (0 to 1) such that cdf(k, n, p) = y + static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING // ADL of std functions. + + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + // Check dist and P. + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_prob + (function, r, p, P, &result, Policy())) + { + return result; + } + + // Special cases. + if (P == 1) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument is 1, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (P == 0) + { // No failures are expected if P = 0. + return 0; // Total trials will be just dist.successes. + } + if (P <= pow(dist.success_fraction(), dist.successes())) + { // p <= pdf(dist, 0) == cdf(dist, 0) + return 0; + } + if(p == 0) + { // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Success fraction is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + /* + // Calculate quantile of negative_binomial using the inverse incomplete beta function. + using boost::math::ibeta_invb; + return ibeta_invb(r, p, P, Policy()) - 1; // + */ + RealType guess = 0; + RealType factor = 5; + if(r * r * r * P * p > 0.005) + guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), P, RealType(1-P), Policy()); + + if(guess < 10) + { + // + // Cornish-Fisher Negative binomial approximation not accurate in this area: + // + guess = (std::min)(RealType(r * 2), RealType(10)); + } + else + factor = (1-P < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + typedef typename Policy::discrete_quantile_type discrete_type; + return detail::inverse_discrete_quantile( + dist, + P, + false, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // RealType quantile(const negative_binomial_distribution dist, p) + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile or Percent Point Binomial function. + // Return the number of expected failures k for a given + // complement of the probability Q = 1 - P. + static const char* function = "boost::math::quantile(const negative_binomial_distribution<%1%>&, %1%)"; + BOOST_MATH_STD_USING + + // Error checks: + RealType Q = c.param; + const negative_binomial_distribution& dist = c.dist; + RealType p = dist.success_fraction(); + RealType r = dist.successes(); + RealType result = 0; + if(false == negative_binomial_detail::check_dist_and_prob( + function, + r, + p, + Q, + &result, Policy())) + { + return result; + } + + // Special cases: + // + if(Q == 1) + { // There may actually be no answer to this question, + // since the probability of zero failures may be non-zero, + return 0; // but zero is the best we can do: + } + if(Q == 0) + { // Probability 1 - Q == 1 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Probability argument complement is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + if (-Q <= boost::math::powm1(dist.success_fraction(), dist.successes(), Policy())) + { // q <= cdf(complement(dist, 0)) == pdf(dist, 0) + return 0; // + } + if(p == 0) + { // Success fraction is 0 so infinite failures to achieve certainty. + // Would need +infinity failures for total confidence. + result = policies::raise_overflow_error( + function, + "Success fraction is 0, which implies infinite failures !", Policy()); + return result; + // usually means return +std::numeric_limits::infinity(); + // unless #define BOOST_MATH_THROW_ON_OVERFLOW_ERROR + } + //return ibetac_invb(r, p, Q, Policy()) -1; + RealType guess = 0; + RealType factor = 5; + if(r * r * r * (1-Q) * p > 0.005) + guess = detail::inverse_negative_binomial_cornish_fisher(r, p, RealType(1-p), RealType(1-Q), Q, Policy()); + + if(guess < 10) + { + // + // Cornish-Fisher Negative binomial approximation not accurate in this area: + // + guess = (std::min)(RealType(r * 2), RealType(10)); + } + else + factor = (Q < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + typedef typename Policy::discrete_quantile_type discrete_type; + return detail::inverse_discrete_quantile( + dist, + Q, + true, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile complement + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#if defined (BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_SPECIAL_NEGATIVE_BINOMIAL_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/non_central_beta.hpp b/libcxx/src/third-party/boost/math/distributions/non_central_beta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/non_central_beta.hpp @@ -0,0 +1,940 @@ +// boost\math\distributions\non_central_beta.hpp + +// Copyright John Maddock 2008. + +// 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_NON_CENTRAL_BETA_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP + +#include +#include // for incomplete gamma. gamma_q +#include // complements +#include // central distribution +#include +#include // error checks +#include // isnan. +#include // for root finding. +#include + +namespace boost +{ + namespace math + { + + template + class non_central_beta_distribution; + + namespace detail{ + + template + T non_central_beta_p(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0) + { + BOOST_MATH_STD_USING + using namespace boost::math; + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, + // note that unlike other similar code, we do not set + // k to zero, when l2 is small, as forward iteration + // is unstable: + // + int k = itrunc(l2); + if(k == 0) + k = 1; + // Starting Poisson weight: + T pois = gamma_p_derivative(T(k+1), l2, pol); + if(pois == 0) + return init_val; + // recurance term: + T xterm; + // Starting beta term: + T beta = x < y + ? detail::ibeta_imp(T(a + k), b, x, pol, false, true, &xterm) + : detail::ibeta_imp(b, T(a + k), y, pol, true, true, &xterm); + + xterm *= y / (a + b + k - 1); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + + if((beta == 0) && (xterm == 0)) + return init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + T last_term = 0; + std::uintmax_t count = k; + for(int i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + if(((fabs(term/sum) < errtol) && (last_term >= term)) || (term == 0)) + { + count = k - i; + break; + } + pois *= i / l2; + beta += xterm; + + if (a + b + i != 2) + { + xterm *= (a + i - 1) / (x * (a + b + i - 2)); + } + + last_term = term; + } + for(int i = k + 1; ; ++i) + { + poisf *= l2 / i; + xtermf *= (x * (a + b + i - 2)) / (a + i - 1); + betaf -= xtermf; + + T term = poisf * betaf; + sum += term; + if((fabs(term/sum) < errtol) || (term == 0)) + { + break; + } + if(static_cast(count + i - k) > max_iter) + { + return policies::raise_evaluation_error( + "cdf(non_central_beta_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + } + return sum; + } + + template + T non_central_beta_q(T a, T b, T lam, T x, T y, const Policy& pol, T init_val = 0) + { + BOOST_MATH_STD_USING + using namespace boost::math; + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + int k = itrunc(l2); + T pois; + if(k <= 30) + { + // + // Might as well start at 0 since we'll likely have this number of terms anyway: + // + if(a + b > 1) + k = 0; + else if(k == 0) + k = 1; + } + if(k == 0) + { + // Starting Poisson weight: + pois = exp(-l2); + } + else + { + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), l2, pol); + } + if(pois == 0) + return init_val; + // recurance term: + T xterm; + // Starting beta term: + T beta = x < y + ? detail::ibeta_imp(T(a + k), b, x, pol, true, true, &xterm) + : detail::ibeta_imp(b, T(a + k), y, pol, false, true, &xterm); + + xterm *= y / (a + b + k - 1); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((beta == 0) && (xterm == 0)) + return init_val; + // + // Forwards recursion first, this is the stable + // direction for recursion, and the location + // of the bulk of the sum: + // + T last_term = 0; + std::uintmax_t count = 0; + for(int i = k + 1; ; ++i) + { + poisf *= l2 / i; + xtermf *= (x * (a + b + i - 2)) / (a + i - 1); + betaf += xtermf; + + T term = poisf * betaf; + sum += term; + if((fabs(term/sum) < errtol) && (last_term >= term)) + { + count = i - k; + break; + } + if(static_cast(i - k) > max_iter) + { + return policies::raise_evaluation_error( + "cdf(non_central_beta_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + last_term = term; + } + for(int i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + if(fabs(term/sum) < errtol) + { + break; + } + if(static_cast(count + k - i) > max_iter) + { + return policies::raise_evaluation_error( + "cdf(non_central_beta_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + pois *= i / l2; + beta -= xterm; + xterm *= (a + i - 1) / (x * (a + b + i - 2)); + } + return sum; + } + + template + inline RealType non_central_beta_cdf(RealType x, RealType y, RealType a, RealType b, RealType l, bool invert, const Policy&) + { + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + + if(x == 0) + return invert ? 1.0f : 0.0f; + if(y == 0) + return invert ? 0.0f : 1.0f; + value_type result; + value_type c = a + b + l / 2; + value_type cross = 1 - (b / c) * (1 + l / (2 * c * c)); + if(l == 0) + result = cdf(boost::math::beta_distribution(a, b), x); + else if(x > cross) + { + // Complement is the smaller of the two: + result = detail::non_central_beta_q( + static_cast(a), + static_cast(b), + static_cast(l), + static_cast(x), + static_cast(y), + forwarding_policy(), + static_cast(invert ? 0 : -1)); + invert = !invert; + } + else + { + result = detail::non_central_beta_p( + static_cast(a), + static_cast(b), + static_cast(l), + static_cast(x), + static_cast(y), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + if(invert) + result = -result; + return policies::checked_narrowing_cast( + result, + "boost::math::non_central_beta_cdf<%1%>(%1%, %1%, %1%)"); + } + + template + struct nc_beta_quantile_functor + { + nc_beta_quantile_functor(const non_central_beta_distribution& d, T t, bool c) + : dist(d), target(t), comp(c) {} + + T operator()(const T& x) + { + return comp ? + T(target - cdf(complement(dist, x))) + : T(cdf(dist, x) - target); + } + + private: + non_central_beta_distribution dist; + T target; + bool comp; + }; + + // + // This is more or less a copy of bracket_and_solve_root, but + // modified to search only the interval [0,1] using similar + // heuristics. + // + template + std::pair bracket_and_solve_root_01(F f, const T& guess, T factor, bool rising, Tol tol, std::uintmax_t& max_iter, const Policy& pol) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::tools::bracket_and_solve_root_01<%1%>"; + // + // Set up initial brackets: + // + T a = guess; + T b = a; + T fa = f(a); + T fb = fa; + // + // Set up invocation count: + // + std::uintmax_t count = max_iter - 1; + + if((fa < 0) == (guess < 0 ? !rising : rising)) + { + // + // Zero is to the right of b, so walk upwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(count == 0) + { + b = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol); + return std::make_pair(a, b); + } + // + // Heuristic: every 20 iterations we double the growth factor in case the + // initial guess was *really* bad ! + // + if((max_iter - count) % 20 == 0) + factor *= 2; + // + // Now go ahead and move are guess by "factor", + // we do this by reducing 1-guess by factor: + // + a = b; + fa = fb; + b = 1 - ((1 - b) / factor); + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); + } + if(count == 0) + { + a = policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol); + return std::make_pair(a, b); + } + // + // Heuristic: every 20 iterations we double the growth factor in case the + // initial guess was *really* bad ! + // + if((max_iter - count) % 20 == 0) + factor *= 2; + // + // Now go ahead and move are guess by "factor": + // + b = a; + fb = fa; + a /= factor; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + max_iter -= count; + max_iter += 1; + std::pair r = toms748_solve( + f, + (a < 0 ? b : a), + (a < 0 ? a : b), + (a < 0 ? fb : fa), + (a < 0 ? fa : fb), + tol, + count, + pol); + max_iter += count; + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + return r; + } + + template + RealType nc_beta_quantile(const non_central_beta_distribution& dist, const RealType& p, bool comp) + { + static const char* function = "quantile(non_central_beta_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type a = dist.alpha(); + value_type b = dist.beta(); + value_type l = dist.non_centrality(); + value_type r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_probability( + function, + static_cast(p), + &r, + Policy())) + return (RealType)r; + // + // Special cases first: + // + if(p == 0) + return comp + ? 1.0f + : 0.0f; + if(p == 1) + return !comp + ? 1.0f + : 0.0f; + + value_type c = a + b + l / 2; + value_type mean = 1 - (b / c) * (1 + l / (2 * c * c)); + /* + // + // Calculate a normal approximation to the quantile, + // uses mean and variance approximations from: + // Algorithm AS 310: + // Computing the Non-Central Beta Distribution Function + // R. Chattamvelli; R. Shanmugam + // Applied Statistics, Vol. 46, No. 1. (1997), pp. 146-156. + // + // Unfortunately, when this is wrong it tends to be *very* + // wrong, so it's disabled for now, even though it often + // gets the initial guess quite close. Probably we could + // do much better by factoring in the skewness if only + // we could calculate it.... + // + value_type delta = l / 2; + value_type delta2 = delta * delta; + value_type delta3 = delta * delta2; + value_type delta4 = delta2 * delta2; + value_type G = c * (c + 1) + delta; + value_type alpha = a + b; + value_type alpha2 = alpha * alpha; + value_type eta = (2 * alpha + 1) * (2 * alpha + 1) + 1; + value_type H = 3 * alpha2 + 5 * alpha + 2; + value_type F = alpha2 * (alpha + 1) + H * delta + + (2 * alpha + 4) * delta2 + delta3; + value_type P = (3 * alpha + 1) * (9 * alpha + 17) + + 2 * alpha * (3 * alpha + 2) * (3 * alpha + 4) + 15; + value_type Q = 54 * alpha2 + 162 * alpha + 130; + value_type R = 6 * (6 * alpha + 11); + value_type D = delta + * (H * H + 2 * P * delta + Q * delta2 + R * delta3 + 9 * delta4); + value_type variance = (b / G) + * (1 + delta * (l * l + 3 * l + eta) / (G * G)) + - (b * b / F) * (1 + D / (F * F)); + value_type sd = sqrt(variance); + + value_type guess = comp + ? quantile(complement(normal_distribution(static_cast(mean), static_cast(sd)), p)) + : quantile(normal_distribution(static_cast(mean), static_cast(sd)), p); + + if(guess >= 1) + guess = mean; + if(guess <= tools::min_value()) + guess = mean; + */ + value_type guess = mean; + detail::nc_beta_quantile_functor + f(non_central_beta_distribution(a, b, l), p, comp); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + + std::pair ir + = bracket_and_solve_root_01( + f, guess, value_type(2.5), true, tol, + max_iter, Policy()); + value_type result = ir.first + (ir.second - ir.first) / 2; + + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " either there is no answer to quantile of the non central beta distribution" + " or the answer is infinite. Current best guess is %1%", + policies::checked_narrowing_cast( + result, + function), Policy()); + } + return policies::checked_narrowing_cast( + result, + function); + } + + template + T non_central_beta_pdf(T a, T b, T lam, T x, T y, const Policy& pol) + { + BOOST_MATH_STD_USING + // + // Special cases: + // + if((x == 0) || (y == 0)) + return 0; + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T l2 = lam / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + int k = itrunc(l2); + // Starting Poisson weight: + T pois = gamma_p_derivative(T(k+1), l2, pol); + // Starting beta term: + T beta = x < y ? + ibeta_derivative(a + k, b, x, pol) + : ibeta_derivative(b, a + k, y, pol); + T sum = 0; + T poisf(pois); + T betaf(beta); + + // + // Stable backwards recursion first: + // + std::uintmax_t count = k; + for(int i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + if((fabs(term/sum) < errtol) || (term == 0)) + { + count = k - i; + break; + } + pois *= i / l2; + + if (a + b + i != 1) + { + beta *= (a + i - 1) / (x * (a + i + b - 1)); + } + } + for(int i = k + 1; ; ++i) + { + poisf *= l2 / i; + betaf *= x * (a + b + i - 1) / (a + i - 1); + + T term = poisf * betaf; + sum += term; + if((fabs(term/sum) < errtol) || (term == 0)) + { + break; + } + if(static_cast(count + i - k) > max_iter) + { + return policies::raise_evaluation_error( + "pdf(non_central_beta_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + } + return sum; + } + + template + RealType nc_beta_pdf(const non_central_beta_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING + static const char* function = "pdf(non_central_beta_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type a = dist.alpha(); + value_type b = dist.beta(); + value_type l = dist.non_centrality(); + value_type r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + static_cast(x), + &r, + Policy())) + return (RealType)r; + + if(l == 0) + return pdf(boost::math::beta_distribution(dist.alpha(), dist.beta()), x); + return policies::checked_narrowing_cast( + non_central_beta_pdf(a, b, l, static_cast(x), value_type(1 - static_cast(x)), forwarding_policy()), + "function"); + } + + template + struct hypergeometric_2F2_sum + { + typedef T result_type; + hypergeometric_2F2_sum(T a1_, T a2_, T b1_, T b2_, T z_) : a1(a1_), a2(a2_), b1(b1_), b2(b2_), z(z_), term(1), k(0) {} + T operator()() + { + T result = term; + term *= a1 * a2 / (b1 * b2); + a1 += 1; + a2 += 1; + b1 += 1; + b2 += 1; + k += 1; + term /= k; + term *= z; + return result; + } + T a1, a2, b1, b2, z, term, k; + }; + + template + T hypergeometric_2F2(T a1, T a2, T b1, T b2, T z, const Policy& pol) + { + typedef typename policies::evaluation::type value_type; + + const char* function = "boost::math::detail::hypergeometric_2F2<%1%>(%1%,%1%,%1%,%1%,%1%)"; + + hypergeometric_2F2_sum s(a1, a2, b1, b2, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + value_type result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return policies::checked_narrowing_cast(result, function); + } + + } // namespace detail + + template > + class non_central_beta_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + non_central_beta_distribution(RealType a_, RealType b_, RealType lambda) : a(a_), b(b_), ncp(lambda) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::non_central_beta_distribution(%1%,%1%)"; + RealType r; + beta_detail::check_alpha( + function, + a, &r, Policy()); + beta_detail::check_beta( + function, + b, &r, Policy()); + detail::check_non_centrality( + function, + lambda, + &r, + Policy()); + } // non_central_beta_distribution constructor. + + RealType alpha() const + { // Private data getter function. + return a; + } + RealType beta() const + { // Private data getter function. + return b; + } + RealType non_centrality() const + { // Private data getter function. + return ncp; + } + private: + // Data member, initialized by constructor. + RealType a; // alpha. + RealType b; // beta. + RealType ncp; // non-centrality parameter + }; // template class non_central_beta_distribution + + typedef non_central_beta_distribution non_central_beta; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_beta_distribution(RealType,RealType,RealType)->non_central_beta_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline const std::pair range(const non_central_beta_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline const std::pair support(const non_central_beta_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), static_cast(1)); + } + + template + inline RealType mode(const non_central_beta_distribution& dist) + { // mode. + static const char* function = "mode(non_central_beta_distribution<%1%> const&)"; + + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return (RealType)r; + RealType c = a + b + l / 2; + RealType mean = 1 - (b / c) * (1 + l / (2 * c * c)); + return detail::generic_find_mode_01( + dist, + mean, + function); + } + + // + // We don't have the necessary information to implement + // these at present. These are just disabled for now, + // prototypes retained so we can fill in the blanks + // later: + // + template + inline RealType mean(const non_central_beta_distribution& dist) + { + BOOST_MATH_STD_USING + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType d = dist.non_centrality(); + RealType apb = a + b; + return exp(-d / 2) * a * detail::hypergeometric_2F2(1 + a, apb, a, 1 + apb, d / 2, Policy()) / apb; + } // mean + + template + inline RealType variance(const non_central_beta_distribution& dist) + { + // + // Relative error of this function may be arbitrarily large... absolute + // error will be small however... that's the best we can do for now. + // + BOOST_MATH_STD_USING + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType d = dist.non_centrality(); + RealType apb = a + b; + RealType result = detail::hypergeometric_2F2(RealType(1 + a), apb, a, RealType(1 + apb), RealType(d / 2), Policy()); + result *= result * -exp(-d) * a * a / (apb * apb); + result += exp(-d / 2) * a * (1 + a) * detail::hypergeometric_2F2(RealType(2 + a), apb, a, RealType(2 + apb), RealType(d / 2), Policy()) / (apb * (1 + apb)); + return result; + } + + // RealType standard_deviation(const non_central_beta_distribution& dist) + // standard_deviation provided by derived accessors. + template + inline RealType skewness(const non_central_beta_distribution& /*dist*/) + { // skewness = sqrt(l). + const char* function = "boost::math::non_central_beta_distribution<%1%>::skewness()"; + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "Assert type is undefined."); + + return policies::raise_evaluation_error( + function, + "This function is not yet implemented, the only sensible result is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); // infinity? + } + + template + inline RealType kurtosis_excess(const non_central_beta_distribution& /*dist*/) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::kurtosis_excess()"; + typedef typename Policy::assert_undefined_type assert_type; + static_assert(assert_type::value == 0, "Assert type is undefined."); + + return policies::raise_evaluation_error( + function, + "This function is not yet implemented, the only sensible result is %1%.", + std::numeric_limits::quiet_NaN(), Policy()); // infinity? + } // kurtosis_excess + + template + inline RealType kurtosis(const non_central_beta_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType pdf(const non_central_beta_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + return detail::nc_beta_pdf(dist, x); + } // pdf + + template + RealType cdf(const non_central_beta_distribution& dist, const RealType& x) + { + const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)"; + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + x, + &r, + Policy())) + return (RealType)r; + + if(l == 0) + return cdf(beta_distribution(a, b), x); + + return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, false, Policy()); + } // cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + const char* function = "boost::math::non_central_beta_distribution<%1%>::cdf(%1%)"; + non_central_beta_distribution const& dist = c.dist; + RealType a = dist.alpha(); + RealType b = dist.beta(); + RealType l = dist.non_centrality(); + RealType x = c.param; + RealType r; + if(!beta_detail::check_alpha( + function, + a, &r, Policy()) + || + !beta_detail::check_beta( + function, + b, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !beta_detail::check_x( + function, + x, + &r, + Policy())) + return (RealType)r; + + if(l == 0) + return cdf(complement(beta_distribution(a, b), x)); + + return detail::non_central_beta_cdf(x, RealType(1 - x), a, b, l, true, Policy()); + } // ccdf + + template + inline RealType quantile(const non_central_beta_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + return detail::nc_beta_quantile(dist, p, false); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + return detail::nc_beta_quantile(c.dist, c.param, true); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_BETA_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/non_central_chi_squared.hpp b/libcxx/src/third-party/boost/math/distributions/non_central_chi_squared.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/non_central_chi_squared.hpp @@ -0,0 +1,1003 @@ +// boost\math\distributions\non_central_chi_squared.hpp + +// Copyright John Maddock 2008. + +// 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_NON_CENTRAL_CHI_SQUARE_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP + +#include +#include // for incomplete gamma. gamma_q +#include // for cyl_bessel_i +#include // for iround +#include // complements +#include // central distribution +#include // error checks +#include // isnan. +#include // for root finding. +#include +#include + +namespace boost +{ + namespace math + { + + template + class non_central_chi_squared_distribution; + + namespace detail{ + + template + T non_central_chi_square_q(T x, T f, T theta, const Policy& pol, T init_sum = 0) + { + // + // Computes the complement of the Non-Central Chi-Square + // Distribution CDF by summing a weighted sum of complements + // of the central-distributions. The weighting factor is + // a Poisson Distribution. + // + // This is an application of the technique described in: + // + // Computing discrete mixtures of continuous + // distributions: noncentral chisquare, noncentral t + // and the distribution of the square of the sample + // multiple correlation coefficient. + // D. Benton, K. Krishnamoorthy. + // Computational Statistics & Data Analysis 43 (2003) 249 - 267 + // + BOOST_MATH_STD_USING + + // Special case: + if(x == 0) + return 1; + + // + // Initialize the variables we'll be using: + // + T lambda = theta / 2; + T del = f / 2; + T y = x / 2; + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T sum = init_sum; + // + // k is the starting location for iteration, we'll + // move both forwards and backwards from this point. + // k is chosen as the peek of the Poisson weights, which + // will occur *before* the largest term. + // + int k = iround(lambda, pol); + // Forwards and backwards Poisson weights: + T poisf = boost::math::gamma_p_derivative(static_cast(1 + k), lambda, pol); + T poisb = poisf * k / lambda; + // Initial forwards central chi squared term: + T gamf = boost::math::gamma_q(del + k, y, pol); + // Forwards and backwards recursion terms on the central chi squared: + T xtermf = boost::math::gamma_p_derivative(del + 1 + k, y, pol); + T xtermb = xtermf * (del + k) / y; + // Initial backwards central chi squared term: + T gamb = gamf - xtermb; + + // + // Forwards iteration first, this is the + // stable direction for the gamma function + // recurrences: + // + int i; + for(i = k; static_cast(i-k) < max_iter; ++i) + { + T term = poisf * gamf; + sum += term; + poisf *= lambda / (i + 1); + gamf += xtermf; + xtermf *= y / (del + i + 1); + if(((sum == 0) || (fabs(term / sum) < errtol)) && (term >= poisf * gamf)) + break; + } + //Error check: + if(static_cast(i-k) >= max_iter) + return policies::raise_evaluation_error( + "cdf(non_central_chi_squared_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + // + // Now backwards iteration: the gamma + // function recurrences are unstable in this + // direction, we rely on the terms diminishing in size + // faster than we introduce cancellation errors. + // For this reason it's very important that we start + // *before* the largest term so that backwards iteration + // is strictly converging. + // + for(i = k - 1; i >= 0; --i) + { + T term = poisb * gamb; + sum += term; + poisb *= i / lambda; + xtermb *= (del + i) / y; + gamb -= xtermb; + if((sum == 0) || (fabs(term / sum) < errtol)) + break; + } + + return sum; + } + + template + T non_central_chi_square_p_ding(T x, T f, T theta, const Policy& pol, T init_sum = 0) + { + // + // This is an implementation of: + // + // Algorithm AS 275: + // Computing the Non-Central #2 Distribution Function + // Cherng G. Ding + // Applied Statistics, Vol. 41, No. 2. (1992), pp. 478-482. + // + // This uses a stable forward iteration to sum the + // CDF, unfortunately this can not be used for large + // values of the non-centrality parameter because: + // * The first term may underflow to zero. + // * We may need an extra-ordinary number of terms + // before we reach the first *significant* term. + // + BOOST_MATH_STD_USING + // Special case: + if(x == 0) + return 0; + T tk = boost::math::gamma_p_derivative(f/2 + 1, x/2, pol); + T lambda = theta / 2; + T vk = exp(-lambda); + T uk = vk; + T sum = init_sum + tk * vk; + if(sum == 0) + return sum; + + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + + int i; + T lterm(0), term(0); + for(i = 1; static_cast(i) < max_iter; ++i) + { + tk = tk * x / (f + 2 * i); + uk = uk * lambda / i; + vk = vk + uk; + lterm = term; + term = vk * tk; + sum += term; + if((fabs(term / sum) < errtol) && (term <= lterm)) + break; + } + //Error check: + if(static_cast(i) >= max_iter) + return policies::raise_evaluation_error( + "cdf(non_central_chi_squared_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + return sum; + } + + + template + T non_central_chi_square_p(T y, T n, T lambda, const Policy& pol, T init_sum) + { + // + // This is taken more or less directly from: + // + // Computing discrete mixtures of continuous + // distributions: noncentral chisquare, noncentral t + // and the distribution of the square of the sample + // multiple correlation coefficient. + // D. Benton, K. Krishnamoorthy. + // Computational Statistics & Data Analysis 43 (2003) 249 - 267 + // + // We're summing a Poisson weighting term multiplied by + // a central chi squared distribution. + // + BOOST_MATH_STD_USING + // Special case: + if(y == 0) + return 0; + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T errorf(0), errorb(0); + + T x = y / 2; + T del = lambda / 2; + // + // Starting location for the iteration, we'll iterate + // both forwards and backwards from this point. The + // location chosen is the maximum of the Poisson weight + // function, which ocurrs *after* the largest term in the + // sum. + // + int k = iround(del, pol); + T a = n / 2 + k; + // Central chi squared term for forward iteration: + T gamkf = boost::math::gamma_p(a, x, pol); + + if(lambda == 0) + return gamkf; + // Central chi squared term for backward iteration: + T gamkb = gamkf; + // Forwards Poisson weight: + T poiskf = gamma_p_derivative(static_cast(k+1), del, pol); + // Backwards Poisson weight: + T poiskb = poiskf; + // Forwards gamma function recursion term: + T xtermf = boost::math::gamma_p_derivative(a, x, pol); + // Backwards gamma function recursion term: + T xtermb = xtermf * x / a; + T sum = init_sum + poiskf * gamkf; + if(sum == 0) + return sum; + int i = 1; + // + // Backwards recursion first, this is the stable + // direction for gamma function recurrences: + // + while(i <= k) + { + xtermb *= (a - i + 1) / x; + gamkb += xtermb; + poiskb = poiskb * (k - i + 1) / del; + errorf = errorb; + errorb = gamkb * poiskb; + sum += errorb; + if((fabs(errorb / sum) < errtol) && (errorb <= errorf)) + break; + ++i; + } + i = 1; + // + // Now forwards recursion, the gamma function + // recurrence relation is unstable in this direction, + // so we rely on the magnitude of successive terms + // decreasing faster than we introduce cancellation error. + // For this reason it's vital that k is chosen to be *after* + // the largest term, so that successive forward iterations + // are strictly (and rapidly) converging. + // + do + { + xtermf = xtermf * x / (a + i - 1); + gamkf = gamkf - xtermf; + poiskf = poiskf * del / (k + i); + errorf = poiskf * gamkf; + sum += errorf; + ++i; + }while((fabs(errorf / sum) > errtol) && (static_cast(i) < max_iter)); + + //Error check: + if(static_cast(i) >= max_iter) + return policies::raise_evaluation_error( + "cdf(non_central_chi_squared_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + + return sum; + } + + template + T non_central_chi_square_pdf(T x, T n, T lambda, const Policy& pol) + { + // + // As above but for the PDF: + // + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T x2 = x / 2; + T n2 = n / 2; + T l2 = lambda / 2; + T sum = 0; + int k = itrunc(l2); + T pois = gamma_p_derivative(static_cast(k + 1), l2, pol) * gamma_p_derivative(static_cast(n2 + k), x2); + if(pois == 0) + return 0; + T poisb = pois; + for(int i = k; ; ++i) + { + sum += pois; + if(pois / sum < errtol) + break; + if(static_cast(i - k) >= max_iter) + return policies::raise_evaluation_error( + "pdf(non_central_chi_squared_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + pois *= l2 * x2 / ((i + 1) * (n2 + i)); + } + for(int i = k - 1; i >= 0; --i) + { + poisb *= (i + 1) * (n2 + i) / (l2 * x2); + sum += poisb; + if(poisb / sum < errtol) + break; + } + return sum / 2; + } + + template + inline RealType non_central_chi_squared_cdf(RealType x, RealType k, RealType l, bool invert, const Policy&) + { + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + value_type result; + if(l == 0) + return invert == false ? cdf(boost::math::chi_squared_distribution(k), x) : cdf(complement(boost::math::chi_squared_distribution(k), x)); + else if(x > k + l) + { + // Complement is the smaller of the two: + result = detail::non_central_chi_square_q( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? 0 : -1)); + invert = !invert; + } + else if(l < 200) + { + // For small values of the non-centrality parameter + // we can use Ding's method: + result = detail::non_central_chi_square_p_ding( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + else + { + // For largers values of the non-centrality + // parameter Ding's method will consume an + // extra-ordinary number of terms, and worse + // may return zero when the result is in fact + // finite, use Krishnamoorthy's method instead: + result = detail::non_central_chi_square_p( + static_cast(x), + static_cast(k), + static_cast(l), + forwarding_policy(), + static_cast(invert ? -1 : 0)); + } + if(invert) + result = -result; + return policies::checked_narrowing_cast( + result, + "boost::math::non_central_chi_squared_cdf<%1%>(%1%, %1%, %1%)"); + } + + template + struct nccs_quantile_functor + { + nccs_quantile_functor(const non_central_chi_squared_distribution& d, T t, bool c) + : dist(d), target(t), comp(c) {} + + T operator()(const T& x) + { + return comp ? + target - cdf(complement(dist, x)) + : cdf(dist, x) - target; + } + + private: + non_central_chi_squared_distribution dist; + T target; + bool comp; + }; + + template + RealType nccs_quantile(const non_central_chi_squared_distribution& dist, const RealType& p, bool comp) + { + BOOST_MATH_STD_USING + static const char* function = "quantile(non_central_chi_squared_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type k = dist.degrees_of_freedom(); + value_type l = dist.non_centrality(); + value_type r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_probability( + function, + static_cast(p), + &r, + Policy())) + return (RealType)r; + // + // Special cases get short-circuited first: + // + if(p == 0) + return comp ? policies::raise_overflow_error(function, 0, Policy()) : 0; + if(p == 1) + return comp ? 0 : policies::raise_overflow_error(function, 0, Policy()); + // + // This is Pearson's approximation to the quantile, see + // Pearson, E. S. (1959) "Note on an approximation to the distribution of + // noncentral chi squared", Biometrika 46: 364. + // See also: + // "A comparison of approximations to percentiles of the noncentral chi2-distribution", + // Hardeo Sahai and Mario Miguel Ojeda, Revista de Matematica: Teoria y Aplicaciones 2003 10(1-2) : 57-76. + // Note that the latter reference refers to an approximation of the CDF, when they really mean the quantile. + // + value_type b = -(l * l) / (k + 3 * l); + value_type c = (k + 3 * l) / (k + 2 * l); + value_type ff = (k + 2 * l) / (c * c); + value_type guess; + if(comp) + { + guess = b + c * quantile(complement(chi_squared_distribution(ff), p)); + } + else + { + guess = b + c * quantile(chi_squared_distribution(ff), p); + } + // + // Sometimes guess goes very small or negative, in that case we have + // to do something else for the initial guess, this approximation + // was provided in a private communication from Thomas Luu, PhD candidate, + // University College London. It's an asymptotic expansion for the + // quantile which usually gets us within an order of magnitude of the + // correct answer. + // Fast and accurate parallel computation of quantile functions for random number generation, + // Thomas LuuDoctorial Thesis 2016 + // http://discovery.ucl.ac.uk/1482128/ + // + if(guess < 0.005) + { + value_type pp = comp ? 1 - p : p; + //guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k, 2 / k); + guess = pow(pow(value_type(2), (k / 2 - 1)) * exp(l / 2) * pp * k * boost::math::tgamma(k / 2, forwarding_policy()), (2 / k)); + if(guess == 0) + guess = tools::min_value(); + } + value_type result = detail::generic_quantile( + non_central_chi_squared_distribution(k, l), + p, + guess, + comp, + function); + + return policies::checked_narrowing_cast( + result, + function); + } + + template + RealType nccs_pdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING + static const char* function = "pdf(non_central_chi_squared_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type k = dist.degrees_of_freedom(); + value_type l = dist.non_centrality(); + value_type r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + (value_type)x, + &r, + Policy())) + return (RealType)r; + + if(l == 0) + return pdf(boost::math::chi_squared_distribution(dist.degrees_of_freedom()), x); + + // Special case: + if(x == 0) + return 0; + if(l > 50) + { + r = non_central_chi_square_pdf(static_cast(x), k, l, forwarding_policy()); + } + else + { + r = log(x / l) * (k / 4 - 0.5f) - (x + l) / 2; + if(fabs(r) >= tools::log_max_value() / 4) + { + r = non_central_chi_square_pdf(static_cast(x), k, l, forwarding_policy()); + } + else + { + r = exp(r); + r = 0.5f * r + * boost::math::cyl_bessel_i(k/2 - 1, sqrt(l * x), forwarding_policy()); + } + } + return policies::checked_narrowing_cast( + r, + function); + } + + template + struct degrees_of_freedom_finder + { + degrees_of_freedom_finder( + RealType lam_, RealType x_, RealType p_, bool c) + : lam(lam_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& v) + { + non_central_chi_squared_distribution d(v, lam); + return comp ? + RealType(p - cdf(complement(d, x))) + : RealType(cdf(d, x) - p); + } + private: + RealType lam; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_degrees_of_freedom( + RealType lam, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + if((p == 0) || (q == 0)) + { + // + // Can't a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, + "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%", + RealType(std::numeric_limits::quiet_NaN()), Policy()); + } + degrees_of_freedom_finder f(lam, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know will give us a probability + // right around 0.5. + // + RealType guess = x - lam; + if(guess < 1) + guess = 1; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " or there is no answer to problem. Current best guess is %1%", result, Policy()); + } + return result; + } + + template + struct non_centrality_finder + { + non_centrality_finder( + RealType v_, RealType x_, RealType p_, bool c) + : v(v_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& lam) + { + non_central_chi_squared_distribution d(v, lam); + return comp ? + RealType(p - cdf(complement(d, x))) + : RealType(cdf(d, x) - p); + } + private: + RealType v; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_non_centrality( + RealType v, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_chi_squared<%1%>::find_non_centrality"; + if((p == 0) || (q == 0)) + { + // + // Can't do a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, + "Can't find non centrality parameter when the probability is 0 or 1, only possible answer is %1%", + RealType(std::numeric_limits::quiet_NaN()), Policy()); + } + non_centrality_finder f(v, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know will give us a probability + // right around 0.5. + // + RealType guess = x - v; + if(guess < 1) + guess = 1; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " or there is no answer to problem. Current best guess is %1%", result, Policy()); + } + return result; + } + + } + + template > + class non_central_chi_squared_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + non_central_chi_squared_distribution(RealType df_, RealType lambda) : df(df_), ncp(lambda) + { + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::non_central_chi_squared_distribution(%1%,%1%)"; + RealType r; + detail::check_df( + function, + df, &r, Policy()); + detail::check_non_centrality( + function, + ncp, + &r, + Policy()); + } // non_central_chi_squared_distribution constructor. + + RealType degrees_of_freedom() const + { // Private data getter function. + return df; + } + RealType non_centrality() const + { // Private data getter function. + return ncp; + } + static RealType find_degrees_of_freedom(RealType lam, RealType x, RealType p) + { + const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_degrees_of_freedom( + static_cast(lam), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_degrees_of_freedom(const complemented3_type& c) + { + const char* function = "non_central_chi_squared<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_degrees_of_freedom( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + static RealType find_non_centrality(RealType v, RealType x, RealType p) + { + const char* function = "non_central_chi_squared<%1%>::find_non_centrality"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_non_centrality( + static_cast(v), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_non_centrality(const complemented3_type& c) + { + const char* function = "non_central_chi_squared<%1%>::find_non_centrality"; + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + eval_type result = detail::find_non_centrality( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + private: + // Data member, initialized by constructor. + RealType df; // degrees of freedom. + RealType ncp; // non-centrality parameter + }; // template class non_central_chi_squared_distribution + + typedef non_central_chi_squared_distribution non_central_chi_squared; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_chi_squared_distribution(RealType,RealType)->non_central_chi_squared_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline const std::pair range(const non_central_chi_squared_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // Max integer? + } + + template + inline const std::pair support(const non_central_chi_squared_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); + } + + template + inline RealType mean(const non_central_chi_squared_distribution& dist) + { // Mean of poisson distribution = lambda. + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::mean()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + return k + l; + } // mean + + template + inline RealType mode(const non_central_chi_squared_distribution& dist) + { // mode. + static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)"; + + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return (RealType)r; + bool asymptotic_mode = k < l/4; + RealType starting_point = asymptotic_mode ? k + l - RealType(3) : RealType(1) + k; + return detail::generic_find_mode(dist, starting_point, function); + } + + template + inline RealType variance(const non_central_chi_squared_distribution& dist) + { // variance. + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::variance()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + return 2 * (2 * l + k); + } + + // RealType standard_deviation(const non_central_chi_squared_distribution& dist) + // standard_deviation provided by derived accessors. + + template + inline RealType skewness(const non_central_chi_squared_distribution& dist) + { // skewness = sqrt(l). + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::skewness()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + BOOST_MATH_STD_USING + return pow(2 / (k + 2 * l), RealType(3)/2) * (k + 3 * l); + } + + template + inline RealType kurtosis_excess(const non_central_chi_squared_distribution& dist) + { + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::kurtosis_excess()"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + return 12 * (k + 4 * l) / ((k + 2 * l) * (k + 2 * l)); + } // kurtosis_excess + + template + inline RealType kurtosis(const non_central_chi_squared_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType pdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + return detail::nccs_pdf(dist, x); + } // pdf + + template + RealType cdf(const non_central_chi_squared_distribution& dist, const RealType& x) + { + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)"; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + x, + &r, + Policy())) + return r; + + return detail::non_central_chi_squared_cdf(x, k, l, false, Policy()); + } // cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + const char* function = "boost::math::non_central_chi_squared_distribution<%1%>::cdf(%1%)"; + non_central_chi_squared_distribution const& dist = c.dist; + RealType x = c.param; + RealType k = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + k, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy()) + || + !detail::check_positive_x( + function, + x, + &r, + Policy())) + return r; + + return detail::non_central_chi_squared_cdf(x, k, l, true, Policy()); + } // ccdf + + template + inline RealType quantile(const non_central_chi_squared_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + return detail::nccs_quantile(dist, p, false); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + return detail::nccs_quantile(c.dist, c.param, true); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_CHI_SQUARE_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/non_central_f.hpp b/libcxx/src/third-party/boost/math/distributions/non_central_f.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/non_central_f.hpp @@ -0,0 +1,415 @@ +// boost\math\distributions\non_central_f.hpp + +// Copyright John Maddock 2008. + +// 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_NON_CENTRAL_F_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP + +#include +#include +#include + +namespace boost +{ + namespace math + { + template > + class non_central_f_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + non_central_f_distribution(RealType v1_, RealType v2_, RealType lambda) : v1(v1_), v2(v2_), ncp(lambda) + { + const char* function = "boost::math::non_central_f_distribution<%1%>::non_central_f_distribution(%1%,%1%)"; + RealType r; + detail::check_df( + function, + v1, &r, Policy()); + detail::check_df( + function, + v2, &r, Policy()); + detail::check_non_centrality( + function, + lambda, + &r, + Policy()); + } // non_central_f_distribution constructor. + + RealType degrees_of_freedom1()const + { + return v1; + } + RealType degrees_of_freedom2()const + { + return v2; + } + RealType non_centrality() const + { // Private data getter function. + return ncp; + } + private: + // Data member, initialized by constructor. + RealType v1; // alpha. + RealType v2; // beta. + RealType ncp; // non-centrality parameter + }; // template class non_central_f_distribution + + typedef non_central_f_distribution non_central_f; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_f_distribution(RealType,RealType,RealType)->non_central_f_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline const std::pair range(const non_central_f_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); + } + + template + inline const std::pair support(const non_central_f_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); + } + + template + inline RealType mean(const non_central_f_distribution& dist) + { + const char* function = "mean(non_central_f_distribution<%1%> const&)"; + RealType v1 = dist.degrees_of_freedom1(); + RealType v2 = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + v1, &r, Policy()) + || + !detail::check_df( + function, + v2, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(v2 <= 2) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 2 !", + v2, Policy()); + return v2 * (v1 + l) / (v1 * (v2 - 2)); + } // mean + + template + inline RealType mode(const non_central_f_distribution& dist) + { // mode. + static const char* function = "mode(non_central_chi_squared_distribution<%1%> const&)"; + + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + RealType guess = m > 2 ? RealType(m * (n + l) / (n * (m - 2))) : RealType(1); + return detail::generic_find_mode( + dist, + guess, + function); + } + + template + inline RealType variance(const non_central_f_distribution& dist) + { // variance. + const char* function = "variance(non_central_f_distribution<%1%> const&)"; + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 4) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 4 !", + m, Policy()); + RealType result = 2 * m * m * ((n + l) * (n + l) + + (m - 2) * (n + 2 * l)); + result /= (m - 4) * (m - 2) * (m - 2) * n * n; + return result; + } + + // RealType standard_deviation(const non_central_f_distribution& dist) + // standard_deviation provided by derived accessors. + + template + inline RealType skewness(const non_central_f_distribution& dist) + { // skewness = sqrt(l). + const char* function = "skewness(non_central_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 6) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 6 !", + m, Policy()); + RealType result = 2 * constants::root_two(); + result *= sqrt(m - 4); + result *= (n * (m + n - 2) *(m + 2 * n - 2) + + 3 * (m + n - 2) * (m + 2 * n - 2) * l + + 6 * (m + n - 2) * l * l + 2 * l * l * l); + result /= (m - 6) * pow(n * (m + n - 2) + 2 * (m + n - 2) * l + l * l, RealType(1.5f)); + return result; + } + + template + inline RealType kurtosis_excess(const non_central_f_distribution& dist) + { + const char* function = "kurtosis_excess(non_central_f_distribution<%1%> const&)"; + BOOST_MATH_STD_USING + RealType n = dist.degrees_of_freedom1(); + RealType m = dist.degrees_of_freedom2(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df( + function, + n, &r, Policy()) + || + !detail::check_df( + function, + m, &r, Policy()) + || + !detail::check_non_centrality( + function, + l, + &r, + Policy())) + return r; + if(m <= 8) + return policies::raise_domain_error( + function, + "Second degrees of freedom parameter was %1%, but must be > 8 !", + m, Policy()); + RealType l2 = l * l; + RealType l3 = l2 * l; + RealType l4 = l2 * l2; + RealType result = (3 * (m - 4) * (n * (m + n - 2) + * (4 * (m - 2) * (m - 2) + + (m - 2) * (m + 10) * n + + (10 + m) * n * n) + + 4 * (m + n - 2) * (4 * (m - 2) * (m - 2) + + (m - 2) * (10 + m) * n + + (10 + m) * n * n) * l + 2 * (10 + m) + * (m + n - 2) * (2 * m + 3 * n - 4) * l2 + + 4 * (10 + m) * (-2 + m + n) * l3 + + (10 + m) * l4)) + / + ((-8 + m) * (-6 + m) * boost::math::pow<2>(n * (-2 + m + n) + + 2 * (-2 + m + n) * l + l2)); + return result; + } // kurtosis_excess + + template + inline RealType kurtosis(const non_central_f_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType pdf(const non_central_f_distribution& dist, const RealType& x) + { // Probability Density/Mass Function. + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + value_type alpha = dist.degrees_of_freedom1() / 2; + value_type beta = dist.degrees_of_freedom2() / 2; + value_type y = x * alpha / beta; + value_type r = pdf(boost::math::non_central_beta_distribution(alpha, beta, dist.non_centrality()), y / (1 + y)); + return policies::checked_narrowing_cast( + r * (dist.degrees_of_freedom1() / dist.degrees_of_freedom2()) / ((1 + y) * (1 + y)), + "pdf(non_central_f_distribution<%1%>, %1%)"); + } // pdf + + template + RealType cdf(const non_central_f_distribution& dist, const RealType& x) + { + const char* function = "cdf(const non_central_f_distribution<%1%>&, %1%)"; + RealType r; + if(!detail::check_df( + function, + dist.degrees_of_freedom1(), &r, Policy()) + || + !detail::check_df( + function, + dist.degrees_of_freedom2(), &r, Policy()) + || + !detail::check_non_centrality( + function, + dist.non_centrality(), + &r, + Policy())) + return r; + + if((x < 0) || !(boost::math::isfinite)(x)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", x, Policy()); + } + + RealType alpha = dist.degrees_of_freedom1() / 2; + RealType beta = dist.degrees_of_freedom2() / 2; + RealType y = x * alpha / beta; + RealType c = y / (1 + y); + RealType cp = 1 / (1 + y); + // + // To ensure accuracy, we pass both x and 1-x to the + // non-central beta cdf routine, this ensures accuracy + // even when we compute x to be ~ 1: + // + r = detail::non_central_beta_cdf(c, cp, alpha, beta, + dist.non_centrality(), false, Policy()); + return r; + } // cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + const char* function = "cdf(complement(const non_central_f_distribution<%1%>&, %1%))"; + RealType r; + if(!detail::check_df( + function, + c.dist.degrees_of_freedom1(), &r, Policy()) + || + !detail::check_df( + function, + c.dist.degrees_of_freedom2(), &r, Policy()) + || + !detail::check_non_centrality( + function, + c.dist.non_centrality(), + &r, + Policy())) + return r; + + if((c.param < 0) || !(boost::math::isfinite)(c.param)) + { + return policies::raise_domain_error( + function, "Random Variable parameter was %1%, but must be > 0 !", c.param, Policy()); + } + + RealType alpha = c.dist.degrees_of_freedom1() / 2; + RealType beta = c.dist.degrees_of_freedom2() / 2; + RealType y = c.param * alpha / beta; + RealType x = y / (1 + y); + RealType cx = 1 / (1 + y); + // + // To ensure accuracy, we pass both x and 1-x to the + // non-central beta cdf routine, this ensures accuracy + // even when we compute x to be ~ 1: + // + r = detail::non_central_beta_cdf(x, cx, alpha, beta, + c.dist.non_centrality(), true, Policy()); + return r; + } // ccdf + + template + inline RealType quantile(const non_central_f_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + RealType alpha = dist.degrees_of_freedom1() / 2; + RealType beta = dist.degrees_of_freedom2() / 2; + RealType x = quantile(boost::math::non_central_beta_distribution(alpha, beta, dist.non_centrality()), p); + if(x == 1) + return policies::raise_overflow_error( + "quantile(const non_central_f_distribution<%1%>&, %1%)", + "Result of non central F quantile is too large to represent.", + Policy()); + return (x / (1 - x)) * (dist.degrees_of_freedom2() / dist.degrees_of_freedom1()); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + RealType alpha = c.dist.degrees_of_freedom1() / 2; + RealType beta = c.dist.degrees_of_freedom2() / 2; + RealType x = quantile(complement(boost::math::non_central_beta_distribution(alpha, beta, c.dist.non_centrality()), c.param)); + if(x == 1) + return policies::raise_overflow_error( + "quantile(complement(const non_central_f_distribution<%1%>&, %1%))", + "Result of non central F quantile is too large to represent.", + Policy()); + return (x / (1 - x)) * (c.dist.degrees_of_freedom2() / c.dist.degrees_of_freedom1()); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_F_HPP + + + diff --git a/libcxx/src/third-party/boost/math/distributions/non_central_t.hpp b/libcxx/src/third-party/boost/math/distributions/non_central_t.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/non_central_t.hpp @@ -0,0 +1,1208 @@ +// boost\math\distributions\non_central_t.hpp + +// Copyright John Maddock 2008. + +// 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_NON_CENTRAL_T_HPP +#define BOOST_MATH_SPECIAL_NON_CENTRAL_T_HPP + +#include +#include // for nc beta +#include // for normal CDF and quantile +#include +#include // quantile + +namespace boost +{ + namespace math + { + + template + class non_central_t_distribution; + + namespace detail{ + + template + T non_central_t2_p(T v, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, we don't + // ever allow k == 0 as this can lead to catastrophic + // cancellation errors later (test case is v = 1621286869049072.3 + // delta = 0.16212868690490723, x = 0.86987415482475994). + // + int k = itrunc(d2); + T pois; + if(k == 0) k = 1; + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + if(pois == 0) + return init_val; + T xterm, beta; + // Recurrence & starting beta terms: + beta = x < y + ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, false, true, &xterm) + : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, true, true, &xterm); + xterm *= y / (v / 2 + k); + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((xterm == 0) && (beta == 0)) + return init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + std::uintmax_t count = 0; + T last_term = 0; + for(int i = k; i >= 0; --i) + { + T term = beta * pois; + sum += term; + // Don't terminate on first term in case we "fixed" k above: + if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol) + break; + last_term = term; + pois *= (i + 0.5f) / d2; + beta += xterm; + xterm *= (i) / (x * (v / 2 + i - 1)); + ++count; + } + last_term = 0; + for(int i = k + 1; ; ++i) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (v / 2 + i - 1)) / (i); + betaf -= xtermf; + T term = poisf * betaf; + sum += term; + if((fabs(last_term) >= fabs(term)) && (fabs(term/sum) < errtol)) + break; + last_term = term; + ++count; + if(count > max_iter) + { + return policies::raise_evaluation_error( + "cdf(non_central_t_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + } + return sum; + } + + template + T non_central_t2_q(T v, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term, we don't allow + // k == 0 as this can cause catastrophic cancellation errors + // (test case is v = 561908036470413.25, delta = 0.056190803647041321, + // x = 1.6155232703966216): + // + int k = itrunc(d2); + if(k == 0) k = 1; + // Starting Poisson weight: + T pois; + if((k < static_cast(max_factorial::value)) && (d2 < tools::log_max_value()) && (log(d2) * k < tools::log_max_value())) + { + // + // For small k we can optimise this calculation by using + // a simpler reduced formula: + // + pois = exp(-d2); + pois *= pow(d2, static_cast(k)); + pois /= boost::math::tgamma(T(k + 1 + 0.5), pol); + pois *= delta / constants::root_two(); + } + else + { + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + } + if(pois == 0) + return init_val; + // Recurance term: + T xterm; + T beta; + // Starting beta term: + if(k != 0) + { + beta = x < y + ? detail::ibeta_imp(T(k + 1), T(v / 2), x, pol, true, true, &xterm) + : detail::ibeta_imp(T(v / 2), T(k + 1), y, pol, false, true, &xterm); + + xterm *= y / (v / 2 + k); + } + else + { + beta = pow(y, v / 2); + xterm = beta; + } + T poisf(pois), betaf(beta), xtermf(xterm); + T sum = init_val; + if((xterm == 0) && (beta == 0)) + return init_val; + + // + // Fused forward and backwards recursion: + // + std::uintmax_t count = 0; + T last_term = 0; + for(int i = k + 1, j = k; ; ++i, --j) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (v / 2 + i - 1)) / (i); + betaf += xtermf; + T term = poisf * betaf; + + if(j >= 0) + { + term += beta * pois; + pois *= (j + 0.5f) / d2; + beta -= xterm; + xterm *= (j) / (x * (v / 2 + j - 1)); + } + + sum += term; + // Don't terminate on first term in case we "fixed" the value of k above: + if((fabs(last_term) > fabs(term)) && fabs(term/sum) < errtol) + break; + last_term = term; + if(count > max_iter) + { + return policies::raise_evaluation_error( + "cdf(non_central_t_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + ++count; + } + return sum; + } + + template + T non_central_t_cdf(T v, T delta, T t, bool invert, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(delta, 1); + return cdf(n, t); + } + // + // Otherwise, for t < 0 we have to use the reflection formula: + if(t < 0) + { + t = -t; + delta = -delta; + invert = !invert; + } + if(fabs(delta / (4 * v)) < policies::get_epsilon()) + { + // Approximate with a Student's T centred on delta, + // the crossover point is based on eq 2.6 from + // "A Comparison of Approximations To Percentiles of the + // Noncentral t-Distribution". H. Sahai and M. M. Ojeda, + // Revista Investigacion Operacional Vol 21, No 2, 2000. + // Original sources referenced in the above are: + // "Some Approximations to the Percentage Points of the Noncentral + // t-Distribution". C. van Eeden. International Statistical Review, 29, 4-31. + // "Continuous Univariate Distributions". N.L. Johnson, S. Kotz and + // N. Balkrishnan. 1995. John Wiley and Sons New York. + T result = cdf(students_t_distribution(v), t - delta); + return invert ? 1 - result : result; + } + // + // x and y are the corresponding random + // variables for the noncentral beta distribution, + // with y = 1 - x: + // + T x = t * t / (v + t * t); + T y = v / (v + t * t); + T d2 = delta * delta; + T a = 0.5f; + T b = v / 2; + T c = a + b + d2 / 2; + // + // Crossover point for calculating p or q is the same + // as for the noncentral beta: + // + T cross = 1 - (b / c) * (1 + d2 / (2 * c * c)); + T result; + if(x < cross) + { + // + // Calculate p: + // + if(x != 0) + { + result = non_central_beta_p(a, b, d2, x, y, pol); + result = non_central_t2_p(v, delta, x, y, pol, result); + result /= 2; + } + else + result = 0; + result += cdf(boost::math::normal_distribution(), -delta); + } + else + { + // + // Calculate q: + // + invert = !invert; + if(x != 0) + { + result = non_central_beta_q(a, b, d2, x, y, pol); + result = non_central_t2_q(v, delta, x, y, pol, result); + result /= 2; + } + else // x == 0 + result = cdf(complement(boost::math::normal_distribution(), -delta)); + } + if(invert) + result = 1 - result; + return result; + } + + template + T non_central_t_quantile(const char* function, T v, T delta, T p, T q, const Policy&) + { + BOOST_MATH_STD_USING + // static const char* function = "quantile(non_central_t_distribution<%1%>, %1%)"; + // now passed as function + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + T r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + delta, + &r, + Policy()) + || + !detail::check_probability( + function, + p, + &r, + Policy())) + return r; + + + value_type guess = 0; + if ( ((boost::math::isinf)(v)) || (v > 1 / boost::math::tools::epsilon()) ) + { // Infinite or very large degrees of freedom, so use normal distribution located at delta. + normal_distribution n(delta, 1); + if (p < q) + { + return quantile(n, p); + } + else + { + return quantile(complement(n, q)); + } + } + else if(v > 3) + { // Use normal distribution to calculate guess. + value_type mean = (v > 1 / policies::get_epsilon()) ? delta : delta * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, T(0.5f)); + value_type var = (v > 1 / policies::get_epsilon()) ? value_type(1) : (((delta * delta + 1) * v) / (v - 2) - mean * mean); + if(p < q) + guess = quantile(normal_distribution(mean, var), p); + else + guess = quantile(complement(normal_distribution(mean, var), q)); + } + // + // We *must* get the sign of the initial guess correct, + // or our root-finder will fail, so double check it now: + // + value_type pzero = non_central_t_cdf( + static_cast(v), + static_cast(delta), + static_cast(0), + !(p < q), + forwarding_policy()); + int s; + if(p < q) + s = boost::math::sign(p - pzero); + else + s = boost::math::sign(pzero - q); + if(s != boost::math::sign(guess)) + { + guess = static_cast(s); + } + + value_type result = detail::generic_quantile( + non_central_t_distribution(v, delta), + (p < q ? p : q), + guess, + (p >= q), + function); + return policies::checked_narrowing_cast( + result, + function); + } + + template + T non_central_t2_pdf(T n, T delta, T x, T y, const Policy& pol, T init_val) + { + BOOST_MATH_STD_USING + // + // Variables come first: + // + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T errtol = boost::math::policies::get_epsilon(); + T d2 = delta * delta / 2; + // + // k is the starting point for iteration, and is the + // maximum of the poisson weighting term: + // + int k = itrunc(d2); + T pois, xterm; + if(k == 0) + k = 1; + // Starting Poisson weight: + pois = gamma_p_derivative(T(k+1), d2, pol) + * tgamma_delta_ratio(T(k + 1), T(0.5f)) + * delta / constants::root_two(); + // Starting beta term: + xterm = x < y + ? ibeta_derivative(T(k + 1), n / 2, x, pol) + : ibeta_derivative(n / 2, T(k + 1), y, pol); + T poisf(pois), xtermf(xterm); + T sum = init_val; + if((pois == 0) || (xterm == 0)) + return init_val; + + // + // Backwards recursion first, this is the stable + // direction for recursion: + // + std::uintmax_t count = 0; + for(int i = k; i >= 0; --i) + { + T term = xterm * pois; + sum += term; + if(((fabs(term/sum) < errtol) && (i != k)) || (term == 0)) + break; + pois *= (i + 0.5f) / d2; + xterm *= (i) / (x * (n / 2 + i)); + ++count; + if(count > max_iter) + { + return policies::raise_evaluation_error( + "pdf(non_central_t_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + } + for(int i = k + 1; ; ++i) + { + poisf *= d2 / (i + 0.5f); + xtermf *= (x * (n / 2 + i)) / (i); + T term = poisf * xtermf; + sum += term; + if((fabs(term/sum) < errtol) || (term == 0)) + break; + ++count; + if(count > max_iter) + { + return policies::raise_evaluation_error( + "pdf(non_central_t_distribution<%1%>, %1%)", + "Series did not converge, closest value was %1%", sum, pol); + } + } + return sum; + } + + template + T non_central_t_pdf(T n, T delta, T t, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(n)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution norm(delta, 1); + return pdf(norm, t); + } + // + // Otherwise, for t < 0 we have to use the reflection formula: + if(t < 0) + { + t = -t; + delta = -delta; + } + if(t == 0) + { + // + // Handle this as a special case, using the formula + // from Weisstein, Eric W. + // "Noncentral Student's t-Distribution." + // From MathWorld--A Wolfram Web Resource. + // http://mathworld.wolfram.com/NoncentralStudentst-Distribution.html + // + // The formula is simplified thanks to the relation + // 1F1(a,b,0) = 1. + // + return tgamma_delta_ratio(n / 2 + 0.5f, T(0.5f)) + * sqrt(n / constants::pi()) + * exp(-delta * delta / 2) / 2; + } + if(fabs(delta / (4 * n)) < policies::get_epsilon()) + { + // Approximate with a Student's T centred on delta, + // the crossover point is based on eq 2.6 from + // "A Comparison of Approximations To Percentiles of the + // Noncentral t-Distribution". H. Sahai and M. M. Ojeda, + // Revista Investigacion Operacional Vol 21, No 2, 2000. + // Original sources referenced in the above are: + // "Some Approximations to the Percentage Points of the Noncentral + // t-Distribution". C. van Eeden. International Statistical Review, 29, 4-31. + // "Continuous Univariate Distributions". N.L. Johnson, S. Kotz and + // N. Balkrishnan. 1995. John Wiley and Sons New York. + return pdf(students_t_distribution(n), t - delta); + } + // + // x and y are the corresponding random + // variables for the noncentral beta distribution, + // with y = 1 - x: + // + T x = t * t / (n + t * t); + T y = n / (n + t * t); + T a = 0.5f; + T b = n / 2; + T d2 = delta * delta; + // + // Calculate pdf: + // + T dt = n * t / (n * n + 2 * n * t * t + t * t * t * t); + T result = non_central_beta_pdf(a, b, d2, x, y, pol); + T tol = tools::epsilon() * result * 500; + result = non_central_t2_pdf(n, delta, x, y, pol, result); + if(result <= tol) + result = 0; + result *= dt; + return result; + } + + template + T mean(T v, T delta, const Policy& pol) + { + if ((boost::math::isinf)(v)) + { + return delta; + } + BOOST_MATH_STD_USING + if (v > 1 / boost::math::tools::epsilon() ) + { + //normal_distribution n(delta, 1); + //return boost::math::mean(n); + return delta; + } + else + { + return delta * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, T(0.5f), pol); + } + // Other moments use mean so using normal distribution is propagated. + } + + template + T variance(T v, T delta, const Policy& pol) + { + if ((boost::math::isinf)(v)) + { + return 1; + } + if (delta == 0) + { // == Student's t + return v / (v - 2); + } + T result = ((delta * delta + 1) * v) / (v - 2); + T m = mean(v, delta, pol); + result -= m * m; + return result; + } + + template + T skewness(T v, T delta, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { + return 0; + } + if(delta == 0) + { // == Student's t + return 0; + } + T mean = boost::math::detail::mean(v, delta, pol); + T l2 = delta * delta; + T var = ((l2 + 1) * v) / (v - 2) - mean * mean; + T result = -2 * var; + result += v * (l2 + 2 * v - 3) / ((v - 3) * (v - 2)); + result *= mean; + result /= pow(var, T(1.5f)); + return result; + } + + template + T kurtosis_excess(T v, T delta, const Policy& pol) + { + BOOST_MATH_STD_USING + if ((boost::math::isinf)(v)) + { + return 1; + } + if (delta == 0) + { // == Student's t + return 1; + } + T mean = boost::math::detail::mean(v, delta, pol); + T l2 = delta * delta; + T var = ((l2 + 1) * v) / (v - 2) - mean * mean; + T result = -3 * var; + result += v * (l2 * (v + 1) + 3 * (3 * v - 5)) / ((v - 3) * (v - 2)); + result *= -mean * mean; + result += v * v * (l2 * l2 + 6 * l2 + 3) / ((v - 4) * (v - 2)); + result /= var * var; + result -= static_cast(3); + return result; + } + +#if 0 + // + // This code is disabled, since there can be multiple answers to the + // question, and it's not clear how to find the "right" one. + // + template + struct t_degrees_of_freedom_finder + { + t_degrees_of_freedom_finder( + RealType delta_, RealType x_, RealType p_, bool c) + : delta(delta_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& v) + { + non_central_t_distribution d(v, delta); + return comp ? + p - cdf(complement(d, x)) + : cdf(d, x) - p; + } + private: + RealType delta; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_t_degrees_of_freedom( + RealType delta, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + if((p == 0) || (q == 0)) + { + // + // Can't a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, + "Can't find degrees of freedom when the probability is 0 or 1, only possible answer is %1%", + RealType(std::numeric_limits::quiet_NaN()), Policy()); + } + t_degrees_of_freedom_finder f(delta, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess: + // + RealType guess = 200; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " or there is no answer to problem. Current best guess is %1%", result, Policy()); + } + return result; + } + + template + struct t_non_centrality_finder + { + t_non_centrality_finder( + RealType v_, RealType x_, RealType p_, bool c) + : v(v_), x(x_), p(p_), comp(c) {} + + RealType operator()(const RealType& delta) + { + non_central_t_distribution d(v, delta); + return comp ? + p - cdf(complement(d, x)) + : cdf(d, x) - p; + } + private: + RealType v; + RealType x; + RealType p; + bool comp; + }; + + template + inline RealType find_t_non_centrality( + RealType v, RealType x, RealType p, RealType q, const Policy& pol) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + if((p == 0) || (q == 0)) + { + // + // Can't do a thing if one of p and q is zero: + // + return policies::raise_evaluation_error(function, + "Can't find non-centrality parameter when the probability is 0 or 1, only possible answer is %1%", + RealType(std::numeric_limits::quiet_NaN()), Policy()); + } + t_non_centrality_finder f(v, x, p < q ? p : q, p < q ? false : true); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Pick an initial guess that we know is the right side of + // zero: + // + RealType guess; + if(f(0) < 0) + guess = 1; + else + guess = -1; + std::pair ir = tools::bracket_and_solve_root( + f, guess, RealType(2), false, tol, max_iter, pol); + RealType result = ir.first + (ir.second - ir.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " or there is no answer to problem. Current best guess is %1%", result, Policy()); + } + return result; + } +#endif + } // namespace detail ====================================================================== + + template > + class non_central_t_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + non_central_t_distribution(RealType v_, RealType lambda) : v(v_), ncp(lambda) + { + const char* function = "boost::math::non_central_t_distribution<%1%>::non_central_t_distribution(%1%,%1%)"; + RealType r; + detail::check_df_gt0_to_inf( + function, + v, &r, Policy()); + detail::check_finite( + function, + lambda, + &r, + Policy()); + } // non_central_t_distribution constructor. + + RealType degrees_of_freedom() const + { // Private data getter function. + return v; + } + RealType non_centrality() const + { // Private data getter function. + return ncp; + } +#if 0 + // + // This code is disabled, since there can be multiple answers to the + // question, and it's not clear how to find the "right" one. + // + static RealType find_degrees_of_freedom(RealType delta, RealType x, RealType p) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_degrees_of_freedom( + static_cast(delta), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_degrees_of_freedom(const complemented3_type& c) + { + const char* function = "non_central_t<%1%>::find_degrees_of_freedom"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_degrees_of_freedom( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + static RealType find_non_centrality(RealType v, RealType x, RealType p) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_non_centrality( + static_cast(v), + static_cast(x), + static_cast(p), + static_cast(1-p), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } + template + static RealType find_non_centrality(const complemented3_type& c) + { + const char* function = "non_central_t<%1%>::find_t_non_centrality"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + value_type result = detail::find_t_non_centrality( + static_cast(c.dist), + static_cast(c.param1), + static_cast(1-c.param2), + static_cast(c.param2), + forwarding_policy()); + return policies::checked_narrowing_cast( + result, + function); + } +#endif + private: + // Data member, initialized by constructor. + RealType v; // degrees of freedom + RealType ncp; // non-centrality parameter + }; // template class non_central_t_distribution + + typedef non_central_t_distribution non_central_t; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + non_central_t_distribution(RealType,RealType)->non_central_t_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline const std::pair range(const non_central_t_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); + } + + template + inline const std::pair support(const non_central_t_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); + } + + template + inline RealType mode(const non_central_t_distribution& dist) + { // mode. + static const char* function = "mode(non_central_t_distribution<%1%> const&)"; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy())) + return (RealType)r; + + BOOST_MATH_STD_USING + + RealType m = v < 3 ? 0 : detail::mean(v, l, Policy()); + RealType var = v < 4 ? 1 : detail::variance(v, l, Policy()); + + return detail::generic_find_mode( + dist, + m, + function, + sqrt(var)); + } + + template + inline RealType mean(const non_central_t_distribution& dist) + { + BOOST_MATH_STD_USING + const char* function = "mean(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy())) + return (RealType)r; + if(v <= 1) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined mean for degrees of freedom <= 1: got v=%1%.", v, Policy()); + // return l * sqrt(v / 2) * tgamma_delta_ratio((v - 1) * 0.5f, RealType(0.5f)); + return policies::checked_narrowing_cast( + detail::mean(static_cast(v), static_cast(l), forwarding_policy()), function); + + } // mean + + template + inline RealType variance(const non_central_t_distribution& dist) + { // variance. + const char* function = "variance(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + BOOST_MATH_STD_USING + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy())) + return (RealType)r; + if(v <= 2) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined variance for degrees of freedom <= 2: got v=%1%.", v, Policy()); + return policies::checked_narrowing_cast( + detail::variance(static_cast(v), static_cast(l), forwarding_policy()), function); + } + + // RealType standard_deviation(const non_central_t_distribution& dist) + // standard_deviation provided by derived accessors. + + template + inline RealType skewness(const non_central_t_distribution& dist) + { // skewness = sqrt(l). + const char* function = "skewness(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy())) + return (RealType)r; + if(v <= 3) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined skewness for degrees of freedom <= 3: got v=%1%.", v, Policy());; + return policies::checked_narrowing_cast( + detail::skewness(static_cast(v), static_cast(l), forwarding_policy()), function); + } + + template + inline RealType kurtosis_excess(const non_central_t_distribution& dist) + { + const char* function = "kurtosis_excess(const non_central_t_distribution<%1%>&)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy())) + return (RealType)r; + if(v <= 4) + return policies::raise_domain_error( + function, + "The non-central t distribution has no defined kurtosis for degrees of freedom <= 4: got v=%1%.", v, Policy());; + return policies::checked_narrowing_cast( + detail::kurtosis_excess(static_cast(v), static_cast(l), forwarding_policy()), function); + } // kurtosis_excess + + template + inline RealType kurtosis(const non_central_t_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType pdf(const non_central_t_distribution& dist, const RealType& t) + { // Probability Density/Mass Function. + const char* function = "pdf(non_central_t_distribution<%1%>, %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy()) + || + !detail::check_x( + function, + t, + &r, + Policy())) + return (RealType)r; + return policies::checked_narrowing_cast( + detail::non_central_t_pdf(static_cast(v), + static_cast(l), + static_cast(t), + Policy()), + function); + } // pdf + + template + RealType cdf(const non_central_t_distribution& dist, const RealType& x) + { + const char* function = "boost::math::cdf(non_central_t_distribution<%1%>&, %1%)"; +// was const char* function = "boost::math::non_central_t_distribution<%1%>::cdf(%1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy()) + || + !detail::check_x( + function, + x, + &r, + Policy())) + return (RealType)r; + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(l, 1); + cdf(n, x); + //return cdf(normal_distribution(l, 1), x); + } + + if(l == 0) + { // NO non-centrality, so use Student's t instead. + return cdf(students_t_distribution(v), x); + } + return policies::checked_narrowing_cast( + detail::non_central_t_cdf( + static_cast(v), + static_cast(l), + static_cast(x), + false, Policy()), + function); + } // cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function + // was const char* function = "boost::math::non_central_t_distribution<%1%>::cdf(%1%)"; + const char* function = "boost::math::cdf(const complement(non_central_t_distribution<%1%>&), %1%)"; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + non_central_t_distribution const& dist = c.dist; + RealType x = c.param; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); // aka delta + RealType r; + if(!detail::check_df_gt0_to_inf( + function, + v, &r, Policy()) + || + !detail::check_finite( + function, + l, + &r, + Policy()) + || + !detail::check_x( + function, + x, + &r, + Policy())) + return (RealType)r; + + if ((boost::math::isinf)(v)) + { // Infinite degrees of freedom, so use normal distribution located at delta. + normal_distribution n(l, 1); + return cdf(complement(n, x)); + } + if(l == 0) + { // zero non-centrality so use Student's t distribution. + return cdf(complement(students_t_distribution(v), x)); + } + return policies::checked_narrowing_cast( + detail::non_central_t_cdf( + static_cast(v), + static_cast(l), + static_cast(x), + true, Policy()), + function); + } // ccdf + + template + inline RealType quantile(const non_central_t_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) function. + static const char* function = "quantile(const non_central_t_distribution<%1%>, %1%)"; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + return detail::non_central_t_quantile(function, v, l, p, RealType(1-p), Policy()); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) function. + static const char* function = "quantile(const complement(non_central_t_distribution<%1%>, %1%))"; + non_central_t_distribution const& dist = c.dist; + RealType q = c.param; + RealType v = dist.degrees_of_freedom(); + RealType l = dist.non_centrality(); + return detail::non_central_t_quantile(function, v, l, RealType(1-q), q, Policy()); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_MATH_SPECIAL_NON_CENTRAL_T_HPP + diff --git a/libcxx/src/third-party/boost/math/distributions/normal.hpp b/libcxx/src/third-party/boost/math/distributions/normal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/normal.hpp @@ -0,0 +1,365 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007. + +// 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_STATS_NORMAL_HPP +#define BOOST_STATS_NORMAL_HPP + +// http://en.wikipedia.org/wiki/Normal_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Normal Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/NormalDistribution.html + +#include +#include // for erf/erfc. +#include +#include + +#include +#include + +namespace boost{ namespace math{ + +template > +class normal_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit normal_distribution(RealType l_mean = 0, RealType sd = 1) + : m_mean(l_mean), m_sd(sd) + { // Default is a 'standard' normal distribution N01. + static const char* function = "boost::math::normal_distribution<%1%>::normal_distribution"; + + RealType result; + detail::check_scale(function, sd, &result, Policy()); + detail::check_location(function, l_mean, &result, Policy()); + } + + RealType mean()const + { // alias for location. + return m_mean; + } + + RealType standard_deviation()const + { // alias for scale. + return m_sd; + } + + // Synonyms, provided to allow generic use of find_location and find_scale. + RealType location()const + { // location. + return m_mean; + } + RealType scale()const + { // scale. + return m_sd; + } + +private: + // + // Data members: + // + RealType m_mean; // distribution mean or location. + RealType m_sd; // distribution standard deviation or scale. +}; // class normal_distribution + +using normal = normal_distribution; + +// +// Deduction guides, note we don't check the +// value of __cpp_deduction_guides, just assume +// they work as advertised, even if this is pre-final C++17. +// +#ifdef __cpp_deduction_guides + +template +normal_distribution(RealType, RealType)->normal_distribution::type>; +template +normal_distribution(RealType)->normal_distribution::type>; + +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +template +inline std::pair range(const normal_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + if (std::numeric_limits::has_infinity) + { + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } +} + +template +inline std::pair support(const normal_distribution& /*dist*/) +{ // This is range values for random variable x where cdf rises from 0 to 1, and outside it, the pdf is zero. + if (std::numeric_limits::has_infinity) + { + return std::pair(-std::numeric_limits::infinity(), std::numeric_limits::infinity()); // - to + infinity. + } + else + { // Can only use max_value. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +inline RealType pdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + + static const char* function = "boost::math::pdf(const normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + RealType exponent = x - mean; + exponent *= -exponent; + exponent /= 2 * sd * sd; + + result = exp(exponent); + result /= sd * sqrt(2 * constants::pi()); + + return result; +} // pdf + +template +inline RealType logpdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + const RealType sd = dist.standard_deviation(); + const RealType mean = dist.mean(); + + static const char* function = "boost::math::logpdf(const normal_distribution<%1%>&, %1%)"; + + RealType result = -std::numeric_limits::infinity(); + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return result; // pdf + and - infinity is zero so logpdf is -inf + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType pi = boost::math::constants::pi(); + const RealType half = boost::math::constants::half(); + + result = -log(sd) - half*log(2*pi) - (x-mean)*(x-mean)/(2*sd*sd); + + return result; +} + +template +inline RealType cdf(const normal_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + static const char* function = "boost::math::cdf(const normal_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, mean, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + RealType diff = (x - mean) / (sd * constants::root_two()); + result = boost::math::erfc(-diff, Policy()) / 2; + return result; +} // cdf + +template +inline RealType quantile(const normal_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = dist.standard_deviation(); + RealType mean = dist.mean(); + static const char* function = "boost::math::quantile(const normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + result= boost::math::erfc_inv(2 * p, Policy()); + result = -result; + result *= sd * constants::root_two(); + result += mean; + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = c.dist.standard_deviation(); + RealType mean = c.dist.mean(); + RealType x = c.param; + static const char* function = "boost::math::cdf(const complement(normal_distribution<%1%>&), %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero + } + if(false == detail::check_x(function, x, &result, Policy())) + return result; + + RealType diff = (x - mean) / (sd * constants::root_two()); + result = boost::math::erfc(diff, Policy()) / 2; + return result; +} // cdf complement + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType sd = c.dist.standard_deviation(); + RealType mean = c.dist.mean(); + static const char* function = "boost::math::quantile(const complement(normal_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, sd, &result, Policy())) + return result; + if(false == detail::check_location(function, mean, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + result = boost::math::erfc_inv(2 * q, Policy()); + result *= sd * constants::root_two(); + result += mean; + return result; +} // quantile + +template +inline RealType mean(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +inline RealType standard_deviation(const normal_distribution& dist) +{ + return dist.standard_deviation(); +} + +template +inline RealType mode(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +inline RealType median(const normal_distribution& dist) +{ + return dist.mean(); +} + +template +inline RealType skewness(const normal_distribution& /*dist*/) +{ + return 0; +} + +template +inline RealType kurtosis(const normal_distribution& /*dist*/) +{ + return 3; +} + +template +inline RealType kurtosis_excess(const normal_distribution& /*dist*/) +{ + return 0; +} + +template +inline RealType entropy(const normal_distribution & dist) +{ + using std::log; + RealType arg = constants::two_pi()*constants::e()*dist.standard_deviation()*dist.standard_deviation(); + return log(arg)/2; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_NORMAL_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/pareto.hpp b/libcxx/src/third-party/boost/math/distributions/pareto.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/pareto.hpp @@ -0,0 +1,461 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007, 2009 +// 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_STATS_PARETO_HPP +#define BOOST_STATS_PARETO_HPP + +// http://en.wikipedia.org/wiki/Pareto_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3661.htm +// Also: +// Weisstein, Eric W. "Pareto Distribution." +// From MathWorld--A Wolfram Web Resource. +// http://mathworld.wolfram.com/ParetoDistribution.html +// Handbook of Statistical Distributions with Applications, K Krishnamoorthy, ISBN 1-58488-635-8, Chapter 23, pp 257 - 267. +// Caution KK's a and b are the reverse of Mathworld! + +#include +#include +#include +#include + +#include // for BOOST_CURRENT_VALUE? + +namespace boost +{ + namespace math + { + namespace detail + { // Parameter checking. + template + inline bool check_pareto_scale( + const char* function, + RealType scale, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(scale)) + { // any > 0 finite value is OK. + if (scale > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be > 0!", scale, pol); + return false; + } + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Scale parameter is %1%, but must be finite!", scale, pol); + return false; + } + } // bool check_pareto_scale + + template + inline bool check_pareto_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(shape)) + { // Any finite value > 0 is OK. + if (shape > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0!", shape, pol); + return false; + } + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be finite!", shape, pol); + return false; + } + } // bool check_pareto_shape( + + template + inline bool check_pareto_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // + if (x > 0) + { + return true; + } + else + { + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be > 0 !", x, pol); + return false; + } + } + else + { // Not finite.. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_pareto_x + + template + inline bool check_pareto( // distribution parameters. + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) + { + return check_pareto_scale(function, scale, result, pol) + && check_pareto_shape(function, shape, result, pol); + } // bool check_pareto( + + } // namespace detail + + template > + class pareto_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + pareto_distribution(RealType l_scale = 1, RealType l_shape = 1) + : m_scale(l_scale), m_shape(l_shape) + { // Constructor. + RealType result = 0; + detail::check_pareto("boost::math::pareto_distribution<%1%>::pareto_distribution", l_scale, l_shape, &result, Policy()); + } + + RealType scale()const + { // AKA Xm and Wolfram b and beta + return m_scale; + } + + RealType shape()const + { // AKA k and Wolfram a and alpha + return m_shape; + } + private: + // Data members: + RealType m_scale; // distribution scale (xm) or beta + RealType m_shape; // distribution shape (k) or alpha + }; + + typedef pareto_distribution pareto; // Convenience to allow pareto(2., 3.); + + #ifdef __cpp_deduction_guides + template + pareto_distribution(RealType)->pareto_distribution::type>; + template + pareto_distribution(RealType,RealType)->pareto_distribution::type>; + #endif + + + template + inline const std::pair range(const pareto_distribution& /*dist*/) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // scale zero to + infinity. + } // range + + template + inline const std::pair support(const pareto_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(dist.scale(), max_value() ); // scale to + infinity. + } // support + + template + inline RealType pdf(const pareto_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + RealType result = 0; + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + if (x < scale) + { // regardless of shape, pdf is zero (or should be disallow x < scale and throw an exception?). + return 0; + } + result = shape * pow(scale, shape) / pow(x, shape+1); + return result; + } // pdf + + template + inline RealType cdf(const pareto_distribution& dist, const RealType& x) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + static const char* function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)"; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + RealType result = 0; + + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero. + return 0; + } + + // result = RealType(1) - pow((scale / x), shape); + result = -boost::math::powm1(scale/x, shape, Policy()); // should be more accurate. + return result; + } // cdf + + template + inline RealType quantile(const pareto_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + static const char* function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + if(false == (detail::check_probability(function, p, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + { + return result; + } + if (p == 0) + { + return scale; // x must be scale (or less). + } + if (p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); // x = + infinity. + } + result = scale / + (pow((1 - p), 1 / shape)); + // K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3 + return result; + } // quantile + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + static const char* function = "boost::math::cdf(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType x = c.param; + RealType scale = c.dist.scale(); + RealType shape = c.dist.shape(); + if(false == (detail::check_pareto_x(function, x, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + return result; + + if (x <= scale) + { // regardless of shape, cdf is zero, and complement is unity. + return 1; + } + result = pow((scale/x), shape); + + return result; + } // cdf complement + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // for ADL of std function pow. + static const char* function = "boost::math::quantile(const pareto_distribution<%1%>&, %1%)"; + RealType result = 0; + RealType q = c.param; + RealType scale = c.dist.scale(); + RealType shape = c.dist.shape(); + if(false == (detail::check_probability(function, q, &result, Policy()) + && detail::check_pareto(function, scale, shape, &result, Policy()))) + { + return result; + } + if (q == 1) + { + return scale; // x must be scale (or less). + } + if (q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); // x = + infinity. + } + result = scale / (pow(q, 1 / shape)); + // K. Krishnamoorthy, ISBN 1-58488-635-8 eq 23.1.3 + return result; + } // quantile complement + + template + inline RealType mean(const pareto_distribution& dist) + { + RealType result = 0; + static const char* function = "boost::math::mean(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy())) + { + return result; + } + if (dist.shape() > RealType(1)) + { + return dist.shape() * dist.scale() / (dist.shape() - 1); + } + else + { + using boost::math::tools::max_value; + return max_value(); // +infinity. + } + } // mean + + template + inline RealType mode(const pareto_distribution& dist) + { + return dist.scale(); + } // mode + + template + inline RealType median(const pareto_distribution& dist) + { + RealType result = 0; + static const char* function = "boost::math::median(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), dist.shape(), &result, Policy())) + { + return result; + } + BOOST_MATH_STD_USING + return dist.scale() * pow(RealType(2), (1/dist.shape())); + } // median + + template + inline RealType variance(const pareto_distribution& dist) + { + RealType result = 0; + RealType scale = dist.scale(); + RealType shape = dist.shape(); + static const char* function = "boost::math::variance(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, scale, shape, &result, Policy())) + { + return result; + } + if (shape > 2) + { + result = (scale * scale * shape) / + ((shape - 1) * (shape - 1) * (shape - 2)); + } + else + { + result = policies::raise_domain_error( + function, + "variance is undefined for shape <= 2, but got %1%.", dist.shape(), Policy()); + } + return result; + } // variance + + template + inline RealType skewness(const pareto_distribution& dist) + { + BOOST_MATH_STD_USING + RealType result = 0; + RealType shape = dist.shape(); + static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 3) + { + result = sqrt((shape - 2) / shape) * + 2 * (shape + 1) / + (shape - 3); + } + else + { + result = policies::raise_domain_error( + function, + "skewness is undefined for shape <= 3, but got %1%.", dist.shape(), Policy()); + } + return result; + } // skewness + + template + inline RealType kurtosis(const pareto_distribution& dist) + { + RealType result = 0; + RealType shape = dist.shape(); + static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 4) + { + result = 3 * ((shape - 2) * (3 * shape * shape + shape + 2)) / + (shape * (shape - 3) * (shape - 4)); + } + else + { + result = policies::raise_domain_error( + function, + "kurtosis_excess is undefined for shape <= 4, but got %1%.", shape, Policy()); + } + return result; + } // kurtosis + + template + inline RealType kurtosis_excess(const pareto_distribution& dist) + { + RealType result = 0; + RealType shape = dist.shape(); + static const char* function = "boost::math::pdf(const pareto_distribution<%1%>&, %1%)"; + if(false == detail::check_pareto(function, dist.scale(), shape, &result, Policy())) + { + return result; + } + if (shape > 4) + { + result = 6 * ((shape * shape * shape) + (shape * shape) - 6 * shape - 2) / + (shape * (shape - 3) * (shape - 4)); + } + else + { + result = policies::raise_domain_error( + function, + "kurtosis_excess is undefined for shape <= 4, but got %1%.", dist.shape(), Policy()); + } + return result; + } // kurtosis_excess + + template + inline RealType entropy(const pareto_distribution& dist) + { + using std::log; + RealType xm = dist.scale(); + RealType alpha = dist.shape(); + return log(xm/alpha) + 1 + 1/alpha; + } + + } // namespace math + } // namespace boost + + // This include must be at the end, *after* the accessors + // for this distribution have been defined, in order to + // keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_PARETO_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/poisson.hpp b/libcxx/src/third-party/boost/math/distributions/poisson.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/poisson.hpp @@ -0,0 +1,562 @@ +// boost\math\distributions\poisson.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007. + +// 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) + +// Poisson distribution is a discrete probability distribution. +// It expresses the probability of a number (k) of +// events, occurrences, failures or arrivals occurring in a fixed time, +// assuming these events occur with a known average or mean rate (lambda) +// and are independent of the time since the last event. +// The distribution was discovered by Simeon-Denis Poisson (1781-1840). + +// Parameter lambda is the mean number of events in the given time interval. +// The random variate k is the number of events, occurrences or arrivals. +// k argument may be integral, signed, or unsigned, or floating point. +// If necessary, it has already been promoted from an integral type. + +// Note that the Poisson distribution +// (like others including the binomial, negative binomial & Bernoulli) +// is strictly defined as a discrete function: +// only integral values of k are envisaged. +// However because the method of calculation uses a continuous gamma function, +// it is convenient to treat it as if a continuous function, +// and permit non-integral values of k. +// To enforce the strict mathematical model, users should use floor or ceil functions +// on k outside this function to ensure that k is integral. + +// See http://en.wikipedia.org/wiki/Poisson_distribution +// http://documents.wolfram.com/v5/Add-onsLinks/StandardPackages/Statistics/DiscreteDistributions.html + +#ifndef BOOST_MATH_SPECIAL_POISSON_HPP +#define BOOST_MATH_SPECIAL_POISSON_HPP + +#include +#include // for incomplete gamma. gamma_q +#include // for incomplete gamma. gamma_q +#include // complements +#include // error checks +#include // isnan. +#include // factorials. +#include // for root finding. +#include + +#include +#include + +namespace boost +{ + namespace math + { + namespace poisson_detail + { + // Common error checking routines for Poisson distribution functions. + // These are convoluted, & apparently redundant, to try to ensure that + // checks are always performed, even if exceptions are not enabled. + + template + inline bool check_mean(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { + if(!(boost::math::isfinite)(mean) || (mean < 0)) + { + *result = policies::raise_domain_error( + function, + "Mean argument is %1%, but must be >= 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean + + template + inline bool check_mean_NZ(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { // mean == 0 is considered an error. + if( !(boost::math::isfinite)(mean) || (mean <= 0)) + { + *result = policies::raise_domain_error( + function, + "Mean argument is %1%, but must be > 0 !", mean, pol); + return false; + } + return true; + } // bool check_mean_NZ + + template + inline bool check_dist(const char* function, const RealType& mean, RealType* result, const Policy& pol) + { // Only one check, so this is redundant really but should be optimized away. + return check_mean_NZ(function, mean, result, pol); + } // bool check_dist + + template + inline bool check_k(const char* function, const RealType& k, RealType* result, const Policy& pol) + { + if((k < 0) || !(boost::math::isfinite)(k)) + { + *result = policies::raise_domain_error( + function, + "Number of events k argument is %1%, but must be >= 0 !", k, pol); + return false; + } + return true; + } // bool check_k + + template + inline bool check_dist_and_k(const char* function, RealType mean, RealType k, RealType* result, const Policy& pol) + { + if((check_dist(function, mean, result, pol) == false) || + (check_k(function, k, result, pol) == false)) + { + return false; + } + return true; + } // bool check_dist_and_k + + template + inline bool check_prob(const char* function, const RealType& p, RealType* result, const Policy& pol) + { // Check 0 <= p <= 1 + if(!(boost::math::isfinite)(p) || (p < 0) || (p > 1)) + { + *result = policies::raise_domain_error( + function, + "Probability argument is %1%, but must be >= 0 and <= 1 !", p, pol); + return false; + } + return true; + } // bool check_prob + + template + inline bool check_dist_and_prob(const char* function, RealType mean, RealType p, RealType* result, const Policy& pol) + { + if((check_dist(function, mean, result, pol) == false) || + (check_prob(function, p, result, pol) == false)) + { + return false; + } + return true; + } // bool check_dist_and_prob + + } // namespace poisson_detail + + template > + class poisson_distribution + { + public: + using value_type = RealType; + using policy_type = Policy; + + explicit poisson_distribution(RealType l_mean = 1) : m_l(l_mean) // mean (lambda). + { // Expected mean number of events that occur during the given interval. + RealType r; + poisson_detail::check_dist( + "boost::math::poisson_distribution<%1%>::poisson_distribution", + m_l, + &r, Policy()); + } // poisson_distribution constructor. + + RealType mean() const + { // Private data getter function. + return m_l; + } + private: + // Data member, initialized by constructor. + RealType m_l; // mean number of occurrences. + }; // template class poisson_distribution + + using poisson = poisson_distribution; // Reserved name of type double. + + #ifdef __cpp_deduction_guides + template + poisson_distribution(RealType)->poisson_distribution::type>; + #endif + + // Non-member functions to give properties of the distribution. + + template + inline std::pair range(const poisson_distribution& /* dist */) + { // Range of permissible values for random variable k. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); // Max integer? + } + + template + inline std::pair support(const poisson_distribution& /* dist */) + { // Range of supported values for random variable k. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); + } + + template + inline RealType mean(const poisson_distribution& dist) + { // Mean of poisson distribution = lambda. + return dist.mean(); + } // mean + + template + inline RealType mode(const poisson_distribution& dist) + { // mode. + BOOST_MATH_STD_USING // ADL of std functions. + return floor(dist.mean()); + } + + // Median now implemented via quantile(half) in derived accessors. + + template + inline RealType variance(const poisson_distribution& dist) + { // variance. + return dist.mean(); + } + + // standard_deviation provided by derived accessors. + + template + inline RealType skewness(const poisson_distribution& dist) + { // skewness = sqrt(l). + BOOST_MATH_STD_USING // ADL of std functions. + return 1 / sqrt(dist.mean()); + } + + template + inline RealType kurtosis_excess(const poisson_distribution& dist) + { // skewness = sqrt(l). + return 1 / dist.mean(); // kurtosis_excess 1/mean from Wiki & MathWorld eq 31. + // http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess + // is more convenient because the kurtosis excess of a normal distribution is zero + // whereas the true kurtosis is 3. + } // RealType kurtosis_excess + + template + inline RealType kurtosis(const poisson_distribution& dist) + { // kurtosis is 4th moment about the mean = u4 / sd ^ 4 + // http://en.wikipedia.org/wiki/Kurtosis + // kurtosis can range from -2 (flat top) to +infinity (sharp peak & heavy tails). + // http://www.itl.nist.gov/div898/handbook/eda/section3/eda35b.htm + return 3 + 1 / dist.mean(); // NIST. + // http://mathworld.wolfram.com/Kurtosis.html explains that the kurtosis excess + // is more convenient because the kurtosis excess of a normal distribution is zero + // whereas the true kurtosis is 3. + } // RealType kurtosis + + template + RealType pdf(const poisson_distribution& dist, const RealType& k) + { // Probability Density/Mass Function. + // Probability that there are EXACTLY k occurrences (or arrivals). + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType mean = dist.mean(); + // Error check: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::pdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + + // Special case of mean zero, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is zero. + return 0; + } + if (k == 0) + { // mean ^ k = 1, and k! = 1, so can simplify. + return exp(-mean); + } + return boost::math::gamma_p_derivative(k+1, mean, Policy()); + } // pdf + + template + RealType logpdf(const poisson_distribution& dist, const RealType& k) + { + BOOST_FPU_EXCEPTION_GUARD + + BOOST_MATH_STD_USING // for ADL of std functions. + using boost::math::lgamma; + + RealType mean = dist.mean(); + // Error check: + RealType result = -std::numeric_limits::infinity(); + if(false == poisson_detail::check_dist_and_k( + "boost::math::pdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + + // Special case of mean zero, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is zero. + return std::numeric_limits::quiet_NaN(); + } + + // Special case where k and lambda are both positive + if(k > 0 && mean > 0) + { + return -lgamma(k+1) + k*log(mean) - mean; + } + + result = log(pdf(dist, k)); + return result; + } + + template + RealType cdf(const poisson_distribution& dist, const RealType& k) + { // Cumulative Distribution Function Poisson. + // The random variate k is the number of occurrences(or arrivals) + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + // Returns the sum of the terms 0 through k of the Poisson Probability Density or Mass (pdf). + + // But note that the Poisson distribution + // (like others including the binomial, negative binomial & Bernoulli) + // is strictly defined as a discrete function: only integral values of k are envisaged. + // However because of the method of calculation using a continuous gamma function, + // it is convenient to treat it as if it is a continuous function + // and permit non-integral values of k. + // To enforce the strict mathematical model, users should use floor or ceil functions + // outside this function to ensure that k is integral. + + // The terms are not summed directly (at least for larger k) + // instead the incomplete gamma integral is employed, + + BOOST_MATH_STD_USING // for ADL of std function exp. + + RealType mean = dist.mean(); + // Error checks: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::cdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + // Special cases: + if (mean == 0) + { // Probability for any k is zero. + return 0; + } + if (k == 0) + { + // mean (and k) have already been checked, + // so this avoids unnecessary repeated checks. + return exp(-mean); + } + // For small integral k could use a finite sum - + // it's cheaper than the gamma function. + // BUT this is now done efficiently by gamma_q function. + // Calculate poisson cdf using the gamma_q function. + return gamma_q(k+1, mean, Policy()); + } // binomial cdf + + template + RealType cdf(const complemented2_type, RealType>& c) + { // Complemented Cumulative Distribution Function Poisson + // The random variate k is the number of events, occurrences or arrivals. + // k argument may be integral, signed, or unsigned, or floating point. + // If necessary, it has already been promoted from an integral type. + // But note that the Poisson distribution + // (like others including the binomial, negative binomial & Bernoulli) + // is strictly defined as a discrete function: only integral values of k are envisaged. + // However because of the method of calculation using a continuous gamma function, + // it is convenient to treat it as is it is a continuous function + // and permit non-integral values of k. + // To enforce the strict mathematical model, users should use floor or ceil functions + // outside this function to ensure that k is integral. + + // Returns the sum of the terms k+1 through inf of the Poisson Probability Density/Mass (pdf). + // The terms are not summed directly (at least for larger k) + // instead the incomplete gamma integral is employed, + + RealType const& k = c.param; + poisson_distribution const& dist = c.dist; + + RealType mean = dist.mean(); + + // Error checks: + RealType result = 0; + if(false == poisson_detail::check_dist_and_k( + "boost::math::cdf(const poisson_distribution<%1%>&, %1%)", + mean, + k, + &result, Policy())) + { + return result; + } + // Special case of mean, regardless of the number of events k. + if (mean == 0) + { // Probability for any k is unity, complement of zero. + return 1; + } + if (k == 0) + { // Avoid repeated checks on k and mean in gamma_p. + return -boost::math::expm1(-mean, Policy()); + } + // Unlike un-complemented cdf (sum from 0 to k), + // can't use finite sum from k+1 to infinity for small integral k, + // anyway it is now done efficiently by gamma_p. + return gamma_p(k + 1, mean, Policy()); // Calculate Poisson cdf using the gamma_p function. + // CCDF = gamma_p(k+1, lambda) + } // poisson ccdf + + template + inline RealType quantile(const poisson_distribution& dist, const RealType& p) + { // Quantile (or Percent Point) Poisson function. + // Return the number of expected events k for a given probability p. + static const char* function = "boost::math::quantile(const poisson_distribution<%1%>&, %1%)"; + RealType result = 0; // of Argument checks: + if(false == poisson_detail::check_prob( + function, + p, + &result, Policy())) + { + return result; + } + // Special case: + if (dist.mean() == 0) + { // if mean = 0 then p = 0, so k can be anything? + if (false == poisson_detail::check_mean_NZ( + function, + dist.mean(), + &result, Policy())) + { + return result; + } + } + if(p == 0) + { + return 0; // Exact result regardless of discrete-quantile Policy + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + using discrete_type = typename Policy::discrete_quantile_type; + std::uintmax_t max_iter = policies::get_max_root_iterations(); + RealType guess; + RealType factor = 8; + RealType z = dist.mean(); + if(z < 1) + guess = z; + else + guess = boost::math::detail::inverse_poisson_cornish_fisher(z, p, RealType(1-p), Policy()); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + + return detail::inverse_discrete_quantile( + dist, + p, + false, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { // Quantile (or Percent Point) of Poisson function. + // Return the number of expected events k for a given + // complement of the probability q. + // + // Error checks: + static const char* function = "boost::math::quantile(complement(const poisson_distribution<%1%>&, %1%))"; + RealType q = c.param; + const poisson_distribution& dist = c.dist; + RealType result = 0; // of argument checks. + if(false == poisson_detail::check_prob( + function, + q, + &result, Policy())) + { + return result; + } + // Special case: + if (dist.mean() == 0) + { // if mean = 0 then p = 0, so k can be anything? + if (false == poisson_detail::check_mean_NZ( + function, + dist.mean(), + &result, Policy())) + { + return result; + } + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(q == 1) + { + return 0; // Exact result regardless of discrete-quantile Policy + } + using discrete_type = typename Policy::discrete_quantile_type; + std::uintmax_t max_iter = policies::get_max_root_iterations(); + RealType guess; + RealType factor = 8; + RealType z = dist.mean(); + if(z < 1) + guess = z; + else + guess = boost::math::detail::inverse_poisson_cornish_fisher(z, RealType(1-q), q, Policy()); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + + return detail::inverse_discrete_quantile( + dist, + q, + true, + guess, + factor, + RealType(1), + discrete_type(), + max_iter); + } // quantile complement. + + } // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include +#include + +#endif // BOOST_MATH_SPECIAL_POISSON_HPP + + + diff --git a/libcxx/src/third-party/boost/math/distributions/rayleigh.hpp b/libcxx/src/third-party/boost/math/distributions/rayleigh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/rayleigh.hpp @@ -0,0 +1,334 @@ +// Copyright Paul A. Bristow 2007. +// 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_STATS_rayleigh_HPP +#define BOOST_STATS_rayleigh_HPP + +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +#include +#include + +namespace boost{ namespace math{ + +namespace detail +{ // Error checks: + template + inline bool verify_sigma(const char* function, RealType sigma, RealType* presult, const Policy& pol) + { + if((sigma <= 0) || (!(boost::math::isfinite)(sigma))) + { + *presult = policies::raise_domain_error( + function, + "The scale parameter \"sigma\" must be > 0 and finite, but was: %1%.", sigma, pol); + return false; + } + return true; + } // bool verify_sigma + + template + inline bool verify_rayleigh_x(const char* function, RealType x, RealType* presult, const Policy& pol) + { + if((x < 0) || (boost::math::isnan)(x)) + { + *presult = policies::raise_domain_error( + function, + "The random variable must be >= 0, but was: %1%.", x, pol); + return false; + } + return true; + } // bool verify_rayleigh_x +} // namespace detail + +template > +class rayleigh_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit rayleigh_distribution(RealType l_sigma = 1) + : m_sigma(l_sigma) + { + RealType err; + detail::verify_sigma("boost::math::rayleigh_distribution<%1%>::rayleigh_distribution", l_sigma, &err, Policy()); + } // rayleigh_distribution + + RealType sigma()const + { // Accessor. + return m_sigma; + } + +private: + RealType m_sigma; +}; // class rayleigh_distribution + +using rayleigh = rayleigh_distribution; + +#ifdef __cpp_deduction_guides +template +rayleigh_distribution(RealType)->rayleigh_distribution::type>; +#endif + +template +inline std::pair range(const rayleigh_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : max_value()); +} + +template +inline std::pair support(const rayleigh_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline RealType pdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + + RealType sigma = dist.sigma(); + RealType result = 0; + static const char* function = "boost::math::pdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; + } + RealType sigmasqr = sigma * sigma; + result = x * (exp(-(x * x) / ( 2 * sigmasqr))) / sigmasqr; + return result; +} // pdf + +template +inline RealType logpdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std function exp. + + const RealType sigma = dist.sigma(); + RealType result = -std::numeric_limits::infinity(); + static const char* function = "boost::math::logpdf(const rayleigh_distribution<%1%>&, %1%)"; + + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return result; + } + + result = -(x*x)/(2*sigma*sigma) - 2*log(sigma) + log(x); + return result; +} // logpdf + +template +inline RealType cdf(const rayleigh_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = dist.sigma(); + static const char* function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + result = -boost::math::expm1(-x * x / ( 2 * sigma * sigma), Policy()); + return result; +} // cdf + +template +inline RealType quantile(const rayleigh_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = dist.sigma(); + static const char* function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 0) + { + return 0; + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = sqrt(-2 * sigma * sigma * boost::math::log1p(-p, Policy())); + return result; +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + RealType result = 0; + RealType sigma = c.dist.sigma(); + static const char* function = "boost::math::cdf(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + RealType x = c.param; + if(false == detail::verify_rayleigh_x(function, x, &result, Policy())) + { + return result; + } + RealType ea = x * x / (2 * sigma * sigma); + // Fix for VC11/12 x64 bug in exp(float): + if (ea >= tools::max_value()) + return 0; + result = exp(-ea); + return result; +} // cdf complement + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions, log & sqrt. + + RealType result = 0; + RealType sigma = c.dist.sigma(); + static const char* function = "boost::math::quantile(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + { + return result; + } + if(q == 1) + { + return 0; + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + result = sqrt(-2 * sigma * sigma * log(q)); + return result; +} // quantile complement + +template +inline RealType mean(const rayleigh_distribution& dist) +{ + RealType result = 0; + RealType sigma = dist.sigma(); + static const char* function = "boost::math::mean(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + using boost::math::constants::root_half_pi; + return sigma * root_half_pi(); +} // mean + +template +inline RealType variance(const rayleigh_distribution& dist) +{ + RealType result = 0; + RealType sigma = dist.sigma(); + static const char* function = "boost::math::variance(const rayleigh_distribution<%1%>&, %1%)"; + if(false == detail::verify_sigma(function, sigma, &result, Policy())) + { + return result; + } + using boost::math::constants::four_minus_pi; + return four_minus_pi() * sigma * sigma / 2; +} // variance + +template +inline RealType mode(const rayleigh_distribution& dist) +{ + return dist.sigma(); +} + +template +inline RealType median(const rayleigh_distribution& dist) +{ + using boost::math::constants::root_ln_four; + return root_ln_four() * dist.sigma(); +} + +template +inline RealType skewness(const rayleigh_distribution& /*dist*/) +{ + return static_cast(0.63111065781893713819189935154422777984404221106391L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // 2 * sqrt(pi) * (pi-3) / pow(4, 2/3) - pi +} + +template +inline RealType kurtosis(const rayleigh_distribution& /*dist*/) +{ + return static_cast(3.2450893006876380628486604106197544154170667057995L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // 3 - (6*pi*pi - 24*pi + 16) / pow(4-pi, 2) +} + +template +inline RealType kurtosis_excess(const rayleigh_distribution& /*dist*/) +{ + return static_cast(0.2450893006876380628486604106197544154170667057995L); + // Computed using NTL at 150 bit, about 50 decimal digits. + // -(6*pi*pi - 24*pi + 16) / pow(4-pi,2) +} // kurtosis_excess + +template +inline RealType entropy(const rayleigh_distribution& dist) +{ + using std::log; + return 1 + log(dist.sigma()*constants::one_div_root_two()) + constants::euler()/2; +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_rayleigh_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/skew_normal.hpp b/libcxx/src/third-party/boost/math/distributions/skew_normal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/skew_normal.hpp @@ -0,0 +1,728 @@ +// Copyright Benjamin Sobotta 2012 + +// 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_STATS_SKEW_NORMAL_HPP +#define BOOST_STATS_SKEW_NORMAL_HPP + +// http://en.wikipedia.org/wiki/Skew_normal_distribution +// http://azzalini.stat.unipd.it/SN/ +// Also: +// Azzalini, A. (1985). "A class of distributions which includes the normal ones". +// Scand. J. Statist. 12: 171-178. + +#include // TODO add skew_normal distribution to fwd.hpp! +#include // Owen's T function +#include +#include +#include +#include +#include +#include // Newton-Raphson +#include +#include // pdf max finder. + +#include +#include // std::lower_bound, std::distance + +namespace boost{ namespace math{ + + namespace detail + { + template + inline bool check_skew_normal_shape( + const char* function, + RealType shape, + RealType* result, + const Policy& pol) + { + if(!(boost::math::isfinite)(shape)) + { + *result = + policies::raise_domain_error(function, + "Shape parameter is %1%, but must be finite!", + shape, pol); + return false; + } + return true; + } + + } // namespace detail + + template > + class skew_normal_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + skew_normal_distribution(RealType l_location = 0, RealType l_scale = 1, RealType l_shape = 0) + : location_(l_location), scale_(l_scale), shape_(l_shape) + { // Default is a 'standard' normal distribution N01. (shape=0 results in the normal distribution with no skew) + static const char* function = "boost::math::skew_normal_distribution<%1%>::skew_normal_distribution"; + + RealType result; + detail::check_scale(function, l_scale, &result, Policy()); + detail::check_location(function, l_location, &result, Policy()); + detail::check_skew_normal_shape(function, l_shape, &result, Policy()); + } + + RealType location()const + { + return location_; + } + + RealType scale()const + { + return scale_; + } + + RealType shape()const + { + return shape_; + } + + + private: + // + // Data members: + // + RealType location_; // distribution location. + RealType scale_; // distribution scale. + RealType shape_; // distribution shape. + }; // class skew_normal_distribution + + typedef skew_normal_distribution skew_normal; + + #ifdef __cpp_deduction_guides + template + skew_normal_distribution(RealType)->skew_normal_distribution::type>; + template + skew_normal_distribution(RealType,RealType)->skew_normal_distribution::type>; + template + skew_normal_distribution(RealType,RealType,RealType)->skew_normal_distribution::type>; + #endif + + template + inline const std::pair range(const skew_normal_distribution& /*dist*/) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair( + std::numeric_limits::has_infinity ? -std::numeric_limits::infinity() : -max_value(), + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : max_value()); // - to + max value. + } + + template + inline const std::pair support(const skew_normal_distribution& /*dist*/) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + max value. + } + + template + inline RealType pdf(const skew_normal_distribution& dist, const RealType& x) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::pdf(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + return 0; // pdf + and - infinity is zero. + } + // Below produces MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && abs(x) == std::numeric_limits::infinity()) + //{ // pdf + and - infinity is zero. + // return 0; + //} + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = pdf(std_normal, transformed_x) * cdf(std_normal, shape*transformed_x) * 2 / scale; + + return result; + } // pdf + + template + inline RealType cdf(const skew_normal_distribution& dist, const RealType& x) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::cdf(const skew_normal_distribution<%1%>&, %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + { + return result; + } + if(false == detail::check_location(function, location, &result, Policy())) + { + return result; + } + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + { + return result; + } + if((boost::math::isinf)(x)) + { + if(x < 0) return 0; // -infinity + return 1; // + infinity + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && x == std::numeric_limits::infinity()) + //{ // cdf +infinity is unity. + // return 1; + //} + //if(std::numeric_limits::has_infinity && x == -std::numeric_limits::infinity()) + //{ // cdf -infinity is zero. + // return 0; + //} + if(false == detail::check_x(function, x, &result, Policy())) + { + return result; + } + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = cdf(std_normal, transformed_x) - owens_t(transformed_x, shape)*static_cast(2); + + return result; + } // cdf + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { + const RealType scale = c.dist.scale(); + const RealType location = c.dist.location(); + const RealType shape = c.dist.shape(); + const RealType x = c.param; + + static const char* function = "boost::math::cdf(const complement(skew_normal_distribution<%1%>&), %1%)"; + + if((boost::math::isinf)(x)) + { + if(x < 0) return 1; // cdf complement -infinity is unity. + return 0; // cdf complement +infinity is zero + } + // These produce MSVC 4127 warnings, so the above used instead. + //if(std::numeric_limits::has_infinity && x == std::numeric_limits::infinity()) + //{ // cdf complement +infinity is zero. + // return 0; + //} + //if(std::numeric_limits::has_infinity && x == -std::numeric_limits::infinity()) + //{ // cdf complement -infinity is unity. + // return 1; + //} + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + if(false == detail::check_x(function, x, &result, Policy())) + return result; + + const RealType transformed_x = (x-location)/scale; + + normal_distribution std_normal; + + result = cdf(complement(std_normal, transformed_x)) + owens_t(transformed_x, shape)*static_cast(2); + return result; + } // cdf complement + + template + inline RealType location(const skew_normal_distribution& dist) + { + return dist.location(); + } + + template + inline RealType scale(const skew_normal_distribution& dist) + { + return dist.scale(); + } + + template + inline RealType shape(const skew_normal_distribution& dist) + { + return dist.shape(); + } + + template + inline RealType mean(const skew_normal_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + + using namespace boost::math::constants; + + //const RealType delta = dist.shape() / sqrt(static_cast(1)+dist.shape()*dist.shape()); + + //return dist.location() + dist.scale() * delta * root_two_div_pi(); + + return dist.location() + dist.scale() * dist.shape() / sqrt(pi()+pi()*dist.shape()*dist.shape()) * root_two(); + } + + template + inline RealType variance(const skew_normal_distribution& dist) + { + using namespace boost::math::constants; + + const RealType delta2 = dist.shape() != 0 ? static_cast(1) / (static_cast(1)+static_cast(1)/(dist.shape()*dist.shape())) : static_cast(0); + //const RealType inv_delta2 = static_cast(1)+static_cast(1)/(dist.shape()*dist.shape()); + + RealType variance = dist.scale()*dist.scale()*(static_cast(1)-two_div_pi()*delta2); + //RealType variance = dist.scale()*dist.scale()*(static_cast(1)-two_div_pi()/inv_delta2); + + return variance; + } + + namespace detail + { + /* + TODO No closed expression for mode, so use max of pdf. + */ + + template + inline RealType mode_fallback(const skew_normal_distribution& dist) + { // mode. + static const char* function = "mode(skew_normal_distribution<%1%> const&)"; + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + RealType result; + if(!detail::check_scale( + function, + scale, &result, Policy()) + || + !detail::check_skew_normal_shape( + function, + shape, + &result, + Policy())) + return result; + + if( shape == 0 ) + { + return location; + } + + if( shape < 0 ) + { + skew_normal_distribution D(0, 1, -shape); + result = mode_fallback(D); + result = location-scale*result; + return result; + } + + BOOST_MATH_STD_USING + + // 21 elements + static const RealType shapes[] = { + 0.0, + 1.000000000000000e-004, + 2.069138081114790e-004, + 4.281332398719396e-004, + 8.858667904100824e-004, + 1.832980710832436e-003, + 3.792690190732250e-003, + 7.847599703514606e-003, + 1.623776739188722e-002, + 3.359818286283781e-002, + 6.951927961775606e-002, + 1.438449888287663e-001, + 2.976351441631319e-001, + 6.158482110660261e-001, + 1.274274985703135e+000, + 2.636650898730361e+000, + 5.455594781168514e+000, + 1.128837891684688e+001, + 2.335721469090121e+001, + 4.832930238571753e+001, + 1.000000000000000e+002}; + + // 21 elements + static const RealType guess[] = { + 0.0, + 5.000050000525391e-005, + 1.500015000148736e-004, + 3.500035000350010e-004, + 7.500075000752560e-004, + 1.450014500145258e-003, + 3.050030500305390e-003, + 6.250062500624765e-003, + 1.295012950129504e-002, + 2.675026750267495e-002, + 5.525055250552491e-002, + 1.132511325113255e-001, + 2.249522495224952e-001, + 3.992539925399257e-001, + 5.353553535535358e-001, + 4.954549545495457e-001, + 3.524535245352451e-001, + 2.182521825218249e-001, + 1.256512565125654e-001, + 6.945069450694508e-002, + 3.735037350373460e-002 + }; + + const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape); + + typedef typename std::iterator_traits::difference_type diff_type; + + const diff_type d = std::distance(shapes, result_ptr); + + BOOST_MATH_ASSERT(d > static_cast(0)); + + // refine + if(d < static_cast(21)) // shape smaller 100 + { + result = guess[d-static_cast(1)] + + (guess[d]-guess[d-static_cast(1)])/(shapes[d]-shapes[d-static_cast(1)]) + * (shape-shapes[d-static_cast(1)]); + } + else // shape greater 100 + { + result = 1e-4; + } + + skew_normal_distribution helper(0, 1, shape); + + result = detail::generic_find_mode_01(helper, result, function); + + result = result*scale + location; + + return result; + } // mode_fallback + + + /* + * TODO No closed expression for mode, so use f'(x) = 0 + */ + template + struct skew_normal_mode_functor + { + skew_normal_mode_functor(const boost::math::skew_normal_distribution dist) + : distribution(dist) + { + } + + boost::math::tuple operator()(RealType const& x) + { + normal_distribution std_normal; + const RealType shape = distribution.shape(); + const RealType pdf_x = pdf(distribution, x); + const RealType normpdf_x = pdf(std_normal, x); + const RealType normpdf_ax = pdf(std_normal, x*shape); + RealType fx = static_cast(2)*shape*normpdf_ax*normpdf_x - x*pdf_x; + RealType dx = static_cast(2)*shape*x*normpdf_x*normpdf_ax*(static_cast(1) + shape*shape) + pdf_x + x*fx; + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, -dx); + } + private: + const boost::math::skew_normal_distribution distribution; + }; + + } // namespace detail + + template + inline RealType mode(const skew_normal_distribution& dist) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::mode(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + + if( shape == 0 ) + { + return location; + } + + if( shape < 0 ) + { + skew_normal_distribution D(0, 1, -shape); + result = mode(D); + result = location-scale*result; + return result; + } + + // 21 elements + static const RealType shapes[] = { + 0.0, + static_cast(1.000000000000000e-004), + static_cast(2.069138081114790e-004), + static_cast(4.281332398719396e-004), + static_cast(8.858667904100824e-004), + static_cast(1.832980710832436e-003), + static_cast(3.792690190732250e-003), + static_cast(7.847599703514606e-003), + static_cast(1.623776739188722e-002), + static_cast(3.359818286283781e-002), + static_cast(6.951927961775606e-002), + static_cast(1.438449888287663e-001), + static_cast(2.976351441631319e-001), + static_cast(6.158482110660261e-001), + static_cast(1.274274985703135e+000), + static_cast(2.636650898730361e+000), + static_cast(5.455594781168514e+000), + static_cast(1.128837891684688e+001), + static_cast(2.335721469090121e+001), + static_cast(4.832930238571753e+001), + static_cast(1.000000000000000e+002) + }; + + // 21 elements + static const RealType guess[] = { + 0.0, + static_cast(5.000050000525391e-005), + static_cast(1.500015000148736e-004), + static_cast(3.500035000350010e-004), + static_cast(7.500075000752560e-004), + static_cast(1.450014500145258e-003), + static_cast(3.050030500305390e-003), + static_cast(6.250062500624765e-003), + static_cast(1.295012950129504e-002), + static_cast(2.675026750267495e-002), + static_cast(5.525055250552491e-002), + static_cast(1.132511325113255e-001), + static_cast(2.249522495224952e-001), + static_cast(3.992539925399257e-001), + static_cast(5.353553535535358e-001), + static_cast(4.954549545495457e-001), + static_cast(3.524535245352451e-001), + static_cast(2.182521825218249e-001), + static_cast(1.256512565125654e-001), + static_cast(6.945069450694508e-002), + static_cast(3.735037350373460e-002) + }; + + const RealType* result_ptr = std::lower_bound(shapes, shapes+21, shape); + + typedef typename std::iterator_traits::difference_type diff_type; + + const diff_type d = std::distance(shapes, result_ptr); + + BOOST_MATH_ASSERT(d > static_cast(0)); + + // TODO: make the search bounds smarter, depending on the shape parameter + RealType search_min = 0; // below zero was caught above + RealType search_max = 0.55f; // will never go above 0.55 + + // refine + if(d < static_cast(21)) // shape smaller 100 + { + // it is safe to assume that d > 0, because shape==0.0 is caught earlier + result = guess[d-static_cast(1)] + + (guess[d]-guess[d-static_cast(1)])/(shapes[d]-shapes[d-static_cast(1)]) + * (shape-shapes[d-static_cast(1)]); + } + else // shape greater 100 + { + result = 1e-4f; + search_max = guess[19]; // set 19 instead of 20 to have a safety margin because the table may not be exact @ shape=100 + } + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t m = policies::get_max_root_iterations(); // and max iterations. + + skew_normal_distribution helper(0, 1, shape); + + result = tools::newton_raphson_iterate(detail::skew_normal_mode_functor(helper), result, + search_min, search_max, get_digits, m); + + result = result*scale + location; + + return result; + } + + + + template + inline RealType skewness(const skew_normal_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + using namespace boost::math::constants; + + static const RealType factor = four_minus_pi()/static_cast(2); + const RealType delta = dist.shape() / sqrt(static_cast(1)+dist.shape()*dist.shape()); + + return static_cast(factor * pow(root_two_div_pi() * delta, 3) / + pow(static_cast(1)-two_div_pi()*delta*delta, static_cast(1.5))); + } + + template + inline RealType kurtosis(const skew_normal_distribution& dist) + { + return kurtosis_excess(dist)+static_cast(3); + } + + template + inline RealType kurtosis_excess(const skew_normal_distribution& dist) + { + using namespace boost::math::constants; + + static const RealType factor = pi_minus_three()*static_cast(2); + + const RealType delta2 = dist.shape() != 0 ? static_cast(1) / (static_cast(1)+static_cast(1)/(dist.shape()*dist.shape())) : static_cast(0); + + const RealType x = static_cast(1)-two_div_pi()*delta2; + const RealType y = two_div_pi() * delta2; + + return factor * y*y / (x*x); + } + + namespace detail + { + + template + struct skew_normal_quantile_functor + { + skew_normal_quantile_functor(const boost::math::skew_normal_distribution dist, RealType const& p) + : distribution(dist), prob(p) + { + } + + boost::math::tuple operator()(RealType const& x) + { + RealType c = cdf(distribution, x); + RealType fx = c - prob; // Difference cdf - value - to minimize. + RealType dx = pdf(distribution, x); // pdf is 1st derivative. + // return both function evaluation difference f(x) and 1st derivative f'(x). + return boost::math::make_tuple(fx, dx); + } + private: + const boost::math::skew_normal_distribution distribution; + RealType prob; + }; + + } // namespace detail + + template + inline RealType quantile(const skew_normal_distribution& dist, const RealType& p) + { + const RealType scale = dist.scale(); + const RealType location = dist.location(); + const RealType shape = dist.shape(); + + static const char* function = "boost::math::quantile(const skew_normal_distribution<%1%>&, %1%)"; + + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + // Compute initial guess via Cornish-Fisher expansion. + RealType x = -boost::math::erfc_inv(2 * p, Policy()) * constants::root_two(); + + // Avoid unnecessary computations if there is no skew. + if(shape != 0) + { + const RealType skew = skewness(dist); + const RealType exk = kurtosis_excess(dist); + + x = x + (x*x-static_cast(1))*skew/static_cast(6) + + x*(x*x-static_cast(3))*exk/static_cast(24) + - x*(static_cast(2)*x*x-static_cast(5))*skew*skew/static_cast(36); + } // if(shape != 0) + + result = standard_deviation(dist)*x+mean(dist); + + // handle special case of non-skew normal distribution. + if(shape == 0) + return result; + + // refine the result by numerically searching the root of (p-cdf) + + const RealType search_min = range(dist).first; + const RealType search_max = range(dist).second; + + const int get_digits = policies::digits();// get digits from policy, + std::uintmax_t m = policies::get_max_root_iterations(); // and max iterations. + + result = tools::newton_raphson_iterate(detail::skew_normal_quantile_functor(dist, p), result, + search_min, search_max, get_digits, m); + + return result; + } // quantile + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + const RealType scale = c.dist.scale(); + const RealType location = c.dist.location(); + const RealType shape = c.dist.shape(); + + static const char* function = "boost::math::quantile(const complement(skew_normal_distribution<%1%>&), %1%)"; + RealType result = 0; + if(false == detail::check_scale(function, scale, &result, Policy())) + return result; + if(false == detail::check_location(function, location, &result, Policy())) + return result; + if(false == detail::check_skew_normal_shape(function, shape, &result, Policy())) + return result; + RealType q = c.param; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + skew_normal_distribution D(-location, scale, -shape); + + result = -quantile(D, q); + + return result; + } // quantile + + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_SKEW_NORMAL_HPP + + diff --git a/libcxx/src/third-party/boost/math/distributions/students_t.hpp b/libcxx/src/third-party/boost/math/distributions/students_t.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/students_t.hpp @@ -0,0 +1,511 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2006, 2012, 2017. +// Copyright Thomas Mang 2012. + +// 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_STATS_STUDENTS_T_HPP +#define BOOST_STATS_STUDENTS_T_HPP + +// http://en.wikipedia.org/wiki/Student%27s_t_distribution +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3664.htm + +#include +#include // for ibeta(a, b, x). +#include +#include +#include +#include + +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +#endif + +namespace boost { namespace math { + +template > +class students_t_distribution +{ +public: + typedef RealType value_type; + typedef Policy policy_type; + + students_t_distribution(RealType df) : df_(df) + { // Constructor. + RealType result; + detail::check_df_gt0_to_inf( // Checks that df > 0 or df == inf. + "boost::math::students_t_distribution<%1%>::students_t_distribution", df_, &result, Policy()); + } // students_t_distribution + + RealType degrees_of_freedom()const + { + return df_; + } + + // Parameter estimation: + static RealType find_degrees_of_freedom( + RealType difference_from_mean, + RealType alpha, + RealType beta, + RealType sd, + RealType hint = 100); + +private: + // Data member: + RealType df_; // degrees of freedom is a real number > 0 or +infinity. +}; + +typedef students_t_distribution students_t; // Convenience typedef for double version. + +#ifdef __cpp_deduction_guides +template +students_t_distribution(RealType)->students_t_distribution::type>; +#endif + +template +inline const std::pair range(const students_t_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + // Now including infinity. + using boost::math::tools::max_value; + //return std::pair(-max_value(), max_value()); + return std::pair(((::std::numeric_limits::is_specialized & ::std::numeric_limits::has_infinity) ? -std::numeric_limits::infinity() : -max_value()), ((::std::numeric_limits::is_specialized & ::std::numeric_limits::has_infinity) ? +std::numeric_limits::infinity() : +max_value())); +} + +template +inline const std::pair support(const students_t_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // Now including infinity. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + //return std::pair(-max_value(), max_value()); + return std::pair(((::std::numeric_limits::is_specialized & ::std::numeric_limits::has_infinity) ? -std::numeric_limits::infinity() : -max_value()), ((::std::numeric_limits::is_specialized & ::std::numeric_limits::has_infinity) ? +std::numeric_limits::infinity() : +max_value())); +} + +template +inline RealType pdf(const students_t_distribution& dist, const RealType& x) +{ + BOOST_FPU_EXCEPTION_GUARD + BOOST_MATH_STD_USING // for ADL of std functions. + + RealType error_result; + if(false == detail::check_x_not_NaN( + "boost::math::pdf(const students_t_distribution<%1%>&, %1%)", x, &error_result, Policy())) + return error_result; + RealType df = dist.degrees_of_freedom(); + if(false == detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + "boost::math::pdf(const students_t_distribution<%1%>&, %1%)", df, &error_result, Policy())) + return error_result; + + RealType result; + if ((boost::math::isinf)(x)) + { // - or +infinity. + result = static_cast(0); + return result; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps + // - use normal distribution which is much faster and more accurate. + normal_distribution n(0, 1); + result = pdf(n, x); + } + else + { // + RealType basem1 = x * x / df; + if(basem1 < 0.125) + { + result = exp(-boost::math::log1p(basem1, Policy()) * (1+df) / 2); + } + else + { + result = pow(1 / (1 + basem1), (df + 1) / 2); + } + result /= sqrt(df) * boost::math::beta(df / 2, RealType(0.5f), Policy()); + } + return result; +} // pdf + +template +inline RealType cdf(const students_t_distribution& dist, const RealType& x) +{ + RealType error_result; + // degrees_of_freedom > 0 or infinity check: + RealType df = dist.degrees_of_freedom(); + if (false == detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + "boost::math::cdf(const students_t_distribution<%1%>&, %1%)", df, &error_result, Policy())) + { + return error_result; + } + // Check for bad x first. + if(false == detail::check_x_not_NaN( + "boost::math::cdf(const students_t_distribution<%1%>&, %1%)", x, &error_result, Policy())) + { + return error_result; + } + if (x == 0) + { // Special case with exact result. + return static_cast(0.5); + } + if ((boost::math::isinf)(x)) + { // x == - or + infinity, regardless of df. + return ((x < 0) ? static_cast(0) : static_cast(1)); + } + + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps (perhaps infinite?) + // - use normal distribution which is much faster and more accurate. + normal_distribution n(0, 1); + RealType result = cdf(n, x); + return result; + } + else + { // normal df case. + // + // Calculate probability of Student's t using the incomplete beta function. + // probability = ibeta(degrees_of_freedom / 2, 1/2, degrees_of_freedom / (degrees_of_freedom + t*t)) + // + // However when t is small compared to the degrees of freedom, that formula + // suffers from rounding error, use the identity formula to work around + // the problem: + // + // I[x](a,b) = 1 - I[1-x](b,a) + // + // and: + // + // x = df / (df + t^2) + // + // so: + // + // 1 - x = t^2 / (df + t^2) + // + RealType x2 = x * x; + RealType probability; + if(df > 2 * x2) + { + RealType z = x2 / (df + x2); + probability = ibetac(static_cast(0.5), df / 2, z, Policy()) / 2; + } + else + { + RealType z = df / (df + x2); + probability = ibeta(df / 2, static_cast(0.5), z, Policy()) / 2; + } + return (x > 0 ? 1 - probability : probability); + } +} // cdf + +template +inline RealType quantile(const students_t_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + // + // Obtain parameters: + RealType probability = p; + + // Check for domain errors: + RealType df = dist.degrees_of_freedom(); + static const char* function = "boost::math::quantile(const students_t_distribution<%1%>&, %1%)"; + RealType error_result; + if(false == (detail::check_df_gt0_to_inf( // Check that df > 0 or == +infinity. + function, df, &error_result, Policy()) + && detail::check_probability(function, probability, &error_result, Policy()))) + return error_result; + // Special cases, regardless of degrees_of_freedom. + if (probability == 0) + return -policies::raise_overflow_error(function, 0, Policy()); + if (probability == 1) + return policies::raise_overflow_error(function, 0, Policy()); + if (probability == static_cast(0.5)) + return 0; // + // +#if 0 + // This next block is disabled in favour of a faster method than + // incomplete beta inverse, but code retained for future reference: + // + // Calculate quantile of Student's t using the incomplete beta function inverse: + probability = (probability > 0.5) ? 1 - probability : probability; + RealType t, x, y; + x = ibeta_inv(degrees_of_freedom / 2, RealType(0.5), 2 * probability, &y); + if(degrees_of_freedom * y > tools::max_value() * x) + t = tools::overflow_error(function); + else + t = sqrt(degrees_of_freedom * y / x); + // + // Figure out sign based on the size of p: + // + if(p < 0.5) + t = -t; + + return t; +#endif + // + // Depending on how many digits RealType has, this may forward + // to the incomplete beta inverse as above. Otherwise uses a + // faster method that is accurate to ~15 digits everywhere + // and a couple of epsilon at double precision and in the central + // region where most use cases will occur... + // + return boost::math::detail::fast_students_t_quantile(df, probability, Policy()); +} // quantile + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + return cdf(c.dist, -c.param); +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + return -quantile(c.dist, c.param); +} + +// +// Parameter estimation follows: +// +namespace detail{ +// +// Functors for finding degrees of freedom: +// +template +struct sample_size_func +{ + sample_size_func(RealType a, RealType b, RealType s, RealType d) + : alpha(a), beta(b), ratio(s*s/(d*d)) {} + + RealType operator()(const RealType& df) + { + if(df <= tools::min_value()) + { // + return 1; + } + students_t_distribution t(df); + RealType qa = quantile(complement(t, alpha)); + RealType qb = quantile(complement(t, beta)); + qa += qb; + qa *= qa; + qa *= ratio; + qa -= (df + 1); + return qa; + } + RealType alpha, beta, ratio; +}; + +} // namespace detail + +template +RealType students_t_distribution::find_degrees_of_freedom( + RealType difference_from_mean, + RealType alpha, + RealType beta, + RealType sd, + RealType hint) +{ + static const char* function = "boost::math::students_t_distribution<%1%>::find_degrees_of_freedom"; + // + // Check for domain errors: + // + RealType error_result; + if(false == detail::check_probability( + function, alpha, &error_result, Policy()) + && detail::check_probability(function, beta, &error_result, Policy())) + return error_result; + + if(hint <= 0) + hint = 1; + + detail::sample_size_func f(alpha, beta, sd, difference_from_mean); + tools::eps_tolerance tol(policies::digits()); + std::uintmax_t max_iter = policies::get_max_root_iterations(); + std::pair r = tools::bracket_and_solve_root(f, hint, RealType(2), false, tol, max_iter, Policy()); + RealType result = r.first + (r.second - r.first) / 2; + if(max_iter >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate solution in a reasonable time:" + " either there is no answer to how many degrees of freedom are required" + " or the answer is infinite. Current best guess is %1%", result, Policy()); + } + return result; +} + +template +inline RealType mode(const students_t_distribution& /*dist*/) +{ + // Assume no checks on degrees of freedom are useful (unlike mean). + return 0; // Always zero by definition. +} + +template +inline RealType median(const students_t_distribution& /*dist*/) +{ + // Assume no checks on degrees of freedom are useful (unlike mean). + return 0; // Always zero by definition. +} + +// See section 5.1 on moments at http://en.wikipedia.org/wiki/Student%27s_t-distribution + +template +inline RealType mean(const students_t_distribution& dist) +{ // Revised for https://svn.boost.org/trac/boost/ticket/7177 + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 1) ) + { // mean is undefined for moment <= 1! + return policies::raise_domain_error( + "boost::math::mean(students_t_distribution<%1%> const&, %1%)", + "Mean is undefined for degrees of freedom < 1 but got %1%.", df, Policy()); + return std::numeric_limits::quiet_NaN(); + } + return 0; +} // mean + +template +inline RealType variance(const students_t_distribution& dist) +{ // http://en.wikipedia.org/wiki/Student%27s_t-distribution + // Revised for https://svn.boost.org/trac/boost/ticket/7177 + RealType df = dist.degrees_of_freedom(); + if ((boost::math::isnan)(df) || (df <= 2)) + { // NaN or undefined for <= 2. + return policies::raise_domain_error( + "boost::math::variance(students_t_distribution<%1%> const&, %1%)", + "variance is undefined for degrees of freedom <= 2, but got %1%.", + df, Policy()); + return std::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 1; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 1; + } + else + { + return df / (df - 2); + } +} // variance + +template +inline RealType skewness(const students_t_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + if( ((boost::math::isnan)(df)) || (dist.degrees_of_freedom() <= 3)) + { // Undefined for moment k = 3. + return policies::raise_domain_error( + "boost::math::skewness(students_t_distribution<%1%> const&, %1%)", + "Skewness is undefined for degrees of freedom <= 3, but got %1%.", + dist.degrees_of_freedom(), Policy()); + return std::numeric_limits::quiet_NaN(); + } + return 0; // For all valid df, including infinity. +} // skewness + +template +inline RealType kurtosis(const students_t_distribution& dist) +{ + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 4)) + { // Undefined or infinity for moment k = 4. + return policies::raise_domain_error( + "boost::math::kurtosis(students_t_distribution<%1%> const&, %1%)", + "Kurtosis is undefined for degrees of freedom <= 4, but got %1%.", + df, Policy()); + return std::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 3; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 3; + } + else + { + //return 3 * (df - 2) / (df - 4); re-arranged to + return 6 / (df - 4) + 3; + } +} // kurtosis + +template +inline RealType kurtosis_excess(const students_t_distribution& dist) +{ + // see http://mathworld.wolfram.com/Kurtosis.html + + RealType df = dist.degrees_of_freedom(); + if(((boost::math::isnan)(df)) || (df <= 4)) + { // Undefined or infinity for moment k = 4. + return policies::raise_domain_error( + "boost::math::kurtosis_excess(students_t_distribution<%1%> const&, %1%)", + "Kurtosis_excess is undefined for degrees of freedom <= 4, but got %1%.", + df, Policy()); + return std::numeric_limits::quiet_NaN(); // Undefined. + } + if ((boost::math::isinf)(df)) + { // +infinity. + return 0; + } + RealType limit = policies::get_epsilon(); + // Use policies so that if policy requests lower precision, + // then get the normal distribution approximation earlier. + limit = static_cast(1) / limit; // 1/eps + // for 64-bit double 1/eps = 4503599627370496 + if (df > limit) + { // Special case for really big degrees_of_freedom > 1 / eps. + return 0; + } + else + { + return 6 / (df - 4); + } +} + +template +inline RealType entropy(const students_t_distribution& dist) +{ + using std::log; + using std::sqrt; + RealType v = dist.degrees_of_freedom(); + RealType vp1 = (v+1)/2; + RealType vd2 = v/2; + + return vp1*(digamma(vp1) - digamma(vd2)) + log(sqrt(v)*beta(vd2, RealType(1)/RealType(2))); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_STUDENTS_T_HPP diff --git a/libcxx/src/third-party/boost/math/distributions/triangular.hpp b/libcxx/src/third-party/boost/math/distributions/triangular.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/triangular.hpp @@ -0,0 +1,547 @@ +// Copyright John Maddock 2006, 2007. +// Copyright Paul A. Bristow 2006, 2007. +// 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_STATS_TRIANGULAR_HPP +#define BOOST_STATS_TRIANGULAR_HPP + +// http://mathworld.wolfram.com/TriangularDistribution.html +// Note that the 'constructors' defined by Wolfram are difference from those here, +// for example +// N[variance[triangulardistribution{1, +2}, 1.5], 50] computes +// 0.041666666666666666666666666666666666666666666666667 +// TriangularDistribution{1, +2}, 1.5 is the analog of triangular_distribution(1, 1.5, 2) + +// http://en.wikipedia.org/wiki/Triangular_distribution + +#include +#include +#include +#include +#include + +#include + +namespace boost{ namespace math +{ + namespace detail + { + template + inline bool check_triangular_lower( + const char* function, + RealType lower, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(lower)) + { // Any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Lower parameter is %1%, but must be finite!", lower, pol); + return false; + } + } // bool check_triangular_lower( + + template + inline bool check_triangular_mode( + const char* function, + RealType mode, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(mode)) + { // any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Mode parameter is %1%, but must be finite!", mode, pol); + return false; + } + } // bool check_triangular_mode( + + template + inline bool check_triangular_upper( + const char* function, + RealType upper, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(upper)) + { // any finite value is OK. + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "Upper parameter is %1%, but must be finite!", upper, pol); + return false; + } + } // bool check_triangular_upper( + + template + inline bool check_triangular_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // Any finite value is OK + return true; + } + else + { // Not finite: infinity or NaN. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_triangular_x + + template + inline bool check_triangular( + const char* function, + RealType lower, + RealType mode, + RealType upper, + RealType* result, const Policy& pol) + { + if ((check_triangular_lower(function, lower, result, pol) == false) + || (check_triangular_mode(function, mode, result, pol) == false) + || (check_triangular_upper(function, upper, result, pol) == false)) + { // Some parameter not finite. + return false; + } + else if (lower >= upper) // lower == upper NOT useful. + { // lower >= upper. + *result = policies::raise_domain_error( + function, + "lower parameter is %1%, but must be less than upper!", lower, pol); + return false; + } + else + { // Check lower <= mode <= upper. + if (mode < lower) + { + *result = policies::raise_domain_error( + function, + "mode parameter is %1%, but must be >= than lower!", lower, pol); + return false; + } + if (mode > upper) + { + *result = policies::raise_domain_error( + function, + "mode parameter is %1%, but must be <= than upper!", upper, pol); + return false; + } + return true; // All OK. + } + } // bool check_triangular + } // namespace detail + + template > + class triangular_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + triangular_distribution(RealType l_lower = -1, RealType l_mode = 0, RealType l_upper = 1) + : m_lower(l_lower), m_mode(l_mode), m_upper(l_upper) // Constructor. + { // Evans says 'standard triangular' is lower 0, mode 1/2, upper 1, + // has median sqrt(c/2) for c <=1/2 and 1 - sqrt(1-c)/2 for c >= 1/2 + // But this -1, 0, 1 is more useful in most applications to approximate normal distribution, + // where the central value is the most likely and deviations either side equally likely. + RealType result; + detail::check_triangular("boost::math::triangular_distribution<%1%>::triangular_distribution",l_lower, l_mode, l_upper, &result, Policy()); + } + // Accessor functions. + RealType lower()const + { + return m_lower; + } + RealType mode()const + { + return m_mode; + } + RealType upper()const + { + return m_upper; + } + private: + // Data members: + RealType m_lower; // distribution lower aka a + RealType m_mode; // distribution mode aka c + RealType m_upper; // distribution upper aka b + }; // class triangular_distribution + + typedef triangular_distribution triangular; + + #ifdef __cpp_deduction_guides + template + triangular_distribution(RealType)->triangular_distribution::type>; + template + triangular_distribution(RealType,RealType)->triangular_distribution::type>; + template + triangular_distribution(RealType,RealType,RealType)->triangular_distribution::type>; + #endif + + template + inline const std::pair range(const triangular_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); + } + + template + inline const std::pair support(const triangular_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + return std::pair(dist.lower(), dist.upper()); + } + + template + RealType pdf(const triangular_distribution& dist, const RealType& x) + { + static const char* function = "boost::math::pdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if((x < lower) || (x > upper)) + { + return 0; + } + if (x == lower) + { // (mode - lower) == 0 which would lead to divide by zero! + return (mode == lower) ? 2 / (upper - lower) : RealType(0); + } + else if (x == upper) + { + return (mode == upper) ? 2 / (upper - lower) : RealType(0); + } + else if (x <= mode) + { + return 2 * (x - lower) / ((upper - lower) * (mode - lower)); + } + else + { // (x > mode) + return 2 * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType pdf(const triangular_distribution& dist, const RealType& x) + + template + inline RealType cdf(const triangular_distribution& dist, const RealType& x) + { + static const char* function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if((x <= lower)) + { + return 0; + } + if (x >= upper) + { + return 1; + } + // else lower < x < upper + if (x <= mode) + { + return ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower)); + } + else + { + return 1 - (upper - x) * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType cdf(const triangular_distribution& dist, const RealType& x) + + template + RealType quantile(const triangular_distribution& dist, const RealType& p) + { + BOOST_MATH_STD_USING // for ADL of std functions (sqrt). + static const char* function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, p, &result, Policy())) + { + return result; + } + if(p == 0) + { + return lower; + } + if(p == 1) + { + return upper; + } + RealType p0 = (mode - lower) / (upper - lower); + RealType q = 1 - p; + if (p < p0) + { + result = sqrt((upper - lower) * (mode - lower) * p) + lower; + } + else if (p == p0) + { + result = mode; + } + else // p > p0 + { + result = upper - sqrt((upper - lower) * (upper - mode) * q); + } + return result; + + } // RealType quantile(const triangular_distribution& dist, const RealType& q) + + template + RealType cdf(const complemented2_type, RealType>& c) + { + static const char* function = "boost::math::cdf(const triangular_distribution<%1%>&, %1%)"; + RealType lower = c.dist.lower(); + RealType mode = c.dist.mode(); + RealType upper = c.dist.upper(); + RealType x = c.param; + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_triangular_x(function, x, &result, Policy())) + { + return result; + } + if (x <= lower) + { + return 1; + } + if (x >= upper) + { + return 0; + } + if (x <= mode) + { + return 1 - ((x - lower) * (x - lower)) / ((upper - lower) * (mode - lower)); + } + else + { + return (upper - x) * (upper - x) / ((upper - lower) * (upper - mode)); + } + } // RealType cdf(const complemented2_type, RealType>& c) + + template + RealType quantile(const complemented2_type, RealType>& c) + { + BOOST_MATH_STD_USING // Aid ADL for sqrt. + static const char* function = "boost::math::quantile(const triangular_distribution<%1%>&, %1%)"; + RealType l = c.dist.lower(); + RealType m = c.dist.mode(); + RealType u = c.dist.upper(); + RealType q = c.param; // probability 0 to 1. + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, l, m, u, &result, Policy())) + { + return result; + } + if(false == detail::check_probability(function, q, &result, Policy())) + { + return result; + } + if(q == 0) + { + return u; + } + if(q == 1) + { + return l; + } + RealType lower = c.dist.lower(); + RealType mode = c.dist.mode(); + RealType upper = c.dist.upper(); + + RealType p = 1 - q; + RealType p0 = (mode - lower) / (upper - lower); + if(p < p0) + { + RealType s = (upper - lower) * (mode - lower); + s *= p; + result = sqrt((upper - lower) * (mode - lower) * p) + lower; + } + else if (p == p0) + { + result = mode; + } + else // p > p0 + { + result = upper - sqrt((upper - lower) * (upper - mode) * q); + } + return result; + } // RealType quantile(const complemented2_type, RealType>& c) + + template + inline RealType mean(const triangular_distribution& dist) + { + static const char* function = "boost::math::mean(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + return (lower + upper + mode) / 3; + } // RealType mean(const triangular_distribution& dist) + + + template + inline RealType variance(const triangular_distribution& dist) + { + static const char* function = "boost::math::mean(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function, lower, mode, upper, &result, Policy())) + { + return result; + } + return (lower * lower + upper * upper + mode * mode - lower * upper - lower * mode - upper * mode) / 18; + } // RealType variance(const triangular_distribution& dist) + + template + inline RealType mode(const triangular_distribution& dist) + { + static const char* function = "boost::math::mode(const triangular_distribution<%1%>&)"; + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular_mode(function, mode, &result, Policy())) + { // This should never happen! + return result; + } + return mode; + } // RealType mode + + template + inline RealType median(const triangular_distribution& dist) + { + BOOST_MATH_STD_USING // ADL of std functions. + static const char* function = "boost::math::median(const triangular_distribution<%1%>&)"; + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular_mode(function, mode, &result, Policy())) + { // This should never happen! + return result; + } + RealType lower = dist.lower(); + RealType upper = dist.upper(); + if (mode >= (upper + lower) / 2) + { + return lower + sqrt((upper - lower) * (mode - lower)) / constants::root_two(); + } + else + { + return upper - sqrt((upper - lower) * (upper - mode)) / constants::root_two(); + } + } // RealType mode + + template + inline RealType skewness(const triangular_distribution& dist) + { + BOOST_MATH_STD_USING // for ADL of std functions + using namespace boost::math::constants; // for root_two + static const char* function = "boost::math::skewness(const triangular_distribution<%1%>&)"; + + RealType lower = dist.lower(); + RealType mode = dist.mode(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == boost::math::detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return root_two() * (lower + upper - 2 * mode) * (2 * lower - upper - mode) * (lower - 2 * upper + mode) / + (5 * pow((lower * lower + upper * upper + mode * mode + - lower * upper - lower * mode - upper * mode), RealType(3)/RealType(2))); + // #11768: Skewness formula for triangular distribution is incorrect - corrected 29 Oct 2015 for release 1.61. + } // RealType skewness(const triangular_distribution& dist) + + template + inline RealType kurtosis(const triangular_distribution& dist) + { // These checks may be belt and braces as should have been checked on construction? + static const char* function = "boost::math::kurtosis(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return static_cast(12)/5; // 12/5 = 2.4; + } // RealType kurtosis_excess(const triangular_distribution& dist) + + template + inline RealType kurtosis_excess(const triangular_distribution& dist) + { // These checks may be belt and braces as should have been checked on construction? + static const char* function = "boost::math::kurtosis_excess(const triangular_distribution<%1%>&)"; + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType mode = dist.mode(); + RealType result = 0; // of checks. + if(false == detail::check_triangular(function,lower, mode, upper, &result, Policy())) + { + return result; + } + return static_cast(-3)/5; // - 3/5 = -0.6 + // Assuming mathworld really means kurtosis excess? Wikipedia now corrected to match this. + } + + template + inline RealType entropy(const triangular_distribution& dist) + { + using std::log; + return constants::half() + log((dist.upper() - dist.lower())/2); + } + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_TRIANGULAR_HPP + + + diff --git a/libcxx/src/third-party/boost/math/distributions/uniform.hpp b/libcxx/src/third-party/boost/math/distributions/uniform.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/uniform.hpp @@ -0,0 +1,396 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 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) + +// TODO deal with infinity as special better - or remove. +// + +#ifndef BOOST_STATS_UNIFORM_HPP +#define BOOST_STATS_UNIFORM_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm +// http://mathworld.wolfram.com/UniformDistribution.html +// http://documents.wolfram.com/calculationcenter/v2/Functions/ListsMatrices/Statistics/UniformDistribution.html +// http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29 + +#include +#include +#include + +#include + +namespace boost{ namespace math +{ + namespace detail + { + template + inline bool check_uniform_lower( + const char* function, + RealType lower, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(lower)) + { // any finite value is OK. + return true; + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Lower parameter is %1%, but must be finite!", lower, pol); + return false; + } + } // bool check_uniform_lower( + + template + inline bool check_uniform_upper( + const char* function, + RealType upper, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(upper)) + { // Any finite value is OK. + return true; + } + else + { // Not finite. + *result = policies::raise_domain_error( + function, + "Upper parameter is %1%, but must be finite!", upper, pol); + return false; + } + } // bool check_uniform_upper( + + template + inline bool check_uniform_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) + { + if((boost::math::isfinite)(x)) + { // Any finite value is OK + return true; + } + else + { // Not finite.. + *result = policies::raise_domain_error( + function, + "x parameter is %1%, but must be finite!", x, pol); + return false; + } + } // bool check_uniform_x + + template + inline bool check_uniform( + const char* function, + RealType lower, + RealType upper, + RealType* result, const Policy& pol) + { + if((check_uniform_lower(function, lower, result, pol) == false) + || (check_uniform_upper(function, upper, result, pol) == false)) + { + return false; + } + else if (lower >= upper) // If lower == upper then 1 / (upper-lower) = 1/0 = +infinity! + { // upper and lower have been checked before, so must be lower >= upper. + *result = policies::raise_domain_error( + function, + "lower parameter is %1%, but must be less than upper!", lower, pol); + return false; + } + else + { // All OK, + return true; + } + } // bool check_uniform( + + } // namespace detail + + template > + class uniform_distribution + { + public: + typedef RealType value_type; + typedef Policy policy_type; + + uniform_distribution(RealType l_lower = 0, RealType l_upper = 1) // Constructor. + : m_lower(l_lower), m_upper(l_upper) // Default is standard uniform distribution. + { + RealType result; + detail::check_uniform("boost::math::uniform_distribution<%1%>::uniform_distribution", l_lower, l_upper, &result, Policy()); + } + // Accessor functions. + RealType lower()const + { + return m_lower; + } + + RealType upper()const + { + return m_upper; + } + private: + // Data members: + RealType m_lower; // distribution lower aka a. + RealType m_upper; // distribution upper aka b. + }; // class uniform_distribution + + typedef uniform_distribution uniform; + + #ifdef __cpp_deduction_guides + template + uniform_distribution(RealType)->uniform_distribution::type>; + template + uniform_distribution(RealType,RealType)->uniform_distribution::type>; + #endif + + template + inline const std::pair range(const uniform_distribution& /* dist */) + { // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(-max_value(), max_value()); // - to + 'infinity'. + // Note RealType infinity is NOT permitted, only max_value. + } + + template + inline const std::pair support(const uniform_distribution& dist) + { // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + return std::pair(dist.lower(), dist.upper()); + } + + template + inline RealType pdf(const uniform_distribution& dist, const RealType& x) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::pdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + + if((x < lower) || (x > upper) ) + { + return 0; + } + else + { + return 1 / (upper - lower); + } + } // RealType pdf(const uniform_distribution& dist, const RealType& x) + + template + inline RealType cdf(const uniform_distribution& dist, const RealType& x) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + if (x < lower) + { + return 0; + } + if (x > upper) + { + return 1; + } + return (x - lower) / (upper - lower); // lower <= x <= upper + } // RealType cdf(const uniform_distribution& dist, const RealType& x) + + template + inline RealType quantile(const uniform_distribution& dist, const RealType& p) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks + if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)",lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", p, &result, Policy())) + { + return result; + } + if(p == 0) + { + return lower; + } + if(p == 1) + { + return upper; + } + return p * (upper - lower) + lower; + } // RealType quantile(const uniform_distribution& dist, const RealType& p) + + template + inline RealType cdf(const complemented2_type, RealType>& c) + { + RealType lower = c.dist.lower(); + RealType upper = c.dist.upper(); + RealType x = c.param; + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_uniform_x("boost::math::cdf(const uniform_distribution<%1%>&, %1%)", x, &result, Policy())) + { + return result; + } + if (x < lower) + { + return 1; + } + if (x > upper) + { + return 0; + } + return (upper - x) / (upper - lower); + } // RealType cdf(const complemented2_type, RealType>& c) + + template + inline RealType quantile(const complemented2_type, RealType>& c) + { + RealType lower = c.dist.lower(); + RealType upper = c.dist.upper(); + RealType q = c.param; + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", lower, upper, &result, Policy())) + { + return result; + } + if(false == detail::check_probability("boost::math::quantile(const uniform_distribution<%1%>&, %1%)", q, &result, Policy())) + { + return result; + } + if(q == 0) + { + return upper; + } + if(q == 1) + { + return lower; + } + return -q * (upper - lower) + upper; + } // RealType quantile(const complemented2_type, RealType>& c) + + template + inline RealType mean(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::mean(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (lower + upper ) / 2; + } // RealType mean(const uniform_distribution& dist) + + template + inline RealType variance(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::variance(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (upper - lower) * ( upper - lower) / 12; + // for standard uniform = 0.833333333333333333333333333333333333333333; + } // RealType variance(const uniform_distribution& dist) + + template + inline RealType mode(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::mode(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + result = lower; // Any value [lower, upper] but arbitrarily choose lower. + return result; + } + + template + inline RealType median(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::median(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return (lower + upper) / 2; // + } + template + inline RealType skewness(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::skewness(const uniform_distribution<%1%>&)",lower, upper, &result, Policy())) + { + return result; + } + return 0; + } // RealType skewness(const uniform_distribution& dist) + + template + inline RealType kurtosis_excess(const uniform_distribution& dist) + { + RealType lower = dist.lower(); + RealType upper = dist.upper(); + RealType result = 0; // of checks. + if(false == detail::check_uniform("boost::math::kurtosis_execess(const uniform_distribution<%1%>&)", lower, upper, &result, Policy())) + { + return result; + } + return static_cast(-6)/5; // -6/5 = -1.2; + } // RealType kurtosis_excess(const uniform_distribution& dist) + + template + inline RealType kurtosis(const uniform_distribution& dist) + { + return kurtosis_excess(dist) + 3; + } + + template + inline RealType entropy(const uniform_distribution& dist) + { + using std::log; + return log(dist.upper() - dist.lower()); + } + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_UNIFORM_HPP + + + diff --git a/libcxx/src/third-party/boost/math/distributions/weibull.hpp b/libcxx/src/third-party/boost/math/distributions/weibull.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/distributions/weibull.hpp @@ -0,0 +1,442 @@ +// 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_STATS_WEIBULL_HPP +#define BOOST_STATS_WEIBULL_HPP + +// http://www.itl.nist.gov/div898/handbook/eda/section3/eda3668.htm +// http://mathworld.wolfram.com/WeibullDistribution.html + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost{ namespace math +{ +namespace detail{ + +template +inline bool check_weibull_shape( + const char* function, + RealType shape, + RealType* result, const Policy& pol) +{ + if((shape <= 0) || !(boost::math::isfinite)(shape)) + { + *result = policies::raise_domain_error( + function, + "Shape parameter is %1%, but must be > 0 !", shape, pol); + return false; + } + return true; +} + +template +inline bool check_weibull_x( + const char* function, + RealType const& x, + RealType* result, const Policy& pol) +{ + if((x < 0) || !(boost::math::isfinite)(x)) + { + *result = policies::raise_domain_error( + function, + "Random variate is %1% but must be >= 0 !", x, pol); + return false; + } + return true; +} + +template +inline bool check_weibull( + const char* function, + RealType scale, + RealType shape, + RealType* result, const Policy& pol) +{ + return check_scale(function, scale, result, pol) && check_weibull_shape(function, shape, result, pol); +} + +} // namespace detail + +template > +class weibull_distribution +{ +public: + using value_type = RealType; + using policy_type = Policy; + + explicit weibull_distribution(RealType l_shape, RealType l_scale = 1) + : m_shape(l_shape), m_scale(l_scale) + { + RealType result; + detail::check_weibull("boost::math::weibull_distribution<%1%>::weibull_distribution", l_scale, l_shape, &result, Policy()); + } + + RealType shape()const + { + return m_shape; + } + + RealType scale()const + { + return m_scale; + } +private: + // + // Data members: + // + RealType m_shape; // distribution shape + RealType m_scale; // distribution scale +}; + +using weibull = weibull_distribution; + +#ifdef __cpp_deduction_guides +template +weibull_distribution(RealType)->weibull_distribution::type>; +template +weibull_distribution(RealType,RealType)->weibull_distribution::type>; +#endif + +template +inline std::pair range(const weibull_distribution& /*dist*/) +{ // Range of permissible values for random variable x. + using boost::math::tools::max_value; + return std::pair(static_cast(0), max_value()); +} + +template +inline std::pair support(const weibull_distribution& /*dist*/) +{ // Range of supported values for random variable x. + // This is range where cdf rises from 0 to 1, and outside it, the pdf is zero. + using boost::math::tools::max_value; + using boost::math::tools::min_value; + return std::pair(min_value(), max_value()); + // A discontinuity at x == 0, so only support down to min_value. +} + +template +inline RealType pdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::pdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + if(shape == 1) + { + return 1 / scale; + } + if(shape > 1) + { + return 0; + } + return policies::raise_overflow_error(function, 0, Policy()); + } + result = exp(-pow(x / scale, shape)); + result *= pow(x / scale, shape - 1) * shape / scale; + + return result; +} + +template +inline RealType logpdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::logpdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + if(x == 0) + { + if(shape == 1) + { + return log(1 / scale); + } + if(shape > 1) + { + return 0; + } + return policies::raise_overflow_error(function, 0, Policy()); + } + + result = log(shape) - shape * log(scale) + log(x) * (shape - 1) - pow(x / scale, shape); + + return result; +} + +template +inline RealType cdf(const weibull_distribution& dist, const RealType& x) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, x, &result, Policy())) + return result; + + result = -boost::math::expm1(-pow(x / scale, shape), Policy()); + + return result; +} + +template +inline RealType quantile(const weibull_distribution& dist, const RealType& p) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, p, &result, Policy())) + return result; + + if(p == 1) + return policies::raise_overflow_error(function, 0, Policy()); + + result = scale * pow(-boost::math::log1p(-p, Policy()), 1 / shape); + + return result; +} + +template +inline RealType cdf(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::cdf(const weibull_distribution<%1%>, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_weibull_x(function, c.param, &result, Policy())) + return result; + + result = exp(-pow(c.param / scale, shape)); + + return result; +} + +template +inline RealType quantile(const complemented2_type, RealType>& c) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::quantile(const weibull_distribution<%1%>, %1%)"; + + RealType shape = c.dist.shape(); + RealType scale = c.dist.scale(); + RealType q = c.param; + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + if(false == detail::check_probability(function, q, &result, Policy())) + return result; + + if(q == 0) + return policies::raise_overflow_error(function, 0, Policy()); + + result = scale * pow(-log(q), 1 / shape); + + return result; +} + +template +inline RealType mean(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::mean(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + + result = scale * boost::math::tgamma(1 + 1 / shape, Policy()); + return result; +} + +template +inline RealType variance(const weibull_distribution& dist) +{ + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + static const char* function = "boost::math::variance(const weibull_distribution<%1%>)"; + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + result = boost::math::tgamma(1 + 1 / shape, Policy()); + result *= -result; + result += boost::math::tgamma(1 + 2 / shape, Policy()); + result *= scale * scale; + return result; +} + +template +inline RealType mode(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std function pow. + + static const char* function = "boost::math::mode(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + if(shape <= 1) + return 0; + result = scale * pow((shape - 1) / shape, 1 / shape); + return result; +} + +template +inline RealType median(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std function pow. + + static const char* function = "boost::math::median(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); // Wikipedia k + RealType scale = dist.scale(); // Wikipedia lambda + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + using boost::math::constants::ln_two; + result = scale * pow(ln_two(), 1 / shape); + return result; +} + +template +inline RealType skewness(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::skewness(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + { + return result; + } + + RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy()); + RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy()); + RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy()); + RealType d = pow(g2 - g1 * g1, RealType(1.5)); + + result = (2 * g1 * g1 * g1 - 3 * g1 * g2 + g3) / d; + return result; +} + +template +inline RealType kurtosis_excess(const weibull_distribution& dist) +{ + BOOST_MATH_STD_USING // for ADL of std functions + + static const char* function = "boost::math::kurtosis_excess(const weibull_distribution<%1%>)"; + + RealType shape = dist.shape(); + RealType scale = dist.scale(); + + RealType result = 0; + if(false == detail::check_weibull(function, scale, shape, &result, Policy())) + return result; + + RealType g1 = boost::math::tgamma(1 + 1 / shape, Policy()); + RealType g2 = boost::math::tgamma(1 + 2 / shape, Policy()); + RealType g3 = boost::math::tgamma(1 + 3 / shape, Policy()); + RealType g4 = boost::math::tgamma(1 + 4 / shape, Policy()); + RealType g1_2 = g1 * g1; + RealType g1_4 = g1_2 * g1_2; + RealType d = g2 - g1_2; + d *= d; + + result = -6 * g1_4 + 12 * g1_2 * g2 - 3 * g2 * g2 - 4 * g1 * g3 + g4; + result /= d; + return result; +} + +template +inline RealType kurtosis(const weibull_distribution& dist) +{ + return kurtosis_excess(dist) + 3; +} + +template +inline RealType entropy(const weibull_distribution& dist) +{ + using std::log; + RealType k = dist.shape(); + RealType lambda = dist.scale(); + return constants::euler()*(1-1/k) + log(lambda/k) + 1; +} + +} // namespace math +} // namespace boost + +// This include must be at the end, *after* the accessors +// for this distribution have been defined, in order to +// keep compilers that support two-phase lookup happy. +#include + +#endif // BOOST_STATS_WEIBULL_HPP + + diff --git a/libcxx/src/third-party/boost/math/filters/daubechies.hpp b/libcxx/src/third-party/boost/math/filters/daubechies.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/filters/daubechies.hpp @@ -0,0 +1,91 @@ +/* + * Copyright Nick Thompson, John Maddock 2020 + * 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_FILTERS_DAUBECHIES_HPP +#define BOOST_MATH_FILTERS_DAUBECHIES_HPP +#include +#include +#include + +namespace boost::math::filters { + +template +constexpr std::array daubechies_scaling_filter() +{ + static_assert(p < 20, "Filter coefficients only implemented up to 19."); + if constexpr (p == 1) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.70710678118654752440084436210484903928483593768847403658833986899536623923), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.70710678118654752440084436210484903928483593768847403658833986899536623923) }; + } + if constexpr (p == 2) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.48296291314453414337487159986444868381695241950420227520117153815521160699), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.83651630373780790557529378091687320345937038834843929349534147265289472661), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.22414386804201338102597276224040035546788351818427176138716833084015463224), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12940952255126038117444941881202416417453445065996525690700160365752848737) }; + } + if constexpr (p == 3) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.33267055295008261599851158913900563001292339924506835970847057855179372371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.80689150931109257649449360408871349051929739499482361816509206360348683533), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.45987750211849157009515194214761672080811017743149230664338678024864033563), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.135011020010254588696389906699374480562219845223781191975686255357062768), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.085441273882026661692819169181773311536197638988086629763517489805067820106), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.035226291885709536602740664715510029327758387917431610398934060748942171898) }; + } + if constexpr (p == 4) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.23037781330889650086329118304407085000161524824830929779109684402827164374), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.71484657055291564708992195527399260370760840109930817584501100344262504653), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63088076792985890788171633830061522020322292267719511740574732848435336141), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.027983769416859854211413747180075385411987320224491752840033582653363093001), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.18703481171909308407957067278908141958454417437458009120577708759399258629), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.030841381835560763627219362534959050170314821720034033418212190936063233775), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.032883011666885199735407513549244388664541941137549712597272784076733820371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.01059740178506903210488320852402722918109996490637641983484974272995894807) }; + } + if constexpr (p == 5) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16010239797419291448072374802042073365054412462505783277256992020754721449), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60382926979718967054011930652506210750742216310169869879692833603686283702), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.72430852843777292772807124410221864076875621823200737257673350480409279922), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13842814590132073150539714633902469731410579117395610226946522108855217638), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.24229488706638203186257137947461636199149080806261859839137269134106547424), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.032244869584638374648479755062134928313564984163798472254342681319811609232), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.077571493840045713523130489388601819806230994520125279832101462389556715934), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0062414902127982742741905191129201929707635571656876073234174353259085160535), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012580751999081999468509739931775792949204591626097850201692327064765016178), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0033357252854737712779981834158173557476365247423053150997064285156713511141) }; + } + if constexpr (p == 6) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.11154074335010946362132391724092343904253959198442167590823604579765159644), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4946238903984530856772041768778555886377863828962743623531834526188698465), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.75113390802109535067893449843973168558025478333826120097304206594799266889), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31525035170919762908598965481092639664951992351729452444041638160625244927), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22626469396543982007631450066090346567054015397289699401434877917897027718), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12976686756726193556228960587658546084523374922358147015993106558172041337), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.097501605587323049102343552538125342339830747495255142798931931211277981638), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027522865530305728625540839504193213657387587830434543214942028790000299266), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.031582039317486029565079080699848669057479532373148423375114649352606045848), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00055384220116149613925191839804650122061102627738649642954765245675247527348), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0047772575109455106396359752468207070502305012165814342975932545700203152873), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0010773010853084795648526216095872000352352336093344196898185808947884177076) }; + } + if constexpr (p == 7) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.077852054085009179019963521957893748379183052927955684387029371799629765558), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3965393194819173065390003909368428563587151149333287401110499620754878153), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.72913209084623511991694307033928205171796606119013637826977157495535702874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4697822874051931224715911609744517386817913056787359532392529141008369217), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.14390600392856497540506836221304600179527357054990848344017530142299184121), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22403618499387498263814042023325096447578308967732465526650953072415165804), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.071309219266830264750876570501129048227113274514123146595751132202029061555), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.080612609151083071912922480359381905858238209656294890581392184772265275649), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.038029936935014413579592061601858035854461969384678698982831227165741061737), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.016574541630666880654107674891702654792045043948207137052392725487143490786), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.012550998556099840612989886034187779572894740460487100384118183441674102341), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00042957797292136652113212912281973222282353503969424097429463669354494184942), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0018016407040474909152682629127395509625856514696410906253238648145908160214), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00035371379997452024844629583630642543109590600595200400125242756452643355644) }; + } + if constexpr (p == 8) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.054415842243104009955009405202999355035995542947330503977292808677193622648), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31287159091429997065916237550571772194973197403702291856987124211531149794), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.67563073629728980680780076704718314998691159063363642277667598381172874696), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.58535468365420671277126552004509819443032666780533690557071753488957052267), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.015829105256349305667380547876466304157744711545028265597353359560312661545), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.28401554296154692651620313237416473246843501248714517935992048090937585953), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00047248457391328277036059000982589498619480112887700746440840960229954465856), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.12874742662047845885702928750970838430226015755564887955770001654977066319), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.017369301001807546169616148868095983114130865294883943169773153885119747929), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.044088253930794751506763723238963501897518391901109964727503919854754335188), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013981027917398281648722930572633451442395595329343471691463681144262938301), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0087460940474057767163827432464756401804021470811406767426867470261177584378), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0048703529934515743104221815571098240166349785121570037647362085321921707468), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00039174037337694704629808035732377626752293500738904937244926946775919522535), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00067544940645056936636954757387929912184896300135584321036170773750596688963), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00011747678412476953373062823169889094440866939503115039276200135351481307347) }; + } + if constexpr (p == 9) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.038077947363878346588697658879551184487717144962784174766471924848268047975), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.24383467461259035373204158164928441552636110856092313614290881035764194652), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60482312369011111190307686743423617089595627118961175653337135326621948137), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.6572880780513005380782126390451732140305858669245918854436034065588449216), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13319738582500757619095494589979555369217807684336611361543468378391202935), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.29327378327917490880640319524219873104389616285899068257251128264977749451), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.096840783222976460513508133537696602248254581045990996794712676084296381974), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14854074933810638013507271750604230247912585772806030607716493946005155866), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.03072568147933337921231740072037882714105805024670744781503060505807447087), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.067632829061329973675642274829719015925787908713537399007483312098453778674), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00025094711483145195758718974998855433151762719937096333218341646914339924457), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0223616621236790972053737827026909524185564668830885375472181623365153339), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0047232047577513972779257078482424654057295149126279380187585268565784573968), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0042815036824634298344967950023145318764811818114632883748604550376910299936), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0018476468830562264766191294911256770511210813596003181607325150457467472311), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00023038576352319596720521639282454216929406620524637119722600068668037624505), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00025196318894271013697498868428786066072821815434780282141342653512309743183), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.934732031627159948068988306589150707782477055517013507359938155440548714e-05) }; + } + if constexpr (p == 10) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026670057900555553586617448771308582771924982908512899327799757762165073565), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1881768000776914890208929736790939942702546758640393484348595444098866088), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.52720118893172558648174482795950819249814026808402234453185494714513982787), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.68845903945360356574187178254923585397713640424073395372796811583990344659), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.28117234366057746074872699844558928762438888590261504138315439518337480745), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.24984642432731537941610189792077910005646697371320737150131215971067630043), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.1959462743773770435042992543190981318766776476382778474396781876838561782), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.12736934033579326008267723320140097707861774804222459955630975237390670344), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.093057364603572351160352289835452732269429179989469258680639741022454756675), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.071394147166397087145336093076050647672926119837021509175237563479658240953), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.029457536821875812858283237601418391993882005160649487797696542831849016741), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.033212674059341001739763653182159128979783374132670960433233512708331299782), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0036065535669561696554232914171334032995173505186189947627306122912865631829), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.01073317548333057504431811410651364448111548781143923213370333937093436962), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0013953517470529011657893184479577075676605428556885524267211177234294314032), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0019924052951850561171587422426406432117625553655141052800679364782486446064), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00068585669495971162656137098192657141966250433367869205162119035617579793186), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00011646685512928545095148097102589918915274618543475973628192350744688585366), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 9.3588670320069591334050130342228543996884562152972764435218739396771960302e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.3264202894521244812436675312266833057492409606058297564006746194667132319e-05) }; + } + if constexpr (p == 11) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.018694297761471084025435729395619757289677744559219585432866920854463984821), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1440670211506245127951915849361001143023718967556239604318852482176121098), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.4498997643560453347688940373853603677806895378648933474599655795863440433), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.68568677491620051112093863169630979359402049645677034950515890174507509031), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.41196436894790746292593964857106673074304004101878453156972425113333086269), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.16227524502749036224058272699855115407442643242121302096496674298183214991), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.27423084681794696120210094528352666286480895217751782219057783900502396695), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.066043588196683191900614578881263026567531421689407915411134572260157270027), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14981201246637849640665626170441932985882724202674846537969095942150753335), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.046479955116684187271617225890237445772232609668482607474503209875958431693), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.06643878569502520527899215536971203191819566896079739622858574023360652697), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.031335090219046076030947984083031445363581056808800319649364455090954740139), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.020840904360181063022948112556564910151577618327347156911266922007670347371), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.015364820906201599426198116099588227440143264957730001202058486279377738507), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0033408588730144456060908086179824061019306583594991908456567317772540817346), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0049284176560590411231707397417082736902855477299158024183974580101937664126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00030859285881514316517545907262789533071802166050784885819215622760236544448), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00089302325066626461339008246226486539898795198786207287931333582240853430266), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00024915252355282349887122168726668010882211993028554253819713924909320282452), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.4439074699368471673578568795768321919366785256007939780436889201682941436e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -3.4634984186984995541280851599740432145064880482334580359436013556794022457e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.4942742772365100954156482823101309164104979873837534605717417484340085911e-06) }; + } + if constexpr (p == 12) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013112257957229517506746090888933280656655106419313250077482807981375136912), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1095662728211851546057045050248905426075680503066774046383657434145947162), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.37735513521421265709282126048792061490109417060575263347058391156288509976), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.65719872257930708930276112866411698342502032899884121413942819500193920417), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.51588647842781560875603264805430327006776930870360900561276472986750316737), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.04476388565377462666762747311540166529284543631505924139071704101179655136), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.31617845375278553686480293534780310985088390325473643895742033716004955521), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.02377925725606972768399754609133225784553366558331741152482612716033502819), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.18247860592757967985404361161892417102947714480963026983290112608341065294), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0053595696743521503282762767297683322888626651841927058216363426180926941677), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.096432120096507082026503205343224841274308801430452205143464027486190605026), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.010849130255822184380890102377481521886616305676033346593225122643407774116), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.041546277495084440739270946819065748645135322213883748612870789941361661575), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012218649069748280719987982664715677129824660931165581753448110455020838418), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.012840825198300683294660344718947284962061098323140976332752255734850878212), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0067114990087955091777670270682156724506481121858564567403794553368864243964), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.002248607240995237599950865211267234018343199786146177099262010279010074457), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0021795036186277604715989033795841711878400752918605712649809429870507326048), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.5451282125095955665004303993271107291117705688973566307145520074184844383e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00038865306282093144358972888377959817919174885734201775234360961313833182126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.8504109208204324208216459615537265987383221514719328080154430300199184715e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.4241545757030784029789153205317195804237783626642822393775322072922884523e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.2776952219379766587140463626166208873759609414394287560553539204265370227e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.529071758068510902712239164522901223197615439660340672602696416832185426e-06) }; + } + if constexpr (p == 13) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0092021335389623679729701634756441846675341719164165623860097030371191217305), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.082861243872902779644320271312304664052081133328901350725142774200948295461), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.31199632216043806339607841122140496939466835289671803171603901730851565412), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.61105585115878765282119951367441805620736126760182394385265829401520403811), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.58888957043121890807103953473953339276659863828128360422355734065024957534), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.08698572617964723731023739838087494399231884076619701250882016643780541724), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.31497290771138863299816982559322825828768884506787890259503068186813077354), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12457673075081525894138083360212601807927392951736347195720693207526097203), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.17947607942933984323484500723393690135819662562441333930428814546967642382), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.072948933656777163809028306104776619833259290268798735536279632846163669865), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.10580761818793432645096673041964648494788607548012366582323605107782068188), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.026488406475343694639639122480347857264196048442976970162642241213351984244), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.05613947710028342886214501998387331119988378792543100244737056253966757901), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0023799722540590788114651709585542083580943946120519348684751392707093052796), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.023831420710323649032064030677577391342529227176362262740772986334105772526), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0039239414487974162433163702208155265588247466234514040439184072878721741534), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0072555894016175661945183933005026988989735296796466836952698286726005062515), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0027619112346568621780145762660984459953500933305018180249663164832661496432), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0013156739118922989366138353705936433760604125926536523072381245947457012192), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00093232613086726338622265178025485141009180882998019523079915692711270149142), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.9251525126289461921409573878665962101037782993888235008400944566113947075e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00016512898855650548946166877092380007558985482146597767033478014935998742089), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0678537579325493466494832285754762366004282172379005631282307485528301752e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.0441930571408137081707149910805969516707064362173281696414740684382080067e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.7004164793608683256501951650617713216503835829709585565680597113341224593e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.2200350984548646917364243548431769767470521552435570015319010534889500617e-07) }; + } + if constexpr (p == 14) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0064611534600879478181663974486228142723271594192011992181014041682131963958), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.062364758849398898327985667584348774283053336934076671646025188061380759653), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.25485026779262135366590778867782866861870424163671374437800842023823271874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.55430561794089383599268314498511548440782698309516346096839977753222684278), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63118784910485677955766171353581723486239524565700172897888095924843364054), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21867068775890652149174759182175170517657743212704320590302732335253422232), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.27168855227874804141421924761811710946048824656833308143118966692384906639), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.21803352999327604475555588127023119119752406694706047527471270417978599672), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13839521386480659107399396900215737139899004632296861190591199023906568404), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.13998901658446070124929431622711634403282215556143261813336838173012766117), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.086748411568169689045608220667277953829791495395175036574929644598228933263), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.071548955504046130735841451151738079909580696731295380999909130933544719175), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.055237126259216044116188340605334033979138336325116721576711076599596585739), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026981408307912916973990314032151933433757665958072742332843492806013139065), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.030185351540390635187148226234891375737815754066586526248837561937906600698), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0056150495303569591332183713676914986374572972039258103876986801691601779992), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.012789493266333408961573307057840792993749038615720583134815345194814152872), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0007462189892683849371817160739181780971958187988813302900435487508701832207), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.003849638868022187445786349316095551774096818508285700493058915725327777667), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0010616910856067618430325667493884111730339415821478308638939395615438824882), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00070802115423552785864429776976171289834718634641815953716700944226680311764), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00038683194731295448210766633980573144273289021078421653799014684260953603847), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.1777245770372597352679795398392589283897265901327301310543237300793962875e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.8755042526975096038734370216280316018903706876518752798827278989286730311e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.0337209184570773946614073425948145862692725094907448506914430590564776387e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.3897049017813941152540425613671698293230853608008257181510491943726938635e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.7249946753678127698857126927417985235878947098673565769107179471945464675e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.7871399683113590763341929384708393438829903099769594469940228456912731758e-07) }; + } + if constexpr (p == 15) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0045385373615788988814593949102116963466636712437887869979165135973061826537), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.046743394892766271891709693348435757765791517002149435131131973437721383622), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.20602386398699573153989150094763072193061385056419309027020472662490156122), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.49263177170813962360677570740299463726172215651309324021601600369752281377), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.64581314035742435817642091201069179964326082874940461810714894789553306679), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3390025354547315276912641143835773918756769491793554669336690115093975569), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.19320413960914542870639905343214717463040900391428638279377549215058972689), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.28888259656696564624841250098223329813114356304353425949712929625629348294), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.065282952848772816922831079198695748820391742855961441259651013056195336897), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.19014671400712298234848931165860205179595012581743366968781560605525428795), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.039666176555790944483843667518962006683817428206837368054497453529283868676), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.11112093603723169336567103246740586088586237621659141205056578840053963186), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.033877143923507686208548178444335237708647446874112653694631959912301278547), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.05478055058450761268913790312581879108609415997422768564244845364080300918), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.025767007328439962585945257542698263922036416348253401383968368254171628001), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.020810050169693081677884834246770001620546579513648990409961661727192610178), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.015083918027835902363292744601703227362448928233056277162339688903695078372), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0051010003604075431697088601855653147248010665273442220555266310691657585506), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0064877345603157449951816831492186908169558456393888264079289674694518478686), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00024175649076162428116672253263001796052299469958145352233294119288913115604), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0019433239803822115417649123325410874410114248655795314014523026178946534131), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00037348235413761699200980942136454146113876309680302566257402267355583112012), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00035956524436246881216496200759098088581942024540840903056274804667283876243), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00015589648992059974794716582412271088162555670596254959152286036304283062436), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.5792699155318936809258624176168559129440423687673407091601197370095004239e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.8133296266047813647553247770784786657914438762937889042672556207530238846e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.3629871817375798031248452104201774721348466558640781871863045015033003361e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.8112704079405770837685109122858411605770859253375078505902906808655395748e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.3168823258816644212015972995176576541661379151211955104166416260677217926e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.1333599133057520290562994602897886019891904508853965121738455950580467421e-08) }; + } + if constexpr (p == 16) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0031892209253477380297695475646459586870670867501314287678758781777869486255), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.034907714323673346410301472240230200092182414305039841461400546477376377996), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16506428348885311789912527305611348115848350023427232402135928290203409966), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.43031272284600381374039254243576846206339704780369867739246462911886492889), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.63735633208378889863198524129960305364985959408141981259677515932255242966), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.44029025688635690003908691635716792885278030351352725787898843221650113068), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.089751089402489642857187180774425974306592474455826601496247184152268478657), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.32706331052791770464629056756891196417572289182288124281417235311673360956), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.027918208133028276682645195950268732043399712191747360415354797624368497971), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21119069394710428872096801632688379009284914261676794392510428265923934071), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027340263752716041364852457572016179654290278195071302202315002681181103625), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.13238830556381039045004741477564933750922878177060279787985490274221256881), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0062397227524748717656745033941200258654446563116787609907614580866382455691), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.075924236044276315821484987439414224615304059461009433519403139995132210368), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.007588974368857737638494890864636995796586975144990925400097160943671446065), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.036888397691730142333526663208945543147187484297067308310640687651290473968), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.010297659640955969411650005800766169005288562658036622088541473449733491006), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.013993768859828731029504518736703297264098402917278689884901007836048645298), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0069900145634139166702842495365172883380578561996464690781157596750271110103), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0036442796214983899321690005409336293870553339733531086688412150466993897338), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0031280233812062688316612025598546787678214719061936081174503608103102062028), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00040789698084971283624174703234060957824319529723105467150713971109834118994), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00094102174935956758892664539536358754077547472167344805092502736794906570513), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00011424152003872239264402280995556629458396843449364726528770914231509741867), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00017478724522533818038017586376607468749860247286153998979719535958918304821), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.1035966214109358351623691505222128119572599819659191439617228139148512866e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.3945668988208893451990783119984019823252735691986753354087079704564463183e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.1336608661276258587588487628865369975194710682037536617578434288137908852e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.0435713423116065015254547372626154048874789306356764715460326802862590987e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -7.3636567854512055120996957197255636465854455458416633274335692328538306759e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.3087840868575458664054127329420061213063067358666555253725448647310885248e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.1093396301007430970005726236034899068362975845916053077453499495253372784e-08) }; + } + if constexpr (p == 17) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0022418070010373128535359626770744369140621918805603707332505311813341919259), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.025985393703606043389148645917207883154739445248782412943999482768766372542), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.1312149033078244065775506231859069960144293609259978530067004394590336311), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.37035072415264115044925481907218864494770788768968038236504259357952962858), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.61099661568462281818866788676793720827370938933587262913717839049083529043), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.51831576405693783932545385280859680462168171977184164024399049868328890005), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027314970403293635004312507191475864803504698189645630036729428228327122309), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.32832074836396173609096653407250617675815976981515580246791305268967637817), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12659975221588270287446791109338255050539662601040861621037283235916492881), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.19731058956501099278540470447819301425514224141356469171222842260045667421), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.10113548917747027215096998564334348021966225454996648761094379629310502982), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.12681569177828631109485711286623316803847921859150170657321374899495682695), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.057091419631676927289112394786513823241611608698453470539901446405938289849), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.081105986654160885079658857485554292010243641909544991940206782277507046299), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.022312336178103795953391360595348137562322421140936892440208691931826899684), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.04692243838926973733300897059211400507138768125498030602878439278261681888), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0032709555358192937816553602221774944520695259580616093928092757512244970215), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.022733676583946270318456162447884489699067137413383394980248641327563508924), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.003042989981354637068592482637907206078633395457225096588287881355853146664), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0086029215203228548317137064132436599179267362842717306119209867025723028123), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0029679966915260948728064850600080382699594638465483789950441950342910257421), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0023012052421535456243020598690384236042419766801894474760647649372848372532), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0014368453048029761262228904029803849035036745307299358095614347112123643258), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0003281325194098379713954444017520115075812402442728749700195651589580752544), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00043946542776864367783856775273178416322892493197388921794659107576228639092), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.561010956654845882729891210949920221664082061531909655178413745234158599e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.2048032024533918390954825762821898661362730496367643386895936421343224507e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.3186813798745950844820682057062775721066951740918953385307347893104278256e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 6.9906009850767512732045497008553786277627585859020579640274813805087794281e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -4.5059424772229881941022682063783121297135726007164999449184166870668358606e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.016549609994557415605207594879939763476168705217646897702706189847154081e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 2.9577009333168567549799052588161513678703456289243173073546394956952199848e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.4239484460026801787870712969228770684103109422227996225931334161777920896e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 7.2674929685616081108797674414090350341585817197897910888920464080702904824e-09) }; + } + if constexpr (p == 18) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0015763102184407604315407449299397777476707537109916603636844298618471400136), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.019288531724146377059213917158290524199546670252884975722367148333214257583), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.10358846582242359622419104919372535964706965552202416729762241846965639407), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.3146789413370316990571998255652579931786706190489374509491307510367406906), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.57182680776660722348185893709006234193936737431309305612953240480326532941), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.5718016548886513352891119994065965025668047882818525060759395264214055574), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14722311196992814157509772710810723125578641073557013878016771358441101668), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.29365404073655874424790309949811507239357107290350532396617523080121257803), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.21648093400514297112376786256682714714379372356694924083886923936637850636), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.14953397556537778935093017389136672088048166918937656102619430719129024846), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.16708131276325740451493181399501347453242056463539880831522506333701390259), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.092331884150846280604293725586594597314318480001445696120745084674620649946), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.10675224665982848559322005816149848613852664046241120839177020546784793523), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.06488721621190544281947577955141911463129382116634147846137149845158777673), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.057051247738536884120907688464996222605962261204310385246006764232075504463), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.044526141902982324715561435597446534929714778914398335927550346682023149009), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.023733210395860001032752095826652161101975193307134902330715657901430091468), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.026670705926470590299879086316720203432078959999360728133634715203759565359), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0062621679543057074852360931444978825019903252047450131902680523152575205897), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.013051480946612001772776364476008071697551910545075716666061335803862913986), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00011863003385811746573017415921618190845448994174523174051856157299661793944), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0049433436054667381306655295168029748342996383133664777652952032600306770112), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0011187326669924970728006588552386501823180604825849701455126871198522790015), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0013405962983361066295175672282515836098230445246859866403239426912072388874), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00062846568296514571256194498854208382175510227963015828743496528807647838152), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0002135815619103406884039052814341926025873200325996466522543440510602714976), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00019864855231174794857982454163624895549277978802640178761396052157321846575), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.5359171235347246750697703358767171937004724270215132365872881022095732925e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.7412378807400381810922081380353939523042926157939850307313638513284983136e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -8.5206025374466952039192549116555230224375969562263765123059170652407353738e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -3.3326344788858218887824520333410368273115059077964984398293372795640596047e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.7687129836276154558763287307553751764125013591140588154531006192349912666e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -7.6916326898851761460001528785395984058173975881565251167699086518741626737e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.1760987670282316984509823565612925613475797776953969535281413678099558364e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0688358630451748009354782949339753724501797878945744929305701163444205366e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -2.5079344549485982671951731831471267318063171448682758199414032678582329327e-09) }; + } + if constexpr (p == 19) { + return {BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0011086697631817105710991541952097151642452996777734359321354552903838392437), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.014281098450764397374398891529501992347456634421636659578707159911077107554), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.081278113265459550652963067849016248398449799710286203664977268640601914766), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.26438843174089678467481003802894268738623778072119207184173858147735135325), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.5244363774646549153360575975484064626044633641048072116393160236280782601), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.60170454912753789488670771359218026205365656395859632933139314339208321996), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.26089495265103882928724566753105283241726731013019077399252138987658244676), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.22809139421548264637463257760546372070937872370864259095348224177661957967), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.2858386317558262418545975695028984237217356095588335149922119373572946758), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.074652269708103266367634331118788190058658661497319096563653999513477365762), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.21234974330627848880906085670598241970770742008788394484169086980366838817), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.033518541902302878681693884187857315069778450752389668198140325857348144255), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.14278569503873657497796027316261128129984977061524285086275624334185303587), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.027584350625628668750147435201621986553744745969634230807628183098383677126), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.086906755555812232488476454288084430347852080024681927596403529749277245343), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.026501236250123040899018358436763873610750680176867478081713456471923315261), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.045674226277230908056454442142957960179389357321156300508801097842329883502), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.021623767409585047130329842571723723543180970678587525425710208194990717941), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.019375549889176127646370943544579998144968850958758255464069637242167682526), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.013988388678535141632504012352486625219168138674530958368083666866969990669), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0058669222810121747265844934360543737738146083408087581773727651715064285159), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0070407473671052431530145112074006201094016898976653830782293980831623467743), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.0007689543592575483559749139148673955163477947086039406129546422516486233949), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.0026875518007015820039573638550703986365340389209824782901702671996059483895), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.000341808653458595776565165729046380813521421484881951725779403154942704075), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 0.00073580252050543520702604819053972818751831757927799048581894949173298761722), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00026067613567862800573183151308975227903839393620735634086135475594271631675), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -0.00012460079173415877534497844089016539903173414133419809047575920469834920407), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 8.7112704672199229654168623881911282684129338932820835177294434200975612019e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 5.105950487073886053049222809934231573687367992106282669389264164311557866e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.6640176297154944546206777198991986303336756088120181087391449229369242509e-05), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 3.0109643162965263396953344547259436326457989381624271688513825000813231431e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.5319314766911930639318323810866360312031230327234774636241410593622067271e-06), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -6.862755657769142701883554613486732854452740752771392411758418826691795609e-07), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 1.4470882987978445420782198632916154205516735740713678343161676502124977734e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 4.6369377757826042234308577282109488988717482910859622966493207002061571346e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, -1.116402067035825816390504769142472586464975799284473682246076559584239149e-08), BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits::digits, 8.6668488389976193503230135407821246272897421902730593191228406494140940156e-10) }; + } +} + +template +std::array daubechies_wavelet_filter() { + std::array g; + auto h = daubechies_scaling_filter(); + for (size_t i = 0; i < g.size(); i += 2) + { + g[i] = h[g.size() - i - 1]; + g[i+1] = -h[g.size() - i - 2]; + } + return g; +} + +} // namespaces +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/barycentric_rational.hpp b/libcxx/src/third-party/boost/math/interpolators/barycentric_rational.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/barycentric_rational.hpp @@ -0,0 +1,99 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + * + * Given N samples (t_i, y_i) which are irregularly spaced, this routine constructs an + * interpolant s which is constructed in O(N) time, occupies O(N) space, and can be evaluated in O(N) time. + * The interpolation is stable, unless one point is incredibly close to another, and the next point is incredibly far. + * The measure of this stability is the "local mesh ratio", which can be queried from the routine. + * Pictorially, the following t_i spacing is bad (has a high local mesh ratio) + * || | | | | + * and this t_i spacing is good (has a low local mesh ratio) + * | | | | | | | | | | + * + * + * If f is C^{d+2}, then the interpolant is O(h^(d+1)) accurate, where d is the interpolation order. + * A disadvantage of this interpolant is that it does not reproduce rational functions; for example, 1/(1+x^2) is not interpolated exactly. + * + * References: + * Floater, Michael S., and Kai Hormann. "Barycentric rational interpolation with no poles and high rates of approximation." +* Numerische Mathematik 107.2 (2007): 315-331. + * Press, William H., et al. "Numerical recipes third edition: the art of scientific computing." Cambridge University Press 32 (2007): 10013-2473. + */ + +#ifndef BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_HPP +#define BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_HPP + +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ + +template +class barycentric_rational +{ +public: + barycentric_rational(const Real* const x, const Real* const y, size_t n, size_t approximation_order = 3); + + barycentric_rational(std::vector&& x, std::vector&& y, size_t approximation_order = 3); + + template + barycentric_rational(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order = 3, typename std::enable_if::value>::type* = nullptr); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + std::vector&& return_x() + { + return m_imp->return_x(); + } + + std::vector&& return_y() + { + return m_imp->return_y(); + } + +private: + std::shared_ptr> m_imp; +}; + +template +barycentric_rational::barycentric_rational(const Real* const x, const Real* const y, size_t n, size_t approximation_order): + m_imp(std::make_shared>(x, x + n, y, approximation_order)) +{ + return; +} + +template +barycentric_rational::barycentric_rational(std::vector&& x, std::vector&& y, size_t approximation_order): + m_imp(std::make_shared>(std::move(x), std::move(y), approximation_order)) +{ + return; +} + + +template +template +barycentric_rational::barycentric_rational(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order, typename std::enable_if::value>::type*) + : m_imp(std::make_shared>(start_x, end_x, start_y, approximation_order)) +{ +} + +template +Real barycentric_rational::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real barycentric_rational::prime(Real x) const +{ + return m_imp->prime(x); +} + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/bezier_polynomial.hpp b/libcxx/src/third-party/boost/math/interpolators/bezier_polynomial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/bezier_polynomial.hpp @@ -0,0 +1,60 @@ +// Copyright Nick Thompson, 2021 +// 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_INTERPOLATORS_BEZIER_POLYNOMIAL_HPP +#define BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_HPP +#include +#include + +#ifdef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES +#warning "Thread local storage support is necessary for the Bezier polynomial class to work." +#endif + +namespace boost::math::interpolators { + +template +class bezier_polynomial +{ +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Z = typename RandomAccessContainer::size_type; + + bezier_polynomial(RandomAccessContainer && control_points) + : m_imp(std::make_shared>(std::move(control_points))) + { + } + + inline Point operator()(Real t) const + { + return (*m_imp)(t); + } + + inline Point prime(Real t) const + { + return m_imp->prime(t); + } + + void edit_control_point(Point const & p, Z index) + { + m_imp->edit_control_point(p, index); + } + + RandomAccessContainer const & control_points() const + { + return m_imp->control_points(); + } + + friend std::ostream& operator<<(std::ostream& out, bezier_polynomial const & bp) { + out << *bp.m_imp; + return out; + } + +private: + std::shared_ptr> m_imp; +}; + +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/bilinear_uniform.hpp b/libcxx/src/third-party/boost/math/interpolators/bilinear_uniform.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/bilinear_uniform.hpp @@ -0,0 +1,54 @@ +// Copyright Nick Thompson, 2021 +// 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) + +// This implements bilinear interpolation on a uniform grid. +// If dx and dy are both positive, then the (x,y) = (x0, y0) is associated with data index 0 (herein referred to as f[0]) +// The point (x0 + dx, y0) is associated with f[1], and (x0 + i*dx, y0) is associated with f[i], +// i.e., we are assuming traditional C row major order. +// The y coordinate increases *downward*, as is traditional in 2D computer graphics. +// This is *not* how people generally think in numerical analysis (although it *is* how they lay out matrices). +// Providing the capability of a grid rotation is too expensive and not ergonomic; you'll need to perform any rotations at the call level. + +// For clarity, the value f(x0 + i*dx, y0 + j*dy) must be stored in the f[j*cols + i] position. + +#ifndef BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_HPP +#define BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_HPP + +#include +#include +#include + +namespace boost::math::interpolators { + +template +class bilinear_uniform +{ +public: + using Real = typename RandomAccessContainer::value_type; + using Z = typename RandomAccessContainer::size_type; + + bilinear_uniform(RandomAccessContainer && fieldData, Z rows, Z cols, Real dx = 1, Real dy = 1, Real x0 = 0, Real y0 = 0) + : m_imp(std::make_shared>(std::move(fieldData), rows, cols, dx, dy, x0, y0)) + { + } + + Real operator()(Real x, Real y) const + { + return m_imp->operator()(x,y); + } + + + friend std::ostream& operator<<(std::ostream& out, bilinear_uniform const & bu) { + out << *bu.m_imp; + return out; + } + +private: + std::shared_ptr> m_imp; +}; + +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cardinal_cubic_b_spline.hpp b/libcxx/src/third-party/boost/math/interpolators/cardinal_cubic_b_spline.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cardinal_cubic_b_spline.hpp @@ -0,0 +1,87 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This implements the compactly supported cubic b spline algorithm described in +// Kress, Rainer. "Numerical analysis, volume 181 of Graduate Texts in Mathematics." (1998). +// Splines of compact support are faster to evaluate and are better conditioned than classical cubic splines. + +// Let f be the function we are trying to interpolate, and s be the interpolating spline. +// The routine constructs the interpolant in O(N) time, and evaluating s at a point takes constant time. +// The order of accuracy depends on the regularity of the f, however, assuming f is +// four-times continuously differentiable, the error is of O(h^4). +// In addition, we can differentiate the spline and obtain a good interpolant for f'. +// The main restriction of this method is that the samples of f must be evenly spaced. +// Look for barycentric rational interpolation for non-evenly sampled data. +// Properties: +// - s(x_j) = f(x_j) +// - All cubic polynomials interpolated exactly + +#ifndef BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_HPP + +#include + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_cubic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cardinal_cubic_b_spline(const BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + cardinal_cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + cardinal_cubic_b_spline() = default; + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::shared_ptr> m_imp; +}; + +template +cardinal_cubic_b_spline::cardinal_cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, f + length, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +template +cardinal_cubic_b_spline::cardinal_cubic_b_spline(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, end_p, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +Real cardinal_cubic_b_spline::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real cardinal_cubic_b_spline::prime(Real x) const +{ + return m_imp->prime(x); +} + +template +Real cardinal_cubic_b_spline::double_prime(Real x) const +{ + return m_imp->double_prime(x); +} + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cardinal_quadratic_b_spline.hpp b/libcxx/src/third-party/boost/math/interpolators/cardinal_quadratic_b_spline.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cardinal_quadratic_b_spline.hpp @@ -0,0 +1,57 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_HPP +#include +#include + + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_quadratic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n - 1] = y(b), step_size = (b - a)/(n -1). + cardinal_quadratic_b_spline(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + : impl_(std::make_shared>(y, n, t0, h, left_endpoint_derivative, right_endpoint_derivative)) + {} + + // Oh the bizarre error messages if we template this on a RandomAccessContainer: + cardinal_quadratic_b_spline(std::vector const & y, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + : impl_(std::make_shared>(y.data(), y.size(), t0, h, left_endpoint_derivative, right_endpoint_derivative)) + {} + + + Real operator()(Real t) const { + return impl_->operator()(t); + } + + Real prime(Real t) const { + return impl_->prime(t); + } + + Real t_max() const { + return impl_->t_max(); + } + +private: + std::shared_ptr> impl_; +}; + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cardinal_quintic_b_spline.hpp b/libcxx/src/third-party/boost/math/interpolators/cardinal_quintic_b_spline.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cardinal_quintic_b_spline.hpp @@ -0,0 +1,62 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_HPP +#include +#include +#include + + +namespace boost{ namespace math{ namespace interpolators { + +template +class cardinal_quintic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n - 1] = y(b), step_size = (b - a)/(n -1). + cardinal_quintic_b_spline(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, + std::pair right_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}) + : impl_(std::make_shared>(y, n, t0, h, left_endpoint_derivatives, right_endpoint_derivatives)) + {} + + // Oh the bizarre error messages if we template this on a RandomAccessContainer: + cardinal_quintic_b_spline(std::vector const & y, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}, + std::pair right_endpoint_derivatives = {std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()}) + : impl_(std::make_shared>(y.data(), y.size(), t0, h, left_endpoint_derivatives, right_endpoint_derivatives)) + {} + + + Real operator()(Real t) const { + return impl_->operator()(t); + } + + Real prime(Real t) const { + return impl_->prime(t); + } + + Real double_prime(Real t) const { + return impl_->double_prime(t); + } + + Real t_max() const { + return impl_->t_max(); + } + +private: + std::shared_ptr> impl_; +}; + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cardinal_trigonometric.hpp b/libcxx/src/third-party/boost/math/interpolators/cardinal_trigonometric.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cardinal_trigonometric.hpp @@ -0,0 +1,58 @@ +// (C) Copyright Nick Thompson 2019. +// 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_INTERPOLATORS_CARDINAL_TRIGONOMETRIC_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_TRIGONOMETRIC_HPP +#include +#include + +namespace boost { namespace math { namespace interpolators { + +template +class cardinal_trigonometric +{ +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_trigonometric(RandomAccessContainer const & v, Real t0, Real h) + { + m_impl = std::make_shared>(v.data(), v.size(), t0, h); + } + + Real operator()(Real t) const + { + return m_impl->operator()(t); + } + + Real prime(Real t) const + { + return m_impl->prime(t); + } + + Real double_prime(Real t) const + { + return m_impl->double_prime(t); + } + + Real period() const + { + return m_impl->period(); + } + + Real integrate() const + { + return m_impl->integrate(); + } + + Real squared_l2() const + { + return m_impl->squared_l2(); + } + +private: + std::shared_ptr> m_impl; +}; + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/catmull_rom.hpp b/libcxx/src/third-party/boost/math/interpolators/catmull_rom.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/catmull_rom.hpp @@ -0,0 +1,310 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This computes the Catmull-Rom spline from a list of points. + +#ifndef BOOST_MATH_INTERPOLATORS_CATMULL_ROM +#define BOOST_MATH_INTERPOLATORS_CATMULL_ROM + +#include +#include +#include +#include +#include +#include + +namespace std_workaround { + +#if defined(__cpp_lib_nonmember_container_access) || (defined(_MSC_VER) && (_MSC_VER >= 1900)) + using std::size; +#else + template + inline constexpr std::size_t size(const C& c) + { + return c.size(); + } + template + inline constexpr std::size_t size(const T(&array)[N]) noexcept + { + return N; + } +#endif +} + +namespace boost{ namespace math{ + + namespace detail + { + template + typename Point::value_type alpha_distance(Point const & p1, Point const & p2, typename Point::value_type alpha) + { + using std::pow; + using std_workaround::size; + typename Point::value_type dsq = 0; + for (size_t i = 0; i < size(p1); ++i) + { + typename Point::value_type dx = p1[i] - p2[i]; + dsq += dx*dx; + } + return pow(dsq, alpha/2); + } + } + +template > +class catmull_rom +{ + typedef typename Point::value_type value_type; +public: + + catmull_rom(RandomAccessContainer&& points, bool closed = false, value_type alpha = (value_type) 1/ (value_type) 2); + + catmull_rom(std::initializer_list l, bool closed = false, value_type alpha = (value_type) 1/ (value_type) 2) : catmull_rom(RandomAccessContainer(l), closed, alpha) {} + + value_type max_parameter() const + { + return m_max_s; + } + + value_type parameter_at_point(size_t i) const + { + return m_s[i+1]; + } + + Point operator()(const value_type s) const; + + Point prime(const value_type s) const; + + RandomAccessContainer&& get_points() + { + return std::move(m_pnts); + } + +private: + RandomAccessContainer m_pnts; + std::vector m_s; + value_type m_max_s; +}; + +template +catmull_rom::catmull_rom(RandomAccessContainer&& points, bool closed, typename Point::value_type alpha) : m_pnts(std::move(points)) +{ + std::size_t num_pnts = m_pnts.size(); + //std::cout << "Number of points = " << num_pnts << "\n"; + if (num_pnts < 4) + { + throw std::domain_error("The Catmull-Rom curve requires at least 4 points."); + } + if (alpha < 0 || alpha > 1) + { + throw std::domain_error("The parametrization alpha must be in the range [0,1]."); + } + + using std::abs; + m_s.resize(num_pnts+3); + m_pnts.resize(num_pnts+3); + //std::cout << "Number of points now = " << m_pnts.size() << "\n"; + + m_pnts[num_pnts+1] = m_pnts[0]; + m_pnts[num_pnts+2] = m_pnts[1]; + + auto tmp = m_pnts[num_pnts-1]; + for (auto i = num_pnts; i > 0; --i) + { + m_pnts[i] = m_pnts[i - 1]; + } + m_pnts[0] = tmp; + + m_s[0] = -detail::alpha_distance(m_pnts[0], m_pnts[1], alpha); + if (abs(m_s[0]) < std::numeric_limits::epsilon()) + { + throw std::domain_error("The first and last point should not be the same.\n"); + } + m_s[1] = 0; + for (size_t i = 2; i < m_s.size(); ++i) + { + typename Point::value_type d = detail::alpha_distance(m_pnts[i], m_pnts[i-1], alpha); + if (abs(d) < std::numeric_limits::epsilon()) + { + throw std::domain_error("The control points of the Catmull-Rom curve are too close together; this will lead to ill-conditioning.\n"); + } + m_s[i] = m_s[i-1] + d; + } + if(closed) + { + m_max_s = m_s[num_pnts+1]; + } + else + { + m_max_s = m_s[num_pnts]; + } +} + + +template +Point catmull_rom::operator()(const typename Point::value_type s) const +{ + using std_workaround::size; + if (s < 0 || s > m_max_s) + { + throw std::domain_error("Parameter outside bounds."); + } + auto it = std::upper_bound(m_s.begin(), m_s.end(), s); + //Now *it >= s. We want the index such that m_s[i] <= s < m_s[i+1]: + size_t i = std::distance(m_s.begin(), it - 1); + + // Only denom21 is used twice: + typename Point::value_type denom21 = 1/(m_s[i+1] - m_s[i]); + typename Point::value_type s0s = m_s[i-1] - s; + typename Point::value_type s1s = m_s[i] - s; + typename Point::value_type s2s = m_s[i+1] - s; + size_t ip2 = i + 2; + // When the curve is closed and we evaluate at the end, the endpoint is in fact the startpoint. + if (ip2 == m_s.size()) { + ip2 = 0; + } + typename Point::value_type s3s = m_s[ip2] - s; + + Point A1_or_A3; + typename Point::value_type denom = 1/(m_s[i] - m_s[i-1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1_or_A3[j] = denom*(s1s*m_pnts[i-1][j] - s0s*m_pnts[i][j]); + } + + Point A2_or_B2; + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2_or_B2[j] = denom21*(s2s*m_pnts[i][j] - s1s*m_pnts[i+1][j]); + } + + Point B1_or_C; + denom = 1/(m_s[i+1] - m_s[i-1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1_or_C[j] = denom*(s2s*A1_or_A3[j] - s0s*A2_or_B2[j]); + } + + denom = 1/(m_s[ip2] - m_s[i+1]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1_or_A3[j] = denom*(s3s*m_pnts[i+1][j] - s2s*m_pnts[ip2][j]); + } + + Point B2; + denom = 1/(m_s[ip2] - m_s[i]); + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2[j] = denom*(s3s*A2_or_B2[j] - s1s*A1_or_A3[j]); + } + + for(size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1_or_C[j] = denom21*(s2s*B1_or_C[j] - s1s*B2[j]); + } + + return B1_or_C; +} + +template +Point catmull_rom::prime(const typename Point::value_type s) const +{ + using std_workaround::size; + // https://math.stackexchange.com/questions/843595/how-can-i-calculate-the-derivative-of-a-catmull-rom-spline-with-nonuniform-param + // http://denkovacs.com/2016/02/catmull-rom-spline-derivatives/ + if (s < 0 || s > m_max_s) + { + throw std::domain_error("Parameter outside bounds.\n"); + } + auto it = std::upper_bound(m_s.begin(), m_s.end(), s); + //Now *it >= s. We want the index such that m_s[i] <= s < m_s[i+1]: + size_t i = std::distance(m_s.begin(), it - 1); + Point A1; + typename Point::value_type denom = 1/(m_s[i] - m_s[i-1]); + typename Point::value_type k1 = (m_s[i]-s)*denom; + typename Point::value_type k2 = (s - m_s[i-1])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1[j] = k1*m_pnts[i-1][j] + k2*m_pnts[i][j]; + } + + Point A1p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A1p[j] = denom*(m_pnts[i][j] - m_pnts[i-1][j]); + } + + Point A2; + denom = 1/(m_s[i+1] - m_s[i]); + k1 = (m_s[i+1]-s)*denom; + k2 = (s - m_s[i])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2[j] = k1*m_pnts[i][j] + k2*m_pnts[i+1][j]; + } + + Point A2p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A2p[j] = denom*(m_pnts[i+1][j] - m_pnts[i][j]); + } + + + Point B1; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1[j] = k1*A1[j] + k2*A2[j]; + } + + Point A3; + denom = 1/(m_s[i+2] - m_s[i+1]); + k1 = (m_s[i+2]-s)*denom; + k2 = (s - m_s[i+1])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A3[j] = k1*m_pnts[i+1][j] + k2*m_pnts[i+2][j]; + } + + Point A3p; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + A3p[j] = denom*(m_pnts[i+2][j] - m_pnts[i+1][j]); + } + + Point B2; + denom = 1/(m_s[i+2] - m_s[i]); + k1 = (m_s[i+2]-s)*denom; + k2 = (s - m_s[i])*denom; + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2[j] = k1*A2[j] + k2*A3[j]; + } + + Point B1p; + denom = 1/(m_s[i+1] - m_s[i-1]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B1p[j] = denom*(A2[j] - A1[j] + (m_s[i+1]- s)*A1p[j] + (s-m_s[i-1])*A2p[j]); + } + + Point B2p; + denom = 1/(m_s[i+2] - m_s[i]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + B2p[j] = denom*(A3[j] - A2[j] + (m_s[i+2] - s)*A2p[j] + (s - m_s[i])*A3p[j]); + } + + Point Cp; + denom = 1/(m_s[i+1] - m_s[i]); + for (size_t j = 0; j < size(m_pnts[0]); ++j) + { + Cp[j] = denom*(B2[j] - B1[j] + (m_s[i+1] - s)*B1p[j] + (s - m_s[i])*B2p[j]); + } + return Cp; +} + + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cubic_b_spline.hpp b/libcxx/src/third-party/boost/math/interpolators/cubic_b_spline.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cubic_b_spline.hpp @@ -0,0 +1,90 @@ +// Copyright Nick Thompson, 2017 +// 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) + +// This implements the compactly supported cubic b spline algorithm described in +// Kress, Rainer. "Numerical analysis, volume 181 of Graduate Texts in Mathematics." (1998). +// Splines of compact support are faster to evaluate and are better conditioned than classical cubic splines. + +// Let f be the function we are trying to interpolate, and s be the interpolating spline. +// The routine constructs the interpolant in O(N) time, and evaluating s at a point takes constant time. +// The order of accuracy depends on the regularity of the f, however, assuming f is +// four-times continuously differentiable, the error is of O(h^4). +// In addition, we can differentiate the spline and obtain a good interpolant for f'. +// The main restriction of this method is that the samples of f must be evenly spaced. +// Look for barycentric rational interpolation for non-evenly sampled data. +// Properties: +// - s(x_j) = f(x_j) +// - All cubic polynomials interpolated exactly + +#ifndef BOOST_MATH_INTERPOLATORS_CUBIC_B_SPLINE_HPP +#define BOOST_MATH_INTERPOLATORS_CUBIC_B_SPLINE_HPP + +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost{ namespace math{ + +template +class cubic_b_spline +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cubic_b_spline(const BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + cubic_b_spline() = default; + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::shared_ptr> m_imp; +}; + +template +cubic_b_spline::cubic_b_spline(const Real* const f, size_t length, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, f + length, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +template +cubic_b_spline::cubic_b_spline(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_imp(std::make_shared>(f, end_p, left_endpoint, step_size, left_endpoint_derivative, right_endpoint_derivative)) +{ +} + +template +Real cubic_b_spline::operator()(Real x) const +{ + return m_imp->operator()(x); +} + +template +Real cubic_b_spline::prime(Real x) const +{ + return m_imp->prime(x); +} + +template +Real cubic_b_spline::double_prime(Real x) const +{ + return m_imp->double_prime(x); +} + + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/cubic_hermite.hpp b/libcxx/src/third-party/boost/math/interpolators/cubic_hermite.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/cubic_hermite.hpp @@ -0,0 +1,141 @@ +// Copyright Nick Thompson, 2020 +// 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_INTERPOLATORS_CUBIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_CUBIC_HERMITE_HPP +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class cubic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + + cubic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx) + : impl_(std::make_shared>(std::move(x), std::move(y), std::move(dydx))) + {} + + inline Real operator()(Real x) const { + return impl_->operator()(x); + } + + inline Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cubic_hermite & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y, Real dydx) + { + impl_->push_back(x, y, dydx); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_cubic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + + cardinal_cubic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, Real x0, Real dx) + : impl_(std::make_shared>(std::move(y), std::move(dydx), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cardinal_cubic_hermite & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class cardinal_cubic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + cardinal_cubic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const cardinal_cubic_hermite_aos & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/barycentric_rational_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/barycentric_rational_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/barycentric_rational_detail.hpp @@ -0,0 +1,214 @@ +/* + * Copyright Nick Thompson, 2017 + * 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_INTERPOLATORS_BARYCENTRIC_RATIONAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BARYCENTRIC_RATIONAL_DETAIL_HPP + +#include +#include // for std::move +#include // for std::is_sorted +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators { namespace detail{ + +template +class barycentric_rational_imp +{ +public: + template + barycentric_rational_imp(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order = 3); + + barycentric_rational_imp(std::vector&& x, std::vector&& y, size_t approximation_order = 3); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + // The barycentric weights are not really that interesting; except to the unit tests! + Real weight(size_t i) const { return m_w[i]; } + + std::vector&& return_x() + { + return std::move(m_x); + } + + std::vector&& return_y() + { + return std::move(m_y); + } + +private: + + void calculate_weights(size_t approximation_order); + + std::vector m_x; + std::vector m_y; + std::vector m_w; +}; + +template +template +barycentric_rational_imp::barycentric_rational_imp(InputIterator1 start_x, InputIterator1 end_x, InputIterator2 start_y, size_t approximation_order) +{ + std::ptrdiff_t n = std::distance(start_x, end_x); + + if (approximation_order >= (std::size_t)n) + { + throw std::domain_error("Approximation order must be < data length."); + } + + // Big sad memcpy. + m_x.resize(n); + m_y.resize(n); + for(unsigned i = 0; start_x != end_x; ++start_x, ++start_y, ++i) + { + // But if we're going to do a memcpy, we can do some error checking which is inexpensive relative to the copy: + if(boost::math::isnan(*start_x)) + { + std::string msg = std::string("x[") + std::to_string(i) + "] is a NAN"; + throw std::domain_error(msg); + } + + if(boost::math::isnan(*start_y)) + { + std::string msg = std::string("y[") + std::to_string(i) + "] is a NAN"; + throw std::domain_error(msg); + } + + m_x[i] = *start_x; + m_y[i] = *start_y; + } + calculate_weights(approximation_order); +} + +template +barycentric_rational_imp::barycentric_rational_imp(std::vector&& x, std::vector&& y,size_t approximation_order) : m_x(std::move(x)), m_y(std::move(y)) +{ + BOOST_MATH_ASSERT_MSG(m_x.size() == m_y.size(), "There must be the same number of abscissas and ordinates."); + BOOST_MATH_ASSERT_MSG(approximation_order < m_x.size(), "Approximation order must be < data length."); + BOOST_MATH_ASSERT_MSG(std::is_sorted(m_x.begin(), m_x.end()), "The abscissas must be listed in increasing order x[0] < x[1] < ... < x[n-1]."); + calculate_weights(approximation_order); +} + +template +void barycentric_rational_imp::calculate_weights(size_t approximation_order) +{ + using std::abs; + int64_t n = m_x.size(); + m_w.resize(n, 0); + for(int64_t k = 0; k < n; ++k) + { + int64_t i_min = (std::max)(k - static_cast(approximation_order), static_cast(0)); + int64_t i_max = k; + if (k >= n - (std::ptrdiff_t)approximation_order) + { + i_max = n - approximation_order - 1; + } + + for(int64_t i = i_min; i <= i_max; ++i) + { + Real inv_product = 1; + int64_t j_max = (std::min)(static_cast(i + approximation_order), static_cast(n - 1)); + for(int64_t j = i; j <= j_max; ++j) + { + if (j == k) + { + continue; + } + + Real diff = m_x[k] - m_x[j]; + using std::numeric_limits; + if (abs(diff) < (numeric_limits::min)()) + { + std::string msg = std::string("Spacing between x[") + + std::to_string(k) + std::string("] and x[") + + std::to_string(i) + std::string("] is ") + + std::string("smaller than the epsilon of ") + + std::string(typeid(Real).name()); + throw std::logic_error(msg); + } + inv_product *= diff; + } + if (i % 2 == 0) + { + m_w[k] += 1/inv_product; + } + else + { + m_w[k] -= 1/inv_product; + } + } + } +} + + +template +Real barycentric_rational_imp::operator()(Real x) const +{ + Real numerator = 0; + Real denominator = 0; + for(size_t i = 0; i < m_x.size(); ++i) + { + // Presumably we should see if the accuracy is improved by using ULP distance of say, 5 here, instead of testing for floating point equality. + // However, it has been shown that if x approx x_i, but x != x_i, then inaccuracy in the numerator cancels the inaccuracy in the denominator, + // and the result is fairly accurate. See: http://epubs.siam.org/doi/pdf/10.1137/S0036144502417715 + if (x == m_x[i]) + { + return m_y[i]; + } + Real t = m_w[i]/(x - m_x[i]); + numerator += t*m_y[i]; + denominator += t; + } + return numerator/denominator; +} + +/* + * A formula for computing the derivative of the barycentric representation is given in + * "Some New Aspects of Rational Interpolation", by Claus Schneider and Wilhelm Werner, + * Mathematics of Computation, v47, number 175, 1986. + * http://www.ams.org/journals/mcom/1986-47-175/S0025-5718-1986-0842136-8/S0025-5718-1986-0842136-8.pdf + * and reviewed in + * Recent developments in barycentric rational interpolation + * Jean-Paul Berrut, Richard Baltensperger and Hans D. Mittelmann + * + * Is it possible to complete this in one pass through the data? + */ + +template +Real barycentric_rational_imp::prime(Real x) const +{ + Real rx = this->operator()(x); + Real numerator = 0; + Real denominator = 0; + for(size_t i = 0; i < m_x.size(); ++i) + { + if (x == m_x[i]) + { + Real sum = 0; + for (size_t j = 0; j < m_x.size(); ++j) + { + if (j == i) + { + continue; + } + sum += m_w[j]*(m_y[i] - m_y[j])/(m_x[i] - m_x[j]); + } + return -sum/m_w[i]; + } + Real t = m_w[i]/(x - m_x[i]); + Real diff = (rx - m_y[i])/(x-m_x[i]); + numerator += t*diff; + denominator += t; + } + + return numerator/denominator; +} +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/bezier_polynomial_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/bezier_polynomial_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/bezier_polynomial_detail.hpp @@ -0,0 +1,167 @@ +// Copyright Nick Thompson, 2021 +// 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_INTERPOLATORS_BEZIER_POLYNOMIAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BEZIER_POLYNOMIAL_DETAIL_HPP + +#include +#include +#include +#include + +namespace boost::math::interpolators::detail { + + +template +static inline RandomAccessContainer& get_bezier_storage() +{ + static thread_local RandomAccessContainer the_storage; + return the_storage; +} + + +template +class bezier_polynomial_imp +{ +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Z = typename RandomAccessContainer::size_type; + + bezier_polynomial_imp(RandomAccessContainer && control_points) + { + using std::to_string; + if (control_points.size() < 2) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " At least two points are required to form a Bezier curve. Only " + to_string(control_points.size()) + " points have been provided."; + throw std::logic_error(err); + } + Z dimension = control_points[0].size(); + for (Z i = 0; i < control_points.size(); ++i) { + if (control_points[i].size() != dimension) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " All points passed to the Bezier polynomial must have the same dimension."; + throw std::logic_error(err); + } + } + control_points_ = std::move(control_points); + auto & storage = get_bezier_storage(); + if (storage.size() < control_points_.size() -1) { + storage.resize(control_points_.size() -1); + } + } + + inline Point operator()(Real t) const + { + if (t < 0 || t > 1) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the Bezier curve interpolator at t = " << t << " is not allowed; t in [0,1] is required.\n"; + Point p; + for (Z i = 0; i < p.size(); ++i) { + p[i] = std::numeric_limits::quiet_NaN(); + } + return p; + } + + auto & scratch_space = get_bezier_storage(); + for (Z i = 0; i < control_points_.size() - 1; ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[i][j] = (1-t)*control_points_[i][j] + t*control_points_[i+1][j]; + } + } + + decasteljau_recursion(scratch_space, scratch_space.size(), t); + return scratch_space[0]; + } + + Point prime(Real t) { + auto & scratch_space = get_bezier_storage(); + for (Z i = 0; i < control_points_.size() - 1; ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[i][j] = control_points_[i+1][j] - control_points_[i][j]; + } + } + decasteljau_recursion(scratch_space, control_points_.size() - 1, t); + for (Z j = 0; j < control_points_[0].size(); ++j) { + scratch_space[0][j] *= (control_points_.size()-1); + } + return scratch_space[0]; + } + + + void edit_control_point(Point const & p, Z index) + { + if (index >= control_points_.size()) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Attempting to edit a control point outside the bounds of the container; requested edit of index " << index << ", but there are only " << control_points_.size() << " control points.\n"; + return; + } + control_points_[index] = p; + } + + RandomAccessContainer const & control_points() const { + return control_points_; + } + + // See "Bezier and B-spline techniques", section 2.7: + // I cannot figure out why this doesn't work. + /*RandomAccessContainer indefinite_integral() const { + using std::fma; + // control_points_.size() == n + 1 + RandomAccessContainer c(control_points_.size() + 1); + // This is the constant of integration, chosen arbitarily to be zero: + for (Z j = 0; j < control_points_[0].size(); ++j) { + c[0][j] = Real(0); + } + + // Make the reciprocal approximation to unroll the iteration into a pile of fma's: + Real rnp1 = Real(1)/control_points_.size(); + for (Z i = 1; i < c.size(); ++i) { + for (Z j = 0; j < control_points_[0].size(); ++j) { + //c[i][j] = c[i-1][j] + control_points_[i-1][j]*rnp1; + c[i][j] = fma(rnp1, control_points_[i-1][j], c[i-1][j]); + } + } + return c; + }*/ + + friend std::ostream& operator<<(std::ostream& out, bezier_polynomial_imp const & bp) { + out << "{"; + for (Z i = 0; i < bp.control_points_.size() - 1; ++i) { + out << "("; + for (Z j = 0; j < bp.control_points_[0].size() - 1; ++j) { + out << bp.control_points_[i][j] << ", "; + } + out << bp.control_points_[i][bp.control_points_[0].size() - 1] << "), "; + } + out << "("; + for (Z j = 0; j < bp.control_points_[0].size() - 1; ++j) { + out << bp.control_points_.back()[j] << ", "; + } + out << bp.control_points_.back()[bp.control_points_[0].size() - 1] << ")}"; + return out; + } + +private: + + void decasteljau_recursion(RandomAccessContainer & points, Z n, Real t) const { + if (n <= 1) { + return; + } + for (Z i = 0; i < n - 1; ++i) { + for (Z j = 0; j < points[0].size(); ++j) { + points[i][j] = (1-t)*points[i][j] + t*points[i+1][j]; + } + } + decasteljau_recursion(points, n - 1, t); + } + + RandomAccessContainer control_points_; +}; + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/bilinear_uniform_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/bilinear_uniform_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/bilinear_uniform_detail.hpp @@ -0,0 +1,137 @@ +// Copyright Nick Thompson, 2021 +// 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_INTERPOLATORS_BILINEAR_UNIFORM_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_BILINEAR_UNIFORM_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost::math::interpolators::detail { + +template +class bilinear_uniform_imp +{ +public: + using Real = typename RandomAccessContainer::value_type; + using Z = typename RandomAccessContainer::size_type; + + bilinear_uniform_imp(RandomAccessContainer && fieldData, Z rows, Z cols, Real dx = 1, Real dy = 1, Real x0 = 0, Real y0 = 0) + { + using std::to_string; + if(fieldData.size() != rows*cols) + { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + + " The field data must have rows*cols elements. There are " + to_string(rows) + " rows and " + to_string(cols) + " columns but " + to_string(fieldData.size()) + " elements in the field data."; + throw std::logic_error(err); + } + if (rows < 2) { + throw std::logic_error("There must be at least two rows of data for bilinear interpolation to be well-defined."); + } + if (cols < 2) { + throw std::logic_error("There must be at least two columns of data for bilinear interpolation to be well-defined."); + } + + fieldData_ = std::move(fieldData); + rows_ = rows; + cols_ = cols; + x0_ = x0; + y0_ = y0; + dx_ = dx; + dy_ = dy; + + if (dx_ <= 0) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + " dx = " + to_string(dx) + ", but dx > 0 is required. Are the arguments out of order?"; + throw std::logic_error(err); + } + if (dy_ <= 0) { + std::string err = std::string(__FILE__) + ":" + to_string(__LINE__) + " dy = " + to_string(dy) + ", but dy > 0 is required. Are the arguments out of order?"; + throw std::logic_error(err); + } + } + + Real operator()(Real x, Real y) const + { + using std::floor; + if (x > x0_ + (cols_ - 1)*dx_ || x < x0_) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the bilinear_uniform interpolator at (x,y) = (" << x << ", " << y << ") is not allowed.\n"; + std::cerr << "x must lie in the interval [" << x0_ << ", " << x0_ + (cols_ -1)*dx_ << "]\n"; + return std::numeric_limits::quiet_NaN(); + } + if (y > y0_ + (rows_ - 1)*dy_ || y < y0_) { + std::cerr << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n"; + std::cerr << "Querying the bilinear_uniform interpolator at (x,y) = (" << x << ", " << y << ") is not allowed.\n"; + std::cerr << "y must lie in the interval [" << y0_ << ", " << y0_ + (rows_ -1)*dy_ << "]\n"; + return std::numeric_limits::quiet_NaN(); + } + + Real s = (x - x0_)/dx_; + Real s0 = floor(s); + Real t = (y - y0_)/dy_; + Real t0 = floor(t); + auto xidx = static_cast(s0); + auto yidx = static_cast(t0); + Z idx = yidx*cols_ + xidx; + Real alpha = s - s0; + Real beta = t - t0; + + Real fhi; + // If alpha = 0, then we can segfault by reading fieldData_[idx+1]: + if (alpha <= 2*s0*std::numeric_limits::epsilon()) { + fhi = fieldData_[idx]; + } else { + fhi = (1 - alpha)*fieldData_[idx] + alpha*fieldData_[idx + 1]; + } + + // Again, we can get OOB access without this check. + // This corresponds to interpolation over a line segment aligned with the axes. + if (beta <= 2*t0*std::numeric_limits::epsilon()) { + return fhi; + } + + auto bottom_left = fieldData_[idx + cols_]; + Real flo; + if (alpha <= 2*s0*std::numeric_limits::epsilon()) { + flo = bottom_left; + } + else { + flo = (1 - alpha)*bottom_left + alpha*fieldData_[idx + cols_ + 1]; + } + // Convex combination over vertical to get the value: + return (1 - beta)*fhi + beta*flo; + } + + friend std::ostream& operator<<(std::ostream& out, bilinear_uniform_imp const & bu) { + out << "(x0, y0) = (" << bu.x0_ << ", " << bu.y0_ << "), (dx, dy) = (" << bu.dx_ << ", " << bu.dy_ << "), "; + out << "(xf, yf) = (" << bu.x0_ + (bu.cols_ - 1)*bu.dx_ << ", " << bu.y0_ + (bu.rows_ - 1)*bu.dy_ << ")\n"; + for (Z j = 0; j < bu.rows_; ++j) { + out << "{"; + for (Z i = 0; i < bu.cols_ - 1; ++i) { + out << bu.fieldData_[j*bu.cols_ + i] << ", "; + } + out << bu.fieldData_[j*bu.cols_ + bu.cols_ - 1] << "}\n"; + } + return out; + } + +private: + RandomAccessContainer fieldData_; + Z rows_; + Z cols_; + Real x0_; + Real y0_; + Real dx_; + Real dy_; +}; + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_cubic_b_spline_detail.hpp @@ -0,0 +1,331 @@ +// Copyright Nick Thompson, 2017 +// 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_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_CUBIC_B_SPLINE_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + + +template +class cardinal_cubic_b_spline_imp +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cardinal_cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::vector m_beta; + Real m_h_inv; + Real m_a; + Real m_avg; +}; + + + +template +Real b3_spline(Real x) +{ + using std::abs; + Real absx = abs(x); + if (absx < 1) + { + Real y = 2 - absx; + Real z = 1 - absx; + return boost::math::constants::sixth()*(y*y*y - 4*z*z*z); + } + if (absx < 2) + { + Real y = 2 - absx; + return boost::math::constants::sixth()*y*y*y; + } + return static_cast(0); +} + +template +Real b3_spline_prime(Real x) +{ + if (x < 0) + { + return -b3_spline_prime(-x); + } + + if (x < 1) + { + return x*(3*boost::math::constants::half()*x - 2); + } + if (x < 2) + { + return -boost::math::constants::half()*(2 - x)*(2 - x); + } + return static_cast(0); +} + +template +Real b3_spline_double_prime(Real x) +{ + if (x < 0) + { + return b3_spline_double_prime(-x); + } + + if (x < 1) + { + return 3*x - 2; + } + if (x < 2) + { + return (2 - x); + } + return static_cast(0); +} + + +template +template +cardinal_cubic_b_spline_imp::cardinal_cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_a(left_endpoint), m_avg(0) +{ + using boost::math::constants::third; + + std::size_t length = end_p - f; + + if (length < 5) + { + if (boost::math::isnan(left_endpoint_derivative) || boost::math::isnan(right_endpoint_derivative)) + { + throw std::logic_error("Interpolation using a cubic b spline with derivatives estimated at the endpoints requires at least 5 points.\n"); + } + if (length < 3) + { + throw std::logic_error("Interpolation using a cubic b spline requires at least 3 points.\n"); + } + } + + if (boost::math::isnan(left_endpoint)) + { + throw std::logic_error("Left endpoint is NAN; this is disallowed.\n"); + } + if (left_endpoint + length*step_size >= (std::numeric_limits::max)()) + { + throw std::logic_error("Right endpoint overflows the maximum representable number of the specified precision.\n"); + } + if (step_size <= 0) + { + throw std::logic_error("The step size must be strictly > 0.\n"); + } + // Storing the inverse of the stepsize does provide a measurable speedup. + // It's not huge, but nonetheless worthwhile. + m_h_inv = 1/step_size; + + // Following Kress's notation, s'(a) = a1, s'(b) = b1 + Real a1 = left_endpoint_derivative; + // See the finite-difference table on Wikipedia for reference on how + // to construct high-order estimates for one-sided derivatives: + // https://en.wikipedia.org/wiki/Finite_difference_coefficient#Forward_and_backward_finite_difference + // Here, we estimate then to O(h^4), as that is the maximum accuracy we could obtain from this method. + if (boost::math::isnan(a1)) + { + // For simple functions (linear, quadratic, so on) + // almost all the error comes from derivative estimation. + // This does pairwise summation which gives us another digit of accuracy over naive summation. + Real t0 = 4*(f[1] + third()*f[3]); + Real t1 = -(25*third()*f[0] + f[4])/4 - 3*f[2]; + a1 = m_h_inv*(t0 + t1); + } + + Real b1 = right_endpoint_derivative; + if (boost::math::isnan(b1)) + { + size_t n = length - 1; + Real t0 = -4*(f[n - 1] + third()*f[n - 3]); + Real t1 = (25*third()*f[n] + f[n - 4])/4 + 3*f[n - 2]; + + b1 = m_h_inv*(t0 + t1); + } + + // s(x) = \sum \alpha_i B_{3}( (x- x_i - a)/h ) + // Of course we must reindex from Kress's notation, since he uses negative indices which make C++ unhappy. + m_beta.resize(length + 2, std::numeric_limits::quiet_NaN()); + + // Since the splines have compact support, they decay to zero very fast outside the endpoints. + // This is often very annoying; we'd like to evaluate the interpolant a little bit outside the + // boundary [a,b] without massive error. + // A simple way to deal with this is just to subtract the DC component off the signal, so we need the average. + // This algorithm for computing the average is recommended in + // http://www.heikohoffmann.de/htmlthesis/node134.html + Real t = 1; + for (size_t i = 0; i < length; ++i) + { + if (boost::math::isnan(f[i])) + { + std::string err = "This function you are trying to interpolate is a nan at index " + std::to_string(i) + "\n"; + throw std::logic_error(err); + } + m_avg += (f[i] - m_avg) / t; + t += 1; + } + + + // Now we must solve an almost-tridiagonal system, which requires O(N) operations. + // There are, in fact 5 diagonals, but they only differ from zero on the first and last row, + // so we can patch up the tridiagonal row reduction algorithm to deal with two special rows. + // See Kress, equations 8.41 + // The the "tridiagonal" matrix is: + // 1 0 -1 + // 1 4 1 + // 1 4 1 + // 1 4 1 + // .... + // 1 4 1 + // 1 0 -1 + // Numerical estimate indicate that as N->Infinity, cond(A) -> 6.9, so this matrix is good. + std::vector rhs(length + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(length + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -2*step_size*a1; + rhs[rhs.size() - 1] = -2*step_size*b1; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) + { + rhs[i] = 6*(f[i - 1] - m_avg); + super_diagonal[i] = 1; + } + + + // One step of row reduction on the first row to patch up the 5-diagonal problem: + // 1 0 -1 | r0 + // 1 4 1 | r1 + // mapsto: + // 1 0 -1 | r0 + // 0 4 2 | r1 - r0 + // mapsto + // 1 0 -1 | r0 + // 0 1 1/2| (r1 - r0)/4 + super_diagonal[1] = 0.5; + rhs[1] = (rhs[1] - rhs[0])/4; + + // Now do a tridiagonal row reduction the standard way, until just before the last row: + for (size_t i = 2; i < rhs.size() - 1; ++i) + { + Real diagonal = 4 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // Now the last row, which is in the form + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 1 0 -1 | rhs[n-1] + Real final_subdiag = -super_diagonal[rhs.size() - 3]; + rhs[rhs.size() - 1] = (rhs[rhs.size() - 1] - rhs[rhs.size() - 3])/final_subdiag; + Real final_diag = -1/final_subdiag; + // Now we're here: + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 0 1 final_diag | (rhs[n-1] - rhs[n-3])/diag + + final_diag = final_diag - super_diagonal[rhs.size() - 2]; + rhs[rhs.size() - 1] = rhs[rhs.size() - 1] - rhs[rhs.size() - 2]; + + + // Back substitutions: + m_beta[rhs.size() - 1] = rhs[rhs.size() - 1]/final_diag; + for(size_t i = rhs.size() - 2; i > 0; --i) + { + m_beta[i] = rhs[i] - super_diagonal[i]*m_beta[i + 1]; + } + m_beta[0] = m_beta[2] + rhs[0]; +} + +template +Real cardinal_cubic_b_spline_imp::operator()(Real x) const +{ + // See Kress, 8.40: Since B3 has compact support, we don't have to sum over all terms, + // just the (at most 5) whose support overlaps the argument. + Real z = m_avg; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((max)((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2))), 0l)); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline(t - k); + } + + return z; +} + +template +Real cardinal_cubic_b_spline_imp::prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_prime(t - k); + } + return z*m_h_inv; +} + +template +Real cardinal_cubic_b_spline_imp::double_prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_double_prime(t - k); + } + return z*m_h_inv*m_h_inv; +} + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quadratic_b_spline_detail.hpp @@ -0,0 +1,208 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUADRATIC_B_SPLINE_DETAIL_HPP +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + +template +Real b2_spline(Real x) { + using std::abs; + Real absx = abs(x); + if (absx < 1/Real(2)) + { + Real y = absx - 1/Real(2); + Real z = absx + 1/Real(2); + return (2-y*y-z*z)/2; + } + if (absx < Real(3)/Real(2)) + { + Real y = absx - Real(3)/Real(2); + return y*y/2; + } + return static_cast(0); +} + +template +Real b2_spline_prime(Real x) { + if (x < 0) { + return -b2_spline_prime(-x); + } + + if (x < 1/Real(2)) + { + return -2*x; + } + if (x < Real(3)/Real(2)) + { + return x - Real(3)/Real(2); + } + return static_cast(0); +} + + +template +class cardinal_quadratic_b_spline_detail +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n -1] = y(b), step_size = (b - a)/(n -1). + + cardinal_quadratic_b_spline_detail(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + if (h <= 0) { + throw std::logic_error("Spacing must be > 0."); + } + m_inv_h = 1/h; + m_t0 = t0; + + if (n < 3) { + throw std::logic_error("The interpolator requires at least 3 points."); + } + + using std::isnan; + Real a; + if (isnan(left_endpoint_derivative)) { + // http://web.media.mit.edu/~crtaylor/calculator.html + a = -3*y[0] + 4*y[1] - y[2]; + } + else { + a = 2*h*left_endpoint_derivative; + } + + Real b; + if (isnan(right_endpoint_derivative)) { + b = 3*y[n-1] - 4*y[n-2] + y[n-3]; + } + else { + b = 2*h*right_endpoint_derivative; + } + + m_alpha.resize(n + 2); + + // Begin row reduction: + std::vector rhs(n + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(n + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -a; + rhs[rhs.size() - 1] = b; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) { + rhs[i] = 8*y[i - 1]; + super_diagonal[i] = 1; + } + + // Patch up 5-diagonal problem: + rhs[1] = (rhs[1] - rhs[0])/6; + super_diagonal[1] = Real(1)/Real(3); + // First two rows are now: + // 1 0 -1 | -2hy0' + // 0 1 1/3| (8y0+2hy0')/6 + + + // Start traditional tridiagonal row reduction: + for (size_t i = 2; i < rhs.size() - 1; ++i) { + Real diagonal = 6 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // 1 sd[n-1] 0 | rhs[n-1] + // 0 1 sd[n] | rhs[n] + // -1 0 1 | rhs[n+1] + + rhs[n+1] = rhs[n+1] + rhs[n-1]; + Real bottom_subdiagonal = super_diagonal[n-1]; + + // We're here: + // 1 sd[n-1] 0 | rhs[n-1] + // 0 1 sd[n] | rhs[n] + // 0 bs 1 | rhs[n+1] + + rhs[n+1] = (rhs[n+1]-bottom_subdiagonal*rhs[n])/(1-bottom_subdiagonal*super_diagonal[n]); + + m_alpha[n+1] = rhs[n+1]; + for (size_t i = n; i > 0; --i) { + m_alpha[i] = rhs[i] - m_alpha[i+1]*super_diagonal[i]; + } + m_alpha[0] = m_alpha[2] + rhs[0]; + } + + Real operator()(Real t) const { + if (t < m_t0 || t > m_t0 + (m_alpha.size()-2)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quadratic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + // Let k, gamma be defined via t = t0 + kh + gamma * h. + // Now find all j: |k-j+1+gamma|< 3/2, or, in other words + // j_min = ceil((t-t0)/h - 1/2) + // j_max = floor(t-t0)/h + 5/2) + using std::floor; + using std::ceil; + Real x = (t-m_t0)*m_inv_h; + auto j_min = static_cast(ceil(x - Real(1)/Real(2))); + auto j_max = static_cast(ceil(x + Real(5)/Real(2))); + if (j_max >= m_alpha.size()) { + j_max = m_alpha.size() - 1; + } + + Real y = 0; + x += 1; + for (size_t j = j_min; j <= j_max; ++j) { + y += m_alpha[j]*detail::b2_spline(x - j); + } + return y; + } + + Real prime(Real t) const { + if (t < m_t0 || t > m_t0 + (m_alpha.size()-2)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quadratic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + // Let k, gamma be defined via t = t0 + kh + gamma * h. + // Now find all j: |k-j+1+gamma|< 3/2, or, in other words + // j_min = ceil((t-t0)/h - 1/2) + // j_max = floor(t-t0)/h + 5/2) + using std::floor; + using std::ceil; + Real x = (t-m_t0)*m_inv_h; + auto j_min = static_cast(ceil(x - Real(1)/Real(2))); + auto j_max = static_cast(ceil(x + Real(5)/Real(2))); + if (j_max >= m_alpha.size()) { + j_max = m_alpha.size() - 1; + } + + Real y = 0; + x += 1; + for (size_t j = j_min; j <= j_max; ++j) { + y += m_alpha[j]*detail::b2_spline_prime(x - j); + } + return y*m_inv_h; + } + + Real t_max() const { + return m_t0 + (m_alpha.size()-3)/m_inv_h; + } + +private: + std::vector m_alpha; + Real m_inv_h; + Real m_t0; +}; + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_quintic_b_spline_detail.hpp @@ -0,0 +1,240 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_CARDINAL_QUINTIC_B_SPLINE_DETAIL_HPP +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + + +template +class cardinal_quintic_b_spline_detail +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // y[0] = y(a), y[n -1] = y(b), step_size = (b - a)/(n -1). + + cardinal_quintic_b_spline_detail(const Real* const y, + size_t n, + Real t0 /* initial time, left endpoint */, + Real h /*spacing, stepsize*/, + std::pair left_endpoint_derivatives, + std::pair right_endpoint_derivatives) + { + static_assert(!std::is_integral::value, "The quintic B-spline interpolator only works with floating point types."); + if (h <= 0) { + throw std::logic_error("Spacing must be > 0."); + } + m_inv_h = 1/h; + m_t0 = t0; + + if (n < 8) { + throw std::logic_error("The quintic B-spline interpolator requires at least 8 points."); + } + + using std::isnan; + // This interpolator has error of order h^6, so the derivatives should be estimated with the same error. + // See: https://en.wikipedia.org/wiki/Finite_difference_coefficient + if (isnan(left_endpoint_derivatives.first)) { + Real tmp = -49*y[0]/20 + 6*y[1] - 15*y[2]/2 + 20*y[3]/3 - 15*y[4]/4 + 6*y[5]/5 - y[6]/6; + left_endpoint_derivatives.first = tmp/h; + } + if (isnan(right_endpoint_derivatives.first)) { + Real tmp = 49*y[n-1]/20 - 6*y[n-2] + 15*y[n-3]/2 - 20*y[n-4]/3 + 15*y[n-5]/4 - 6*y[n-6]/5 + y[n-7]/6; + right_endpoint_derivatives.first = tmp/h; + } + if(isnan(left_endpoint_derivatives.second)) { + Real tmp = 469*y[0]/90 - 223*y[1]/10 + 879*y[2]/20 - 949*y[3]/18 + 41*y[4] - 201*y[5]/10 + 1019*y[6]/180 - 7*y[7]/10; + left_endpoint_derivatives.second = tmp/(h*h); + } + if (isnan(right_endpoint_derivatives.second)) { + Real tmp = 469*y[n-1]/90 - 223*y[n-2]/10 + 879*y[n-3]/20 - 949*y[n-4]/18 + 41*y[n-5] - 201*y[n-6]/10 + 1019*y[n-7]/180 - 7*y[n-8]/10; + right_endpoint_derivatives.second = tmp/(h*h); + } + + // This is really challenging my mental limits on by-hand row reduction. + // I debated bringing in a dependency on a sparse linear solver, but given that that would cause much agony for users I decided against it. + + std::vector rhs(n+4); + rhs[0] = 20*y[0] - 12*h*left_endpoint_derivatives.first + 2*h*h*left_endpoint_derivatives.second; + rhs[1] = 60*y[0] - 12*h*left_endpoint_derivatives.first; + for (size_t i = 2; i < n + 2; ++i) { + rhs[i] = 120*y[i-2]; + } + rhs[n+2] = 60*y[n-1] + 12*h*right_endpoint_derivatives.first; + rhs[n+3] = 20*y[n-1] + 12*h*right_endpoint_derivatives.first + 2*h*h*right_endpoint_derivatives.second; + + std::vector diagonal(n+4, 66); + diagonal[0] = 1; + diagonal[1] = 18; + diagonal[n+2] = 18; + diagonal[n+3] = 1; + + std::vector first_superdiagonal(n+4, 26); + first_superdiagonal[0] = 10; + first_superdiagonal[1] = 33; + first_superdiagonal[n+2] = 1; + // There is one less superdiagonal than diagonal; make sure that if we read it, it shows up as a bug: + first_superdiagonal[n+3] = std::numeric_limits::quiet_NaN(); + + std::vector second_superdiagonal(n+4, 1); + second_superdiagonal[0] = 9; + second_superdiagonal[1] = 8; + second_superdiagonal[n+2] = std::numeric_limits::quiet_NaN(); + second_superdiagonal[n+3] = std::numeric_limits::quiet_NaN(); + + std::vector first_subdiagonal(n+4, 26); + first_subdiagonal[0] = std::numeric_limits::quiet_NaN(); + first_subdiagonal[1] = 1; + first_subdiagonal[n+2] = 33; + first_subdiagonal[n+3] = 10; + + std::vector second_subdiagonal(n+4, 1); + second_subdiagonal[0] = std::numeric_limits::quiet_NaN(); + second_subdiagonal[1] = std::numeric_limits::quiet_NaN(); + second_subdiagonal[n+2] = 8; + second_subdiagonal[n+3] = 9; + + + for (size_t i = 0; i < n+2; ++i) { + Real di = diagonal[i]; + diagonal[i] = 1; + first_superdiagonal[i] /= di; + second_superdiagonal[i] /= di; + rhs[i] /= di; + + // Eliminate first subdiagonal: + Real nfsub = -first_subdiagonal[i+1]; + // Superfluous: + first_subdiagonal[i+1] /= nfsub; + // Not superfluous: + diagonal[i+1] /= nfsub; + first_superdiagonal[i+1] /= nfsub; + second_superdiagonal[i+1] /= nfsub; + rhs[i+1] /= nfsub; + + diagonal[i+1] += first_superdiagonal[i]; + first_superdiagonal[i+1] += second_superdiagonal[i]; + rhs[i+1] += rhs[i]; + // Superfluous, but clarifying: + first_subdiagonal[i+1] = 0; + + // Eliminate second subdiagonal: + Real nssub = -second_subdiagonal[i+2]; + first_subdiagonal[i+2] /= nssub; + diagonal[i+2] /= nssub; + first_superdiagonal[i+2] /= nssub; + second_superdiagonal[i+2] /= nssub; + rhs[i+2] /= nssub; + + first_subdiagonal[i+2] += first_superdiagonal[i]; + diagonal[i+2] += second_superdiagonal[i]; + rhs[i+2] += rhs[i]; + // Superfluous, but clarifying: + second_subdiagonal[i+2] = 0; + } + + // Eliminate last subdiagonal: + Real dnp2 = diagonal[n+2]; + diagonal[n+2] = 1; + first_superdiagonal[n+2] /= dnp2; + rhs[n+2] /= dnp2; + Real nfsubnp3 = -first_subdiagonal[n+3]; + diagonal[n+3] /= nfsubnp3; + rhs[n+3] /= nfsubnp3; + + diagonal[n+3] += first_superdiagonal[n+2]; + rhs[n+3] += rhs[n+2]; + + m_alpha.resize(n + 4, std::numeric_limits::quiet_NaN()); + + m_alpha[n+3] = rhs[n+3]/diagonal[n+3]; + m_alpha[n+2] = rhs[n+2] - first_superdiagonal[n+2]*m_alpha[n+3]; + for (int64_t i = int64_t(n+1); i >= 0; --i) { + m_alpha[i] = rhs[i] - first_superdiagonal[i]*m_alpha[i+1] - second_superdiagonal[i]*m_alpha[i+2]; + } + + } + + Real operator()(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline; + // tf = t0 + (n-1)*h + // alpha.size() = n+4 + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5. + // TODO: Zero pad m_alpha so that only the domain check is necessary. + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + // TODO: Use Cox 1972 to generate all integer translates of B5 simultaneously. + s += m_alpha[j]*cardinal_b_spline<5, Real>(x - j + 2); + } + return s; + } + + Real prime(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline_prime; + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5 + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + s += m_alpha[j]*cardinal_b_spline_prime<5, Real>(x - j + 2); + } + return s*m_inv_h; + + } + + Real double_prime(Real t) const { + using std::ceil; + using std::floor; + using boost::math::cardinal_b_spline_double_prime; + if (t < m_t0 || t > m_t0 + (m_alpha.size()-5)/m_inv_h) { + const char* err_msg = "Tried to evaluate the cardinal quintic b-spline outside the domain of of interpolation; extrapolation does not work."; + throw std::domain_error(err_msg); + } + Real x = (t-m_t0)*m_inv_h; + // Support of B_5 is [-3, 3]. So -3 < x - j + 2 < 3, so x-1 < j < x+5 + int64_t j_min = (std::max)(int64_t(0), int64_t(ceil(x-1))); + int64_t j_max = (std::min)(int64_t(m_alpha.size() - 1), int64_t(floor(x+5)) ); + Real s = 0; + for (int64_t j = j_min; j <= j_max; ++j) { + s += m_alpha[j]*cardinal_b_spline_double_prime<5, Real>(x - j + 2); + } + return s*m_inv_h*m_inv_h; + } + + + Real t_max() const { + return m_t0 + (m_alpha.size()-5)/m_inv_h; + } + +private: + std::vector m_alpha; + Real m_inv_h; + Real m_t0; +}; + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cardinal_trigonometric_detail.hpp @@ -0,0 +1,684 @@ +// (C) Copyright Nick Thompson 2019. +// 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_INTERPOLATORS_DETAIL_CARDINAL_TRIGONOMETRIC_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_CARDINAL_TRIGONOMETRIC_HPP +#include +#include +#include +#include + +#ifdef BOOST_HAS_FLOAT128 +#include +#endif + +#ifdef __has_include +# if __has_include() +# include +# else +# error "This feature is unavailable without fftw3 installed" +#endif +#endif + +namespace boost { namespace math { namespace interpolators { namespace detail { + +template +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const Real* data, size_t length, Real t0, Real h) + { + m_data = data; + m_length = length; + m_t0 = t0; + m_h = h; + throw std::domain_error("Not implemented."); + } +private: + size_t m_length; + Real m_t0; + Real m_h; + Real* m_data; +}; + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const float* data, size_t length, float t0, float h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + // The period sadly must be stored, since the complex vector has length that cannot be used to recover the period: + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwf_alloc_complex(m_complex_vector_size); + // The const_cast is legitimate: FFTW does not change the data as long as FFTW_ESTIMATE is provided. + fftwf_plan plan = fftwf_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + // FFTW says a null plan is impossible with the basic interface we are using, and I have no reason to doubt them. + // But it just feels weird not to check this: + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwf_execute(plan); + fftwf_destroy_plan(plan); + + float denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + // numerically, m_gamma[m_complex_vector_size -1][1] should be zero . . . + // I believe, but need to check, that FFTW guarantees that it is identically zero. + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + float operator()(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float s = m_gamma[0][0]; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + // boost::math::cos_pi with a redefinition of x? Not now . . . + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + float prime(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + float double_prime(float t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + float x = two_pi()*(t - m_t0)/m_T; + fftwf_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwf_complex b{0, 0}; + // u = b*z + fftwf_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + float period() const + { + return m_T; + } + + float integrate() const + { + return m_T*m_gamma[0][0]; + } + + float squared_l2() const + { + float s = 0; + // Always add smallest to largest for accuracy. + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwf_free(m_gamma); + m_gamma = nullptr; + } + } + + +private: + float m_t0; + float m_h; + float m_T; + fftwf_complex* m_gamma; + size_t m_complex_vector_size; +}; + + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const double* data, size_t length, double t0, double h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftw_alloc_complex(m_complex_vector_size); + fftw_plan plan = fftw_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftw_execute(plan); + fftw_destroy_plan(plan); + + double denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + double operator()(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double s = m_gamma[0][0]; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + double prime(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + double double_prime(double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + double x = two_pi()*(t - m_t0)/m_T; + fftw_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftw_complex b{0, 0}; + // u = b*z + fftw_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + double period() const + { + return m_T; + } + + double integrate() const + { + return m_T*m_gamma[0][0]; + } + + double squared_l2() const + { + double s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftw_free(m_gamma); + m_gamma = nullptr; + } + } + +private: + double m_t0; + double m_h; + double m_T; + fftw_complex* m_gamma; + size_t m_complex_vector_size; +}; + + +template<> +class cardinal_trigonometric_detail { +public: + cardinal_trigonometric_detail(const long double* data, size_t length, long double t0, long double h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwl_alloc_complex(m_complex_vector_size); + fftwl_plan plan = fftwl_plan_dft_r2c_1d(length, const_cast(data), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwl_execute(plan); + fftwl_destroy_plan(plan); + + long double denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + + if (length % 2 == 0) { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + long double operator()(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double s = m_gamma[0][0]; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + long double prime(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + // u = b*z + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + long double double_prime(long double t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + long double x = two_pi()*(t - m_t0)/m_T; + fftwl_complex z; + z[0] = cos(x); + z[1] = sin(x); + fftwl_complex b{0, 0}; + // u = b*z + fftwl_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi()*two_pi()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + long double period() const + { + return m_T; + } + + long double integrate() const + { + return m_T*m_gamma[0][0]; + } + + long double squared_l2() const + { + long double s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwl_free(m_gamma); + m_gamma = nullptr; + } + } + +private: + long double m_t0; + long double m_h; + long double m_T; + fftwl_complex* m_gamma; + size_t m_complex_vector_size; +}; + +#ifdef BOOST_HAS_FLOAT128 +template<> +class cardinal_trigonometric_detail<__float128> { +public: + cardinal_trigonometric_detail(const __float128* data, size_t length, __float128 t0, __float128 h) : m_t0{t0}, m_h{h} + { + if (length == 0) + { + throw std::logic_error("At least one sample is required."); + } + if (h <= 0) + { + throw std::logic_error("The step size must be > 0"); + } + m_T = m_h*length; + m_complex_vector_size = length/2 + 1; + m_gamma = fftwq_alloc_complex(m_complex_vector_size); + fftwq_plan plan = fftwq_plan_dft_r2c_1d(length, reinterpret_cast<__float128*>(const_cast<__float128*>(data)), m_gamma, FFTW_ESTIMATE); + if (!plan) + { + throw std::logic_error("A null fftw plan was created."); + } + + fftwq_execute(plan); + fftwq_destroy_plan(plan); + + __float128 denom = length; + for (size_t k = 0; k < m_complex_vector_size; ++k) + { + m_gamma[k][0] /= denom; + m_gamma[k][1] /= denom; + } + if (length % 2 == 0) + { + m_gamma[m_complex_vector_size -1][0] /= 2; + } + } + + cardinal_trigonometric_detail(const cardinal_trigonometric_detail& old) = delete; + + cardinal_trigonometric_detail& operator=(const cardinal_trigonometric_detail&) = delete; + + cardinal_trigonometric_detail(cardinal_trigonometric_detail &&) = delete; + + __float128 operator()(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 s = m_gamma[0][0]; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = m_gamma[k][0] + u[0]; + b[1] = m_gamma[k][1] + u[1]; + } + + s += 2*(b[0]*z[0] - b[1]*z[1]); + return s; + } + + __float128 prime(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + // u = b*z + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*m_gamma[k][0] + u[0]; + b[1] = k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi<__float128>()*(b[1]*z[0] + b[0]*z[1])/m_T; + } + + __float128 double_prime(__float128 t) const + { + using std::sin; + using std::cos; + using boost::math::constants::two_pi; + using std::exp; + __float128 x = two_pi<__float128>()*(t - m_t0)/m_T; + fftwq_complex z; + z[0] = cosq(x); + z[1] = sinq(x); + fftwq_complex b{0, 0}; + // u = b*z + fftwq_complex u; + for (size_t k = m_complex_vector_size - 1; k >= 1; --k) + { + u[0] = b[0]*z[0] - b[1]*z[1]; + u[1] = b[0]*z[1] + b[1]*z[0]; + b[0] = k*k*m_gamma[k][0] + u[0]; + b[1] = k*k*m_gamma[k][1] + u[1]; + } + // b*z = (b[0]*z[0] - b[1]*z[1]) + i(b[1]*z[0] + b[0]*z[1]) + return -2*two_pi<__float128>()*two_pi<__float128>()*(b[0]*z[0] - b[1]*z[1])/(m_T*m_T); + } + + __float128 period() const + { + return m_T; + } + + __float128 integrate() const + { + return m_T*m_gamma[0][0]; + } + + __float128 squared_l2() const + { + __float128 s = 0; + for (size_t i = m_complex_vector_size - 1; i >= 1; --i) + { + s += (m_gamma[i][0]*m_gamma[i][0] + m_gamma[i][1]*m_gamma[i][1]); + } + s *= 2; + s += m_gamma[0][0]*m_gamma[0][0]; + return s*m_T; + } + + ~cardinal_trigonometric_detail() + { + if (m_gamma) + { + fftwq_free(m_gamma); + m_gamma = nullptr; + } + } + + +private: + __float128 m_t0; + __float128 m_h; + __float128 m_T; + fftwq_complex* m_gamma; + size_t m_complex_vector_size; +}; +#endif + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cubic_b_spline_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cubic_b_spline_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cubic_b_spline_detail.hpp @@ -0,0 +1,330 @@ +// Copyright Nick Thompson, 2017 +// 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 CUBIC_B_SPLINE_DETAIL_HPP +#define CUBIC_B_SPLINE_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + + +template +class cubic_b_spline_imp +{ +public: + // If you don't know the value of the derivative at the endpoints, leave them as nans and the routine will estimate them. + // f[0] = f(a), f[length -1] = b, step_size = (b - a)/(length -1). + template + cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()); + + Real operator()(Real x) const; + + Real prime(Real x) const; + + Real double_prime(Real x) const; + +private: + std::vector m_beta; + Real m_h_inv; + Real m_a; + Real m_avg; +}; + + + +template +Real b3_spline(Real x) +{ + using std::abs; + Real absx = abs(x); + if (absx < 1) + { + Real y = 2 - absx; + Real z = 1 - absx; + return boost::math::constants::sixth()*(y*y*y - 4*z*z*z); + } + if (absx < 2) + { + Real y = 2 - absx; + return boost::math::constants::sixth()*y*y*y; + } + return static_cast(0); +} + +template +Real b3_spline_prime(Real x) +{ + if (x < 0) + { + return -b3_spline_prime(-x); + } + + if (x < 1) + { + return x*(3*boost::math::constants::half()*x - 2); + } + if (x < 2) + { + return -boost::math::constants::half()*(2 - x)*(2 - x); + } + return static_cast(0); +} + +template +Real b3_spline_double_prime(Real x) +{ + if (x < 0) + { + return b3_spline_double_prime(-x); + } + + if (x < 1) + { + return 3*x - 2; + } + if (x < 2) + { + return (2 - x); + } + return static_cast(0); +} + + +template +template +cubic_b_spline_imp::cubic_b_spline_imp(BidiIterator f, BidiIterator end_p, Real left_endpoint, Real step_size, + Real left_endpoint_derivative, Real right_endpoint_derivative) : m_a(left_endpoint), m_avg(0) +{ + using boost::math::constants::third; + + std::size_t length = end_p - f; + + if (length < 5) + { + if (boost::math::isnan(left_endpoint_derivative) || boost::math::isnan(right_endpoint_derivative)) + { + throw std::logic_error("Interpolation using a cubic b spline with derivatives estimated at the endpoints requires at least 5 points.\n"); + } + if (length < 3) + { + throw std::logic_error("Interpolation using a cubic b spline requires at least 3 points.\n"); + } + } + + if (boost::math::isnan(left_endpoint)) + { + throw std::logic_error("Left endpoint is NAN; this is disallowed.\n"); + } + if (left_endpoint + length*step_size >= (std::numeric_limits::max)()) + { + throw std::logic_error("Right endpoint overflows the maximum representable number of the specified precision.\n"); + } + if (step_size <= 0) + { + throw std::logic_error("The step size must be strictly > 0.\n"); + } + // Storing the inverse of the stepsize does provide a measurable speedup. + // It's not huge, but nonetheless worthwhile. + m_h_inv = 1/step_size; + + // Following Kress's notation, s'(a) = a1, s'(b) = b1 + Real a1 = left_endpoint_derivative; + // See the finite-difference table on Wikipedia for reference on how + // to construct high-order estimates for one-sided derivatives: + // https://en.wikipedia.org/wiki/Finite_difference_coefficient#Forward_and_backward_finite_difference + // Here, we estimate then to O(h^4), as that is the maximum accuracy we could obtain from this method. + if (boost::math::isnan(a1)) + { + // For simple functions (linear, quadratic, so on) + // almost all the error comes from derivative estimation. + // This does pairwise summation which gives us another digit of accuracy over naive summation. + Real t0 = 4*(f[1] + third()*f[3]); + Real t1 = -(25*third()*f[0] + f[4])/4 - 3*f[2]; + a1 = m_h_inv*(t0 + t1); + } + + Real b1 = right_endpoint_derivative; + if (boost::math::isnan(b1)) + { + size_t n = length - 1; + Real t0 = 4*(f[n-3] + third()*f[n - 1]); + Real t1 = -(25*third()*f[n - 4] + f[n])/4 - 3*f[n - 2]; + + b1 = m_h_inv*(t0 + t1); + } + + // s(x) = \sum \alpha_i B_{3}( (x- x_i - a)/h ) + // Of course we must reindex from Kress's notation, since he uses negative indices which make C++ unhappy. + m_beta.resize(length + 2, std::numeric_limits::quiet_NaN()); + + // Since the splines have compact support, they decay to zero very fast outside the endpoints. + // This is often very annoying; we'd like to evaluate the interpolant a little bit outside the + // boundary [a,b] without massive error. + // A simple way to deal with this is just to subtract the DC component off the signal, so we need the average. + // This algorithm for computing the average is recommended in + // http://www.heikohoffmann.de/htmlthesis/node134.html + Real t = 1; + for (size_t i = 0; i < length; ++i) + { + if (boost::math::isnan(f[i])) + { + std::string err = "This function you are trying to interpolate is a nan at index " + std::to_string(i) + "\n"; + throw std::logic_error(err); + } + m_avg += (f[i] - m_avg) / t; + t += 1; + } + + + // Now we must solve an almost-tridiagonal system, which requires O(N) operations. + // There are, in fact 5 diagonals, but they only differ from zero on the first and last row, + // so we can patch up the tridiagonal row reduction algorithm to deal with two special rows. + // See Kress, equations 8.41 + // The the "tridiagonal" matrix is: + // 1 0 -1 + // 1 4 1 + // 1 4 1 + // 1 4 1 + // .... + // 1 4 1 + // 1 0 -1 + // Numerical estimate indicate that as N->Infinity, cond(A) -> 6.9, so this matrix is good. + std::vector rhs(length + 2, std::numeric_limits::quiet_NaN()); + std::vector super_diagonal(length + 2, std::numeric_limits::quiet_NaN()); + + rhs[0] = -2*step_size*a1; + rhs[rhs.size() - 1] = -2*step_size*b1; + + super_diagonal[0] = 0; + + for(size_t i = 1; i < rhs.size() - 1; ++i) + { + rhs[i] = 6*(f[i - 1] - m_avg); + super_diagonal[i] = 1; + } + + + // One step of row reduction on the first row to patch up the 5-diagonal problem: + // 1 0 -1 | r0 + // 1 4 1 | r1 + // mapsto: + // 1 0 -1 | r0 + // 0 4 2 | r1 - r0 + // mapsto + // 1 0 -1 | r0 + // 0 1 1/2| (r1 - r0)/4 + super_diagonal[1] = 0.5; + rhs[1] = (rhs[1] - rhs[0])/4; + + // Now do a tridiagonal row reduction the standard way, until just before the last row: + for (size_t i = 2; i < rhs.size() - 1; ++i) + { + Real diagonal = 4 - super_diagonal[i - 1]; + rhs[i] = (rhs[i] - rhs[i - 1])/diagonal; + super_diagonal[i] /= diagonal; + } + + // Now the last row, which is in the form + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 1 0 -1 | rhs[n-1] + Real final_subdiag = -super_diagonal[rhs.size() - 3]; + rhs[rhs.size() - 1] = (rhs[rhs.size() - 1] - rhs[rhs.size() - 3])/final_subdiag; + Real final_diag = -1/final_subdiag; + // Now we're here: + // 1 sd[n-3] 0 | rhs[n-3] + // 0 1 sd[n-2] | rhs[n-2] + // 0 1 final_diag | (rhs[n-1] - rhs[n-3])/diag + + final_diag = final_diag - super_diagonal[rhs.size() - 2]; + rhs[rhs.size() - 1] = rhs[rhs.size() - 1] - rhs[rhs.size() - 2]; + + + // Back substitutions: + m_beta[rhs.size() - 1] = rhs[rhs.size() - 1]/final_diag; + for(size_t i = rhs.size() - 2; i > 0; --i) + { + m_beta[i] = rhs[i] - super_diagonal[i]*m_beta[i + 1]; + } + m_beta[0] = m_beta[2] + rhs[0]; +} + +template +Real cubic_b_spline_imp::operator()(Real x) const +{ + // See Kress, 8.40: Since B3 has compact support, we don't have to sum over all terms, + // just the (at most 5) whose support overlaps the argument. + Real z = m_avg; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((max)((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2))), 0l)); + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline(t - k); + } + + return z; +} + +template +Real cubic_b_spline_imp::prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_prime(t - k); + } + return z*m_h_inv; +} + +template +Real cubic_b_spline_imp::double_prime(Real x) const +{ + Real z = 0; + Real t = m_h_inv*(x - m_a) + 1; + + using std::max; + using std::min; + using std::ceil; + using std::floor; + + size_t k_min = static_cast((max)(static_cast(0), boost::math::ltrunc(ceil(t - 2)))); + size_t k_max = static_cast((min)(static_cast(m_beta.size() - 1), boost::math::ltrunc(floor(t + 2)))); + + for (size_t k = k_min; k <= k_max; ++k) + { + z += m_beta[k]*b3_spline_double_prime(t - k); + } + return z*m_h_inv*m_h_inv; +} + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/cubic_hermite_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/cubic_hermite_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/cubic_hermite_detail.hpp @@ -0,0 +1,438 @@ +// Copyright Nick Thompson, 2020 +// 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_INTERPOLATORS_DETAIL_CUBIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_CUBIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class cubic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + using Size = typename RandomAccessContainer::size_type; + + cubic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer dydx) + : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)} + { + using std::abs; + using std::isnan; + if (x_.size() != y_.size()) + { + throw std::domain_error("There must be the same number of ordinates as abscissas."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("There must be the same number of ordinates as derivative values."); + } + if (x_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + Real x0 = x_[0]; + for (size_t i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Abscissas must be listed in strictly increasing order x0 < x1 < ... < x_{n-1}, "; + oss << "but at x[" << i - 1 << "] = " << x0 << ", and x[" << i << "] = " << x1 << ".\n"; + throw std::domain_error(oss.str()); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) + { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + } + + Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // We need t := (x-x_k)/(x_{k+1}-x_k) \in [0,1) for this to work. + // Sadly this neccessitates this loathesome check, otherwise we get t = 1 at x = xf. + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real s0 = dydx_[i]; + Real s1 = dydx_[i+1]; + Real dx = (x1-x0); + Real t = (x-x0)/dx; + + // See the section 'Representations' in the page + // https://en.wikipedia.org/wiki/Cubic_Hermite_spline + Real y = (1-t)*(1-t)*(y0*(1+2*t) + s0*(x-x0)) + + t*t*(y1*(3-2*t) + dx*s1*(t-1)); + return y; + } + + Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real s0 = dydx_[i]; + Real s1 = dydx_[i+1]; + Real dx = (x1-x0); + + Real d1 = (y1 - y0 - s0*dx)/(dx*dx); + Real d2 = (s1 - s0)/(2*dx); + Real c2 = 3*d1 - 2*d2; + Real c3 = 2*(d2 - d1)/dx; + return s0 + 2*c2*(x-x0) + 3*c3*(x-x0)*(x-x0); + } + + + friend std::ostream& operator<<(std::ostream & os, const cubic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) + { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ")}"; + return os; + } + + Size size() const + { + return x_.size(); + } + + int64_t bytes() const + { + return 3*x_.size()*sizeof(Real) + 3*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; +}; + +template +class cardinal_cubic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + using Size = typename RandomAccessContainer::size_type; + + cardinal_cubic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer dydx, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, x0_{x0}, inv_dx_{1/dx} + { + using std::abs; + using std::isnan; + if (y_.size() != dy_.size()) + { + throw std::domain_error("There must be the same number of derivatives as ordinates."); + } + if (y_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + } + + // Why not implement push_back? It's awkward: If the buffer is circular, x0_ += dx_. + // If the buffer is not circular, x0_ is unchanged. + // We need a concept for circular_buffer! + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + + Real r = 1-t; + return r*r*(y0*(1+2*t) + dy0*t) + + t*t*(y1*(3-2*t) - dy1*r); + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()*inv_dx_; + } + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + + Real dy = 6*t*(1-t)*(y1 - y0) + (3*t*t - 4*t+1)*dy0 + t*(3*t-2)*dy1; + return dy*inv_dx_; + } + + + Size size() const + { + return y_.size(); + } + + int64_t bytes() const + { + return 2*y_.size()*sizeof(Real) + 2*sizeof(y_) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + + RandomAccessContainer y_; + RandomAccessContainer dy_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_cubic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + using Size = typename RandomAccessContainer::size_type; + + cardinal_cubic_hermite_detail_aos(RandomAccessContainer && dat, Real x0, Real dx) + : dat_{std::move(dat)}, x0_{x0}, inv_dx_{1/dx} + { + if (dat_.size() < 2) + { + throw std::domain_error("Must be at least two data points."); + } + if (dat_[0].size() != 2) + { + throw std::domain_error("Each datum must contain (y, y'), and nothing else."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & d : dat_) + { + d[1] *= dx; + } + } + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (dat_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dat_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + + Real t = s - ii; + // If we had infinite precision, this would never happen. + // But we don't have infinite precision. + if (t == 0) + { + return dat_[i][0]; + } + Real y0 = dat_[i][0]; + Real y1 = dat_[i+1][0]; + Real dy0 = dat_[i][1]; + Real dy1 = dat_[i+1][1]; + + Real r = 1-t; + return r*r*(y0*(1+2*t) + dy0*t) + + t*t*(y1*(3-2*t) - dy1*r); + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (dat_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dat_.back()[1]*inv_dx_; + } + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return dat_[i][1]*inv_dx_; + } + Real y0 = dat_[i][0]; + Real dy0 = dat_[i][1]; + Real y1 = dat_[i+1][0]; + Real dy1 = dat_[i+1][1]; + + Real dy = 6*t*(1-t)*(y1 - y0) + (3*t*t - 4*t+1)*dy0 + t*(3*t-2)*dy1; + return dy*inv_dx_; + } + + + Size size() const + { + return dat_.size(); + } + + int64_t bytes() const + { + return dat_.size()*dat_[0].size()*sizeof(Real) + sizeof(dat_) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (dat_.size()-1)/inv_dx_; + return {x0_, xf}; + } + + +private: + RandomAccessContainer dat_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/quintic_hermite_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/quintic_hermite_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/quintic_hermite_detail.hpp @@ -0,0 +1,585 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_INTERPOLATORS_DETAIL_QUINTIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_QUINTIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class quintic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + quintic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2) : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)}, d2ydx2_{std::move(d2ydx2)} + { + if (x_.size() != y_.size()) + { + throw std::domain_error("Number of abscissas must = number of ordinates."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (x_.size() != d2ydx2_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (x_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + Real x0 = x_[0]; + for (decltype(x_.size()) i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + throw std::domain_error("Abscissas must be sorted in strictly increasing order x0 < x1 < ... < x_{n-1}"); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) + { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + d2ydx2_.push_back(d2ydx2); + } + + inline Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // We need t := (x-x_k)/(x_{k+1}-x_k) \in [0,1) for this to work. + // Sadly this neccessitates this loathesome check, otherwise we get t = 1 at x = xf. + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + + Real dx = (x1-x0); + Real t = (x-x0)/dx; + Real t2 = t*t; + Real t3 = t2*t; + + // See the 'Basis functions' section of: + // https://www.rose-hulman.edu/~finn/CCLI/Notes/day09.pdf + // Also: https://github.com/MrHexxx/QuinticHermiteSpline/blob/master/HermiteSpline.cs + Real y = (1- t3*(10 + t*(-15 + 6*t)))*y0; + y += t*(1+ t2*(-6 + t*(8 -3*t)))*v0*dx; + y += t2*(1 + t*(-3 + t*(3-t)))*a0*dx*dx/2; + y += t3*((1 + t*(-2 + t))*a1*dx*dx/2 + (-4 + t*(7 - 3*t))*v1*dx + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = x1 - x0; + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real t= (x-x0)/dx; + Real t2 = t*t; + + Real dydx = 30*t2*(1 - 2*t + t*t)*(y1-y0)/dx; + dydx += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*v0 - t*t*(12 - 28*t + 15*t*t)*v1; + dydx += (t*dx/2)*((2 - 9*t + 12*t*t - 5*t*t*t)*a0 + t*(3 - 8*t + 5*t*t)*a1); + return dydx; + } + + inline Real double_prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return d2ydx2_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = x1 - x0; + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real t = (x-x0)/dx; + + Real d2ydx2 = 60*t*(1 + t*(-3 + 2*t))*(y1-y0)/(dx*dx); + d2ydx2 += 12*t*(-3 + t*(8 - 5*t))*v0/dx; + d2ydx2 -= 12*t*(2 + t*(-7 + 5*t))*v1/dx; + d2ydx2 += (1 + t*(-9 + t*(18 - 10*t)))*a0; + d2ydx2 += t*(3 + t*(-12 + 10*t))*a1; + + return d2ydx2; + } + + friend std::ostream& operator<<(std::ostream & os, const quintic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << ", " << m.d2ydx2_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ", " << m.d2ydx2_[n] << ")}"; + return os; + } + + int64_t bytes() const + { + return 4*x_.size()*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + +private: + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; + RandomAccessContainer d2ydx2_; +}; + + +template +class cardinal_quintic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_quintic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, d2y_{std::move(d2ydx2)}, x0_{x0}, inv_dx_{1/dx} + { + if (y_.size() != dy_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (y_.size() != d2y_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (y_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + + for (auto & d2y : d2y_) + { + d2y *= (dx*dx)/2; + } + } + + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return y_[i]; + } + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + // See the 'Basis functions' section of: + // https://www.rose-hulman.edu/~finn/CCLI/Notes/day09.pdf + // Also: https://github.com/MrHexxx/QuinticHermiteSpline/blob/master/HermiteSpline.cs + Real y = (1- t*t*t*(10 + t*(-15 + 6*t)))*y0; + y += t*(1+ t*t*(-6 + t*(8 -3*t)))*dy0; + y += t*t*(1 + t*(-3 + t*(3-t)))*d2y0; + y += t*t*t*((1 + t*(-2 + t))*d2y1 + (-4 + t*(7 -3*t))*dy1 + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return dy_[i]*inv_dx_; + } + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + Real dydx = 30*t*t*(1 - 2*t + t*t)*(y1-y0); + dydx += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*dy0 - t*t*(12 - 28*t + 15*t*t)*dy1; + dydx += t*((2 - 9*t + 12*t*t - 5*t*t*t)*d2y0 + t*(3 - 8*t + 5*t*t)*d2y1); + dydx *= inv_dx_; + return dydx; + } + + inline Real double_prime(Real x) const + { + const Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return d2y_.back()*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t==0) + { + return d2y_[i]*2*inv_dx_*inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real d2y0 = d2y_[i]; + Real d2y1 = d2y_[i+1]; + + Real d2ydx2 = 60*t*(1 - 3*t + 2*t*t)*(y1 - y0)*inv_dx_*inv_dx_; + d2ydx2 += (12*t)*((-3 + 8*t - 5*t*t)*dy0 - (2 - 7*t + 5*t*t)*dy1); + d2ydx2 += (1 - 9*t + 18*t*t - 10*t*t*t)*d2y0*(2*inv_dx_*inv_dx_) + t*(3 - 12*t + 10*t*t)*d2y1*(2*inv_dx_*inv_dx_); + return d2ydx2; + } + + int64_t bytes() const + { + return 3*y_.size()*sizeof(Real) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + RandomAccessContainer y_; + RandomAccessContainer dy_; + RandomAccessContainer d2y_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_quintic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_quintic_hermite_detail_aos(RandomAccessContainer && data, Real x0, Real dx) + : data_{std::move(data)} , x0_{x0}, inv_dx_{1/dx} + { + if (data_.size() < 2) + { + throw std::domain_error("At least two points are required to interpolate using cardinal_quintic_hermite_aos"); + } + + if (data_[0].size() != 3) + { + throw std::domain_error("Each datum passed to the cardinal_quintic_hermite_aos must have three elements: {y, y', y''}"); + } + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & datum : data_) + { + datum[1] *= dx; + datum[2] *= (dx*dx/2); + } + } + + + inline Real operator()(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return data_[i][0]; + } + + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real d2y0 = data_[i][2]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real d2y1 = data_[i+1][2]; + + Real y = (1 - t*t*t*(10 + t*(-15 + 6*t)))*y0; + y += t*(1 + t*t*(-6 + t*(8 - 3*t)))*dy0; + y += t*t*(1 + t*(-3 + t*(3 - t)))*d2y0; + y += t*t*t*((1 + t*(-2 + t))*d2y1 + (-4 + t*(7 - 3*t))*dy1 + (10 + t*(-15 + 6*t))*y1); + return y; + } + + inline Real prime(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[1]*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) + { + return data_[i][1]*inv_dx_; + } + + + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real v0 = data_[i][1]; + Real v1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + + Real dy = 30*t*t*(1 - 2*t + t*t)*(y1-y0); + dy += (1-18*t*t + 32*t*t*t - 15*t*t*t*t)*v0 - t*t*(12 - 28*t + 15*t*t)*v1; + dy += t*((2 - 9*t + 12*t*t - 5*t*t*t)*a0 + t*(3 - 8*t + 5*t*t)*a1); + return dy*inv_dx_; + } + + inline Real double_prime(Real x) const + { + const Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[2]*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s = (x-x0_)*inv_dx_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + if (t == 0) { + return data_[i][2]*2*inv_dx_*inv_dx_; + } + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real d2y0 = data_[i][2]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real d2y1 = data_[i+1][2]; + + Real d2ydx2 = 60*t*(1 - 3*t + 2*t*t)*(y1 - y0)*inv_dx_*inv_dx_; + d2ydx2 += (12*t)*((-3 + 8*t - 5*t*t)*dy0 - (2 - 7*t + 5*t*t)*dy1); + d2ydx2 += (1 - 9*t + 18*t*t - 10*t*t*t)*d2y0*(2*inv_dx_*inv_dx_) + t*(3 - 12*t + 10*t*t)*d2y1*(2*inv_dx_*inv_dx_); + return d2ydx2; + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + 2*sizeof(Real); + } + + std::pair domain() const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + return {x0_, xf}; + } + +private: + RandomAccessContainer data_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/septic_hermite_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/septic_hermite_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/septic_hermite_detail.hpp @@ -0,0 +1,652 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_INTERPOLATORS_DETAIL_SEPTIC_HERMITE_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_DETAIL_SEPTIC_HERMITE_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { +namespace detail { + +template +class septic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + septic_hermite_detail(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3) + : x_{std::move(x)}, y_{std::move(y)}, dydx_{std::move(dydx)}, d2ydx2_{std::move(d2ydx2)}, d3ydx3_{std::move(d3ydx3)} + { + if (x_.size() != y_.size()) + { + throw std::domain_error("Number of abscissas must = number of ordinates."); + } + if (x_.size() != dydx_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of abscissas."); + } + if (x_.size() != d2ydx2_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of abscissas."); + } + if (x_.size() != d3ydx3_.size()) + { + throw std::domain_error("Number of third derivatives must equal number of abscissas."); + } + + if (x_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + Real x0 = x_[0]; + for (decltype(x_.size()) i = 1; i < x_.size(); ++i) + { + Real x1 = x_[i]; + if (x1 <= x0) + { + throw std::domain_error("Abscissas must be sorted in strictly increasing order x0 < x1 < ... < x_{n-1}"); + } + x0 = x1; + } + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2, Real d3ydx3) + { + using std::abs; + using std::isnan; + if (x <= x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + x_.push_back(x); + y_.push_back(y); + dydx_.push_back(dydx); + d2ydx2_.push_back(d2ydx2); + d3ydx3_.push_back(d3ydx3); + } + + Real operator()(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + // t \in [0, 1) + if (x == x_.back()) + { + return y_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real dx = (x1-x0); + Real t = (x-x0)/dx; + + // See: + // http://seisweb.usask.ca/classes/GEOL481/2017/Labs/interpolation_utilities_matlab/shermite.m + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + Real dx2 = dx*dx/2; + Real dx3 = dx2*dx/3; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36 + 10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15 + 4*t)))); + Real z3 = t3*(1 + t*(-4 + t*(6 + t*(-4 + t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13 - 4*t))); + Real z7 = t4*(-1 + t*(3 + t*(-3+t))); + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + // Velocity: + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + // Acceleration: + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + // Jerk: + Real j0 = d3ydx3_[i]; + Real j1 = d3ydx3_[i+1]; + + return z0*y0 + z4*y1 + (z1*v0 + z5*v1)*dx + (z2*a0 + z6*a1)*dx2 + (z3*j0 + z7*j1)*dx3; + } + + Real prime(Real x) const + { + if (x < x_[0] || x > x_.back()) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x_[0] << ", " << x_.back() << "]"; + throw std::domain_error(oss.str()); + } + if (x == x_.back()) + { + return dydx_.back(); + } + + auto it = std::upper_bound(x_.begin(), x_.end(), x); + auto i = std::distance(x_.begin(), it) -1; + Real x0 = *(it-1); + Real x1 = *it; + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real v0 = dydx_[i]; + Real v1 = dydx_[i+1]; + Real a0 = d2ydx2_[i]; + Real a1 = d2ydx2_[i+1]; + Real j0 = d3ydx3_[i]; + Real j1 = d3ydx3_[i+1]; + Real dx = x1 - x0; + Real t = (x-x0)/dx; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)/dx; + dydx += z1*v0 + z2*v1; + dydx += (x-x0)*(z3*a0 + z4*a1); + dydx += (x-x0)*(x-x0)*(z5*j0 + z6*j1)/6; + return dydx; + } + + inline Real double_prime(Real) const + { + return std::numeric_limits::quiet_NaN(); + } + + friend std::ostream& operator<<(std::ostream & os, const septic_hermite_detail & m) + { + os << "(x,y,y') = {"; + for (size_t i = 0; i < m.x_.size() - 1; ++i) { + os << "(" << m.x_[i] << ", " << m.y_[i] << ", " << m.dydx_[i] << ", " << m.d2ydx2_[i] << ", " << m.d3ydx3_[i] << "), "; + } + auto n = m.x_.size()-1; + os << "(" << m.x_[n] << ", " << m.y_[n] << ", " << m.dydx_[n] << ", " << m.d2ydx2_[n] << m.d3ydx3_[n] << ")}"; + return os; + } + + int64_t bytes() + { + return 5*x_.size()*sizeof(Real) + 5*sizeof(x_); + } + + std::pair domain() const + { + return {x_.front(), x_.back()}; + } + +private: + RandomAccessContainer x_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; + RandomAccessContainer d2ydx2_; + RandomAccessContainer d3ydx3_; +}; + +template +class cardinal_septic_hermite_detail { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_septic_hermite_detail(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3, Real x0, Real dx) + : y_{std::move(y)}, dy_{std::move(dydx)}, d2y_{std::move(d2ydx2)}, d3y_{std::move(d3ydx3)}, x0_{x0}, inv_dx_{1/dx} + { + if (y_.size() != dy_.size()) + { + throw std::domain_error("Numbers of derivatives must = number of ordinates."); + } + if (y_.size() != d2y_.size()) + { + throw std::domain_error("Number of second derivatives must equal number of ordinates."); + } + if (y_.size() != d3y_.size()) + { + throw std::domain_error("Number of third derivatives must equal number of ordinates."); + } + if (y_.size() < 2) + { + throw std::domain_error("At least 2 abscissas are required."); + } + + if (dx <= 0) + { + throw std::domain_error("dx > 0 is required."); + } + + for (auto & dy : dy_) + { + dy *= dx; + } + for (auto & d2y : d2y_) + { + d2y *= (dx*dx/2); + } + for (auto & d3y : d3y_) + { + d3y *= (dx*dx*dx/6); + } + + } + + inline Real operator()(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return y_.back(); + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) { + return y_[i]; + } + // See: + // http://seisweb.usask.ca/classes/GEOL481/2017/Labs/interpolation_utilities_matlab/shermite.m + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36+10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15+4*t)))); + Real z3 = t3*(1 + t*(-4+t*(6+t*(-4+t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13-4*t))); + Real z7 = t4*(-1 + t*(3+t*(-3+t))); + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + + return z0*y0 + z1*dy0 + z2*a0 + z3*j0 + z4*y1 + z5*dy1 + z6*a1 + z7*j1; + } + + inline Real prime(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return dy_.back()/inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return dy_[i]/inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)*inv_dx_; + dydx += (z1*dy0 + z2*dy1)*inv_dx_; + dydx += 2*t*(z3*a0 + z4*a1)*inv_dx_; + dydx += t*t*(z5*j0 + z6*j1); + return dydx; + } + + inline Real double_prime(Real x) const + { + Real xf = x0_ + (y_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return d2y_.back()*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return d2y_[i]*2*inv_dx_*inv_dx_; + } + + Real y0 = y_[i]; + Real y1 = y_[i+1]; + Real dy0 = dy_[i]; + Real dy1 = dy_[i+1]; + Real a0 = d2y_[i]; + Real a1 = d2y_[i+1]; + Real j0 = d3y_[i]; + Real j1 = d3y_[i+1]; + Real t2 = t*t; + + Real z0 = 420*t2*(1 + t*(-4 + t*(5 - 2*t))); + Real z1 = 60*t2*(-4 + t*(15 + t*(-18 + 7*t))); + Real z2 = 60*t2*(-3 + t*(13 + t*(-17 + 7*t))); + Real z3 = (1 + t2*(-60 + t*(200 + t*(-225 + 84*t)))); + Real z4 = t2*(30 + t*(-140 + t*(195 - 84*t))); + Real z5 = t*(1 + t*(-8 + t*(20 + t*(-20 + 7*t)))); + Real z6 = t2*(-2 + t*(10 + t*(-15 + 7*t))); + + Real d2ydx2 = z0*(y1-y0)*inv_dx_*inv_dx_; + d2ydx2 += (z1*dy0 + z2*dy1)*inv_dx_*inv_dx_; + d2ydx2 += (z3*a0 + z4*a1)*2*inv_dx_*inv_dx_; + d2ydx2 += 6*(z5*j0 + z6*j1)/(inv_dx_*inv_dx_); + + return d2ydx2; + } + + int64_t bytes() const + { + return 4*y_.size()*sizeof(Real) + 2*sizeof(Real) + 4*sizeof(y_); + } + + std::pair domain() const + { + return {x0_, x0_ + (y_.size()-1)/inv_dx_}; + } + +private: + RandomAccessContainer y_; + RandomAccessContainer dy_; + RandomAccessContainer d2y_; + RandomAccessContainer d3y_; + Real x0_; + Real inv_dx_; +}; + + +template +class cardinal_septic_hermite_detail_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_septic_hermite_detail_aos(RandomAccessContainer && dat, Real x0, Real dx) + : data_{std::move(dat)}, x0_{x0}, inv_dx_{1/dx} + { + if (data_.size() < 2) { + throw std::domain_error("At least 2 abscissas are required."); + } + if (data_[0].size() != 4) { + throw std::domain_error("There must be 4 data items per struct."); + } + + for (auto & datum : data_) + { + datum[1] *= dx; + datum[2] *= (dx*dx/2); + datum[3] *= (dx*dx*dx/6); + } + } + + inline Real operator()(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[0]; + } + return this->unchecked_evaluation(x); + } + + inline Real unchecked_evaluation(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t==0) + { + return data_[i][0]; + } + Real t2 = t*t; + Real t3 = t2*t; + Real t4 = t3*t; + + Real s = t4*(-35 + t*(84 + t*(-70 + 20*t))); + Real z4 = -s; + Real z0 = s + 1; + Real z1 = t*(1 + t3*(-20 + t*(45 + t*(-36+10*t)))); + Real z2 = t2*(1 + t2*(-10 + t*(20 + t*(-15+4*t)))); + Real z3 = t3*(1 + t*(-4+t*(6+t*(-4+t)))); + Real z5 = t4*(-15 + t*(39 + t*(-34 + 10*t))); + Real z6 = t4*(5 + t*(-14 + t*(13-4*t))); + Real z7 = t4*(-1 + t*(3+t*(-3+t))); + + Real y0 = data_[i][0]; + Real dy0 = data_[i][1]; + Real a0 = data_[i][2]; + Real j0 = data_[i][3]; + Real y1 = data_[i+1][0]; + Real dy1 = data_[i+1][1]; + Real a1 = data_[i+1][2]; + Real j1 = data_[i+1][3]; + + return z0*y0 + z1*dy0 + z2*a0 + z3*j0 + z4*y1 + z5*dy1 + z6*a1 + z7*j1; + } + + inline Real prime(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[1]*inv_dx_; + } + + return this->unchecked_prime(x); + } + + inline Real unchecked_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) + { + return data_[i][1]*inv_dx_; + } + + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dy0 = data_[i][1]; + Real dy1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + Real j0 = data_[i][3]; + Real j1 = data_[i+1][3]; + Real t2 = t*t; + Real t3 = t2*t; + Real z0 = 140*t3*(1 + t*(-3 + t*(3 - t))); + Real z1 = 1 + t3*(-80 + t*(225 + t*(-216 + 70*t))); + Real z2 = t3*(-60 + t*(195 + t*(-204 + 70*t))); + Real z3 = 1 + t2*(-20 + t*(50 + t*(-45 + 14*t))); + Real z4 = t2*(10 + t*(-35 + t*(39 - 14*t))); + Real z5 = 3 + t*(-16 + t*(30 + t*(-24 + 7*t))); + Real z6 = t*(-4 + t*(15 + t*(-18 + 7*t))); + + Real dydx = z0*(y1-y0)*inv_dx_; + dydx += (z1*dy0 + z2*dy1)*inv_dx_; + dydx += 2*t*(z3*a0 + z4*a1)*inv_dx_; + dydx += t*t*(z5*j0 + z6*j1); + return dydx; + } + + inline Real double_prime(Real x) const + { + Real xf = x0_ + (data_.size()-1)/inv_dx_; + if (x < x0_ || x > xf) + { + std::ostringstream oss; + oss.precision(std::numeric_limits::digits10+3); + oss << "Requested abscissa x = " << x << ", which is outside of allowed range [" + << x0_ << ", " << xf << "]"; + throw std::domain_error(oss.str()); + } + if (x == xf) + { + return data_.back()[2]*2*inv_dx_*inv_dx_; + } + + return this->unchecked_double_prime(x); + } + + inline Real unchecked_double_prime(Real x) const + { + using std::floor; + Real s3 = (x-x0_)*inv_dx_; + Real ii = floor(s3); + auto i = static_cast(ii); + Real t = s3 - ii; + if (t == 0) + { + return data_[i][2]*2*inv_dx_*inv_dx_; + } + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dy0 = data_[i][1]; + Real dy1 = data_[i+1][1]; + Real a0 = data_[i][2]; + Real a1 = data_[i+1][2]; + Real j0 = data_[i][3]; + Real j1 = data_[i+1][3]; + Real t2 = t*t; + + Real z0 = 420*t2*(1 + t*(-4 + t*(5 - 2*t))); + Real z1 = 60*t2*(-4 + t*(15 + t*(-18 + 7*t))); + Real z2 = 60*t2*(-3 + t*(13 + t*(-17 + 7*t))); + Real z3 = (1 + t2*(-60 + t*(200 + t*(-225 + 84*t)))); + Real z4 = t2*(30 + t*(-140 + t*(195 - 84*t))); + Real z5 = t*(1 + t*(-8 + t*(20 + t*(-20 + 7*t)))); + Real z6 = t2*(-2 + t*(10 + t*(-15 + 7*t))); + + Real d2ydx2 = z0*(y1-y0)*inv_dx_*inv_dx_; + d2ydx2 += (z1*dy0 + z2*dy1)*inv_dx_*inv_dx_; + d2ydx2 += (z3*a0 + z4*a1)*2*inv_dx_*inv_dx_; + d2ydx2 += 6*(z5*j0 + z6*j1)/(inv_dx_*inv_dx_); + + return d2ydx2; + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + 2*sizeof(Real) + sizeof(data_); + } + + std::pair domain() const + { + return {x0_, x0_ + (data_.size() -1)/inv_dx_}; + } + +private: + RandomAccessContainer data_; + Real x0_; + Real inv_dx_; +}; + +} +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/vector_barycentric_rational_detail.hpp @@ -0,0 +1,195 @@ +/* + * Copyright Nick Thompson, 2019 + * 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_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_DETAIL_HPP + +#include +#include +#include // for std::move +#include +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ namespace detail{ + +template +class vector_barycentric_rational_imp +{ +public: + using Real = typename TimeContainer::value_type; + using Point = typename SpaceContainer::value_type; + + vector_barycentric_rational_imp(TimeContainer&& t, SpaceContainer&& y, size_t approximation_order); + + void operator()(Point& p, Real t) const; + + void eval_with_prime(Point& x, Point& dxdt, Real t) const; + + // The barycentric weights are only interesting to the unit tests: + Real weight(size_t i) const { return w_[i]; } + +private: + + void calculate_weights(size_t approximation_order); + + TimeContainer t_; + SpaceContainer y_; + TimeContainer w_; +}; + +template +vector_barycentric_rational_imp::vector_barycentric_rational_imp(TimeContainer&& t, SpaceContainer&& y, size_t approximation_order) +{ + using std::numeric_limits; + t_ = std::move(t); + y_ = std::move(y); + + BOOST_MATH_ASSERT_MSG(t_.size() == y_.size(), "There must be the same number of time points as space points."); + BOOST_MATH_ASSERT_MSG(approximation_order < y_.size(), "Approximation order must be < data length."); + for (size_t i = 1; i < t_.size(); ++i) + { + BOOST_MATH_ASSERT_MSG(t_[i] - t_[i-1] > (numeric_limits::min)(), "The abscissas must be listed in strictly increasing order t[0] < t[1] < ... < t[n-1]."); + } + calculate_weights(approximation_order); +} + + +template +void vector_barycentric_rational_imp::calculate_weights(size_t approximation_order) +{ + using Real = typename TimeContainer::value_type; + using std::abs; + int64_t n = t_.size(); + w_.resize(n, Real(0)); + for(int64_t k = 0; k < n; ++k) + { + int64_t i_min = (std::max)(k - static_cast(approximation_order), static_cast(0)); + int64_t i_max = k; + if (k >= n - (std::ptrdiff_t)approximation_order) + { + i_max = n - approximation_order - 1; + } + + for(int64_t i = i_min; i <= i_max; ++i) + { + Real inv_product = 1; + int64_t j_max = (std::min)(static_cast(i + approximation_order), static_cast(n - 1)); + for(int64_t j = i; j <= j_max; ++j) + { + if (j == k) + { + continue; + } + Real diff = t_[k] - t_[j]; + inv_product *= diff; + } + if (i % 2 == 0) + { + w_[k] += 1/inv_product; + } + else + { + w_[k] -= 1/inv_product; + } + } + } +} + + +template +void vector_barycentric_rational_imp::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const +{ + using Real = typename TimeContainer::value_type; + for (auto & x : p) + { + x = Real(0); + } + Real denominator = 0; + for(size_t i = 0; i < t_.size(); ++i) + { + // See associated commentary in the scalar version of this function. + if (t == t_[i]) + { + p = y_[i]; + return; + } + Real x = w_[i]/(t - t_[i]); + for (decltype(p.size()) j = 0; j < p.size(); ++j) + { + p[j] += x*y_[i][j]; + } + denominator += x; + } + for (decltype(p.size()) j = 0; j < p.size(); ++j) + { + p[j] /= denominator; + } + return; +} + +template +void vector_barycentric_rational_imp::eval_with_prime(typename SpaceContainer::value_type& x, typename SpaceContainer::value_type& dxdt, typename TimeContainer::value_type t) const +{ + using Point = typename SpaceContainer::value_type; + using Real = typename TimeContainer::value_type; + this->operator()(x, t); + Point numerator; + for (decltype(x.size()) i = 0; i < x.size(); ++i) + { + numerator[i] = 0; + } + Real denominator = 0; + for(decltype(t_.size()) i = 0; i < t_.size(); ++i) + { + if (t == t_[i]) + { + Point sum; + for (decltype(x.size()) i = 0; i < x.size(); ++i) + { + sum[i] = 0; + } + + for (decltype(t_.size()) j = 0; j < t_.size(); ++j) + { + if (j == i) + { + continue; + } + for (decltype(sum.size()) k = 0; k < sum.size(); ++k) + { + sum[k] += w_[j]*(y_[i][k] - y_[j][k])/(t_[i] - t_[j]); + } + } + for (decltype(sum.size()) k = 0; k < sum.size(); ++k) + { + dxdt[k] = -sum[k]/w_[i]; + } + return; + } + Real tw = w_[i]/(t - t_[i]); + Point diff; + for (decltype(diff.size()) j = 0; j < diff.size(); ++j) + { + diff[j] = (x[j] - y_[i][j])/(t-t_[i]); + } + for (decltype(diff.size()) j = 0; j < diff.size(); ++j) + { + numerator[j] += tw*diff[j]; + } + denominator += tw; + } + + for (decltype(dxdt.size()) j = 0; j < dxdt.size(); ++j) + { + dxdt[j] = numerator[j]/denominator; + } + return; +} + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/detail/whittaker_shannon_detail.hpp b/libcxx/src/third-party/boost/math/interpolators/detail/whittaker_shannon_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/detail/whittaker_shannon_detail.hpp @@ -0,0 +1,126 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_WHITAKKER_SHANNON_DETAIL_HPP +#define BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_DETAIL_HPP +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace interpolators { namespace detail { + +template +class whittaker_shannon_detail { +public: + + using Real = typename RandomAccessContainer::value_type; + whittaker_shannon_detail(RandomAccessContainer&& y, Real const & t0, Real const & h) : m_y{std::move(y)}, m_t0{t0}, m_h{h} + { + for (size_t i = 1; i < m_y.size(); i += 2) + { + m_y[i] = -m_y[i]; + } + } + + inline Real operator()(Real t) const { + using boost::math::constants::pi; + using std::isfinite; + using std::floor; + Real y = 0; + Real x = (t - m_t0)/m_h; + Real z = x; + auto it = m_y.begin(); + + // For some reason, neither clang nor g++ will cache the address of m_y.end() in a register. + // Hence make a copy of it: + auto end = m_y.end(); + while(it != end) + { + y += *it++/z; + z -= 1; + } + + if (!isfinite(y)) + { + BOOST_MATH_ASSERT_MSG(floor(x) == ceil(x), "Floor and ceiling should be equal.\n"); + auto i = static_cast(floor(x)); + if (i & 1) + { + return -m_y[i]; + } + return m_y[i]; + } + return y*boost::math::sin_pi(x)/pi(); + } + + Real prime(Real t) const { + using boost::math::constants::pi; + using std::isfinite; + using std::floor; + + Real x = (t - m_t0)/m_h; + if (ceil(x) == x) { + Real s = 0; + auto j = static_cast(x); + auto n = static_cast(m_y.size()); + for (long i = 0; i < n; ++i) + { + if (j - i != 0) + { + s += m_y[i]/(j-i); + } + // else derivative of sinc at zero is zero. + } + if (j & 1) { + s /= -m_h; + } else { + s /= m_h; + } + return s; + } + Real z = x; + auto it = m_y.begin(); + Real cospix = boost::math::cos_pi(x); + Real sinpix_div_pi = boost::math::sin_pi(x)/pi(); + + Real s = 0; + auto end = m_y.end(); + while(it != end) + { + s += (*it++)*(z*cospix - sinpix_div_pi)/(z*z); + z -= 1; + } + + return s/m_h; + } + + + + Real operator[](size_t i) const { + if (i & 1) + { + return -m_y[i]; + } + return m_y[i]; + } + + RandomAccessContainer&& return_data() { + for (size_t i = 1; i < m_y.size(); i += 2) + { + m_y[i] = -m_y[i]; + } + return std::move(m_y); + } + + +private: + RandomAccessContainer m_y; + Real m_t0; + Real m_h; +}; +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/makima.hpp b/libcxx/src/third-party/boost/math/interpolators/makima.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/makima.hpp @@ -0,0 +1,178 @@ +// Copyright Nick Thompson, 2020 +// 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) + +// See: https://blogs.mathworks.com/cleve/2019/04/29/makima-piecewise-cubic-interpolation/ +// And: https://doi.org/10.1145/321607.321609 + +#ifndef BOOST_MATH_INTERPOLATORS_MAKIMA_HPP +#define BOOST_MATH_INTERPOLATORS_MAKIMA_HPP +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class makima { +public: + using Real = typename RandomAccessContainer::value_type; + + makima(RandomAccessContainer && x, RandomAccessContainer && y, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + using std::isnan; + using std::abs; + if (x.size() < 4) + { + throw std::domain_error("Must be at least four data points."); + } + RandomAccessContainer s(x.size(), std::numeric_limits::quiet_NaN()); + Real m2 = (y[3]-y[2])/(x[3]-x[2]); + Real m1 = (y[2]-y[1])/(x[2]-x[1]); + Real m0 = (y[1]-y[0])/(x[1]-x[0]); + // Quadratic extrapolation: m_{-1} = 2m_0 - m_1: + Real mm1 = 2*m0 - m1; + // Quadratic extrapolation: m_{-2} = 2*m_{-1}-m_0: + Real mm2 = 2*mm1 - m0; + Real w1 = abs(m1-m0) + abs(m1+m0)/2; + Real w2 = abs(mm1-mm2) + abs(mm1+mm2)/2; + if (isnan(left_endpoint_derivative)) + { + s[0] = (w1*mm1 + w2*m0)/(w1+w2); + if (isnan(s[0])) + { + s[0] = 0; + } + } + else + { + s[0] = left_endpoint_derivative; + } + + w1 = abs(m2-m1) + abs(m2+m1)/2; + w2 = abs(m0-mm1) + abs(m0+mm1)/2; + s[1] = (w1*m0 + w2*m1)/(w1+w2); + if (isnan(s[1])) { + s[1] = 0; + } + + for (decltype(s.size()) i = 2; i < s.size()-2; ++i) { + Real mim2 = (y[i-1]-y[i-2])/(x[i-1]-x[i-2]); + Real mim1 = (y[i ]-y[i-1])/(x[i ]-x[i-1]); + Real mi = (y[i+1]-y[i ])/(x[i+1]-x[i ]); + Real mip1 = (y[i+2]-y[i+1])/(x[i+2]-x[i+1]); + w1 = abs(mip1-mi) + abs(mip1+mi)/2; + w2 = abs(mim1-mim2) + abs(mim1+mim2)/2; + s[i] = (w1*mim1 + w2*mi)/(w1+w2); + if (isnan(s[i])) { + s[i] = 0; + } + } + // Quadratic extrapolation at the other end: + + decltype(s.size()) n = s.size(); + Real mnm4 = (y[n-3]-y[n-4])/(x[n-3]-x[n-4]); + Real mnm3 = (y[n-2]-y[n-3])/(x[n-2]-x[n-3]); + Real mnm2 = (y[n-1]-y[n-2])/(x[n-1]-x[n-2]); + Real mnm1 = 2*mnm2 - mnm3; + Real mn = 2*mnm1 - mnm2; + w1 = abs(mnm1 - mnm2) + abs(mnm1+mnm2)/2; + w2 = abs(mnm3 - mnm4) + abs(mnm3+mnm4)/2; + + s[n-2] = (w1*mnm3 + w2*mnm2)/(w1 + w2); + if (isnan(s[n-2])) { + s[n-2] = 0; + } + + w1 = abs(mn - mnm1) + abs(mn+mnm1)/2; + w2 = abs(mnm2 - mnm3) + abs(mnm2+mnm3)/2; + + + if (isnan(right_endpoint_derivative)) + { + s[n-1] = (w1*mnm2 + w2*mnm1)/(w1+w2); + if (isnan(s[n-1])) { + s[n-1] = 0; + } + } + else + { + s[n-1] = right_endpoint_derivative; + } + + impl_ = std::make_shared>(std::move(x), std::move(y), std::move(s)); + } + + Real operator()(Real x) const { + return impl_->operator()(x); + } + + Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const makima & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y) { + using std::abs; + using std::isnan; + if (x <= impl_->x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + impl_->x_.push_back(x); + impl_->y_.push_back(y); + impl_->dydx_.push_back(std::numeric_limits::quiet_NaN()); + // dydx_[n-2] was computed by extrapolation. Now dydx_[n-2] -> dydx_[n-3], and it can be computed by the same formula. + decltype(impl_->size()) n = impl_->size(); + auto i = n - 3; + Real mim2 = (impl_->y_[i-1]-impl_->y_[i-2])/(impl_->x_[i-1]-impl_->x_[i-2]); + Real mim1 = (impl_->y_[i ]-impl_->y_[i-1])/(impl_->x_[i ]-impl_->x_[i-1]); + Real mi = (impl_->y_[i+1]-impl_->y_[i ])/(impl_->x_[i+1]-impl_->x_[i ]); + Real mip1 = (impl_->y_[i+2]-impl_->y_[i+1])/(impl_->x_[i+2]-impl_->x_[i+1]); + Real w1 = abs(mip1-mi) + abs(mip1+mi)/2; + Real w2 = abs(mim1-mim2) + abs(mim1+mim2)/2; + impl_->dydx_[i] = (w1*mim1 + w2*mi)/(w1+w2); + if (isnan(impl_->dydx_[i])) { + impl_->dydx_[i] = 0; + } + + Real mnm4 = (impl_->y_[n-3]-impl_->y_[n-4])/(impl_->x_[n-3]-impl_->x_[n-4]); + Real mnm3 = (impl_->y_[n-2]-impl_->y_[n-3])/(impl_->x_[n-2]-impl_->x_[n-3]); + Real mnm2 = (impl_->y_[n-1]-impl_->y_[n-2])/(impl_->x_[n-1]-impl_->x_[n-2]); + Real mnm1 = 2*mnm2 - mnm3; + Real mn = 2*mnm1 - mnm2; + w1 = abs(mnm1 - mnm2) + abs(mnm1+mnm2)/2; + w2 = abs(mnm3 - mnm4) + abs(mnm3+mnm4)/2; + + impl_->dydx_[n-2] = (w1*mnm3 + w2*mnm2)/(w1 + w2); + if (isnan(impl_->dydx_[n-2])) { + impl_->dydx_[n-2] = 0; + } + + w1 = abs(mn - mnm1) + abs(mn+mnm1)/2; + w2 = abs(mnm2 - mnm3) + abs(mnm2+mnm3)/2; + + impl_->dydx_[n-1] = (w1*mnm2 + w2*mnm1)/(w1+w2); + if (isnan(impl_->dydx_[n-1])) { + impl_->dydx_[n-1] = 0; + } + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/pchip.hpp b/libcxx/src/third-party/boost/math/interpolators/pchip.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/pchip.hpp @@ -0,0 +1,124 @@ +// Copyright Nick Thompson, 2020 +// 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_INTERPOLATORS_PCHIP_HPP +#define BOOST_MATH_INTERPOLATORS_PCHIP_HPP +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class pchip { +public: + using Real = typename RandomAccessContainer::value_type; + + pchip(RandomAccessContainer && x, RandomAccessContainer && y, + Real left_endpoint_derivative = std::numeric_limits::quiet_NaN(), + Real right_endpoint_derivative = std::numeric_limits::quiet_NaN()) + { + using std::isnan; + if (x.size() < 4) + { + throw std::domain_error("Must be at least four data points."); + } + RandomAccessContainer s(x.size(), std::numeric_limits::quiet_NaN()); + if (isnan(left_endpoint_derivative)) + { + // O(h) finite difference derivative: + // This, I believe, is the only derivative guaranteed to be monotonic: + s[0] = (y[1]-y[0])/(x[1]-x[0]); + } + else + { + s[0] = left_endpoint_derivative; + } + + for (decltype(s.size()) k = 1; k < s.size()-1; ++k) { + Real hkm1 = x[k] - x[k-1]; + Real dkm1 = (y[k] - y[k-1])/hkm1; + + Real hk = x[k+1] - x[k]; + Real dk = (y[k+1] - y[k])/hk; + Real w1 = 2*hk + hkm1; + Real w2 = hk + 2*hkm1; + if ( (dk > 0 && dkm1 < 0) || (dk < 0 && dkm1 > 0) || dk == 0 || dkm1 == 0) + { + s[k] = 0; + } + else + { + s[k] = (w1+w2)/(w1/dkm1 + w2/dk); + } + + } + // Quadratic extrapolation at the other end: + auto n = s.size(); + if (isnan(right_endpoint_derivative)) + { + s[n-1] = (y[n-1]-y[n-2])/(x[n-1] - x[n-2]); + } + else + { + s[n-1] = right_endpoint_derivative; + } + impl_ = std::make_shared>(std::move(x), std::move(y), std::move(s)); + } + + Real operator()(Real x) const { + return impl_->operator()(x); + } + + Real prime(Real x) const { + return impl_->prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const pchip & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y) { + using std::abs; + using std::isnan; + if (x <= impl_->x_.back()) { + throw std::domain_error("Calling push_back must preserve the monotonicity of the x's"); + } + impl_->x_.push_back(x); + impl_->y_.push_back(y); + impl_->dydx_.push_back(std::numeric_limits::quiet_NaN()); + auto n = impl_->size(); + impl_->dydx_[n-1] = (impl_->y_[n-1]-impl_->y_[n-2])/(impl_->x_[n-1] - impl_->x_[n-2]); + // Now fix s_[n-2]: + auto k = n-2; + Real hkm1 = impl_->x_[k] - impl_->x_[k-1]; + Real dkm1 = (impl_->y_[k] - impl_->y_[k-1])/hkm1; + + Real hk = impl_->x_[k+1] - impl_->x_[k]; + Real dk = (impl_->y_[k+1] - impl_->y_[k])/hk; + Real w1 = 2*hk + hkm1; + Real w2 = hk + 2*hkm1; + if ( (dk > 0 && dkm1 < 0) || (dk < 0 && dkm1 > 0) || dk == 0 || dkm1 == 0) + { + impl_->dydx_[k] = 0; + } + else + { + impl_->dydx_[k] = (w1+w2)/(w1/dkm1 + w2/dk); + } + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/quintic_hermite.hpp b/libcxx/src/third-party/boost/math/interpolators/quintic_hermite.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/quintic_hermite.hpp @@ -0,0 +1,142 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_INTERPOLATORS_QUINTIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_QUINTIC_HERMITE_HPP +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class quintic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + quintic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2) + : impl_(std::make_shared>(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2))) + {} + + Real operator()(Real x) const + { + return impl_->operator()(x); + } + + Real prime(Real x) const + { + return impl_->prime(x); + } + + Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const quintic_hermite & m) + { + os << *m.impl_; + return os; + } + + void push_back(Real x, Real y, Real dydx, Real d2ydx2) + { + impl_->push_back(x, y, dydx, d2ydx2); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_quintic_hermite { +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_quintic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, RandomAccessContainer && d2ydx2, Real x0, Real dx) + : impl_(std::make_shared>(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx)) + {} + + inline Real operator()(Real x) const { + return impl_->operator()(x); + } + + inline Real prime(Real x) const { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_quintic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_quintic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/septic_hermite.hpp b/libcxx/src/third-party/boost/math/interpolators/septic_hermite.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/septic_hermite.hpp @@ -0,0 +1,146 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_INTERPOLATORS_SEPTIC_HERMITE_HPP +#define BOOST_MATH_INTERPOLATORS_SEPTIC_HERMITE_HPP +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace interpolators { + +template +class septic_hermite +{ +public: + using Real = typename RandomAccessContainer::value_type; + septic_hermite(RandomAccessContainer && x, RandomAccessContainer && y, RandomAccessContainer && dydx, + RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3) + : impl_(std::make_shared>(std::move(x), + std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3))) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + friend std::ostream& operator<<(std::ostream & os, const septic_hermite & m) + { + os << *m.impl_; + return os; + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +template +class cardinal_septic_hermite +{ +public: + using Real = typename RandomAccessContainer::value_type; + cardinal_septic_hermite(RandomAccessContainer && y, RandomAccessContainer && dydx, + RandomAccessContainer && d2ydx2, RandomAccessContainer && d3ydx3, Real x0, Real dx) + : impl_(std::make_shared>( + std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_->bytes() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class cardinal_septic_hermite_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + cardinal_septic_hermite_aos(RandomAccessContainer && data, Real x0, Real dx) + : impl_(std::make_shared>(std::move(data), x0, dx)) + {} + + inline Real operator()(Real x) const + { + return impl_->operator()(x); + } + + inline Real prime(Real x) const + { + return impl_->prime(x); + } + + inline Real double_prime(Real x) const + { + return impl_->double_prime(x); + } + + int64_t bytes() const + { + return impl_.size() + sizeof(impl_); + } + + std::pair domain() const + { + return impl_->domain(); + } + +private: + std::shared_ptr> impl_; +}; + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/vector_barycentric_rational.hpp b/libcxx/src/third-party/boost/math/interpolators/vector_barycentric_rational.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/vector_barycentric_rational.hpp @@ -0,0 +1,82 @@ +/* + * Copyright Nick Thompson, 2019 + * 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) + * + * Exactly the same as barycentric_rational.hpp, but delivers values in $\mathbb{R}^n$. + * In some sense this is trivial, since each component of the vector is computed in exactly the same + * as would be computed by barycentric_rational.hpp. But this is a bit more efficient and convenient. + */ + +#ifndef BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP +#define BOOST_MATH_INTERPOLATORS_VECTOR_BARYCENTRIC_RATIONAL_HPP + +#include +#include + +namespace boost{ namespace math{ namespace interpolators{ + +template +class vector_barycentric_rational +{ +public: + using Real = typename TimeContainer::value_type; + using Point = typename SpaceContainer::value_type; + vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order = 3); + + void operator()(Point& x, Real t) const; + + // I have validated using google benchmark that returning a value is no more expensive populating it, + // at least for Eigen vectors with known size at compile-time. + // This is kinda a weird thing to discover since it goes against the advice of basically every high-performance computing book. + Point operator()(Real t) const { + Point p; + this->operator()(p, t); + return p; + } + + void prime(Point& dxdt, Real t) const { + Point x; + m_imp->eval_with_prime(x, dxdt, t); + } + + Point prime(Real t) const { + Point p; + this->prime(p, t); + return p; + } + + void eval_with_prime(Point& x, Point& dxdt, Real t) const { + m_imp->eval_with_prime(x, dxdt, t); + return; + } + + std::pair eval_with_prime(Real t) const { + Point x; + Point dxdt; + m_imp->eval_with_prime(x, dxdt, t); + return {x, dxdt}; + } + +private: + std::shared_ptr> m_imp; +}; + + +template +vector_barycentric_rational::vector_barycentric_rational(TimeContainer&& times, SpaceContainer&& points, size_t approximation_order): + m_imp(std::make_shared>(std::move(times), std::move(points), approximation_order)) +{ + return; +} + +template +void vector_barycentric_rational::operator()(typename SpaceContainer::value_type& p, typename TimeContainer::value_type t) const +{ + m_imp->operator()(p, t); + return; +} + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/interpolators/whittaker_shannon.hpp b/libcxx/src/third-party/boost/math/interpolators/whittaker_shannon.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/interpolators/whittaker_shannon.hpp @@ -0,0 +1,47 @@ +// Copyright Nick Thompson, 2019 +// 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_INTERPOLATORS_WHITAKKER_SHANNON_HPP +#define BOOST_MATH_INTERPOLATORS_WHITAKKER_SHANNON_HPP +#include +#include + +namespace boost { namespace math { namespace interpolators { + +template +class whittaker_shannon { +public: + + using Real = typename RandomAccessContainer::value_type; + whittaker_shannon(RandomAccessContainer&& y, Real const & t0, Real const & h) + : m_impl(std::make_shared>(std::move(y), t0, h)) + {} + + inline Real operator()(Real t) const + { + return m_impl->operator()(t); + } + + inline Real prime(Real t) const + { + return m_impl->prime(t); + } + + inline Real operator[](size_t i) const + { + return m_impl->operator[](i); + } + + RandomAccessContainer&& return_data() + { + return m_impl->return_data(); + } + + +private: + std::shared_ptr> m_impl; +}; +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/octonion.hpp b/libcxx/src/third-party/boost/math/octonion.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/octonion.hpp @@ -0,0 +1,4243 @@ +// boost octonion.hpp header file + +// (C) Copyright Hubert Holin 2001. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_OCTONION_HPP +#define BOOST_OCTONION_HPP + +#include +#include + + +namespace boost +{ + namespace math + { + +#define BOOST_OCTONION_ACCESSOR_GENERATOR(type) \ + type real() const \ + { \ + return(a); \ + } \ + \ + octonion unreal() const \ + { \ + return( octonion(static_cast(0),b,c,d,e,f,g,h)); \ + } \ + \ + type R_component_1() const \ + { \ + return(a); \ + } \ + \ + type R_component_2() const \ + { \ + return(b); \ + } \ + \ + type R_component_3() const \ + { \ + return(c); \ + } \ + \ + type R_component_4() const \ + { \ + return(d); \ + } \ + \ + type R_component_5() const \ + { \ + return(e); \ + } \ + \ + type R_component_6() const \ + { \ + return(f); \ + } \ + \ + type R_component_7() const \ + { \ + return(g); \ + } \ + \ + type R_component_8() const \ + { \ + return(h); \ + } \ + \ + ::std::complex C_component_1() const \ + { \ + return(::std::complex(a,b)); \ + } \ + \ + ::std::complex C_component_2() const \ + { \ + return(::std::complex(c,d)); \ + } \ + \ + ::std::complex C_component_3() const \ + { \ + return(::std::complex(e,f)); \ + } \ + \ + ::std::complex C_component_4() const \ + { \ + return(::std::complex(g,h)); \ + } \ + \ + ::boost::math::quaternion H_component_1() const \ + { \ + return(::boost::math::quaternion(a,b,c,d)); \ + } \ + \ + ::boost::math::quaternion H_component_2() const \ + { \ + return(::boost::math::quaternion(e,f,g,h)); \ + } + + +#define BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(type) \ + template \ + octonion & operator = (octonion const & a_affecter) \ + { \ + a = static_cast(a_affecter.R_component_1()); \ + b = static_cast(a_affecter.R_component_2()); \ + c = static_cast(a_affecter.R_component_3()); \ + d = static_cast(a_affecter.R_component_4()); \ + e = static_cast(a_affecter.R_component_5()); \ + f = static_cast(a_affecter.R_component_6()); \ + g = static_cast(a_affecter.R_component_7()); \ + h = static_cast(a_affecter.R_component_8()); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (octonion const & a_affecter) \ + { \ + a = a_affecter.a; \ + b = a_affecter.b; \ + c = a_affecter.c; \ + d = a_affecter.d; \ + e = a_affecter.e; \ + f = a_affecter.f; \ + g = a_affecter.g; \ + h = a_affecter.h; \ + \ + return(*this); \ + } \ + \ + octonion & operator = (type const & a_affecter) \ + { \ + a = a_affecter; \ + \ + b = c = d = e = f= g = h = static_cast(0); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (::std::complex const & a_affecter) \ + { \ + a = a_affecter.real(); \ + b = a_affecter.imag(); \ + \ + c = d = e = f = g = h = static_cast(0); \ + \ + return(*this); \ + } \ + \ + octonion & operator = (::boost::math::quaternion const & a_affecter) \ + { \ + a = a_affecter.R_component_1(); \ + b = a_affecter.R_component_2(); \ + c = a_affecter.R_component_3(); \ + d = a_affecter.R_component_4(); \ + \ + e = f = g = h = static_cast(0); \ + \ + return(*this); \ + } + + +#define BOOST_OCTONION_MEMBER_DATA_GENERATOR(type) \ + type a; \ + type b; \ + type c; \ + type d; \ + type e; \ + type f; \ + type g; \ + type h; \ + + + template + class octonion + { + public: + + using value_type = T; + + // constructor for O seen as R^8 + // (also default constructor) + + explicit octonion( T const & requested_a = T(), + T const & requested_b = T(), + T const & requested_c = T(), + T const & requested_d = T(), + T const & requested_e = T(), + T const & requested_f = T(), + T const & requested_g = T(), + T const & requested_h = T()) + : a(requested_a), + b(requested_b), + c(requested_c), + d(requested_d), + e(requested_e), + f(requested_f), + g(requested_g), + h(requested_h) + { + // nothing to do! + } + + + // constructor for H seen as C^4 + + explicit octonion( ::std::complex const & z0, + ::std::complex const & z1 = ::std::complex(), + ::std::complex const & z2 = ::std::complex(), + ::std::complex const & z3 = ::std::complex()) + : a(z0.real()), + b(z0.imag()), + c(z1.real()), + d(z1.imag()), + e(z2.real()), + f(z2.imag()), + g(z3.real()), + h(z3.imag()) + { + // nothing to do! + } + + + // constructor for O seen as H^2 + + explicit octonion( ::boost::math::quaternion const & q0, + ::boost::math::quaternion const & q1 = ::boost::math::quaternion()) + : a(q0.R_component_1()), + b(q0.R_component_2()), + c(q0.R_component_3()), + d(q0.R_component_4()), + e(q1.R_component_1()), + f(q1.R_component_2()), + g(q1.R_component_3()), + h(q1.R_component_4()) + { + // nothing to do! + } + + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + + // templated copy constructor + + template + explicit octonion(octonion const & a_recopier) + : a(static_cast(a_recopier.R_component_1())), + b(static_cast(a_recopier.R_component_2())), + c(static_cast(a_recopier.R_component_3())), + d(static_cast(a_recopier.R_component_4())), + e(static_cast(a_recopier.R_component_5())), + f(static_cast(a_recopier.R_component_6())), + g(static_cast(a_recopier.R_component_7())), + h(static_cast(a_recopier.R_component_8())) + { + // nothing to do! + } + + + // destructor + ~octonion() = default; + + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(T) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(T) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + octonion & operator += (T const & rhs) + { + T at = a + rhs; // exception guard + + a = at; + + return(*this); + } + + + octonion & operator += (::std::complex const & rhs) + { + T at = a + rhs.real(); // exception guard + T bt = b + rhs.imag(); // exception guard + + a = at; + b = bt; + + return(*this); + } + + + octonion & operator += (::boost::math::quaternion const & rhs) + { + T at = a + rhs.R_component_1(); // exception guard + T bt = b + rhs.R_component_2(); // exception guard + T ct = c + rhs.R_component_3(); // exception guard + T dt = d + rhs.R_component_4(); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + + return(*this); + } + + + template + octonion & operator += (octonion const & rhs) + { + T at = a + static_cast(rhs.R_component_1()); // exception guard + T bt = b + static_cast(rhs.R_component_2()); // exception guard + T ct = c + static_cast(rhs.R_component_3()); // exception guard + T dt = d + static_cast(rhs.R_component_4()); // exception guard + T et = e + static_cast(rhs.R_component_5()); // exception guard + T ft = f + static_cast(rhs.R_component_6()); // exception guard + T gt = g + static_cast(rhs.R_component_7()); // exception guard + T ht = h + static_cast(rhs.R_component_8()); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + + octonion & operator -= (T const & rhs) + { + T at = a - rhs; // exception guard + + a = at; + + return(*this); + } + + + octonion & operator -= (::std::complex const & rhs) + { + T at = a - rhs.real(); // exception guard + T bt = b - rhs.imag(); // exception guard + + a = at; + b = bt; + + return(*this); + } + + + octonion & operator -= (::boost::math::quaternion const & rhs) + { + T at = a - rhs.R_component_1(); // exception guard + T bt = b - rhs.R_component_2(); // exception guard + T ct = c - rhs.R_component_3(); // exception guard + T dt = d - rhs.R_component_4(); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + + return(*this); + } + + + template + octonion & operator -= (octonion const & rhs) + { + T at = a - static_cast(rhs.R_component_1()); // exception guard + T bt = b - static_cast(rhs.R_component_2()); // exception guard + T ct = c - static_cast(rhs.R_component_3()); // exception guard + T dt = d - static_cast(rhs.R_component_4()); // exception guard + T et = e - static_cast(rhs.R_component_5()); // exception guard + T ft = f - static_cast(rhs.R_component_6()); // exception guard + T gt = g - static_cast(rhs.R_component_7()); // exception guard + T ht = h - static_cast(rhs.R_component_8()); // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (T const & rhs) + { + T at = a * rhs; // exception guard + T bt = b * rhs; // exception guard + T ct = c * rhs; // exception guard + T dt = d * rhs; // exception guard + T et = e * rhs; // exception guard + T ft = f * rhs; // exception guard + T gt = g * rhs; // exception guard + T ht = h * rhs; // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + + T at = +a*ar-b*br; + T bt = +a*br+b*ar; + T ct = +c*ar+d*br; + T dt = -c*br+d*ar; + T et = +e*ar+f*br; + T ft = -e*br+f*ar; + T gt = +g*ar-h*br; + T ht = +g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator *= (::boost::math::quaternion const & rhs) + { + T ar = rhs.R_component_1(); + T br = rhs.R_component_2(); + T cr = rhs.R_component_2(); + T dr = rhs.R_component_2(); + + T at = +a*ar-b*br-c*cr-d*dr; + T bt = +a*br+b*ar+c*dr-d*cr; + T ct = +a*cr-b*dr+c*ar+d*br; + T dt = +a*dr+b*cr-c*br+d*ar; + T et = +e*ar+f*br+g*cr+h*dr; + T ft = -e*br+f*ar-g*dr+h*cr; + T gt = -e*cr+f*dr+g*ar-h*br; + T ht = -e*dr-f*cr+g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + template + octonion & operator *= (octonion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + T er = static_cast(rhs.R_component_5()); + T fr = static_cast(rhs.R_component_6()); + T gr = static_cast(rhs.R_component_7()); + T hr = static_cast(rhs.R_component_8()); + + T at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; + T bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; + T ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; + T dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; + T et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; + T ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; + T gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; + T ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (T const & rhs) + { + T at = a / rhs; // exception guard + T bt = b / rhs; // exception guard + T ct = c / rhs; // exception guard + T dt = d / rhs; // exception guard + T et = e / rhs; // exception guard + T ft = f / rhs; // exception guard + T gt = g / rhs; // exception guard + T ht = h / rhs; // exception guard + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + + T denominator = ar*ar+br*br; + + T at = (+a*ar-b*br)/denominator; + T bt = (-a*br+b*ar)/denominator; + T ct = (+c*ar-d*br)/denominator; + T dt = (+c*br+d*ar)/denominator; + T et = (+e*ar-f*br)/denominator; + T ft = (+e*br+f*ar)/denominator; + T gt = (+g*ar+h*br)/denominator; + T ht = (+g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + octonion & operator /= (::boost::math::quaternion const & rhs) + { + T ar = rhs.R_component_1(); + T br = rhs.R_component_2(); + T cr = rhs.R_component_2(); + T dr = rhs.R_component_2(); + + T denominator = ar*ar+br*br+cr*cr+dr*dr; + + T at = (+a*ar+b*br+c*cr+d*dr)/denominator; + T bt = (-a*br+b*ar-c*dr+d*cr)/denominator; + T ct = (-a*cr+b*dr+c*ar-d*br)/denominator; + T dt = (-a*dr-b*cr+c*br+d*ar)/denominator; + T et = (+e*ar-f*br-g*cr-h*dr)/denominator; + T ft = (+e*br+f*ar+g*dr-h*cr)/denominator; + T gt = (+e*cr-f*dr+g*ar+h*br)/denominator; + T ht = (+e*dr+f*cr-g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + template + octonion & operator /= (octonion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + T er = static_cast(rhs.R_component_5()); + T fr = static_cast(rhs.R_component_6()); + T gr = static_cast(rhs.R_component_7()); + T hr = static_cast(rhs.R_component_8()); + + T denominator = ar*ar+br*br+cr*cr+dr*dr+er*er+fr*fr+gr*gr+hr*hr; + + T at = (+a*ar+b*br+c*cr+d*dr+e*er+f*fr+g*gr+h*hr)/denominator; + T bt = (-a*br+b*ar-c*dr+d*cr-e*fr+f*er+g*hr-h*gr)/denominator; + T ct = (-a*cr+b*dr+c*ar-d*br-e*gr-f*hr+g*er+h*fr)/denominator; + T dt = (-a*dr-b*cr+c*br+d*ar-e*hr+f*gr-g*fr+h*er)/denominator; + T et = (-a*er+b*fr+c*gr+d*hr+e*ar-f*br-g*cr-h*dr)/denominator; + T ft = (-a*fr-b*er+c*hr-d*gr+e*br+f*ar+g*dr-h*cr)/denominator; + T gt = (-a*gr-b*hr-c*er+d*fr+e*cr-f*dr+g*ar+h*br)/denominator; + T ht = (-a*hr+b*gr-c*fr-d*er+e*dr+f*cr-g*br+h*ar)/denominator; + + a = at; + b = bt; + c = ct; + d = dt; + e = et; + f = ft; + g = gt; + h = ht; + + return(*this); + } + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(T) + + + private: + + }; + + + // declaration of octonion specialization + + template<> class octonion; + template<> class octonion; + template<> class octonion; + + + // helper templates for converting copy constructors (declaration) + + namespace detail + { + + template< typename T, + typename U + > + octonion octonion_type_converter(octonion const & rhs); + } + + + // implementation of octonion specialization + + +#define BOOST_OCTONION_CONSTRUCTOR_GENERATOR(type) \ + explicit octonion( type const & requested_a = static_cast(0), \ + type const & requested_b = static_cast(0), \ + type const & requested_c = static_cast(0), \ + type const & requested_d = static_cast(0), \ + type const & requested_e = static_cast(0), \ + type const & requested_f = static_cast(0), \ + type const & requested_g = static_cast(0), \ + type const & requested_h = static_cast(0)) \ + : a(requested_a), \ + b(requested_b), \ + c(requested_c), \ + d(requested_d), \ + e(requested_e), \ + f(requested_f), \ + g(requested_g), \ + h(requested_h) \ + { \ + } \ + \ + explicit octonion( ::std::complex const & z0, \ + ::std::complex const & z1 = ::std::complex(), \ + ::std::complex const & z2 = ::std::complex(), \ + ::std::complex const & z3 = ::std::complex()) \ + : a(z0.real()), \ + b(z0.imag()), \ + c(z1.real()), \ + d(z1.imag()), \ + e(z2.real()), \ + f(z2.imag()), \ + g(z3.real()), \ + h(z3.imag()) \ + { \ + } \ + \ + explicit octonion( ::boost::math::quaternion const & q0, \ + ::boost::math::quaternion const & q1 = ::boost::math::quaternion()) \ + : a(q0.R_component_1()), \ + b(q0.R_component_2()), \ + c(q0.R_component_3()), \ + d(q0.R_component_4()), \ + e(q1.R_component_1()), \ + f(q1.R_component_2()), \ + g(q1.R_component_3()), \ + h(q1.R_component_4()) \ + { \ + } + + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ + octonion & operator += (type const & rhs) \ + { \ + a += rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ + octonion & operator += (::std::complex const & rhs) \ + { \ + a += rhs.real(); \ + b += rhs.imag(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ + octonion & operator += (::boost::math::quaternion const & rhs) \ + { \ + a += rhs.R_component_1(); \ + b += rhs.R_component_2(); \ + c += rhs.R_component_3(); \ + d += rhs.R_component_4(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) \ + template \ + octonion & operator += (octonion const & rhs) \ + { \ + a += static_cast(rhs.R_component_1()); \ + b += static_cast(rhs.R_component_2()); \ + c += static_cast(rhs.R_component_3()); \ + d += static_cast(rhs.R_component_4()); \ + e += static_cast(rhs.R_component_5()); \ + f += static_cast(rhs.R_component_6()); \ + g += static_cast(rhs.R_component_7()); \ + h += static_cast(rhs.R_component_8()); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ + octonion & operator -= (type const & rhs) \ + { \ + a -= rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ + octonion & operator -= (::std::complex const & rhs) \ + { \ + a -= rhs.real(); \ + b -= rhs.imag(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ + octonion & operator -= (::boost::math::quaternion const & rhs) \ + { \ + a -= rhs.R_component_1(); \ + b -= rhs.R_component_2(); \ + c -= rhs.R_component_3(); \ + d -= rhs.R_component_4(); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) \ + template \ + octonion & operator -= (octonion const & rhs) \ + { \ + a -= static_cast(rhs.R_component_1()); \ + b -= static_cast(rhs.R_component_2()); \ + c -= static_cast(rhs.R_component_3()); \ + d -= static_cast(rhs.R_component_4()); \ + e -= static_cast(rhs.R_component_5()); \ + f -= static_cast(rhs.R_component_6()); \ + g -= static_cast(rhs.R_component_7()); \ + h -= static_cast(rhs.R_component_8()); \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ + octonion & operator *= (type const & rhs) \ + { \ + a *= rhs; \ + b *= rhs; \ + c *= rhs; \ + d *= rhs; \ + e *= rhs; \ + f *= rhs; \ + g *= rhs; \ + h *= rhs; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ + octonion & operator *= (::std::complex const & rhs) \ + { \ + type ar = rhs.real(); \ + type br = rhs.imag(); \ + \ + type at = +a*ar-b*br; \ + type bt = +a*br+b*ar; \ + type ct = +c*ar+d*br; \ + type dt = -c*br+d*ar; \ + type et = +e*ar+f*br; \ + type ft = -e*br+f*ar; \ + type gt = +g*ar-h*br; \ + type ht = +g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ + octonion & operator *= (::boost::math::quaternion const & rhs) \ + { \ + type ar = rhs.R_component_1(); \ + type br = rhs.R_component_2(); \ + type cr = rhs.R_component_2(); \ + type dr = rhs.R_component_2(); \ + \ + type at = +a*ar-b*br-c*cr-d*dr; \ + type bt = +a*br+b*ar+c*dr-d*cr; \ + type ct = +a*cr-b*dr+c*ar+d*br; \ + type dt = +a*dr+b*cr-c*br+d*ar; \ + type et = +e*ar+f*br+g*cr+h*dr; \ + type ft = -e*br+f*ar-g*dr+h*cr; \ + type gt = -e*cr+f*dr+g*ar-h*br; \ + type ht = -e*dr-f*cr+g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) \ + template \ + octonion & operator *= (octonion const & rhs) \ + { \ + type ar = static_cast(rhs.R_component_1()); \ + type br = static_cast(rhs.R_component_2()); \ + type cr = static_cast(rhs.R_component_3()); \ + type dr = static_cast(rhs.R_component_4()); \ + type er = static_cast(rhs.R_component_5()); \ + type fr = static_cast(rhs.R_component_6()); \ + type gr = static_cast(rhs.R_component_7()); \ + type hr = static_cast(rhs.R_component_8()); \ + \ + type at = +a*ar-b*br-c*cr-d*dr-e*er-f*fr-g*gr-h*hr; \ + type bt = +a*br+b*ar+c*dr-d*cr+e*fr-f*er-g*hr+h*gr; \ + type ct = +a*cr-b*dr+c*ar+d*br+e*gr+f*hr-g*er-h*fr; \ + type dt = +a*dr+b*cr-c*br+d*ar+e*hr-f*gr+g*fr-h*er; \ + type et = +a*er-b*fr-c*gr-d*hr+e*ar+f*br+g*cr+h*dr; \ + type ft = +a*fr+b*er-c*hr+d*gr-e*br+f*ar-g*dr+h*cr; \ + type gt = +a*gr+b*hr+c*er-d*fr-e*cr+f*dr+g*ar-h*br; \ + type ht = +a*hr-b*gr+c*fr+d*er-e*dr-f*cr+g*br+h*ar; \ + \ + a = at; \ + b = bt; \ + c = ct; \ + d = dt; \ + e = et; \ + f = ft; \ + g = gt; \ + h = ht; \ + \ + return(*this); \ + } + +// There is quite a lot of repetition in the code below. This is intentional. +// The last conditional block is the normal form, and the others merely +// consist of workarounds for various compiler deficiencies. Hopefully, when +// more compilers are conformant and we can retire support for those that are +// not, we will be able to remove the clutter. This is makes the situation +// (painfully) explicit. + +#define BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ + octonion & operator /= (type const & rhs) \ + { \ + a /= rhs; \ + b /= rhs; \ + c /= rhs; \ + d /= rhs; \ + \ + return(*this); \ + } + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + octonion & operator /= (::std::complex const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(2); \ + \ + tr[0] = rhs.real(); \ + tr[1] = rhs.imag(); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]-b*tr[1]; \ + tt[1] = -a*tr[1]+b*tr[0]; \ + tt[2] = +c*tr[0]-d*tr[1]; \ + tt[3] = +c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]; \ + tt[5] = +e*tr[1]+f*tr[0]; \ + tt[6] = +g*tr[0]+h*tr[1]; \ + tt[7] = +g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + octonion & operator /= (::std::complex const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(2); \ + \ + tr[0] = rhs.real(); \ + tr[1] = rhs.imag(); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]-b*tr[1]; \ + tt[1] = -a*tr[1]+b*tr[0]; \ + tt[2] = +c*tr[0]-d*tr[1]; \ + tt[3] = +c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]; \ + tt[5] = +e*tr[1]+f*tr[0]; \ + tt[6] = +g*tr[0]+h*tr[1]; \ + tt[7] = +g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + octonion & operator /= (::boost::math::quaternion const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(4); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + octonion & operator /= (::boost::math::quaternion const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(4); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]; \ + tt[4] = +e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = +e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = +e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = +e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ + template \ + octonion & operator /= (octonion const & rhs) \ + { \ + using ::std::valarray; \ + using ::std::abs; \ + \ + valarray tr(8); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + tr[4] = static_cast(rhs.R_component_5()); \ + tr[5] = static_cast(rhs.R_component_6()); \ + tr[6] = static_cast(rhs.R_component_7()); \ + tr[7] = static_cast(rhs.R_component_8()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ + tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#else + #define BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) \ + template \ + octonion & operator /= (octonion const & rhs) \ + { \ + using ::std::valarray; \ + \ + valarray tr(8); \ + \ + tr[0] = static_cast(rhs.R_component_1()); \ + tr[1] = static_cast(rhs.R_component_2()); \ + tr[2] = static_cast(rhs.R_component_3()); \ + tr[3] = static_cast(rhs.R_component_4()); \ + tr[4] = static_cast(rhs.R_component_5()); \ + tr[5] = static_cast(rhs.R_component_6()); \ + tr[6] = static_cast(rhs.R_component_7()); \ + tr[7] = static_cast(rhs.R_component_8()); \ + \ + type mixam = static_cast(1)/(abs(tr).max)(); \ + \ + tr *= mixam; \ + \ + valarray tt(8); \ + \ + tt[0] = +a*tr[0]+b*tr[1]+c*tr[2]+d*tr[3]+e*tr[4]+f*tr[5]+g*tr[6]+h*tr[7]; \ + tt[1] = -a*tr[1]+b*tr[0]-c*tr[3]+d*tr[2]-e*tr[5]+f*tr[4]+g*tr[7]-h*tr[6]; \ + tt[2] = -a*tr[2]+b*tr[3]+c*tr[0]-d*tr[1]-e*tr[6]-f*tr[7]+g*tr[4]+h*tr[5]; \ + tt[3] = -a*tr[3]-b*tr[2]+c*tr[1]+d*tr[0]-e*tr[7]+f*tr[6]-g*tr[5]+h*tr[4]; \ + tt[4] = -a*tr[4]+b*tr[5]+c*tr[6]+d*tr[7]+e*tr[0]-f*tr[1]-g*tr[2]-h*tr[3]; \ + tt[5] = -a*tr[5]-b*tr[4]+c*tr[7]-d*tr[6]+e*tr[1]+f*tr[0]+g*tr[3]-h*tr[2]; \ + tt[6] = -a*tr[6]-b*tr[7]-c*tr[4]+d*tr[5]+e*tr[2]-f*tr[3]+g*tr[0]+h*tr[1]; \ + tt[7] = -a*tr[7]+b*tr[6]-c*tr[5]-d*tr[4]+e*tr[3]+f*tr[2]-g*tr[1]+h*tr[0]; \ + \ + tr *= tr; \ + \ + tt *= (mixam/tr.sum()); \ + \ + a = tt[0]; \ + b = tt[1]; \ + c = tt[2]; \ + d = tt[3]; \ + e = tt[4]; \ + f = tt[5]; \ + g = tt[6]; \ + h = tt[7]; \ + \ + return(*this); \ + } +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + +#define BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_1(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_2(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_3(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR_4(type) + +#define BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_ADD_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_SUB_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_MUL_GENERATOR(type) \ + BOOST_OCTONION_MEMBER_DIV_GENERATOR(type) + + + template<> + class octonion + { + public: + + using value_type = float; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(float) + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + // explicit copy constructors (precision-losing converters) + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // destructor + ~octonion() = default; + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(float) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(float) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(float) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(float) + }; + + + template<> + class octonion + { + public: + + using value_type = double; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(double) + + // Untemplated copy constructor + octonion(const octonion&) = default; + + // converting copy constructor + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // explicit copy constructors (precision-losing converters) + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + // destructor + // (this is taken care of by the compiler itself) + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(double) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(double) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(double) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(double) + }; + + + template<> + class octonion + { + public: + + using value_type = long double; + + BOOST_OCTONION_CONSTRUCTOR_GENERATOR(long double) + + // UNtemplated copy constructor + octonion(const octonion&) = default; + + // converting copy constructor + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + + explicit octonion(octonion const & a_recopier) + { + *this = detail::octonion_type_converter(a_recopier); + } + + + // destructor + // (this is taken care of by the compiler itself) + + // accessors + // + // Note: Like complex number, octonions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is an octonion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + BOOST_OCTONION_ACCESSOR_GENERATOR(long double) + + // assignment operators + + BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR(long double) + + // other assignment-related operators + // + // NOTE: Octonion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);"; + // octonion multiplication is also *NOT* associative + + BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR(long double) + + + protected: + + BOOST_OCTONION_MEMBER_DATA_GENERATOR(long double) + + + private: + + }; + + +#undef BOOST_OCTONION_CONSTRUCTOR_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ALGEBRAIC_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_ADD_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_SUB_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_MUL_GENERATOR_4 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_1 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_2 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_3 +#undef BOOST_OCTONION_MEMBER_DIV_GENERATOR_4 + + +#undef BOOST_OCTONION_MEMBER_DATA_GENERATOR + +#undef BOOST_OCTONION_MEMBER_ASSIGNMENT_GENERATOR + +#undef BOOST_OCTONION_ACCESSOR_GENERATOR + + + // operators + +#define BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) \ + { \ + octonion res(lhs); \ + res op##= rhs; \ + return(res); \ + } + +#define BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ + template \ + inline octonion operator op (T const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, T const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ + template \ + inline octonion operator op (::std::complex const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, ::std::complex const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ + template \ + inline octonion operator op (::boost::math::quaternion const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ + template \ + inline octonion operator op (octonion const & lhs, ::boost::math::quaternion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR_4(op) \ + template \ + inline octonion operator op (octonion const & lhs, octonion const & rhs) \ + BOOST_OCTONION_OPERATOR_GENERATOR_BODY(op) + +#define BOOST_OCTONION_OPERATOR_GENERATOR(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_1_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_1_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_2_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_2_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_3_L(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_3_R(op) \ + BOOST_OCTONION_OPERATOR_GENERATOR_4(op) + + + BOOST_OCTONION_OPERATOR_GENERATOR(+) + BOOST_OCTONION_OPERATOR_GENERATOR(-) + BOOST_OCTONION_OPERATOR_GENERATOR(*) + BOOST_OCTONION_OPERATOR_GENERATOR(/) + + +#undef BOOST_OCTONION_OPERATOR_GENERATOR + +#undef BOOST_OCTONION_OPERATOR_GENERATOR_1_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_1_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_2_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_2_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_3_L +#undef BOOST_OCTONION_OPERATOR_GENERATOR_3_R +#undef BOOST_OCTONION_OPERATOR_GENERATOR_4 + +#undef BOOST_OCTONION_OPERATOR_GENERATOR_BODY + + + template + inline octonion operator + (octonion const & o) + { + return(o); + } + + + template + inline octonion operator - (octonion const & o) + { + return(octonion(-o.R_component_1(),-o.R_component_2(),-o.R_component_3(),-o.R_component_4(),-o.R_component_5(),-o.R_component_6(),-o.R_component_7(),-o.R_component_8())); + } + + + template + inline bool operator == (T const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs)&& + (rhs.R_component_2() == static_cast(0))&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0))&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, T const & rhs) + { + return( + (lhs.R_component_1() == rhs)&& + (lhs.R_component_2() == static_cast(0))&& + (lhs.R_component_3() == static_cast(0))&& + (lhs.R_component_4() == static_cast(0))&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (::std::complex const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.real())&& + (rhs.R_component_2() == lhs.imag())&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0))&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, ::std::complex const & rhs) + { + return( + (lhs.R_component_1() == rhs.real())&& + (lhs.R_component_2() == rhs.imag())&& + (lhs.R_component_3() == static_cast(0))&& + (lhs.R_component_4() == static_cast(0))&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (::boost::math::quaternion const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4())&& + (rhs.R_component_5() == static_cast(0))&& + (rhs.R_component_6() == static_cast(0))&& + (rhs.R_component_7() == static_cast(0))&& + (rhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, ::boost::math::quaternion const & rhs) + { + return( + (lhs.R_component_1() == rhs.R_component_1())&& + (lhs.R_component_2() == rhs.R_component_2())&& + (lhs.R_component_3() == rhs.R_component_3())&& + (lhs.R_component_4() == rhs.R_component_4())&& + (lhs.R_component_5() == static_cast(0))&& + (lhs.R_component_6() == static_cast(0))&& + (lhs.R_component_7() == static_cast(0))&& + (lhs.R_component_8() == static_cast(0)) + ); + } + + + template + inline bool operator == (octonion const & lhs, octonion const & rhs) + { + return( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4())&& + (rhs.R_component_5() == lhs.R_component_5())&& + (rhs.R_component_6() == lhs.R_component_6())&& + (rhs.R_component_7() == lhs.R_component_7())&& + (rhs.R_component_8() == lhs.R_component_8()) + ); + } + + +#define BOOST_OCTONION_NOT_EQUAL_GENERATOR \ + { \ + return(!(lhs == rhs)); \ + } + + template + inline bool operator != (T const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, T const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (::std::complex const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, ::std::complex const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (::boost::math::quaternion const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, ::boost::math::quaternion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + template + inline bool operator != (octonion const & lhs, octonion const & rhs) + BOOST_OCTONION_NOT_EQUAL_GENERATOR + + #undef BOOST_OCTONION_NOT_EQUAL_GENERATOR + + + // Note: the default values in the constructors of the complex and quaternions make for + // a very complex and ambiguous situation; we have made choices to disambiguate. + template + ::std::basic_istream & operator >> ( ::std::basic_istream & is, + octonion & o) + { +#ifdef BOOST_NO_STD_LOCALE +#else + const ::std::ctype & ct = ::std::use_facet< ::std::ctype >(is.getloc()); +#endif /* BOOST_NO_STD_LOCALE */ + + T a = T(); + T b = T(); + T c = T(); + T d = T(); + T e = T(); + T f = T(); + T g = T(); + T h = T(); + + ::std::complex u = ::std::complex(); + ::std::complex v = ::std::complex(); + ::std::complex x = ::std::complex(); + ::std::complex y = ::std::complex(); + + ::boost::math::quaternion p = ::boost::math::quaternion(); + ::boost::math::quaternion q = ::boost::math::quaternion(); + + charT ch = charT(); + char cc; + + is >> ch; // get the first lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(" + { + is >> ch; // get the second lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((" + { + is >> ch; // get the third lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(((" + { + is.putback(ch); + + is >> u; // read "((u" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((u)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a))), (((a,b))) + { + o = octonion(u); + } + else if (cc == ',') // read "((u)," + { + p = ::boost::math::quaternion(u); + + is >> q; // read "((u),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a)),q), (((a,b)),q) + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc ==',') // read "((u," + { + is >> v; // read "((u,v" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((u,v)" + { + p = ::boost::math::quaternion(u,v); + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a),v)), (((a,b),v)) + { + o = octonion(p); + } + else if (cc == ',') // read "((u,v)," + { + is >> q; // read "(p,q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // format: (((a),v),q), (((a,b),v),q) + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a" + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a))" + { + o = octonion(a); + } + else if (cc == ',') // read "((a)," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),((" + { + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value! + + is >> q; // read "((a),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),q)" + { + p = ::boost::math::quaternion(a); + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a),(c" or "((a),(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a),(c)," + { + u = ::std::complex(a); + + v = ::std::complex(c); + + is >> x; // read "((a),(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a),(c),x," + { + is >> y; // read "((a),(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(c," or "((a),(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a),(e,(" (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + x = ::std::complex(c); // "c" was actually "e" + + is.putback(ch); // we can only backtrace once + + is >> y; // read "((a),(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,y)" + { + q = ::boost::math::quaternion(x,y); + + is >> ch; // get the next lexeme + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,y))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a),(c,d" or "((a),(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "((a),(c,d)," + { + u = ::std::complex(a); + + v = ::std::complex(c,d); + + is >> x; // read "((a),(c,d),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a),(c,d),x," + { + is >> y; // read "((a),(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + is >> g; // read "((a),(e,f,g" (too late to backtrack) + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g)" + { + q = ::boost::math::quaternion(c,d,g); // "c" was actually "e", and "d" was actually "f" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a),(e,f,g," + { + is >> h; // read "((a),(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g,h)" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" was actually "e", and "d" was actually "f" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),(e,f,g,h))" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "((a),c" (ambiguity resolution) + { + is.putback(ch); + + is >> c; // we extract the third component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c)" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a),c," + { + is >> x; // read "((a),c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c,x)" + { + o = octonion(a,b,c,d,x.real(),x.imag()); + } + else if (cc == ',') // read "((a),c,x," + { + is >> y;if (!is.good()) goto finish; // read "((a),c,x,y" + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a),c,x,y)" + { + o = octonion(a,b,c,d,x.real(),x.imag(),y.real(),y.imag()); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc ==',') // read "((a," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,(" + { + u = ::std::complex(a); + + is.putback(ch); // can only backtrack so much + + is >> v; // read "((a,v" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v))" + { + o = octonion(u,v); + } + else if (cc == ',') // read "((a,v)," + { + p = ::boost::math::quaternion(u,v); + + is >> q; // read "((a,v),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,v),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else + { + is.putback(ch); + + is >> b; // read "((a,b" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b))" + { + o = octonion(a,b); + } + else if (cc == ',') // read "((a,b)," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),((" + { + p = ::boost::math::quaternion(a,b); + + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value + + is >> q; // read "((a,b),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a,b),(c" or "((a,b),(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a,b),(c)," + { + u = ::std::complex(a,b); + + v = ::std::complex(c); + + is >> x; // read "((a,b),(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a,b),(c),x," + { + is >> y; // read "((a,b),(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(c," or "((a,b),(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "((a,b),(e,(" (ambiguity resolution) + { + u = ::std::complex(a,b); + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); + + is >> y; // read "((a,b),(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,y)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,y))" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "((a,b),(c,d" or "((a,b),(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d)" (ambiguity resolution) + { + u = ::std::complex(a,b); + + v = ::std::complex(c,d); + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d))" + { + o = octonion(u,v); + } + else if (cc == ',') // read "((a,b),(c,d)," + { + is >> x; // read "((a,b),(c,d),x + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "((a,b),(c,d),x," + { + is >> y; // read "((a,b),(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a,b); // too late to backtrack + + is >> g; // read "((a,b),(e,f,g" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g))" + { + q = ::boost::math::quaternion(c,d,g); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b),(e,f,g," + { + is >> h; // read "((a,b),(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b),(e,f,g,h)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read ((a,b),(e,f,g,h))" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b," + { + is >> c; // read "((a,b,c" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "((a,b,c)," + { + p = ::boost::math::quaternion(a,b,c); + + is >> q; // read "((a,b,c),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "((a,b,c," + { + is >> d; // read "((a,b,c,d" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "((a,b,c,d)," + { + p = ::boost::math::quaternion(a,b,c,d); + + is >> q; // read "((a,b,c,d),q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "((a,b,c,d),q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "(a" + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a)" + { + o = octonion(a); + } + else if (cc == ',') // read "(a," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,(" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,((" + { + p = ::boost::math::quaternion(a); + + is.putback(ch); + + is.putback(ch); // we backtrack twice, with the same value + + is >> q; // read "(a,q" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,q)" + { + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,(c" or "(a,(e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c))" + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "(a,(c)," + { + u = ::std::complex(a); + + v = ::std::complex(c); + + is >> x; // read "(a,(c),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,(c),x," + { + is >> y; // read "(a,(c),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(c," or "(a,(e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,(e,(" (ambiguity resolution) + { + u = ::std::complex(a); + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); // we backtrack + + is >> y; // read "(a,(e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,y)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,y))" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,(c,d" or "(a,(e,f" + { + is.putback(ch); + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d)" (ambiguity resolution) + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d))" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "(a,(c,d)," + { + u = ::std::complex(a); + + v = ::std::complex(c,d); + + is >> x; // read "(a,(c,d),x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d),x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,(c,d),x," + { + is >> y; // read "(a,(c,d),x,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(c,d),x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(e,f," (ambiguity resolution) + { + p = ::boost::math::quaternion(a); + + is >> g; // read "(a,(e,f,g" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g))" + { + q = ::boost::math::quaternion(c,d,g); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else if (cc == ',') // read "(a,(e,f,g," + { + is >> h; // read "(a,(e,f,g,h" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g,h)" + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,(e,f,g,h))" + { + q = ::boost::math::quaternion(c,d,g,h); // "c" is actually "e" and "d" is actually "f" + + o = octonion(p,q); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // read "(a,b" or "(a,c" (ambiguity resolution) + { + is.putback(ch); + + is >> b; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b)" (ambiguity resolution) + { + o = octonion(a,b); + } + else if (cc == ',') // read "(a,b," or "(a,c," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,c,(" (ambiguity resolution) + { + u = ::std::complex(a); + + v = ::std::complex(b); // "b" is actually "c" + + is.putback(ch); // we backtrack + + is >> x; // read "(a,c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,x)" + { + o = octonion(u,v,x); + } + else if (cc == ',') // read "(a,c,x," + { + is >> y; // read "(a,c,x,y" // read "(a,c,x" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,x,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b,c" or "(a,c,e" + { + is.putback(ch); + + is >> c; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c)" (ambiguity resolution) + { + o = octonion(a,b,c); + } + else if (cc == ',') // read "(a,b,c," or "(a,c,e," + { + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == '(') // read "(a,c,e,(") (ambiguity resolution) + { + u = ::std::complex(a); + + v = ::std::complex(b); // "b" is actually "c" + + x = ::std::complex(c); // "c" is actually "e" + + is.putback(ch); // we backtrack + + is >> y; // read "(a,c,e,y" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,c,e,y)" + { + o = octonion(u,v,x,y); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b,c,d" (ambiguity resolution) + { + is.putback(ch); // we backtrack + + is >> d; + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d)" + { + o = octonion(a,b,c,d); + } + else if (cc == ',') // read "(a,b,c,d," + { + is >> e; // read "(a,b,c,d,e" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e)" + { + o = octonion(a,b,c,d,e); + } + else if (cc == ',') // read "(a,b,c,d,e," + { + is >> f; // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f)" + { + o = octonion(a,b,c,d,e,f); + } + else if (cc == ',') // read "(a,b,c,d,e,f," + { + is >> g; // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f,g)" + { + o = octonion(a,b,c,d,e,f,g); + } + else if (cc == ',') // read "(a,b,c,d,e,f,g," + { + is >> h; // read "(a,b,c,d,e,f,g,h" // read "(a,b,c,d,e,f,g" // read "(a,b,c,d,e,f" + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + +#ifdef BOOST_NO_STD_LOCALE + cc = ch; +#else + cc = ct.narrow(ch, char()); +#endif /* BOOST_NO_STD_LOCALE */ + + if (cc == ')') // read "(a,b,c,d,e,f,g,h)" + { + o = octonion(a,b,c,d,e,f,g,h); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // format: a + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + o = octonion(a); + } + + finish: + return(is); + } + + + template + ::std::basic_ostream & operator << ( ::std::basic_ostream & os, + octonion const & o) + { + ::std::basic_ostringstream s; + + s.flags(os.flags()); +#ifdef BOOST_NO_STD_LOCALE +#else + s.imbue(os.getloc()); +#endif /* BOOST_NO_STD_LOCALE */ + s.precision(os.precision()); + + s << '(' << o.R_component_1() << ',' + << o.R_component_2() << ',' + << o.R_component_3() << ',' + << o.R_component_4() << ',' + << o.R_component_5() << ',' + << o.R_component_6() << ',' + << o.R_component_7() << ',' + << o.R_component_8() << ')'; + + return os << s.str(); + } + + + // values + + template + inline T real(octonion const & o) + { + return(o.real()); + } + + + template + inline octonion unreal(octonion const & o) + { + return(o.unreal()); + } + + +#define BOOST_OCTONION_VALARRAY_LOADER \ + using ::std::valarray; \ + \ + valarray temp(8); \ + \ + temp[0] = o.R_component_1(); \ + temp[1] = o.R_component_2(); \ + temp[2] = o.R_component_3(); \ + temp[3] = o.R_component_4(); \ + temp[4] = o.R_component_5(); \ + temp[5] = o.R_component_6(); \ + temp[6] = o.R_component_7(); \ + temp[7] = o.R_component_8(); + + + template + inline T sup(octonion const & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + BOOST_OCTONION_VALARRAY_LOADER + + return((abs(temp).max)()); + } + + + template + inline T l1(octonion const & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + BOOST_OCTONION_VALARRAY_LOADER + + return(abs(temp).sum()); + } + + + template + inline T abs(const octonion & o) + { +#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + using ::std::abs; +#endif /* BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP */ + + using ::std::sqrt; + + BOOST_OCTONION_VALARRAY_LOADER + + T maxim = (abs(temp).max)(); // overflow protection + + if (maxim == static_cast(0)) + { + return(maxim); + } + else + { + T mixam = static_cast(1)/maxim; // prefer multiplications over divisions + + temp *= mixam; + + temp *= temp; + + return(maxim*sqrt(temp.sum())); + } + + //return(::std::sqrt(norm(o))); + } + + +#undef BOOST_OCTONION_VALARRAY_LOADER + + + // Note: This is the Cayley norm, not the Euclidean norm... + + template + inline T norm(octonion const & o) + { + return(real(o*conj(o))); + } + + + template + inline octonion conj(octonion const & o) + { + return(octonion( +o.R_component_1(), + -o.R_component_2(), + -o.R_component_3(), + -o.R_component_4(), + -o.R_component_5(), + -o.R_component_6(), + -o.R_component_7(), + -o.R_component_8())); + } + + + // Note: There is little point, for the octonions, to introduce the equivalents + // to the complex "arg" and the quaternionic "cylindropolar". + + + template + inline octonion spherical(T const & rho, + T const & theta, + T const & phi1, + T const & phi2, + T const & phi3, + T const & phi4, + T const & phi5, + T const & phi6) + { + using ::std::cos; + using ::std::sin; + + //T a = cos(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T b = sin(theta)*cos(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T c = sin(phi1)*cos(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T d = sin(phi2)*cos(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T e = sin(phi3)*cos(phi4)*cos(phi5)*cos(phi6); + //T f = sin(phi4)*cos(phi5)*cos(phi6); + //T g = sin(phi5)*cos(phi6); + //T h = sin(phi6); + + T courrant = static_cast(1); + + T h = sin(phi6); + + courrant *= cos(phi6); + + T g = sin(phi5)*courrant; + + courrant *= cos(phi5); + + T f = sin(phi4)*courrant; + + courrant *= cos(phi4); + + T e = sin(phi3)*courrant; + + courrant *= cos(phi3); + + T d = sin(phi2)*courrant; + + courrant *= cos(phi2); + + T c = sin(phi1)*courrant; + + courrant *= cos(phi1); + + T b = sin(theta)*courrant; + T a = cos(theta)*courrant; + + return(rho*octonion(a,b,c,d,e,f,g,h)); + } + + + template + inline octonion multipolar(T const & rho1, + T const & theta1, + T const & rho2, + T const & theta2, + T const & rho3, + T const & theta3, + T const & rho4, + T const & theta4) + { + using ::std::cos; + using ::std::sin; + + T a = rho1*cos(theta1); + T b = rho1*sin(theta1); + T c = rho2*cos(theta2); + T d = rho2*sin(theta2); + T e = rho3*cos(theta3); + T f = rho3*sin(theta3); + T g = rho4*cos(theta4); + T h = rho4*sin(theta4); + + return(octonion(a,b,c,d,e,f,g,h)); + } + + + template + inline octonion cylindrical(T const & r, + T const & angle, + T const & h1, + T const & h2, + T const & h3, + T const & h4, + T const & h5, + T const & h6) + { + using ::std::cos; + using ::std::sin; + + T a = r*cos(angle); + T b = r*sin(angle); + + return(octonion(a,b,h1,h2,h3,h4,h5,h6)); + } + + + template + inline octonion exp(octonion const & o) + { + using ::std::exp; + using ::std::cos; + + using ::boost::math::sinc_pi; + + T u = exp(real(o)); + + T z = abs(unreal(o)); + + T w = sinc_pi(z); + + return(u*octonion(cos(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion cos(octonion const & o) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(o)); + + T w = -sin(o.real())*sinhc_pi(z); + + return(octonion(cos(o.real())*cosh(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion sin(octonion const & o) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(o)); + + T w = +cos(o.real())*sinhc_pi(z); + + return(octonion(sin(o.real())*cosh(z), + w*o.R_component_2(), w*o.R_component_3(), + w*o.R_component_4(), w*o.R_component_5(), + w*o.R_component_6(), w*o.R_component_7(), + w*o.R_component_8())); + } + + + template + inline octonion tan(octonion const & o) + { + return(sin(o)/cos(o)); + } + + + template + inline octonion cosh(octonion const & o) + { + return((exp(+o)+exp(-o))/static_cast(2)); + } + + + template + inline octonion sinh(octonion const & o) + { + return((exp(+o)-exp(-o))/static_cast(2)); + } + + + template + inline octonion tanh(octonion const & o) + { + return(sinh(o)/cosh(o)); + } + + + template + octonion pow(octonion const & o, + int n) + { + if (n > 1) + { + int m = n>>1; + + octonion result = pow(o, m); + + result *= result; + + if (n != (m<<1)) + { + result *= o; // n odd + } + + return(result); + } + else if (n == 1) + { + return(o); + } + else if (n == 0) + { + return(octonion(static_cast(1))); + } + else /* n < 0 */ + { + return(pow(octonion(static_cast(1))/o,-n)); + } + } + + + // helper templates for converting copy constructors (definition) + + namespace detail + { + + template< typename T, + typename U + > + octonion octonion_type_converter(octonion const & rhs) + { + return(octonion( static_cast(rhs.R_component_1()), + static_cast(rhs.R_component_2()), + static_cast(rhs.R_component_3()), + static_cast(rhs.R_component_4()), + static_cast(rhs.R_component_5()), + static_cast(rhs.R_component_6()), + static_cast(rhs.R_component_7()), + static_cast(rhs.R_component_8()))); + } + } + } +} + +#endif /* BOOST_OCTONION_HPP */ diff --git a/libcxx/src/third-party/boost/math/policies/error_handling.hpp b/libcxx/src/third-party/boost/math/policies/error_handling.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/policies/error_handling.hpp @@ -0,0 +1,883 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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_POLICY_ERROR_HANDLING_HPP +#define BOOST_MATH_POLICY_ERROR_HANDLING_HPP + +#include +#include +#include +#include +#ifndef BOOST_NO_RTTI +#include +#endif +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_EXCEPTIONS +#include +#include +#endif + +#ifdef _MSC_VER +# pragma warning(push) // Quiet warnings in boost/format.hpp +# pragma warning(disable: 4996) // _SCL_SECURE_NO_DEPRECATE +# pragma warning(disable: 4512) // assignment operator could not be generated. +# pragma warning(disable: 4127) // conditional expression is constant +// And warnings in error handling: +# pragma warning(disable: 4702) // unreachable code. +// Note that this only occurs when the compiler can deduce code is unreachable, +// for example when policy macros are used to ignore errors rather than throw. +#endif +#include + +namespace boost{ namespace math{ + +#ifndef BOOST_NO_EXCEPTIONS + +class evaluation_error : public std::runtime_error +{ +public: + explicit evaluation_error(const std::string& s) : std::runtime_error(s){} +}; + +class rounding_error : public std::runtime_error +{ +public: + explicit rounding_error(const std::string& s) : std::runtime_error(s){} +}; + +#endif + +namespace policies{ +// +// Forward declarations of user error handlers, +// it's up to the user to provide the definition of these: +// +template +T user_domain_error(const char* function, const char* message, const T& val); +template +T user_pole_error(const char* function, const char* message, const T& val); +template +T user_overflow_error(const char* function, const char* message, const T& val); +template +T user_underflow_error(const char* function, const char* message, const T& val); +template +T user_denorm_error(const char* function, const char* message, const T& val); +template +T user_evaluation_error(const char* function, const char* message, const T& val); +template +TargetType user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t); +template +T user_indeterminate_result_error(const char* function, const char* message, const T& val); + +namespace detail +{ + +template +std::string prec_format(const T& val) +{ + typedef typename boost::math::policies::precision >::type prec_type; + std::stringstream ss; + if(prec_type::value) + { + int prec = 2 + (prec_type::value * 30103UL) / 100000UL; + ss << std::setprecision(prec); + } + ss << val; + return ss.str(); +} + +inline void replace_all_in_string(std::string& result, const char* what, const char* with) +{ + std::string::size_type pos = 0; + std::string::size_type slen = std::strlen(what); + std::string::size_type rlen = std::strlen(with); + while((pos = result.find(what, pos)) != std::string::npos) + { + result.replace(pos, slen, with); + pos += rlen; + } +} + +template +inline const char* name_of() +{ +#ifndef BOOST_NO_RTTI + return typeid(T).name(); +#else + return "unknown"; +#endif +} +template <> inline const char* name_of(){ return "float"; } +template <> inline const char* name_of(){ return "double"; } +template <> inline const char* name_of(){ return "long double"; } + +#ifdef BOOST_MATH_USE_FLOAT128 +template <> +inline const char* name_of() +{ + return "__float128"; +} +#endif + +#ifndef BOOST_NO_EXCEPTIONS +template +void raise_error(const char* pfunction, const char* message) +{ + if(pfunction == nullptr) + { + pfunction = "Unknown function operating on type %1%"; + } + if(message == nullptr) + { + message = "Cause unknown"; + } + + std::string function(pfunction); + std::string msg("Error in function "); +#ifndef BOOST_NO_RTTI + replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of()); +#else + replace_all_in_string(function, "%1%", "Unknown"); +#endif + msg += function; + msg += ": "; + msg += message; + + BOOST_MATH_THROW_EXCEPTION(E(msg)) +} + +template +void raise_error(const char* pfunction, const char* pmessage, const T& val) +{ + if(pfunction == nullptr) + { + pfunction = "Unknown function operating on type %1%"; + } + if(pmessage == nullptr) + { + pmessage = "Cause unknown: error caused by bad argument with value %1%"; + } + + std::string function(pfunction); + std::string message(pmessage); + std::string msg("Error in function "); +#ifndef BOOST_NO_RTTI + replace_all_in_string(function, "%1%", boost::math::policies::detail::name_of()); +#else + replace_all_in_string(function, "%1%", "Unknown"); +#endif + msg += function; + msg += ": "; + + std::string sval = prec_format(val); + replace_all_in_string(message, "%1%", sval.c_str()); + msg += message; + + BOOST_MATH_THROW_EXCEPTION(E(msg)) +} +#endif + +template +inline T raise_domain_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return std::numeric_limits::quiet_NaN(); +#endif +} + +template +inline constexpr T raise_domain_error( + const char* , + const char* , + const T& , + const ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return std::numeric_limits::quiet_NaN(); +} + +template +inline T raise_domain_error( + const char* , + const char* , + const T& , + const ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return std::numeric_limits::quiet_NaN(); +} + +template +inline T raise_domain_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::domain_error< ::boost::math::policies::user_error>&) +{ + return user_domain_error(function, message, val); +} + +template +inline T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + return boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::throw_on_error>()); +#endif +} + +template +inline constexpr T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::ignore_error>()); +} + +template +inline constexpr T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + return ::boost::math::policies::detail::raise_domain_error(function, message, val, ::boost::math::policies::domain_error< ::boost::math::policies::errno_on_error>()); +} + +template +inline T raise_pole_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::pole_error< ::boost::math::policies::user_error>&) +{ + return user_pole_error(function, message, val); +} + +template +inline T raise_overflow_error( + const char* function, + const char* message, + const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric overflow"); + // We should never get here: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +#endif +} + +template +inline T raise_overflow_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::overflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric overflow", val); + // We should never get here: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +#endif +} + +template +inline constexpr T raise_overflow_error( + const char* , + const char* , + const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +inline constexpr T raise_overflow_error( + const char* , + const char* , + const T&, + const ::boost::math::policies::overflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +inline T raise_overflow_error( + const char* , + const char* , + const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +inline T raise_overflow_error( + const char* , + const char* , + const T&, + const ::boost::math::policies::overflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : boost::math::tools::max_value(); +} + +template +inline T raise_overflow_error( + const char* function, + const char* message, + const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) +{ + return user_overflow_error(function, message, std::numeric_limits::infinity()); +} + +template +inline T raise_overflow_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::overflow_error< ::boost::math::policies::user_error>&) +{ + std::string m(message ? message : ""); + std::string sval = prec_format(val); + replace_all_in_string(m, "%1%", sval.c_str()); + + return user_overflow_error(function, m.c_str(), std::numeric_limits::infinity()); +} + +template +inline T raise_underflow_error( + const char* function, + const char* message, + const ::boost::math::policies::underflow_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "numeric underflow"); + // We should never get here: + return 0; +#endif +} + +template +inline constexpr T raise_underflow_error( + const char* , + const char* , + const ::boost::math::policies::underflow_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return T(0); +} + +template +inline T raise_underflow_error( + const char* /* function */, + const char* /* message */, + const ::boost::math::policies::underflow_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return T(0); +} + +template +inline T raise_underflow_error( + const char* function, + const char* message, + const ::boost::math::policies::underflow_error< ::boost::math::policies::user_error>&) +{ + return user_underflow_error(function, message, T(0)); +} + +template +inline T raise_denorm_error( + const char* function, + const char* message, + const T& /* val */, + const ::boost::math::policies::denorm_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message ? message : "denormalised result"); + // we never get here: + return T(0); +#endif +} + +template +inline constexpr T raise_denorm_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +inline T raise_denorm_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return val; +} + +template +inline T raise_denorm_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::denorm_error< ::boost::math::policies::user_error>&) +{ + return user_denorm_error(function, message, val); +} + +template +inline T raise_evaluation_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return T(0); +#endif +} + +template +inline constexpr T raise_evaluation_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return val; +} + +template +inline T raise_evaluation_error( + const char* , + const char* , + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return val; +} + +template +inline T raise_evaluation_error( + const char* function, + const char* message, + const T& val, + const ::boost::math::policies::evaluation_error< ::boost::math::policies::user_error>&) +{ + return user_evaluation_error(function, message, val); +} + +template +inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return TargetType(0); +#endif +} + +template +inline constexpr TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + static_assert(std::numeric_limits::is_specialized, "The target type must have std::numeric_limits specialized."); + return val > 0 ? (std::numeric_limits::max)() : (std::numeric_limits::is_integer ? (std::numeric_limits::min)() : -(std::numeric_limits::max)()); +} + +template +inline TargetType raise_rounding_error( + const char* , + const char* , + const T& val, + const TargetType&, + const ::boost::math::policies::rounding_error< ::boost::math::policies::errno_on_error>&) BOOST_MATH_NOEXCEPT(T) +{ + errno = ERANGE; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + static_assert(std::numeric_limits::is_specialized, "The target type must have std::numeric_limits specialized."); + return val > 0 ? (std::numeric_limits::max)() : (std::numeric_limits::is_integer ? (std::numeric_limits::min)() : -(std::numeric_limits::max)()); +} +template +inline TargetType raise_rounding_error( + const char* function, + const char* message, + const T& val, + const TargetType& t, + const ::boost::math::policies::rounding_error< ::boost::math::policies::user_error>&) +{ + return user_rounding_error(function, message, val, t); +} + +template +inline T raise_indeterminate_result_error( + const char* function, + const char* message, + const T& val, + const R& , + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::throw_on_error>&) +{ +#ifdef BOOST_NO_EXCEPTIONS + static_assert(sizeof(T) == 0, "Error handler called with throw_on_error and BOOST_NO_EXCEPTIONS set."); +#else + raise_error(function, message, val); + // we never get here: + return std::numeric_limits::quiet_NaN(); +#endif +} + +template +inline constexpr T raise_indeterminate_result_error( + const char* , + const char* , + const T& , + const R& result, + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::ignore_error>&) BOOST_MATH_NOEXCEPT(T) +{ + // This may or may not do the right thing, but the user asked for the error + // to be ignored so here we go anyway: + return result; +} + +template +inline T raise_indeterminate_result_error( + const char* , + const char* , + const T& , + const R& result, + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::errno_on_error>&) +{ + errno = EDOM; + // This may or may not do the right thing, but the user asked for the error + // to be silent so here we go anyway: + return result; +} + +template +inline T raise_indeterminate_result_error( + const char* function, + const char* message, + const T& val, + const R& , + const ::boost::math::policies::indeterminate_result_error< ::boost::math::policies::user_error>&) +{ + return user_indeterminate_result_error(function, message, val); +} + +} // namespace detail + +template +inline constexpr T raise_domain_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::domain_error_type policy_type; + return detail::raise_domain_error( + function, message ? message : "Domain Error evaluating function at %1%", + val, policy_type()); +} + +template +inline constexpr T raise_pole_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::pole_error_type policy_type; + return detail::raise_pole_error( + function, message ? message : "Evaluation of function at pole %1%", + val, policy_type()); +} + +template +inline constexpr T raise_overflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::overflow_error_type policy_type; + return detail::raise_overflow_error( + function, message ? message : "Overflow Error", + policy_type()); +} + +template +inline constexpr T raise_overflow_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::overflow_error_type policy_type; + return detail::raise_overflow_error( + function, message ? message : "Overflow evaluating function at %1%", + val, policy_type()); +} + +template +inline constexpr T raise_underflow_error(const char* function, const char* message, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::underflow_error_type policy_type; + return detail::raise_underflow_error( + function, message ? message : "Underflow Error", + policy_type()); +} + +template +inline constexpr T raise_denorm_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::denorm_error_type policy_type; + return detail::raise_denorm_error( + function, message ? message : "Denorm Error", + val, + policy_type()); +} + +template +inline constexpr T raise_evaluation_error(const char* function, const char* message, const T& val, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::evaluation_error_type policy_type; + return detail::raise_evaluation_error( + function, message ? message : "Internal Evaluation Error, best value so far was %1%", + val, policy_type()); +} + +template +inline constexpr TargetType raise_rounding_error(const char* function, const char* message, const T& val, const TargetType& t, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::rounding_error_type policy_type; + return detail::raise_rounding_error( + function, message ? message : "Value %1% can not be represented in the target integer type.", + val, t, policy_type()); +} + +template +inline constexpr T raise_indeterminate_result_error(const char* function, const char* message, const T& val, const R& result, const Policy&) noexcept(is_noexcept_error_policy::value && BOOST_MATH_IS_FLOAT(T)) +{ + typedef typename Policy::indeterminate_result_error_type policy_type; + return detail::raise_indeterminate_result_error( + function, message ? message : "Indeterminate result with value %1%", + val, result, policy_type()); +} + +// +// checked_narrowing_cast: +// +namespace detail +{ + +template +BOOST_FORCEINLINE bool check_overflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + BOOST_MATH_STD_USING + if(fabs(val) > tools::max_value()) + { + boost::math::policies::detail::raise_overflow_error(function, nullptr, pol); + *result = static_cast(val); + return true; + } + return false; +} +template +BOOST_FORCEINLINE bool check_overflow(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_overflow(val.real(), &re, function, pol); + r = check_overflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template +BOOST_FORCEINLINE bool check_underflow(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + if((val != 0) && (static_cast(val) == 0)) + { + *result = static_cast(boost::math::policies::detail::raise_underflow_error(function, nullptr, pol)); + return true; + } + return false; +} +template +BOOST_FORCEINLINE bool check_underflow(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_underflow(val.real(), &re, function, pol); + r = check_underflow(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} +template +BOOST_FORCEINLINE bool check_denorm(T val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + BOOST_MATH_STD_USING + if((fabs(val) < static_cast(tools::min_value())) && (static_cast(val) != 0)) + { + *result = static_cast(boost::math::policies::detail::raise_denorm_error(function, 0, static_cast(val), pol)); + return true; + } + return false; +} +template +BOOST_FORCEINLINE bool check_denorm(std::complex val, R* result, const char* function, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && (Policy::value != throw_on_error) && (Policy::value != user_error)) +{ + typedef typename R::value_type r_type; + r_type re, im; + bool r = check_denorm(val.real(), &re, function, pol); + r = check_denorm(val.imag(), &im, function, pol) || r; + *result = R(re, im); + return r; +} + +// Default instantiations with ignore_error policy. +template +BOOST_FORCEINLINE constexpr bool check_overflow(T /* val */, R* /* result */, const char* /* function */, const overflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_FORCEINLINE constexpr bool check_overflow(std::complex /* val */, R* /* result */, const char* /* function */, const overflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_FORCEINLINE constexpr bool check_underflow(T /* val */, R* /* result */, const char* /* function */, const underflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_FORCEINLINE constexpr bool check_underflow(std::complex /* val */, R* /* result */, const char* /* function */, const underflow_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_FORCEINLINE constexpr bool check_denorm(T /* val */, R* /* result*/, const char* /* function */, const denorm_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } +template +BOOST_FORCEINLINE constexpr bool check_denorm(std::complex /* val */, R* /* result*/, const char* /* function */, const denorm_error&) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T)) +{ return false; } + +} // namespace detail + +template +BOOST_FORCEINLINE R checked_narrowing_cast(T val, const char* function) noexcept(BOOST_MATH_IS_FLOAT(R) && BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + typedef typename Policy::overflow_error_type overflow_type; + typedef typename Policy::underflow_error_type underflow_type; + typedef typename Policy::denorm_error_type denorm_type; + // + // Most of what follows will evaluate to a no-op: + // + R result = 0; + if(detail::check_overflow(val, &result, function, overflow_type())) + return result; + if(detail::check_underflow(val, &result, function, underflow_type())) + return result; + if(detail::check_denorm(val, &result, function, denorm_type())) + return result; + + return static_cast(val); +} + +template +inline void check_series_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + if(max_iter >= policies::get_max_series_iterations()) + raise_evaluation_error( + function, + "Series evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +template +inline void check_root_iterations(const char* function, std::uintmax_t max_iter, const Policy& pol) noexcept(BOOST_MATH_IS_FLOAT(T) && is_noexcept_error_policy::value) +{ + if(max_iter >= policies::get_max_root_iterations()) + raise_evaluation_error( + function, + "Root finding evaluation exceeded %1% iterations, giving up now.", static_cast(static_cast(max_iter)), pol); +} + +} //namespace policies + +namespace detail{ + +// +// Simple helper function to assist in returning a pair from a single value, +// that value usually comes from one of the error handlers above: +// +template +std::pair pair_from_single(const T& val) BOOST_MATH_NOEXCEPT(T) +{ + return std::make_pair(val, val); +} + +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +}} // namespaces boost/math + +#endif // BOOST_MATH_POLICY_ERROR_HANDLING_HPP + diff --git a/libcxx/src/third-party/boost/math/policies/policy.hpp b/libcxx/src/third-party/boost/math/policies/policy.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/policies/policy.hpp @@ -0,0 +1,984 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2021. +// 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_POLICY_HPP +#define BOOST_MATH_POLICY_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace mp = tools::meta_programming; + +namespace tools{ + +template +constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept; +template +constexpr T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value); + +} + +namespace policies{ + +// +// Define macros for our default policies, if they're not defined already: +// +// Special cases for exceptions disabled first: +// +#ifdef BOOST_NO_EXCEPTIONS +# ifndef BOOST_MATH_DOMAIN_ERROR_POLICY +# define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_POLE_ERROR_POLICY +# define BOOST_MATH_POLE_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY +# define BOOST_MATH_OVERFLOW_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_EVALUATION_ERROR_POLICY +# define BOOST_MATH_EVALUATION_ERROR_POLICY errno_on_error +# endif +# ifndef BOOST_MATH_ROUNDING_ERROR_POLICY +# define BOOST_MATH_ROUNDING_ERROR_POLICY errno_on_error +# endif +#endif +// +// Then the regular cases: +// +#ifndef BOOST_MATH_DOMAIN_ERROR_POLICY +#define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_POLE_ERROR_POLICY +#define BOOST_MATH_POLE_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_OVERFLOW_ERROR_POLICY +#define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_EVALUATION_ERROR_POLICY +#define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_ROUNDING_ERROR_POLICY +#define BOOST_MATH_ROUNDING_ERROR_POLICY throw_on_error +#endif +#ifndef BOOST_MATH_UNDERFLOW_ERROR_POLICY +#define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_DENORM_ERROR_POLICY +#define BOOST_MATH_DENORM_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY +#define BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY ignore_error +#endif +#ifndef BOOST_MATH_DIGITS10_POLICY +#define BOOST_MATH_DIGITS10_POLICY 0 +#endif +#ifndef BOOST_MATH_PROMOTE_FLOAT_POLICY +#define BOOST_MATH_PROMOTE_FLOAT_POLICY true +#endif +#ifndef BOOST_MATH_PROMOTE_DOUBLE_POLICY +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#define BOOST_MATH_PROMOTE_DOUBLE_POLICY false +#else +#define BOOST_MATH_PROMOTE_DOUBLE_POLICY true +#endif +#endif +#ifndef BOOST_MATH_DISCRETE_QUANTILE_POLICY +#define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards +#endif +#ifndef BOOST_MATH_ASSERT_UNDEFINED_POLICY +#define BOOST_MATH_ASSERT_UNDEFINED_POLICY true +#endif +#ifndef BOOST_MATH_MAX_SERIES_ITERATION_POLICY +#define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000 +#endif +#ifndef BOOST_MATH_MAX_ROOT_ITERATION_POLICY +#define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200 +#endif + +#define BOOST_MATH_META_INT(Type, name, Default) \ + template \ + class name : public std::integral_constant{}; \ + \ + namespace detail{ \ + template \ + char test_is_valid_arg(const name* = nullptr); \ + char test_is_default_arg(const name* = nullptr); \ + \ + template \ + class is_##name##_imp \ + { \ + private: \ + template \ + static char test(const name* = nullptr); \ + static double test(...); \ + public: \ + static constexpr bool value = sizeof(test(static_cast(nullptr))) == sizeof(char); \ + }; \ + } \ + \ + template \ + class is_##name \ + { \ + public: \ + static constexpr bool value = boost::math::policies::detail::is_##name##_imp::value; \ + using type = std::integral_constant; \ + }; + +#define BOOST_MATH_META_BOOL(name, Default) \ + template \ + class name : public std::integral_constant{}; \ + \ + namespace detail{ \ + template \ + char test_is_valid_arg(const name* = nullptr); \ + char test_is_default_arg(const name* = nullptr); \ + \ + template \ + class is_##name##_imp \ + { \ + private: \ + template \ + static char test(const name* = nullptr); \ + static double test(...); \ + public: \ + static constexpr bool value = sizeof(test(static_cast(nullptr))) == sizeof(char); \ + }; \ + } \ + \ + template \ + class is_##name \ + { \ + public: \ + static constexpr bool value = boost::math::policies::detail::is_##name##_imp::value; \ + using type = std::integral_constant; \ + }; + +// +// Begin by defining policy types for error handling: +// +enum error_policy_type +{ + throw_on_error = 0, + errno_on_error = 1, + ignore_error = 2, + user_error = 3 +}; + +BOOST_MATH_META_INT(error_policy_type, domain_error, BOOST_MATH_DOMAIN_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, pole_error, BOOST_MATH_POLE_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, overflow_error, BOOST_MATH_OVERFLOW_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, underflow_error, BOOST_MATH_UNDERFLOW_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, denorm_error, BOOST_MATH_DENORM_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, evaluation_error, BOOST_MATH_EVALUATION_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, rounding_error, BOOST_MATH_ROUNDING_ERROR_POLICY) +BOOST_MATH_META_INT(error_policy_type, indeterminate_result_error, BOOST_MATH_INDETERMINATE_RESULT_ERROR_POLICY) + +// +// Policy types for internal promotion: +// +BOOST_MATH_META_BOOL(promote_float, BOOST_MATH_PROMOTE_FLOAT_POLICY) +BOOST_MATH_META_BOOL(promote_double, BOOST_MATH_PROMOTE_DOUBLE_POLICY) +BOOST_MATH_META_BOOL(assert_undefined, BOOST_MATH_ASSERT_UNDEFINED_POLICY) +// +// Policy types for discrete quantiles: +// +enum discrete_quantile_policy_type +{ + real, + integer_round_outwards, + integer_round_inwards, + integer_round_down, + integer_round_up, + integer_round_nearest +}; + +BOOST_MATH_META_INT(discrete_quantile_policy_type, discrete_quantile, BOOST_MATH_DISCRETE_QUANTILE_POLICY) +// +// Precision: +// +BOOST_MATH_META_INT(int, digits10, BOOST_MATH_DIGITS10_POLICY) +BOOST_MATH_META_INT(int, digits2, 0) +// +// Iterations: +// +BOOST_MATH_META_INT(unsigned long, max_series_iterations, BOOST_MATH_MAX_SERIES_ITERATION_POLICY) +BOOST_MATH_META_INT(unsigned long, max_root_iterations, BOOST_MATH_MAX_ROOT_ITERATION_POLICY) +// +// Define the names for each possible policy: +// +#define BOOST_MATH_PARAMETER(name)\ + BOOST_PARAMETER_TEMPLATE_KEYWORD(name##_name)\ + BOOST_PARAMETER_NAME(name##_name) + +struct default_policy{}; + +namespace detail{ +// +// Trait to work out bits precision from digits10 and digits2: +// +template +struct precision +{ + // + // Now work out the precision: + // + using digits2_type = typename std::conditional< + (Digits10::value == 0), + digits2<0>, + digits2<((Digits10::value + 1) * 1000L) / 301L> + >::type; +public: +#ifdef BOOST_BORLANDC + using type = typename std::conditional< + (Digits2::value > ::boost::math::policies::detail::precision::digits2_type::value), + Digits2, digits2_type>::type; +#else + using type = typename std::conditional< + (Digits2::value > digits2_type::value), + Digits2, digits2_type>::type; +#endif +}; + +double test_is_valid_arg(...); +double test_is_default_arg(...); +char test_is_valid_arg(const default_policy*); +char test_is_default_arg(const default_policy*); + +template +class is_valid_policy_imp +{ +public: + static constexpr bool value = sizeof(boost::math::policies::detail::test_is_valid_arg(static_cast(nullptr))) == sizeof(char); +}; + +template +class is_valid_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_valid_policy_imp::value; +}; + +template +class is_default_policy_imp +{ +public: + static constexpr bool value = sizeof(boost::math::policies::detail::test_is_default_arg(static_cast(nullptr))) == sizeof(char); +}; + +template +class is_default_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_default_policy_imp::value; + using type = std::integral_constant; + + template + struct apply + { + using type = is_default_policy; + }; +}; + +template +struct append_N +{ + using type = typename append_N, T, N-1>::type; +}; + +template +struct append_N +{ + using type = Seq; +}; + +// +// Traits class to work out what template parameters our default +// policy<> class will have when modified for forwarding: +// +template +struct default_args +{ + typedef promote_float arg1; + typedef promote_double arg2; +}; + +template <> +struct default_args +{ + typedef default_policy arg1; + typedef default_policy arg2; +}; + +template <> +struct default_args +{ + typedef promote_float arg1; + typedef default_policy arg2; +}; + +template <> +struct default_args +{ + typedef promote_double arg1; + typedef default_policy arg2; +}; + +typedef default_args::arg1 forwarding_arg1; +typedef default_args::arg2 forwarding_arg2; + +} // detail + +// +// Now define the policy type with enough arguments to handle all +// the policies: +// +template +class policy +{ +private: + // + // Validate all our arguments: + // + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + static_assert(::boost::math::policies::detail::is_valid_policy::value, "::boost::math::policies::detail::is_valid_policy::value"); + // + // Typelist of the arguments: + // + using arg_list = mp::mp_list; + static constexpr std::size_t arg_list_size = mp::mp_size::value; + + template + struct pick_arg + { + using type = A; + }; + + template + struct pick_arg + { + using type = mp::mp_at; + }; + + template + class arg_type + { + private: + using index = mp::mp_find_if_q; + static constexpr bool end = (index::value >= arg_list_size); + public: + using type = typename pick_arg::type; + }; + + // Work out the base 2 and 10 precisions to calculate the public precision_type: + using digits10_type = typename arg_type, digits10<>>::type; + using bits_precision_type = typename arg_type, digits2<>>::type; + +public: + + // Error Types: + using domain_error_type = typename arg_type, domain_error<>>::type; + using pole_error_type = typename arg_type, pole_error<>>::type; + using overflow_error_type = typename arg_type, overflow_error<>>::type; + using underflow_error_type = typename arg_type, underflow_error<>>::type; + using denorm_error_type = typename arg_type, denorm_error<>>::type; + using evaluation_error_type = typename arg_type, evaluation_error<>>::type; + using rounding_error_type = typename arg_type, rounding_error<>>::type; + using indeterminate_result_error_type = typename arg_type, indeterminate_result_error<>>::type; + + // Precision: + using precision_type = typename detail::precision::type; + + // Internal promotion: + using promote_float_type = typename arg_type, promote_float<>>::type; + using promote_double_type = typename arg_type, promote_double<>>::type; + + // Discrete quantiles: + using discrete_quantile_type = typename arg_type, discrete_quantile<>>::type; + + // Mathematically undefined properties: + using assert_undefined_type = typename arg_type, assert_undefined<>>::type; + + // Max iterations: + using max_series_iterations_type = typename arg_type, max_series_iterations<>>::type; + using max_root_iterations_type = typename arg_type, max_root_iterations<>>::type; +}; + +// +// These full specializations are defined to reduce the amount of +// template instantiations that have to take place when using the default +// policies, they have quite a large impact on compile times: +// +template <> +class policy +{ +public: + using domain_error_type = domain_error<>; + using pole_error_type = pole_error<>; + using overflow_error_type = overflow_error<>; + using underflow_error_type = underflow_error<>; + using denorm_error_type = denorm_error<>; + using evaluation_error_type = evaluation_error<>; + using rounding_error_type = rounding_error<>; + using indeterminate_result_error_type = indeterminate_result_error<>; +#if BOOST_MATH_DIGITS10_POLICY == 0 + using precision_type = digits2<>; +#else + using precision_type = detail::precision, digits2<>>::type; +#endif + using promote_float_type = promote_float<>; + using promote_double_type = promote_double<>; + using discrete_quantile_type = discrete_quantile<>; + using assert_undefined_type = assert_undefined<>; + using max_series_iterations_type = max_series_iterations<>; + using max_root_iterations_type = max_root_iterations<>; +}; + +template <> +struct policy +{ +public: + using domain_error_type = domain_error<>; + using pole_error_type = pole_error<>; + using overflow_error_type = overflow_error<>; + using underflow_error_type = underflow_error<>; + using denorm_error_type = denorm_error<>; + using evaluation_error_type = evaluation_error<>; + using rounding_error_type = rounding_error<>; + using indeterminate_result_error_type = indeterminate_result_error<>; +#if BOOST_MATH_DIGITS10_POLICY == 0 + using precision_type = digits2<>; +#else + using precision_type = detail::precision, digits2<>>::type; +#endif + using promote_float_type = promote_float; + using promote_double_type = promote_double; + using discrete_quantile_type = discrete_quantile<>; + using assert_undefined_type = assert_undefined<>; + using max_series_iterations_type = max_series_iterations<>; + using max_root_iterations_type = max_root_iterations<>; +}; + +template +class normalise +{ +private: + using arg_list = mp::mp_list; + static constexpr std::size_t arg_list_size = mp::mp_size::value; + + template + struct pick_arg + { + using type = A; + }; + + template + struct pick_arg + { + using type = mp::mp_at; + }; + + template + class arg_type + { + private: + using index = mp::mp_find_if_q; + static constexpr bool end = (index::value >= arg_list_size); + public: + using type = typename pick_arg::type; + }; + + // Error types: + using domain_error_type = typename arg_type, typename Policy::domain_error_type>::type; + using pole_error_type = typename arg_type, typename Policy::pole_error_type>::type; + using overflow_error_type = typename arg_type, typename Policy::overflow_error_type>::type; + using underflow_error_type = typename arg_type, typename Policy::underflow_error_type>::type; + using denorm_error_type = typename arg_type, typename Policy::denorm_error_type>::type; + using evaluation_error_type = typename arg_type, typename Policy::evaluation_error_type>::type; + using rounding_error_type = typename arg_type, typename Policy::rounding_error_type>::type; + using indeterminate_result_error_type = typename arg_type, typename Policy::indeterminate_result_error_type>::type; + + // Precision: + using digits10_type = typename arg_type, digits10<>>::type; + using bits_precision_type = typename arg_type, typename Policy::precision_type>::type; + using precision_type = typename detail::precision::type; + + // Internal promotion: + using promote_float_type = typename arg_type, typename Policy::promote_float_type>::type; + using promote_double_type = typename arg_type, typename Policy::promote_double_type>::type; + + // Discrete quantiles: + using discrete_quantile_type = typename arg_type, typename Policy::discrete_quantile_type>::type; + + // Mathematically undefined properties: + using assert_undefined_type = typename arg_type, typename Policy::assert_undefined_type>::type; + + // Max iterations: + using max_series_iterations_type = typename arg_type, typename Policy::max_series_iterations_type>::type; + using max_root_iterations_type = typename arg_type, typename Policy::max_root_iterations_type>::type; + + // Define a typelist of the policies: + using result_list = mp::mp_list< + domain_error_type, + pole_error_type, + overflow_error_type, + underflow_error_type, + denorm_error_type, + evaluation_error_type, + rounding_error_type, + indeterminate_result_error_type, + precision_type, + promote_float_type, + promote_double_type, + discrete_quantile_type, + assert_undefined_type, + max_series_iterations_type, + max_root_iterations_type>; + + // Remove all the policies that are the same as the default: + using fn = mp::mp_quote_trait; + using reduced_list = mp::mp_remove_if_q; + + // Pad out the list with defaults: + using result_type = typename detail::append_N::value)>::type; + +public: + using type = policy< + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c, + mp::mp_at_c + >; +}; + +// Full specialisation to speed up compilation of the common case: +template <> +struct normalise, + promote_float, + promote_double, + discrete_quantile<>, + assert_undefined<>, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy> +{ + using type = policy; +}; + +template <> +struct normalise, + promote_float, + promote_double, + discrete_quantile<>, + assert_undefined<>, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy, + default_policy> +{ + using type = policy; +}; + +inline constexpr policy<> make_policy() noexcept +{ return {}; } + +template +inline constexpr typename normalise, A1>::type make_policy(const A1&) noexcept +{ + typedef typename normalise, A1>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2>::type make_policy(const A1&, const A2&) noexcept +{ + typedef typename normalise, A1, A2>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3>::type make_policy(const A1&, const A2&, const A3&) noexcept +{ + typedef typename normalise, A1, A2, A3>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4>::type make_policy(const A1&, const A2&, const A3&, const A4&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>::type result_type; + return result_type(); +} + +template +inline constexpr typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type make_policy(const A1&, const A2&, const A3&, const A4&, const A5&, const A6&, const A7&, const A8&, const A9&, const A10&, const A11&) noexcept +{ + typedef typename normalise, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>::type result_type; + return result_type(); +} + +// +// Traits class to handle internal promotion: +// +template +struct evaluation +{ + typedef Real type; +}; + +template +struct evaluation +{ + using type = typename std::conditional::type; +}; + +template +struct evaluation +{ + using type = typename std::conditional::type; +}; + +template +struct precision +{ + static_assert((std::numeric_limits::radix == 2) || ((std::numeric_limits::is_specialized == 0) || (std::numeric_limits::digits == 0)), + "(std::numeric_limits::radix == 2) || ((std::numeric_limits::is_specialized == 0) || (std::numeric_limits::digits == 0))"); +#ifndef BOOST_BORLANDC + using precision_type = typename Policy::precision_type; + using type = typename std::conditional< + ((std::numeric_limits::is_specialized == 0) || (std::numeric_limits::digits == 0)), + // Possibly unknown precision: + precision_type, + typename std::conditional< + ((std::numeric_limits::digits <= precision_type::value) + || (Policy::precision_type::value <= 0)), + // Default case, full precision for RealType: + digits2< std::numeric_limits::digits>, + // User customised precision: + precision_type + >::type + >::type; +#else + using precision_type = typename Policy::precision_type; + using digits_t = std::integral_constant::digits>; + using spec_t = std::integral_constant::is_specialized>; + using type = typename std::conditional< + (spec_t::value == true std::true_type || digits_t::value == 0), + // Possibly unknown precision: + precision_type, + typename std::conditional< + (digits_t::value <= precision_type::value || precision_type::value <= 0), + // Default case, full precision for RealType: + digits2< std::numeric_limits::digits>, + // User customised precision: + precision_type + >::type + >::type; +#endif +}; + +#ifdef BOOST_MATH_USE_FLOAT128 + +template +struct precision +{ + typedef std::integral_constant type; +}; + +#endif + +namespace detail{ + +template +inline constexpr int digits_imp(std::true_type const&) noexcept +{ + static_assert( std::numeric_limits::is_specialized, "std::numeric_limits::is_specialized"); + typedef typename boost::math::policies::precision::type p_t; + return p_t::value; +} + +template +inline constexpr int digits_imp(std::false_type const&) noexcept +{ + return tools::digits(); +} + +} // namespace detail + +template +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept +{ + typedef std::integral_constant::is_specialized > tag_type; + return detail::digits_imp(tag_type()); +} +template +inline constexpr int digits_base10(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept +{ + return boost::math::policies::digits() * 301 / 1000L; +} + +template +inline constexpr unsigned long get_max_series_iterations() noexcept +{ + typedef typename Policy::max_series_iterations_type iter_type; + return iter_type::value; +} + +template +inline constexpr unsigned long get_max_root_iterations() noexcept +{ + typedef typename Policy::max_root_iterations_type iter_type; + return iter_type::value; +} + +namespace detail{ + +template +struct series_factor_calc +{ + static T get() noexcept(std::is_floating_point::value) + { + return ldexp(T(1.0), 1 - Digits::value); + } +}; + +template +struct series_factor_calc +{ + static constexpr T get() noexcept(std::is_floating_point::value) + { + return boost::math::tools::epsilon(); + } +}; +template +struct series_factor_calc +{ + static constexpr T get() noexcept(std::is_floating_point::value) + { + return 1 / static_cast(static_cast(1u) << (Digits::value - 1)); + } +}; +template +struct series_factor_calc +{ + static constexpr T get() noexcept(std::is_floating_point::value) + { + return boost::math::tools::epsilon(); + } +}; + +template +inline constexpr T get_epsilon_imp(std::true_type const&) noexcept(std::is_floating_point::value) +{ + static_assert(std::numeric_limits::is_specialized, "std::numeric_limits::is_specialized"); + static_assert(std::numeric_limits::radix == 2, "std::numeric_limits::radix == 2"); + + typedef typename boost::math::policies::precision::type p_t; + typedef std::integral_constant::digits> is_small_int; + typedef std::integral_constant= std::numeric_limits::digits> is_default_value; + return series_factor_calc::get(); +} + +template +inline constexpr T get_epsilon_imp(std::false_type const&) noexcept(std::is_floating_point::value) +{ + return tools::epsilon(); +} + +} // namespace detail + +template +inline constexpr T get_epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + typedef std::integral_constant::is_specialized && (std::numeric_limits::radix == 2)) > tag_type; + return detail::get_epsilon_imp(tag_type()); +} + +namespace detail{ + +template +char test_is_policy(const policy*); +double test_is_policy(...); + +template +class is_policy_imp +{ +public: + static constexpr bool value = (sizeof(::boost::math::policies::detail::test_is_policy(static_cast(nullptr))) == sizeof(char)); +}; + +} + +template +class is_policy +{ +public: + static constexpr bool value = boost::math::policies::detail::is_policy_imp

::value; + using type = std::integral_constant; +}; + +// +// Helper traits class for distribution error handling: +// +template +struct constructor_error_check +{ + using domain_error_type = typename Policy::domain_error_type; + using type = typename std::conditional< + (domain_error_type::value == throw_on_error) || (domain_error_type::value == user_error) || (domain_error_type::value == errno_on_error), + std::true_type, + std::false_type>::type; +}; + +template +struct method_error_check +{ + using domain_error_type = typename Policy::domain_error_type; + using type = typename std::conditional< + (domain_error_type::value == throw_on_error), + std::false_type, + std::true_type>::type; +}; +// +// Does the Policy ever throw on error? +// +template +struct is_noexcept_error_policy +{ + typedef typename Policy::domain_error_type t1; + typedef typename Policy::pole_error_type t2; + typedef typename Policy::overflow_error_type t3; + typedef typename Policy::underflow_error_type t4; + typedef typename Policy::denorm_error_type t5; + typedef typename Policy::evaluation_error_type t6; + typedef typename Policy::rounding_error_type t7; + typedef typename Policy::indeterminate_result_error_type t8; + + static constexpr bool value = + ((t1::value != throw_on_error) && (t1::value != user_error) + && (t2::value != throw_on_error) && (t2::value != user_error) + && (t3::value != throw_on_error) && (t3::value != user_error) + && (t4::value != throw_on_error) && (t4::value != user_error) + && (t5::value != throw_on_error) && (t5::value != user_error) + && (t6::value != throw_on_error) && (t6::value != user_error) + && (t7::value != throw_on_error) && (t7::value != user_error) + && (t8::value != throw_on_error) && (t8::value != user_error)); +}; + +}}} // namespaces + +#endif // BOOST_MATH_POLICY_HPP + diff --git a/libcxx/src/third-party/boost/math/quadrature/detail/exp_sinh_detail.hpp b/libcxx/src/third-party/boost/math/quadrature/detail/exp_sinh_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/detail/exp_sinh_detail.hpp @@ -0,0 +1,530 @@ +// Copyright Nick Thompson, 2017 +// 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_QUADRATURE_DETAIL_EXP_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_EXP_SINH_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + +// Returns the exp-sinh quadrature of a function f over the open interval (0, infinity) + +template +class exp_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + exp_sinh_detail(size_t max_refinements); + + template + auto integrate(const F& f, Real* error, Real* L1, const char* function, Real tolerance, std::size_t* levels)->decltype(std::declval()(std::declval())) const; + +private: + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const std::integral_constant&); +#endif + + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + using std::sinh; + using std::cosh; + using std::exp; + std::size_t row = ++m_committed_refinements; + + Real h = ldexp(static_cast(1), -static_cast(row)); + const Real t_max = m_t_min + m_abscissas[0].size() - 1; + + size_t k = static_cast(boost::math::lltrunc(ceil((t_max - m_t_min) / (2 * h)))); + m_abscissas[row].reserve(k); + m_weights[row].reserve(k); + Real arg = m_t_min; + size_t j = 0; + size_t l = 2; + while (arg + l*h < t_max) + { + arg = m_t_min + (2 * j + 1)*h; + Real x = exp(constants::half_pi()*sinh(arg)); + m_abscissas[row].emplace_back(x); + Real w = cosh(arg)*constants::half_pi()*x; + m_weights[row].emplace_back(w); + ++j; + } + } + + Real m_tol, m_t_min; + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + std::size_t m_max_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif +}; + +template +exp_sinh_detail::exp_sinh_detail(size_t max_refinements) + : m_abscissas(max_refinements), m_weights(max_refinements), + m_max_refinements(max_refinements) +{ + init(std::integral_constant()); +} +template +template +auto exp_sinh_detail::integrate(const F& f, Real* error, Real* L1, const char* function, Real tolerance, std::size_t* levels)->decltype(std::declval()(std::declval())) const +{ + typedef decltype(f(static_cast(0))) K; + using std::abs; + using std::floor; + using std::tanh; + using std::sinh; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + // This provided a nice error message for real valued integrals, but it's super awkward for complex-valued integrals: + /*K y_max = f(tools::max_value()); + if(abs(y_max) > tools::epsilon() || !(boost::math::isfinite)(y_max)) + { + K val = abs(y_max); + return static_cast(policies::raise_domain_error(function, "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", val, Policy())); + }*/ + + //std::cout << std::setprecision(5*std::numeric_limits::digits10); + + // Get the party started with two estimates of the integral: + Real min_abscissa{ 0 }, max_abscissa{ boost::math::tools::max_value() }; + K I0 = 0; + Real L1_I0 = 0; + for(size_t i = 0; i < m_abscissas[0].size(); ++i) + { + K y = f(m_abscissas[0][i]); + K I0_last = I0; + I0 += y*m_weights[0][i]; + L1_I0 += abs(y)*m_weights[0][i]; + if ((I0_last == I0) && (abs(I0) != 0)) + { + max_abscissa = m_abscissas[0][i]; + break; + } + } + + //std::cout << "First estimate : " << I0 << std::endl; + K I1 = I0; + Real L1_I1 = L1_I0; + bool have_first_j = false; + std::size_t first_j = 0; + for (size_t i = 0; (i < m_abscissas[1].size()) && (m_abscissas[1][i] < max_abscissa); ++i) + { + K y = f(m_abscissas[1][i]); + K I1_last = I1; + I1 += y*m_weights[1][i]; + L1_I1 += abs(y)*m_weights[1][i]; + if (!have_first_j && (I1_last == I1)) + { + // No change to the sum, disregard these values on the LHS: + min_abscissa = m_abscissas[1][i]; + first_j = i; + } + else + have_first_j = true; + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + //std::cout << "Second estimate: " << I1 << " Error estimate at level " << 1 << " = " << err << std::endl; + + size_t i = 2; + for(; i < m_abscissas.size(); ++i) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1)/static_cast(1 << i); + K sum = 0; + Real absum = 0; + + auto abscissas_row = get_abscissa_row(i); + auto weight_row = get_weight_row(i); + + first_j = first_j == 0 ? 0 : 2 * first_j - 1; // appoximate location to start looking for lowest meaningful abscissa value + BOOST_MATH_MAYBE_UNUSED Real abterm1 = 1; + std::size_t j = first_j; + while (abscissas_row[j] < min_abscissa) + ++j; + for(; (j < m_weights[i].size()) && (abscissas_row[j] < max_abscissa); ++j) + { + Real x = abscissas_row[j]; + K y = f(x); + sum += y*weight_row[j]; + Real abterm0 = abs(y)*weight_row[j]; + absum += abterm0; + abterm1 = abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + //std::cout << "Estimate: " << I1 << " Error estimate at level " << i << " = " << err << std::endl; + // Use L1_I1 here to make it work with both complex and real valued integrands: + if (!isfinite(L1_I1)) + { + return static_cast(policies::raise_evaluation_error(function, "The exp_sinh quadrature evaluated your function at a singular point and returned %1%. Please ensure your function evaluates to a finite number over its entire domain.", I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if(L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + using std::exp; + using std::log; + using std::sqrt; + using std::cosh; + using std::sinh; + using std::asinh; + using std::ceil; + using boost::math::constants::two_div_pi; + using boost::math::constants::half_pi; + using boost::math::constants::half; + + m_committed_refinements = 4; + // m_t_min is chosen such that x = exp(pi/2 sinh(-t_max)) = very small, but not too small. + // This is a compromise; we wish to approach a singularity at zero without hitting it through roundoff error. + // If we choose the small number as epsilon, we do not get close enough to the singularity to achieve high accuracy. + // If we choose the small number as the min(), then we round off to zero and hit the singularity. + // The logarithmic average of the min() and the epsilon() has been found to be a reasonable compromise, which achieves high accuracy + // but does not evaluate the function at the singularity. + Real tmp = (boost::math::tools::log_min_value() + log(boost::math::tools::epsilon()))*half(); + m_t_min = asinh(two_div_pi()*tmp); + + // t_max is chosen to make g'(t_max) ~ sqrt(max) (g' grows faster than g). + // This will allow some flexibility on the users part; they can at least square a number function without overflow. + // But there is no unique choice; the further out we can evaluate the function, the better we can do on slowly decaying integrands. + const Real t_max = log(2 * two_div_pi()*log(2 * two_div_pi()*sqrt(tools::max_value()))); + + for (size_t i = 0; i <= m_committed_refinements; ++i) + { + Real h = static_cast(1) / static_cast(1 << i); + size_t k = static_cast(boost::math::lltrunc(ceil((t_max - m_t_min) / (2 * h)))); + m_abscissas[i].reserve(k); + m_weights[i].reserve(k); + Real arg = m_t_min; + size_t j = 0; + size_t l = 2; + if (i == 0) + { + l = 1; + } + while (arg + l*h < t_max) + { + if (i != 0) + { + arg = m_t_min + (2 * j + 1)*h; + } + else + { + arg = m_t_min + j*h; + } + Real x = exp(half_pi()*sinh(arg)); + m_abscissas[i].emplace_back(x); + Real w = cosh(arg)*half_pi()*x; + m_weights[i].emplace_back(w); + ++j; + } + } + /* + std::cout << std::setprecision(40) << m_t_min << std::endl; + for (unsigned i = 0; i <= m_committed_refinements; ++i) + { + std::cout << "{ "; + for (unsigned j = 0; j < m_abscissas[i].size(); ++j) + std::cout << m_abscissas[i][j] << "Q, "; + std::cout << " },\n"; + } + for (unsigned i = 0; i <= m_committed_refinements; ++i) + { + std::cout << "{ "; + for (unsigned j = 0; j < m_weights[i].size(); ++j) + std::cout << m_weights[i][j] << "Q, "; + std::cout << " },\n"; + } + */ +} + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.47876573e-23f, 5.62503650e-09f, 9.95706124e-04f, 9.67438487e-02f, 7.43599217e-01f, 4.14293205e+00f, 1.08086768e+02f, 4.56291316e+05f, 2.70123007e+15f, }, + { 2.41870864e-14f, 1.02534662e-05f, 1.65637566e-02f, 3.11290799e-01f, 1.64691269e+00f, 1.49800773e+01f, 2.57724301e+03f, 2.24833766e+09f, }, + { 3.24983286e-18f, 2.51095186e-11f, 3.82035773e-07f, 1.33717837e-04f, 4.80260650e-03f, 4.41526928e-02f, 1.83045938e-01f, 4.91960276e-01f, 1.10322609e+00f, 2.53681744e+00f, 7.39791792e+00f, 3.59560256e+01f, 4.36061333e+02f, 2.49501460e+04f, 1.89216933e+07f, 1.03348694e+12f, }, + { 1.51941172e-20f, 3.70201714e-16f, 9.67598102e-13f, 4.44773051e-10f, 5.28493928e-08f, 2.19158236e-06f, 4.00799258e-05f, 3.88011529e-04f, 2.29325538e-03f, 9.25182629e-03f, 2.78117501e-02f, 6.67553298e-02f, 1.35173168e-01f, 2.41374946e-01f, 3.94194704e-01f, 6.07196731e-01f, 9.06432514e-01f, 1.34481045e+00f, 2.03268444e+00f, 3.21243032e+00f, 5.46310949e+00f, 1.03365745e+01f, 2.26486752e+01f, 6.03727778e+01f, 2.08220266e+02f, 1.00431239e+03f, 7.47843388e+03f, 9.75279951e+04f, 2.61755592e+06f, 1.77776624e+08f, 3.98255346e+10f, 4.13443763e+13f, 3.07708133e+17f, }, + { 7.99409438e-22f, 2.41624595e-19f, 3.73461321e-17f, 3.19397902e-15f, 1.62042378e-13f, 5.18579386e-12f, 1.10520072e-10f, 1.64548212e-09f, 1.78534009e-08f, 1.46529196e-07f, 9.40168786e-07f, 4.85507733e-06f, 2.07038029e-05f, 7.45799409e-05f, 2.31536599e-04f, 6.30580368e-04f, 1.53035449e-03f, 3.35582040e-03f, 6.73124842e-03f, 1.24856832e-02f, 2.16245309e-02f, 3.52720523e-02f, 5.45995171e-02f, 8.07587788e-02f, 1.14840025e-01f, 1.57867103e-01f, 2.10837078e-01f, 2.74805391e-01f, 3.51015955e-01f, 4.41077540e-01f, 5.47194016e-01f, 6.72466825e-01f, 8.21304567e-01f, 1.00000000e+00f, 1.21757511e+00f, 1.48706221e+00f, 1.82750536e+00f, 2.26717507e+00f, 2.84887335e+00f, 3.63893880e+00f, 4.74299876e+00f, 6.33444194e+00f, 8.70776542e+00f, 1.23825548e+01f, 1.83151803e+01f, 2.83510579e+01f, 4.62437776e+01f, 8.00917327e+01f, 1.48560852e+02f, 2.97989725e+02f, 6.53443372e+02f, 1.58584068e+03f, 4.31897162e+03f, 1.34084311e+04f, 4.83003053e+04f, 2.05969943e+05f, 1.06363880e+06f, 6.82457850e+06f, 5.60117371e+07f, 6.07724622e+08f, 9.04813016e+09f, 1.92834507e+11f, 6.17122515e+12f, 3.13089095e+14f, 2.67765347e+16f, 4.13865153e+18f, }, + { 1.70893932e-22f, 3.56621447e-21f, 6.19138882e-20f, 9.04299298e-19f, 1.12287188e-17f, 1.19706303e-16f, 1.10583090e-15f, 8.92931857e-15f, 6.35404710e-14f, 4.01527389e-13f, 2.26955738e-12f, 1.15522811e-11f, 5.32913181e-11f, 2.24130967e-10f, 8.64254491e-10f, 3.07161058e-09f, 1.01117742e-08f, 3.09775637e-08f, 8.87004371e-08f, 2.38368096e-07f, 6.03520392e-07f, 1.44488635e-06f, 3.28212299e-06f, 7.09655821e-06f, 1.46494407e-05f, 2.89537394e-05f, 5.49357161e-05f, 1.00313252e-04f, 1.76700203e-04f, 3.00920507e-04f, 4.96484845e-04f, 7.95150594e-04f, 1.23845781e-03f, 1.87911525e-03f, 2.78210510e-03f, 4.02538552e-03f, 5.70009588e-03f, 7.91020800e-03f, 1.07716137e-02f, 1.44106884e-02f, 1.89624177e-02f, 2.45682104e-02f, 3.13735515e-02f, 3.95256605e-02f, 4.91713196e-02f, 6.04550279e-02f, 7.35176150e-02f, 8.84954195e-02f, 1.05520113e-01f, 1.24719213e-01f, 1.46217318e-01f, 1.70138063e-01f, 1.96606781e-01f, 2.25753880e-01f, 2.57718900e-01f, 2.92655274e-01f, 3.30735809e-01f, 3.72158929e-01f, 4.17155794e-01f, 4.65998399e-01f, 5.19008863e-01f, 5.76570161e-01f, 6.39138643e-01f, 7.07258781e-01f, 7.81580731e-01f, 8.62881450e-01f, 9.52090320e-01f, 1.05032052e+00f, 1.15890775e+00f, 1.27945836e+00f, 1.41390963e+00f, 1.56460576e+00f, 1.73439430e+00f, 1.92674937e+00f, 2.14593012e+00f, 2.39718593e+00f, 2.68702407e+00f, 3.02356133e+00f, 3.41698950e+00f, 3.88019661e+00f, 4.42960272e+00f, 5.08629455e+00f, 5.87757956e+00f, 6.83913514e+00f, 8.01801085e+00f, 9.47686632e+00f, 1.13000199e+01f, 1.36021823e+01f, 1.65412214e+01f, 2.03370584e+01f, 2.53000199e+01f, 3.18739815e+01f, 4.07030054e+01f, 5.27358913e+01f, 6.93929374e+01f, 9.28366010e+01f, 1.26418926e+02f, 1.75435645e+02f, 2.48423411e+02f, 3.59440052e+02f, 5.32165336e+02f, 8.07455844e+02f, 1.25762341e+03f, 2.01416017e+03f, 3.32313676e+03f, 5.65930306e+03f, 9.96877263e+03f, 1.82030939e+04f, 3.45378531e+04f, 6.82619916e+04f, 1.40913380e+05f, 3.04680844e+05f, 6.92095957e+05f, 1.65694484e+06f, 4.19519229e+06f, 1.12739016e+07f, 3.22814282e+07f, 9.88946136e+07f, 3.25562103e+08f, 1.15706659e+09f, 4.46167708e+09f, 1.87647826e+10f, 8.65629909e+10f, 4.40614549e+11f, 2.49049013e+12f, 1.57380011e+13f, 1.11990629e+14f, 9.04297390e+14f, 8.35377903e+15f, 8.90573552e+16f, 1.10582857e+18f, 1.61514650e+19f, }, + { 7.75845008e-23f, 3.71846701e-22f, 1.69833677e-21f, 7.40284853e-21f, 3.08399399e-20f, 1.22962599e-19f, 4.69855182e-19f, 1.72288020e-18f, 6.07012059e-18f, 2.05742924e-17f, 6.71669437e-17f, 2.11441966e-16f, 6.42566550e-16f, 1.88715605e-15f, 5.36188198e-15f, 1.47533056e-14f, 3.93507835e-14f, 1.01841667e-13f, 2.55981752e-13f, 6.25453236e-13f, 1.48683211e-12f, 3.44173601e-12f, 7.76421789e-12f, 1.70831312e-11f, 3.66877698e-11f, 7.69632540e-11f, 1.57822184e-10f, 3.16577320e-10f, 6.21604166e-10f, 1.19551931e-09f, 2.25364361e-09f, 4.16647469e-09f, 7.55905964e-09f, 1.34658870e-08f, 2.35675936e-08f, 4.05458117e-08f, 6.86052525e-08f, 1.14227960e-07f, 1.87243781e-07f, 3.02323521e-07f, 4.81026747e-07f, 7.54564302e-07f, 1.16746531e-06f, 1.78236867e-06f, 2.68618781e-06f, 3.99792342e-06f, 5.87841837e-06f, 8.54236163e-06f, 1.22728487e-05f, 1.74387947e-05f, 2.45154696e-05f, 3.41083807e-05f, 4.69806683e-05f, 6.40841007e-05f, 8.65936597e-05f, 1.15945600e-04f, 1.53878746e-04f, 2.02478652e-04f, 2.64224143e-04f, 3.42035594e-04f, 4.39324211e-04f, 5.60041454e-04f, 7.08727668e-04f, 8.90558896e-04f, 1.11139085e-03f, 1.37779898e-03f, 1.69711358e-03f, 2.07744903e-03f, 2.52772622e-03f, 3.05768742e-03f, 3.67790298e-03f, 4.39976940e-03f, 5.23549846e-03f, 6.19809738e-03f, 7.30134015e-03f, 8.55973022e-03f, 9.98845520e-03f, 1.16033342e-02f, 1.34207587e-02f, 1.54576276e-02f, 1.77312787e-02f, 2.02594158e-02f, 2.30600348e-02f, 2.61513493e-02f, 2.95517158e-02f, 3.32795626e-02f, 3.73533204e-02f, 4.17913590e-02f, 4.66119283e-02f, 5.18331072e-02f, 5.74727595e-02f, 6.35484986e-02f, 7.00776615e-02f, 7.70772927e-02f, 8.45641386e-02f, 9.25546518e-02f, 1.01065008e-01f, 1.10111132e-01f, 1.19708739e-01f, 1.29873379e-01f, 1.40620505e-01f, 1.51965539e-01f, 1.63923958e-01f, 1.76511391e-01f, 1.89743720e-01f, 2.03637197e-01f, 2.18208574e-01f, 2.33475238e-01f, 2.49455360e-01f, 2.66168055e-01f, 2.83633553e-01f, 3.01873381e-01f, 3.20910560e-01f, 3.40769809e-01f, 3.61477772e-01f, 3.83063247e-01f, 4.05557445e-01f, 4.28994258e-01f, 4.53410546e-01f, 4.78846448e-01f, 5.05345717e-01f, 5.32956079e-01f, 5.61729623e-01f, 5.91723220e-01f, 6.22998983e-01f, 6.55624768e-01f, 6.89674714e-01f, 7.25229845e-01f, 7.62378724e-01f, 8.01218171e-01f, 8.41854062e-01f, 8.84402205e-01f, 9.28989312e-01f, 9.75754080e-01f, 1.02484839e+00f, 1.07643865e+00f, 1.13070727e+00f, 1.18785434e+00f, 1.24809950e+00f, 1.31168403e+00f, 1.37887320e+00f, 1.44995892e+00f, 1.52526270e+00f, 1.60513906e+00f, 1.68997931e+00f, 1.78021589e+00f, 1.87632722e+00f, 1.97884333e+00f, 2.08835213e+00f, 2.20550671e+00f, 2.33103353e+00f, 2.46574193e+00f, 2.61053497e+00f, 2.76642183e+00f, 2.93453226e+00f, 3.11613304e+00f, 3.31264716e+00f, 3.52567596e+00f, 3.75702486e+00f, 4.00873326e+00f, 4.28310945e+00f, 4.58277134e+00f, 4.91069419e+00f, 5.27026666e+00f, 5.66535674e+00f, 6.10038953e+00f, 6.58043928e+00f, 7.11133842e+00f, 7.69980735e+00f, 8.35360902e+00f, 9.08173387e+00f, 9.89462150e+00f, 1.08044272e+01f, 1.18253437e+01f, 1.29739897e+01f, 1.42698826e+01f, 1.57360130e+01f, 1.73995473e+01f, 1.92926887e+01f, 2.14537359e+01f, 2.39283915e+01f, 2.67713817e+01f, 3.00484719e+01f, 3.38389827e+01f, 3.82389447e+01f, 4.33650689e+01f, 4.93597649e+01f, 5.63975118e+01f, 6.46929803e+01f, 7.45114359e+01f, 8.61821250e+01f, 1.00115581e+02f, 1.16826112e+02f, 1.36961158e+02f, 1.61339834e+02f, 1.91003781e+02f, 2.27284639e+02f, 2.71894067e+02f, 3.27044548e+02f, 3.95612465e+02f, 4.81359585e+02f, 5.89235756e+02f, 7.25795284e+02f, 8.99773468e+02f, 1.12289036e+03f, 1.41097920e+03f, 1.78558211e+03f, 2.27622329e+03f, 2.92367233e+03f, 3.78466551e+03f, 4.93879227e+03f, 6.49862329e+03f, 8.62473434e+03f, 1.15481896e+04f, 1.56044945e+04f, 2.12853507e+04f, 2.93183077e+04f, 4.07905708e+04f, 5.73434125e+04f, 8.14806753e+04f, 1.17063646e+05f, 1.70113785e+05f, 2.50129854e+05f, 3.72274789e+05f, 5.61051155e+05f, 8.56556497e+05f, 1.32526810e+06f, 2.07888648e+06f, 3.30771485e+06f, 5.34063130e+06f, 8.75442405e+06f, 1.45761434e+07f, 2.46634599e+07f, 4.24311457e+07f, 7.42617251e+07f, 1.32291588e+08f, 2.40011058e+08f, 4.43725882e+08f, 8.36456588e+08f, 1.60874083e+09f, 3.15878598e+09f, 6.33624483e+09f, 1.29932136e+10f, 2.72570398e+10f, 5.85372779e+10f, 1.28795973e+11f, 2.90551047e+11f, 6.72570892e+11f, 1.59884056e+12f, 3.90652847e+12f, 9.81916374e+12f, 2.54124546e+13f, 6.77814197e+13f, 1.86501681e+14f, 5.29897885e+14f, 1.55625904e+15f, 4.72943011e+15f, 1.48882761e+16f, 4.86043448e+16f, 1.64741373e+17f, 5.80423410e+17f, 2.12831536e+18f, 8.13255421e+18f, }, + { 5.20331508e-23f, 1.15324162e-22f, 2.52466875e-22f, 5.46028730e-22f, 1.16690465e-21f, 2.46458927e-21f, 5.14543768e-21f, 1.06205431e-20f, 2.16767715e-20f, 4.37564009e-20f, 8.73699691e-20f, 1.72595588e-19f, 3.37377643e-19f, 6.52669145e-19f, 1.24976973e-18f, 2.36916845e-18f, 4.44691383e-18f, 8.26580373e-18f, 1.52174118e-17f, 2.77517606e-17f, 5.01415830e-17f, 8.97689232e-17f, 1.59270821e-16f, 2.80084735e-16f, 4.88253693e-16f, 8.43846463e-16f, 1.44610939e-15f, 2.45762595e-15f, 4.14251017e-15f, 6.92627770e-15f, 1.14889208e-14f, 1.89084205e-14f, 3.08802476e-14f, 5.00504297e-14f, 8.05169965e-14f, 1.28579121e-13f, 2.03847833e-13f, 3.20880532e-13f, 5.01568631e-13f, 7.78600100e-13f, 1.20044498e-12f, 1.83848331e-12f, 2.79712543e-12f, 4.22808302e-12f, 6.35035779e-12f, 9.47805307e-12f, 1.40588174e-11f, 2.07266430e-11f, 3.03739182e-11f, 4.42491437e-11f, 6.40886341e-11f, 9.22929507e-11f, 1.32161843e-10f, 1.88205259e-10f, 2.66552657e-10f, 3.75488615e-10f, 5.26149742e-10f, 7.33426418e-10f, 1.01712318e-09f, 1.40344387e-09f, 1.92688222e-09f, 2.63261606e-09f, 3.57952343e-09f, 4.84396276e-09f, 6.52448685e-09f, 8.74769197e-09f, 1.16754399e-08f, 1.55137320e-08f, 2.05235608e-08f, 2.70341184e-08f, 3.54587968e-08f, 4.63144836e-08f, 6.02447248e-08f, 7.80474059e-08f, 1.00707687e-07f, 1.29437018e-07f, 1.65719157e-07f, 2.11364220e-07f, 2.68571894e-07f, 3.40005066e-07f, 4.28875221e-07f, 5.39041105e-07f, 6.75122241e-07f, 8.42629031e-07f, 1.04811127e-06f, 1.29932703e-06f, 1.60543396e-06f, 1.97720518e-06f, 2.42727196e-06f, 2.97039558e-06f, 3.62377065e-06f, 4.40736236e-06f, 5.34428013e-06f, 6.46118994e-06f, 7.78876789e-06f, 9.36219733e-06f, 1.12217116e-05f, 1.34131848e-05f, 1.59887725e-05f, 1.90076038e-05f, 2.25365270e-05f, 2.66509096e-05f, 3.14354940e-05f, 3.69853096e-05f, 4.34066412e-05f, 5.08180543e-05f, 5.93514765e-05f, 6.91533342e-05f, 8.03857429e-05f, 9.32277499e-05f, 1.07876627e-04f, 1.24549208e-04f, 1.43483273e-04f, 1.64938971e-04f, 1.89200275e-04f, 2.16576471e-04f, 2.47403671e-04f, 2.82046341e-04f, 3.20898851e-04f, 3.64387021e-04f, 4.12969671e-04f, 4.67140163e-04f, 5.27427922e-04f, 5.94399942e-04f, 6.68662248e-04f, 7.50861330e-04f, 8.41685517e-04f, 9.41866302e-04f, 1.05217960e-03f, 1.17344692e-03f, 1.30653650e-03f, 1.45236427e-03f, 1.61189482e-03f, 1.78614219e-03f, 1.97617055e-03f, 2.18309485e-03f, 2.40808123e-03f, 2.65234740e-03f, 2.91716284e-03f, 3.20384886e-03f, 3.51377855e-03f, 3.84837661e-03f, 4.20911898e-03f, 4.59753235e-03f, 5.01519359e-03f, 5.46372894e-03f, 5.94481312e-03f, 6.46016832e-03f, 7.01156301e-03f, 7.60081065e-03f, 8.22976829e-03f, 8.90033499e-03f, 9.61445021e-03f, 1.03740920e-02f, 1.11812753e-02f, 1.20380497e-02f, 1.29464978e-02f, 1.39087327e-02f, 1.49268962e-02f, 1.60031562e-02f, 1.71397050e-02f, 1.83387564e-02f, 1.96025436e-02f, 2.09333170e-02f, 2.23333419e-02f, 2.38048956e-02f, 2.53502659e-02f, 2.69717481e-02f, 2.86716433e-02f, 3.04522558e-02f, 3.23158911e-02f, 3.42648538e-02f, 3.63014456e-02f, 3.84279634e-02f, 4.06466974e-02f, 4.29599296e-02f, 4.53699317e-02f, 4.78789641e-02f, 5.04892744e-02f, 5.32030959e-02f, 5.60226468e-02f, 5.89501290e-02f, 6.19877276e-02f, 6.51376099e-02f, 6.84019251e-02f, 7.17828036e-02f, 7.52823576e-02f, 7.89026802e-02f, 8.26458461e-02f, 8.65139116e-02f, 9.05089155e-02f, 9.46328794e-02f, 9.88878087e-02f, 1.03275694e-01f, 1.07798510e-01f, 1.12458223e-01f, 1.17256783e-01f, 1.22196135e-01f, 1.27278214e-01f, 1.32504950e-01f, 1.37878272e-01f, 1.43400107e-01f, 1.49072382e-01f, 1.54897032e-01f, 1.60875997e-01f, 1.67011231e-01f, 1.73304700e-01f, 1.79758387e-01f, 1.86374297e-01f, 1.93154462e-01f, 2.00100939e-01f, 2.07215821e-01f, 2.14501238e-01f, 2.21959362e-01f, 2.29592410e-01f, 2.37402653e-01f, 2.45392415e-01f, 2.53564085e-01f, 2.61920117e-01f, 2.70463037e-01f, 2.79195450e-01f, 2.88120044e-01f, 2.97239599e-01f, 3.06556989e-01f, 3.16075193e-01f, 3.25797297e-01f, 3.35726506e-01f, 3.45866147e-01f, 3.56219679e-01f, 3.66790698e-01f, 3.77582948e-01f, 3.88600328e-01f, 3.99846898e-01f, 4.11326892e-01f, 4.23044723e-01f, 4.35004995e-01f, 4.47212512e-01f, 4.59672288e-01f, 4.72389556e-01f, 4.85369781e-01f, 4.98618671e-01f, 5.12142186e-01f, 5.25946554e-01f, 5.40038281e-01f, 5.54424165e-01f, 5.69111309e-01f, 5.84107138e-01f, 5.99419409e-01f, 6.15056232e-01f, 6.31026081e-01f, 6.47337815e-01f, 6.64000696e-01f, 6.81024405e-01f, 6.98419060e-01f, 7.16195243e-01f, 7.34364016e-01f, 7.52936944e-01f, 7.71926120e-01f, 7.91344191e-01f, 8.11204381e-01f, 8.31520518e-01f, 8.52307069e-01f, 8.73579162e-01f, 8.95352625e-01f, 9.17644013e-01f, 9.40470650e-01f, 9.63850664e-01f, 9.87803022e-01f, 1.01234758e+00f, 1.03750512e+00f, 1.06329740e+00f, 1.08974721e+00f, 1.11687839e+00f, 1.14471595e+00f, 1.17328606e+00f, 1.20261614e+00f, 1.23273496e+00f, 1.26367264e+00f, 1.29546076e+00f, 1.32813247e+00f, 1.36172249e+00f, 1.39626730e+00f, 1.43180514e+00f, 1.46837616e+00f, 1.50602252e+00f, 1.54478848e+00f, 1.58472055e+00f, 1.62586760e+00f, 1.66828098e+00f, 1.71201469e+00f, 1.75712551e+00f, 1.80367319e+00f, 1.85172058e+00f, 1.90133388e+00f, 1.95258276e+00f, 2.00554062e+00f, 2.06028484e+00f, 2.11689693e+00f, 2.17546288e+00f, 2.23607339e+00f, 2.29882418e+00f, 2.36381627e+00f, 2.43115639e+00f, 2.50095725e+00f, 2.57333803e+00f, 2.64842468e+00f, 2.72635049e+00f, 2.80725648e+00f, 2.89129193e+00f, 2.97861498e+00f, 3.06939317e+00f, 3.16380413e+00f, 3.26203621e+00f, 3.36428929e+00f, 3.47077553e+00f, 3.58172026e+00f, 3.69736291e+00f, 3.81795798e+00f, 3.94377618e+00f, 4.07510558e+00f, 4.21225285e+00f, 4.35554468e+00f, 4.50532923e+00f, 4.66197775e+00f, 4.82588634e+00f, 4.99747780e+00f, 5.17720373e+00f, 5.36554672e+00f, 5.56302277e+00f, 5.77018396e+00f, 5.98762126e+00f, 6.21596768e+00f, 6.45590164e+00f, 6.70815069e+00f, 6.97349551e+00f, 7.25277437e+00f, 7.54688785e+00f, 7.85680417e+00f, 8.18356491e+00f, 8.52829128e+00f, 8.89219104e+00f, 9.27656603e+00f, 9.68282047e+00f, 1.01124700e+01f, 1.05671518e+01f, 1.10486353e+01f, 1.15588347e+01f, 1.20998217e+01f, 1.26738407e+01f, 1.32833247e+01f, 1.39309131e+01f, 1.46194716e+01f, 1.53521138e+01f, 1.61322255e+01f, 1.69634913e+01f, 1.78499242e+01f, 1.87958987e+01f, 1.98061868e+01f, 2.08859991e+01f, 2.20410294e+01f, 2.32775056e+01f, 2.46022448e+01f, 2.60227166e+01f, 2.75471124e+01f, 2.91844234e+01f, 3.09445281e+01f, 3.28382897e+01f, 3.48776660e+01f, 3.70758319e+01f, 3.94473180e+01f, 4.20081658e+01f, 4.47761023e+01f, 4.77707378e+01f, 5.10137879e+01f, 5.45293247e+01f, 5.83440613e+01f, 6.24876734e+01f, 6.69931639e+01f, 7.18972765e+01f, 7.72409663e+01f, 8.30699343e+01f, 8.94352364e+01f, 9.63939781e+01f, 1.04010108e+02f, 1.12355322e+02f, 1.21510104e+02f, 1.31564914e+02f, 1.42621552e+02f, 1.54794728e+02f, 1.68213867e+02f, 1.83025185e+02f, 1.99394097e+02f, 2.17507985e+02f, 2.37579409e+02f, 2.59849828e+02f, 2.84593917e+02f, 3.12124587e+02f, 3.42798827e+02f, 3.77024517e+02f, 4.15268384e+02f, 4.58065302e+02f, 5.06029199e+02f, 5.59865843e+02f, 6.20387872e+02f, 6.88532497e+02f, 7.65382367e+02f, 8.52190227e+02f, 9.50408087e+02f, 1.06172182e+03f, 1.18809220e+03f, 1.33180384e+03f, 1.49552334e+03f, 1.68236894e+03f, 1.89599367e+03f, 2.14068513e+03f, 2.42148533e+03f, 2.74433485e+03f, 3.11624675e+03f, 3.54551666e+03f, 4.04197722e+03f, 4.61730674e+03f, 5.28540457e+03f, 6.06284853e+03f, 6.96945350e+03f, 8.02895513e+03f, 9.26984864e+03f, 1.07264200e+04f, 1.24400169e+04f, 1.44606187e+04f, 1.68487805e+04f, 1.96780458e+04f, 2.30379493e+04f, 2.70377620e+04f, 3.18111749e+04f, 3.75221715e+04f, 4.43724093e+04f, 5.26105241e+04f, 6.25438881e+04f, 7.45535092e+04f, 8.91129656e+04f, 1.06812532e+05f, 1.28390012e+05f, 1.54770253e+05f, 1.87115940e+05f, 2.26893075e+05f, 2.75955654e+05f, 3.36655497e+05f, 4.11985149e+05f, 5.05764405e+05f, 6.22884544e+05f, 7.69629183e+05f, 9.54097173e+05f, 1.18676186e+06f, 1.48121324e+06f, 1.85514609e+06f, 2.33168052e+06f, 2.94113264e+06f, 3.72339780e+06f, 4.73116974e+06f, 6.03430539e+06f, 7.72576515e+06f, 9.92972861e+06f, 1.28127257e+07f, 1.65989637e+07f, 2.15915179e+07f, 2.82017465e+07f, 3.69902945e+07f, 4.87244884e+07f, 6.44590226e+07f, 8.56498776e+07f, 1.14315868e+08f, 1.53268759e+08f, 2.06442545e+08f, 2.79366798e+08f, 3.79850300e+08f, 5.18973079e+08f, 7.12532948e+08f, 9.83165083e+08f, 1.36346329e+09f, 1.90059962e+09f, 2.66319659e+09f, 3.75160395e+09f, 5.31334782e+09f, 7.56648043e+09f, 1.08350637e+10f, 1.56033907e+10f, 2.25993074e+10f, 3.29229832e+10f, 4.82470799e+10f, 7.11297379e+10f, 1.05506900e+11f, 1.57471442e+11f, 2.36513804e+11f, 3.57509889e+11f, 5.43926613e+11f, 8.33024431e+11f, 1.28435637e+12f, 1.99374510e+12f, 3.11642465e+12f, 4.90561997e+12f, 7.77731247e+12f, 1.24197380e+13f, 1.99798484e+13f, 3.23831600e+13f, 5.28864904e+13f, 8.70403770e+13f, 1.44377694e+14f, 2.41399528e+14f, 4.06896744e+14f, 6.91510621e+14f, 1.18504970e+15f, 2.04811559e+15f, 3.57034809e+15f, 6.27861398e+15f, 1.11397125e+16f, 1.99435267e+16f, 3.60337498e+16f, 6.57141972e+16f, 1.20980371e+17f, 2.24875057e+17f, 4.22089025e+17f, 8.00147402e+17f, 1.53216987e+18f, 2.96403754e+18f, 5.79389087e+18f, 1.14455803e+19f, 2.28537992e+19f, }, + }; + m_weights = { + { 1.79979618e-21f, 1.07218106e-07f, 7.05786060e-03f, 2.72310168e-01f, 1.18863515e+00f, 8.77655464e+00f, 5.33879432e+02f, 5.98892409e+06f, 9.60751551e+16f, }, + { 7.59287827e-13f, 1.18886775e-04f, 7.27332179e-02f, 6.09156795e-01f, 2.71431234e+00f, 4.68800805e+01f, 2.06437304e+04f, 4.85431236e+10f, }, + { 1.30963564e-16f, 6.14135316e-10f, 5.67743391e-06f, 1.21108690e-03f, 2.67259824e-02f, 1.54234107e-01f, 4.23412860e-01f, 8.47913037e-01f, 1.73632925e+00f, 4.63203354e+00f, 1.88206826e+01f, 1.40643917e+02f, 2.73736946e+03f, 2.55633252e+05f, 3.18438602e+08f, 2.86363931e+13f, }, + { 6.93769555e-19f, 1.31670336e-14f, 2.68107110e-11f, 9.60294960e-09f, 8.89417585e-07f, 2.87650015e-05f, 4.10649371e-04f, 3.10797444e-03f, 1.43958814e-02f, 4.56980985e-02f, 1.08787148e-01f, 2.08910486e-01f, 3.43887471e-01f, 5.11338439e-01f, 7.19769211e-01f, 1.00073403e+00f, 1.42660267e+00f, 2.14966467e+00f, 3.50341221e+00f, 6.28632057e+00f, 1.26369961e+01f, 2.90949180e+01f, 7.91163114e+01f, 2.65103292e+02f, 1.15872311e+03f, 7.11886439e+03f, 6.77324248e+04f, 1.13081650e+06f, 3.88995005e+07f, 3.38857764e+09f, 9.74063570e+11f, 1.29789430e+15f, 1.24001927e+19f, }, + { 3.88541434e-20f, 1.03646493e-17f, 1.41388360e-15f, 1.06725054e-13f, 4.77908002e-12f, 1.34999345e-10f, 2.53970414e-09f, 3.33804787e-08f, 3.19755978e-07f, 2.31724882e-06f, 1.31302324e-05f, 5.98917639e-05f, 2.25650360e-04f, 7.18397083e-04f, 1.97196929e-03f, 4.75106406e-03f, 1.02072514e-02f, 1.98317011e-02f, 3.52844239e-02f, 5.81350403e-02f, 8.95955146e-02f, 1.30335749e-01f, 1.80445384e-01f, 2.39557131e-01f, 3.07102681e-01f, 3.82648608e-01f, 4.66260909e-01f, 5.58867257e-01f, 6.62616429e-01f, 7.81267733e-01f, 9.20677638e-01f, 1.08949034e+00f, 1.30019425e+00f, 1.57079633e+00f, 1.92752387e+00f, 2.40924883e+00f, 3.07485695e+00f, 4.01578082e+00f, 5.37784753e+00f, 7.40045071e+00f, 1.04890228e+01f, 1.53538346e+01f, 2.32861156e+01f, 3.67307348e+01f, 6.05296516e+01f, 1.04761593e+02f, 1.91598840e+02f, 3.72918009e+02f, 7.78738763e+02f, 1.76101294e+03f, 4.35837629e+03f, 1.19484066e+04f, 3.67841605e+04f, 1.29157756e+05f, 5.26424122e+05f, 2.54082527e+06f, 1.48545930e+07f, 1.07925566e+08f, 1.00317513e+09f, 1.23283860e+10f, 2.07922173e+11f, 5.01997049e+12f, 1.82006578e+14f, 1.04617001e+16f, 1.01373023e+18f, 1.77530238e+20f, }, + { 8.56958007e-21f, 1.68000718e-19f, 2.74008750e-18f, 3.75978801e-17f, 4.38589881e-16f, 4.39263787e-15f, 3.81223973e-14f, 2.89198757e-13f, 1.93338859e-12f, 1.14783389e-11f, 6.09544349e-11f, 2.91499607e-10f, 1.26339559e-09f, 4.99234840e-09f, 1.80872790e-08f, 6.03998541e-08f, 1.86829770e-07f, 5.37807971e-07f, 1.44704121e-06f, 3.65421571e-06f, 8.69454276e-06f, 1.95621880e-05f, 4.17628758e-05f, 8.48713297e-05f, 1.64680159e-04f, 3.05960283e-04f, 5.45748909e-04f, 9.36950301e-04f, 1.55189915e-03f, 2.48542560e-03f, 3.85690505e-03f, 5.81079770e-03f, 8.51529070e-03f, 1.21588421e-02f, 1.69446644e-02f, 2.30834400e-02f, 3.07847946e-02f, 4.02482241e-02f, 5.16542634e-02f, 6.51566792e-02f, 8.08763802e-02f, 9.88975757e-02f, 1.19266512e-01f, 1.41992893e-01f, 1.67053901e-01f, 1.94400532e-01f, 2.23965873e-01f, 2.55674859e-01f, 2.89455038e-01f, 3.25247905e-01f, 3.63020457e-01f, 4.02776696e-01f, 4.44568958e-01f, 4.88509042e-01f, 5.34779290e-01f, 5.83643845e-01f, 6.35460497e-01f, 6.90693630e-01f, 7.49928915e-01f, 8.13890578e-01f, 8.83462209e-01f, 9.59712352e-01f, 1.04392634e+00f, 1.13764623e+00f, 1.24272128e+00f, 1.36137177e+00f, 1.49627028e+00f, 1.65064527e+00f, 1.82841374e+00f, 2.03435175e+00f, 2.27431458e+00f, 2.55552245e+00f, 2.88693336e+00f, 3.27973254e+00f, 3.74797919e+00f, 4.30946679e+00f, 4.98687594e+00f, 5.80933099e+00f, 6.81451887e+00f, 8.05159726e+00f, 9.58522167e+00f, 1.15011733e+01f, 1.39143002e+01f, 1.69798351e+01f, 2.09096993e+01f, 2.59962450e+01f, 3.26472377e+01f, 4.14380231e+01f, 5.31903193e+01f, 6.90928164e+01f, 9.08883744e+01f, 1.21168895e+02f, 1.63847041e+02f, 2.24923217e+02f, 3.13754154e+02f, 4.45189215e+02f, 6.43236850e+02f, 9.47484116e+02f, 1.42457583e+03f, 2.18920236e+03f, 3.44338342e+03f, 5.55184130e+03f, 9.19045432e+03f, 1.56468513e+04f, 2.74471462e+04f, 4.97037777e+04f, 9.31107740e+04f, 1.80835335e+05f, 3.64968793e+05f, 7.67360053e+05f, 1.68525439e+06f, 3.87686515e+06f, 9.37022570e+06f, 2.38705733e+07f, 6.43128750e+07f, 1.83920179e+08f, 5.60444636e+08f, 1.82722217e+09f, 6.40182180e+09f, 2.42153053e+10f, 9.93804949e+10f, 4.44863150e+11f, 2.18425069e+12f, 1.18337660e+13f, 7.11948688e+13f, 4.78870731e+14f, 3.62710215e+15f, 3.11747341e+16f, 3.06542975e+17f, 3.47854955e+18f, 4.59768243e+19f, 7.14806140e+20f, }, + { 3.95175890e-21f, 1.83575349e-20f, 8.12661397e-20f, 3.43336935e-19f, 1.38634563e-18f, 5.35757029e-18f, 1.98424944e-17f, 7.05221126e-17f, 2.40827550e-16f, 7.91175869e-16f, 2.50347754e-15f, 7.63871031e-15f, 2.25003103e-14f, 6.40502166e-14f, 1.76389749e-13f, 4.70424252e-13f, 1.21618334e-12f, 3.05082685e-12f, 7.43273471e-12f, 1.76028616e-11f, 4.05602375e-11f, 9.10055013e-11f, 1.98994391e-10f, 4.24390078e-10f, 8.83436580e-10f, 1.79636925e-09f, 3.57059250e-09f, 6.94247187e-09f, 1.32133371e-08f, 2.46332536e-08f, 4.50110843e-08f, 8.06630537e-08f, 1.41856144e-07f, 2.44958654e-07f, 4.15579069e-07f, 6.93056106e-07f, 1.13675616e-06f, 1.83473665e-06f, 2.91544023e-06f, 4.56318858e-06f, 7.03833675e-06f, 1.07030190e-05f, 1.60534529e-05f, 2.37597559e-05f, 3.47141604e-05f, 5.00883685e-05f, 7.14005734e-05f, 1.00592372e-04f, 1.40115414e-04f, 1.93027181e-04f, 2.63094779e-04f, 3.54905080e-04f, 4.73978972e-04f, 6.26886955e-04f, 8.21362793e-04f, 1.06641153e-03f, 1.37240787e-03f, 1.75118071e-03f, 2.21607971e-03f, 2.78201983e-03f, 3.46550010e-03f, 4.28459361e-03f, 5.25890609e-03f, 6.40950150e-03f, 7.75879384e-03f, 9.33040551e-03f, 1.11489935e-02f, 1.32400455e-02f, 1.56296499e-02f, 1.83442433e-02f, 2.14103400e-02f, 2.48542509e-02f, 2.87017958e-02f, 3.29780164e-02f, 3.77068968e-02f, 4.29110964e-02f, 4.86117029e-02f, 5.48280093e-02f, 6.15773214e-02f, 6.88747982e-02f, 7.67333308e-02f, 8.51634602e-02f, 9.41733378e-02f, 1.03768728e-01f, 1.13953051e-01f, 1.24727473e-01f, 1.36091031e-01f, 1.48040798e-01f, 1.60572082e-01f, 1.73678660e-01f, 1.87353038e-01f, 2.01586736e-01f, 2.16370598e-01f, 2.31695113e-01f, 2.47550758e-01f, 2.63928342e-01f, 2.80819365e-01f, 2.98216379e-01f, 3.16113348e-01f, 3.34506011e-01f, 3.53392244e-01f, 3.72772414e-01f, 3.92649735e-01f, 4.13030618e-01f, 4.33925021e-01f, 4.55346789e-01f, 4.77314001e-01f, 4.99849320e-01f, 5.22980337e-01f, 5.46739932e-01f, 5.71166640e-01f, 5.96305036e-01f, 6.22206131e-01f, 6.48927802e-01f, 6.76535247e-01f, 7.05101473e-01f, 7.34707835e-01f, 7.65444619e-01f, 7.97411688e-01f, 8.30719192e-01f, 8.65488366e-01f, 9.01852407e-01f, 9.39957463e-01f, 9.79963735e-01f, 1.02204672e+00f, 1.06639858e+00f, 1.11322974e+00f, 1.16277062e+00f, 1.21527359e+00f, 1.27101525e+00f, 1.33029891e+00f, 1.39345744e+00f, 1.46085648e+00f, 1.53289803e+00f, 1.61002461e+00f, 1.69272386e+00f, 1.78153384e+00f, 1.87704900e+00f, 1.97992701e+00f, 2.09089644e+00f, 2.21076567e+00f, 2.34043290e+00f, 2.48089770e+00f, 2.63327413e+00f, 2.79880590e+00f, 2.97888368e+00f, 3.17506505e+00f, 3.38909744e+00f, 3.62294469e+00f, 3.87881764e+00f, 4.15920968e+00f, 4.46693789e+00f, 4.80519096e+00f, 5.17758497e+00f, 5.58822853e+00f, 6.04179895e+00f, 6.54363157e+00f, 7.09982467e+00f, 7.71736306e+00f, 8.40426388e+00f, 9.16974906e+00f, 1.00244499e+01f, 1.09806502e+01f, 1.20525758e+01f, 1.32567410e+01f, 1.46123627e+01f, 1.61418586e+01f, 1.78714466e+01f, 1.98318690e+01f, 2.20592694e+01f, 2.45962577e+01f, 2.74932084e+01f, 3.08098460e+01f, 3.46171893e+01f, 3.89999428e+01f, 4.40594471e+01f, 4.99173320e+01f, 5.67200545e+01f, 6.46445583e+01f, 7.39053537e+01f, 8.47634121e+01f, 9.75373786e+01f, 1.12617765e+02f, 1.30484989e+02f, 1.51732386e+02f, 1.77095712e+02f, 2.07491096e+02f, 2.44064119e+02f, 2.88253545e+02f, 3.41874461e+02f, 4.07227291e+02f, 4.87241400e+02f, 5.85665251e+02f, 7.07319497e+02f, 8.58435639e+02f, 1.04711167e+03f, 1.28392853e+03f, 1.58278901e+03f, 1.96206607e+03f, 2.44618436e+03f, 3.06781187e+03f, 3.87091688e+03f, 4.91505977e+03f, 6.28145970e+03f, 8.08162997e+03f, 1.04697579e+04f, 1.36605846e+04f, 1.79554230e+04f, 2.37803156e+04f, 3.17424455e+04f, 4.27142204e+04f, 5.79596727e+04f, 7.93261335e+04f, 1.09537503e+05f, 1.52647130e+05f, 2.14743829e+05f, 3.05063335e+05f, 4.37755687e+05f, 6.34724899e+05f, 9.30240305e+05f, 1.37850753e+06f, 2.06623977e+06f, 3.13377596e+06f, 4.81098405e+06f, 7.47905793e+06f, 1.17782423e+07f, 1.87980927e+07f, 3.04180655e+07f, 4.99257437e+07f, 8.31551852e+07f, 1.40614107e+08f, 2.41519712e+08f, 4.21576502e+08f, 7.48209440e+08f, 1.35089892e+09f, 2.48263348e+09f, 4.64662007e+09f, 8.86235204e+09f, 1.72348930e+10f, 3.41967381e+10f, 6.92714904e+10f, 1.43352142e+11f, 3.03269524e+11f, 6.56345865e+11f, 1.45422052e+12f, 3.30099910e+12f, 7.68267630e+12f, 1.83474885e+13f, 4.49980389e+13f, 1.13430702e+14f, 2.94148450e+14f, 7.85402504e+14f, 2.16127995e+15f, 6.13534293e+15f, 1.79847736e+16f, 5.44944507e+16f, 1.70858922e+17f, 5.54922744e+17f, 1.86905990e+18f, 6.53599225e+18f, 2.37582887e+19f, 8.98810682e+19f, 3.54341330e+20f, }, + { 2.67108015e-21f, 5.82833463e-21f, 1.25616316e-20f, 2.67469785e-20f, 5.62745845e-20f, 1.17014394e-19f, 2.40511019e-19f, 4.88739481e-19f, 9.82072303e-19f, 1.95168062e-18f, 3.83661097e-18f, 7.46163208e-18f, 1.43594942e-17f, 2.73485792e-17f, 5.15573612e-17f, 9.62223075e-17f, 1.77810682e-16f, 3.25389618e-16f, 5.89765054e-16f, 1.05888451e-15f, 1.88354538e-15f, 3.31989417e-15f, 5.79902273e-15f, 1.00398818e-14f, 1.72308010e-14f, 2.93186753e-14f, 4.94655967e-14f, 8.27635884e-14f, 1.37343706e-13f, 2.26082511e-13f, 3.69205736e-13f, 5.98228147e-13f, 9.61866975e-13f, 1.53484658e-12f, 2.43090464e-12f, 3.82185577e-12f, 5.96531965e-12f, 9.24474797e-12f, 1.42267754e-11f, 2.17427910e-11f, 3.30041201e-11f, 4.97635091e-11f, 7.45399354e-11f, 1.10929412e-10f, 1.64031748e-10f, 2.41032586e-10f, 3.51991946e-10f, 5.10905560e-10f, 7.37124150e-10f, 1.05723929e-09f, 1.50757352e-09f, 2.13744796e-09f, 3.01344401e-09f, 4.22492806e-09f, 5.89117093e-09f, 8.17046854e-09f, 1.12717587e-08f, 1.54693324e-08f, 2.11213594e-08f, 2.86930859e-08f, 3.87857241e-08f, 5.21722335e-08f, 6.98414017e-08f, 9.30518593e-08f, 1.23397923e-07f, 1.62889442e-07f, 2.14048123e-07f, 2.80023159e-07f, 3.64729321e-07f, 4.73011070e-07f, 6.10836627e-07f, 7.85526363e-07f, 1.00602028e-06f, 1.28318979e-06f, 1.63019938e-06f, 2.06292424e-06f, 2.60043021e-06f, 3.26552286e-06f, 4.08537275e-06f, 5.09222413e-06f, 6.32419483e-06f, 7.82617466e-06f, 9.65083023e-06f, 1.18597236e-05f, 1.45245521e-05f, 1.77285168e-05f, 2.15678251e-05f, 2.61533347e-05f, 3.16123436e-05f, 3.80905295e-05f, 4.57540432e-05f, 5.47917575e-05f, 6.54176707e-05f, 7.78734661e-05f, 9.24312223e-05f, 1.09396271e-04f, 1.29110197e-04f, 1.51953965e-04f, 1.78351176e-04f, 2.08771424e-04f, 2.43733750e-04f, 2.83810168e-04f, 3.29629253e-04f, 3.81879756e-04f, 4.41314233e-04f, 5.08752659e-04f, 5.85085996e-04f, 6.71279692e-04f, 7.68377076e-04f, 8.77502620e-04f, 9.99865030e-04f, 1.13676015e-03f, 1.28957360e-03f, 1.45978322e-03f, 1.64896113e-03f, 1.85877551e-03f, 2.09099200e-03f, 2.34747474e-03f, 2.63018699e-03f, 2.94119122e-03f, 3.28264890e-03f, 3.65681963e-03f, 4.06605991e-03f, 4.51282135e-03f, 4.99964828e-03f, 5.52917497e-03f, 6.10412222e-03f, 6.72729343e-03f, 7.40157020e-03f, 8.12990738e-03f, 8.91532760e-03f, 9.76091537e-03f, 1.06698107e-02f, 1.16452023e-02f, 1.26903202e-02f, 1.38084285e-02f, 1.50028172e-02f, 1.62767940e-02f, 1.76336759e-02f, 1.90767806e-02f, 2.06094173e-02f, 2.22348784e-02f, 2.39564300e-02f, 2.57773028e-02f, 2.77006834e-02f, 2.97297055e-02f, 3.18674406e-02f, 3.41168899e-02f, 3.64809756e-02f, 3.89625331e-02f, 4.15643030e-02f, 4.42889240e-02f, 4.71389254e-02f, 5.01167213e-02f, 5.32246039e-02f, 5.64647382e-02f, 5.98391571e-02f, 6.33497571e-02f, 6.69982939e-02f, 7.07863800e-02f, 7.47154815e-02f, 7.87869165e-02f, 8.30018539e-02f, 8.73613125e-02f, 9.18661613e-02f, 9.65171203e-02f, 1.01314762e-01f, 1.06259513e-01f, 1.11351656e-01f, 1.16591337e-01f, 1.21978563e-01f, 1.27513213e-01f, 1.33195039e-01f, 1.39023671e-01f, 1.44998628e-01f, 1.51119321e-01f, 1.57385061e-01f, 1.63795066e-01f, 1.70348473e-01f, 1.77044340e-01f, 1.83881662e-01f, 1.90859375e-01f, 1.97976367e-01f, 2.05231492e-01f, 2.12623572e-01f, 2.20151415e-01f, 2.27813822e-01f, 2.35609599e-01f, 2.43537565e-01f, 2.51596569e-01f, 2.59785494e-01f, 2.68103274e-01f, 2.76548903e-01f, 2.85121445e-01f, 2.93820047e-01f, 3.02643950e-01f, 3.11592502e-01f, 3.20665165e-01f, 3.29861530e-01f, 3.39181328e-01f, 3.48624439e-01f, 3.58190905e-01f, 3.67880941e-01f, 3.77694943e-01f, 3.87633504e-01f, 3.97697421e-01f, 4.07887708e-01f, 4.18205605e-01f, 4.28652591e-01f, 4.39230391e-01f, 4.49940993e-01f, 4.60786652e-01f, 4.71769905e-01f, 4.82893580e-01f, 4.94160809e-01f, 5.05575036e-01f, 5.17140031e-01f, 5.28859900e-01f, 5.40739096e-01f, 5.52782432e-01f, 5.64995090e-01f, 5.77382639e-01f, 5.89951040e-01f, 6.02706666e-01f, 6.15656310e-01f, 6.28807202e-01f, 6.42167019e-01f, 6.55743908e-01f, 6.69546490e-01f, 6.83583887e-01f, 6.97865729e-01f, 7.12402181e-01f, 7.27203953e-01f, 7.42282322e-01f, 7.57649155e-01f, 7.73316926e-01f, 7.89298740e-01f, 8.05608358e-01f, 8.22260217e-01f, 8.39269463e-01f, 8.56651970e-01f, 8.74424378e-01f, 8.92604116e-01f, 9.11209442e-01f, 9.30259469e-01f, 9.49774208e-01f, 9.69774604e-01f, 9.90282579e-01f, 1.01132107e+00f, 1.03291408e+00f, 1.05508673e+00f, 1.07786529e+00f, 1.10127728e+00f, 1.12535146e+00f, 1.15011796e+00f, 1.17560829e+00f, 1.20185546e+00f, 1.22889400e+00f, 1.25676010e+00f, 1.28549162e+00f, 1.31512826e+00f, 1.34571158e+00f, 1.37728514e+00f, 1.40989460e+00f, 1.44358784e+00f, 1.47841507e+00f, 1.51442894e+00f, 1.55168471e+00f, 1.59024039e+00f, 1.63015687e+00f, 1.67149810e+00f, 1.71433126e+00f, 1.75872698e+00f, 1.80475947e+00f, 1.85250679e+00f, 1.90205105e+00f, 1.95347869e+00f, 2.00688065e+00f, 2.06235275e+00f, 2.11999592e+00f, 2.17991652e+00f, 2.24222670e+00f, 2.30704472e+00f, 2.37449538e+00f, 2.44471039e+00f, 2.51782884e+00f, 2.59399766e+00f, 2.67337209e+00f, 2.75611628e+00f, 2.84240383e+00f, 2.93241843e+00f, 3.02635449e+00f, 3.12441791e+00f, 3.22682682e+00f, 3.33381238e+00f, 3.44561973e+00f, 3.56250887e+00f, 3.68475574e+00f, 3.81265333e+00f, 3.94651282e+00f, 4.08666490e+00f, 4.23346116e+00f, 4.38727553e+00f, 4.54850596e+00f, 4.71757611e+00f, 4.89493722e+00f, 5.08107015e+00f, 5.27648761e+00f, 5.48173646e+00f, 5.69740032e+00f, 5.92410235e+00f, 6.16250823e+00f, 6.41332946e+00f, 6.67732689e+00f, 6.95531455e+00f, 7.24816384e+00f, 7.55680807e+00f, 7.88224735e+00f, 8.22555401e+00f, 8.58787841e+00f, 8.97045530e+00f, 9.37461076e+00f, 9.80176975e+00f, 1.02534643e+01f, 1.07313428e+01f, 1.12371793e+01f, 1.17728848e+01f, 1.23405187e+01f, 1.29423019e+01f, 1.35806306e+01f, 1.42580922e+01f, 1.49774818e+01f, 1.57418213e+01f, 1.65543795e+01f, 1.74186947e+01f, 1.83385994e+01f, 1.93182476e+01f, 2.03621450e+01f, 2.14751816e+01f, 2.26626686e+01f, 2.39303784e+01f, 2.52845893e+01f, 2.67321348e+01f, 2.82804577e+01f, 2.99376708e+01f, 3.17126238e+01f, 3.36149769e+01f, 3.56552840e+01f, 3.78450835e+01f, 4.01970005e+01f, 4.27248599e+01f, 4.54438126e+01f, 4.83704762e+01f, 5.15230921e+01f, 5.49217006e+01f, 5.85883374e+01f, 6.25472527e+01f, 6.68251567e+01f, 7.14514957e+01f, 7.64587609e+01f, 8.18828353e+01f, 8.77633847e+01f, 9.41442967e+01f, 1.01074176e+02f, 1.08606902e+02f, 1.16802259e+02f, 1.25726650e+02f, 1.35453899e+02f, 1.46066166e+02f, 1.57654979e+02f, 1.70322410e+02f, 1.84182406e+02f, 1.99362306e+02f, 2.16004568e+02f, 2.34268740e+02f, 2.54333703e+02f, 2.76400239e+02f, 3.00693971e+02f, 3.27468728e+02f, 3.57010397e+02f, 3.89641362e+02f, 4.25725590e+02f, 4.65674502e+02f, 5.09953726e+02f, 5.59090900e+02f, 6.13684688e+02f, 6.74415211e+02f, 7.42056139e+02f, 8.17488717e+02f, 9.01718069e+02f, 9.95892168e+02f, 1.10132394e+03f, 1.21951707e+03f, 1.35219615e+03f, 1.50134197e+03f, 1.66923291e+03f, 1.85849349e+03f, 2.07215152e+03f, 2.31370536e+03f, 2.58720328e+03f, 2.89733724e+03f, 3.24955383e+03f, 3.65018587e+03f, 4.10660860e+03f, 4.62742547e+03f, 5.22268956e+03f, 5.90416786e+03f, 6.68565726e+03f, 7.58336313e+03f, 8.61635357e+03f, 9.80710572e+03f, 1.11821637e+04f, 1.27729327e+04f, 1.46166396e+04f, 1.67574960e+04f, 1.92481112e+04f, 2.21512104e+04f, 2.55417295e+04f, 2.95093735e+04f, 3.41617487e+04f, 3.96282043e+04f, 4.60645561e+04f, 5.36589049e+04f, 6.26388223e+04f, 7.32802431e+04f, 8.59184957e+04f, 1.00962017e+05f, 1.18909442e+05f, 1.40370957e+05f, 1.66095034e+05f, 1.97001996e+05f, 2.34226253e+05f, 2.79169596e+05f, 3.33568603e+05f, 3.99580125e+05f, 4.79889989e+05f, 5.77851588e+05f, 6.97663062e+05f, 8.44594440e+05f, 1.02527965e+06f, 1.24809298e+06f, 1.52363581e+06f, 1.86536786e+06f, 2.29042802e+06f, 2.82070529e+06f, 3.48424008e+06f, 4.31706343e+06f, 5.36561882e+06f, 6.68996113e+06f, 8.36799594e+06f, 1.05011160e+07f, 1.32217203e+07f, 1.67032788e+07f, 2.11738506e+07f, 2.69343047e+07f, 3.43829654e+07f, 4.40490690e+07f, 5.66383460e+07f, 7.30953564e+07f, 9.46890531e+07f, 1.23130681e+08f, 1.60736861e+08f, 2.10656057e+08f, 2.77184338e+08f, 3.66207397e+08f, 4.85821891e+08f, 6.47212479e+08f, 8.65895044e+08f, 1.16348659e+09f, 1.57023596e+09f, 2.12865840e+09f, 2.89877917e+09f, 3.96573294e+09f, 5.45082863e+09f, 7.52773593e+09f, 1.04462776e+10f, 1.45675716e+10f, 2.04161928e+10f, 2.87579864e+10f, 4.07167363e+10f, 5.79499965e+10f, 8.29154750e+10f, 1.19276754e+11f, 1.72524570e+11f, 2.50933409e+11f, 3.67042596e+11f, 5.39962441e+11f, 7.98985690e+11f, 1.18927611e+12f, 1.78088199e+12f, 2.68310388e+12f, 4.06753710e+12f, 6.20525592e+12f, 9.52719664e+12f, 1.47228407e+13f, 2.29025392e+13f, 3.58662837e+13f, 5.65517100e+13f, 8.97859411e+13f, 1.43556057e+14f, 2.31171020e+14f, 3.74966777e+14f, 6.12702071e+14f, 1.00868013e+15f, 1.67323268e+15f, 2.79711270e+15f, 4.71267150e+15f, 8.00353033e+15f, 1.37027503e+16f, 2.36538022e+16f, 4.11734705e+16f, 7.22793757e+16f, 1.27982244e+17f, 2.28603237e+17f, 4.11976277e+17f, 7.49169358e+17f, 1.37488861e+18f, 2.54681529e+18f, 4.76248383e+18f, 8.99167123e+18f, 1.71428840e+19f, 3.30088717e+19f, 6.42020070e+19f, 1.26155602e+20f, 2.50480806e+20f, 5.02601059e+20f, 1.01935525e+21f, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -4.18750000f; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 7.241670621354483269e-163, 2.257639733856759198e-60, 1.153241619257215165e-22, 8.747691973876861825e-09, 1.173446923800022477e-03, 1.032756936219208144e-01, 7.719261204224504866e-01, 4.355544675823585545e+00, 1.215101039066652656e+02, 6.228845436711506169e+05, 6.278613977336989392e+15, 9.127414935180233465e+42, 6.091127771174027909e+116, }, + { 4.547459836328942014e-99, 6.678756542928857080e-37, 5.005042973041566360e-14, 1.341318484151208960e-05, 1.833875636365939263e-02, 3.257972971286326131e-01, 1.712014688483495078e+00, 1.613222549264089627e+01, 3.116246745274236447e+03, 3.751603952020919663e+09, 1.132259067258797346e+26, 6.799257464097374238e+70, }, + { 5.314690663257815465e-127, 2.579830034615362946e-77, 3.534801062399966878e-47, 6.733941646704537777e-29, 8.265803726974829043e-18, 4.424914371157762285e-11, 5.390411046738629465e-07, 1.649389713333761449e-04, 5.463728936866216652e-03, 4.787896410534771955e-02, 1.931544616590306846e-01, 5.121421856617965197e-01, 1.144715949265016019e+00, 2.648424684387670480e+00, 7.856804169938798917e+00, 3.944731803343517708e+01, 5.060291993016831194e+02, 3.181117494063683297e+04, 2.820174654949211729e+07, 1.993745099515255184e+12, 1.943469269499068563e+20, 2.858803732300638372e+33, 1.457292199029008637e+55, 8.943565831706355607e+90, 9.016198369791554655e+149, }, + { 8.165631636299519857e-144, 3.658949309353149331e-112, 1.635242513882908826e-87, 2.578381184977746454e-68, 2.305546416275824199e-53, 1.016725540031465162e-41, 1.191823622917539774e-32, 1.379018088205016509e-25, 4.375640088826073184e-20, 8.438464631330991606e-16, 1.838483310261119782e-12, 7.334264181393092650e-10, 7.804740587931068021e-08, 2.970395577741681504e-06, 5.081805431666579484e-05, 4.671401627620431498e-04, 2.652347404231090523e-03, 1.037409202661683856e-02, 3.045225582205323946e-02, 7.178280364982721201e-02, 1.434001065841990688e-01, 2.535640852949085796e-01, 4.113268917643175920e-01, 6.310260805648534613e-01, 9.404706503455087817e-01, 1.396267301972783068e+00, 2.116896928689963277e+00, 3.364289290471596568e+00, 5.770183960005836987e+00, 1.104863531218761752e+01, 2.460224479439805859e+01, 6.699316387888639988e+01, 2.375794092475844708e+02, 1.188092202760116066e+03, 9.269848635975416108e+03, 1.283900116155671304e+05, 3.723397798030112514e+06, 2.793667983952389721e+08, 7.112973790863854188e+10, 8.704037695808749572e+13, 8.001474015782459984e+17, 9.804091819390540578e+22, 3.342777673392873288e+29, 8.160092668471508447e+37, 4.798775331663586528e+48, 3.228614320248853938e+62, 1.836986041572136151e+80, 1.153145986877483804e+103, 2.160972586723647751e+132, }, + { 4.825077401709435655e-153, 3.813781211050297560e-135, 2.377824349780240844e-119, 2.065817295388293122e-105, 4.132105770181358886e-93, 2.963965169989404311e-82, 1.127296662046635391e-72, 3.210346399945695041e-64, 9.282992368222161062e-57, 3.565977853916619677e-50, 2.306962519220473637e-44, 3.098751038516535098e-39, 1.039558064722960891e-34, 1.025256027381235200e-30, 3.432612000569885403e-27, 4.429681881379089961e-24, 2.464589267395236846e-21, 6.526691446363344923e-19, 8.976892324445928684e-17, 6.926277695183452225e-15, 3.208805316815751272e-13, 9.478053068835988899e-12, 1.882052586691155400e-10, 2.632616062773909009e-09, 2.703411837703917665e-08, 2.113642195965330965e-07, 1.299327029813074013e-06, 6.461189935136030673e-06, 2.665090959570723827e-05, 9.322774986189288194e-05, 2.820463407940068813e-04, 7.508613300035051413e-04, 1.786142185986551786e-03, 3.848376610765768211e-03, 7.600810651854199771e-03, 1.390873269178271700e-02, 2.380489559528694982e-02, 3.842796337748997654e-02, 5.895012901671883992e-02, 8.651391160689367948e-02, 1.221961347398101671e-01, 1.670112314557845555e-01, 2.219593619059930701e-01, 2.881200442770917241e-01, 3.667906976948184315e-01, 4.596722879563388211e-01, 5.691113093602836208e-01, 6.984190600916228379e-01, 8.523070690462583711e-01, 1.037505121571600249e+00, 1.263672635742961915e+00, 1.544788480334120896e+00, 1.901333876886441433e+00, 2.363816272813317635e+00, 2.978614980117902904e+00, 3.817957977526709364e+00, 4.997477803461245639e+00, 6.708150685706236545e+00, 9.276566033183386532e+00, 1.328332469239125539e+01, 1.980618680552458639e+01, 3.094452809319702849e+01, 5.101378787119006225e+01, 8.943523638413590523e+01, 1.682138665185088325e+02, 3.427988270281270587e+02, 7.653823671943767281e+02, 1.895993667030670343e+03, 5.285404568827643942e+03, 1.684878049282191210e+04, 6.254388805482299369e+04, 2.759556544455721132e+05, 1.481213238071008345e+06, 9.929728611179601424e+06, 8.564987764771851841e+07, 9.831650826344826952e+08, 1.560339073978569502e+10, 3.575098885016726922e+11, 1.241973798101884982e+13, 6.915106205748805839e+14, 6.571419716645131084e+16, 1.144558033138694099e+19, 3.960915669532823553e+21, 2.984410558028297842e+24, 5.430494850258846715e+27, 2.683747612498502676e+31, 4.114885708325522701e+35, 2.276004816861421600e+40, 5.387544917595833246e+45, 6.623575732955432303e+51, 5.266881304835239338e+58, 3.473234812654772210e+66, 2.517492645985977377e+75, 2.759797646289240629e+85, 6.569603829502412077e+96, 5.116181648220647995e+109, 2.073901892339407423e+124, 7.406462446666255838e+140, }, + { 7.053618140948655098e-158, 2.343354218558056628e-148, 2.062509087689351439e-139, 5.212388628332260488e-131, 4.079380320868843387e-123, 1.061481285006738214e-115, 9.816727607793017691e-109, 3.435400719609722581e-102, 4.825198574681495574e-96, 2.874760995089533358e-90, 7.652499977338879996e-85, 9.556944498127119032e-80, 5.862241023038227937e-75, 1.843934000129616663e-70, 3.096983980846232911e-66, 2.885057452402340330e-62, 1.544904681826443837e-58, 4.917572705671511534e-55, 9.602608566391652866e-52, 1.184882375237471009e-48, 9.499223316355714793e-46, 5.078965858882528461e-43, 1.856080838373584123e-40, 4.744245560917271585e-38, 8.667497891102658240e-36, 1.155086178652063612e-33, 1.144541329818836153e-31, 8.585083084065812874e-30, 4.957702933032408922e-28, 2.239353794616277882e-26, 8.030405447708765492e-25, 2.318459271131684362e-23, 5.460287296679086677e-22, 1.062054307071706375e-20, 1.725955878033239909e-19, 2.369168446274347137e-18, 2.775176063916613602e-17, 2.800847352316621903e-16, 2.457625954357892245e-15, 1.890842052364646528e-14, 1.285791209258834942e-13, 7.786001004707878219e-13, 4.228083024410741194e-12, 2.072664297543567489e-11, 9.229295073519997559e-11, 3.754886152592311575e-10, 1.403443871774813834e-09, 4.843962757371872495e-09, 1.551373196623161433e-08, 4.631448362339623514e-08, 1.294370176865168120e-07, 3.400050664017164356e-07, 8.426290307581447654e-07, 1.977205177561996033e-06, 4.407362363338667830e-06, 9.362197325373404563e-06, 1.900760383449277992e-05, 3.698530963711860636e-05, 6.915333419235766653e-05, 1.245492076251852927e-04, 2.165764713808099093e-04, 3.643870211078977292e-04, 5.943999416122372516e-04, 9.418663022314558591e-04, 1.452364274261880083e-03, 2.183094846035196562e-03, 3.203848855069215278e-03, 4.597532353031862490e-03, 6.460168315117479792e-03, 8.900334989802041559e-03, 1.203804973137064275e-02, 1.600315622064554965e-02, 2.093331703849583304e-02, 2.697174812170771748e-02, 3.426485378063329473e-02, 4.295992956149806344e-02, 5.320309587203163231e-02, 6.513760993479510261e-02, 7.890268021756337834e-02, 9.463287940877026649e-02, 1.124582226719385153e-01, 1.325049504086213973e-01, 1.548970316076579260e-01, 1.797583869192584860e-01, 2.072158210677632145e-01, 2.374026527414815016e-01, 2.704630368855767324e-01, 3.065569893452247137e-01, 3.458661469783558388e-01, 3.886003277325320632e-01, 4.350049951304795319e-01, 4.853697810067132707e-01, 5.400382807495678589e-01, 5.994194092045578293e-01, 6.640006964388650918e-01, 7.343640159321037167e-01, 8.112043806284638130e-01, 8.953526245122194172e-01, 9.878030224123093447e-01, 1.089747207002141516e+00, 1.202616144679226559e+00, 1.328132465995424226e+00, 1.468376159872979355e+00, 1.625867601500928277e+00, 1.803673186618691186e+00, 2.005540624723209206e+00, 2.236073393446881709e+00, 2.500957254018255004e+00, 2.807256477663534857e+00, 3.163804128101147487e+00, 3.581720263742550029e+00, 4.075105576391566303e+00, 4.661977749936137761e+00, 5.365546718714963091e+00, 6.215967676434536043e+00, 7.252774367330402583e+00, 8.528291278204291331e+00, 1.011247001122720391e+01, 1.209982167952718578e+01, 1.461947158782994207e+01, 1.784992423404041042e+01, 2.204102944968352178e+01, 2.754711235628932374e+01, 3.487766600641650640e+01, 4.477610230214251576e+01, 5.834406132739843834e+01, 7.724096630394042216e+01, 1.040101075374387191e+02, 1.426215523101601730e+02, 1.993940974645466479e+02, 2.845939167898235356e+02, 4.152683836292551147e+02, 6.203878718481709769e+02, 9.504080873581791535e+02, 1.495523342124078853e+03, 2.421485328006836634e+03, 4.041977218227396500e+03, 6.969453497454785202e+03, 1.244001690461442846e+04, 2.303794930506892099e+04, 4.437240927040385250e+04, 8.911296561746717657e+04, 1.871159398849787994e+05, 4.119851492265743330e+05, 9.540971729944126398e+05, 2.331680521880789706e+06, 6.034305391011695472e+06, 1.659896369452266448e+07, 4.872448839341613053e+07, 1.532687586549090392e+08, 5.189730792935011722e+08, 1.900599621040508288e+09, 7.566480431232731818e+09, 3.292298322781643849e+10, 1.574714421665075635e+11, 8.330244306239795892e+11, 4.905619969814187571e+12, 3.238316002757222702e+13, 2.413995281454699076e+14, 2.048115587426077343e+15, 1.994352670766892066e+16, 2.248750566422739144e+17, 2.964037541992353401e+18, 4.613233119968213445e+19, 8.569680508342001161e+20, 1.921851711942844799e+22, 5.266829246099861758e+23, 1.786779952992288976e+25, 7.607919705736976491e+26, 4.125721424346450007e+28, 2.894340142292214313e+30, 2.670720269656428272e+32, 3.299248229135205151e+34, 5.560105583582310103e+36, 1.304167266599523020e+39, 4.349382146382717353e+41, 2.109720387774341509e+44, 1.524825352702403324e+47, 1.684941265105084589e+50, 2.925572737558413426e+53, 8.217834961057481281e+56, 3.852117991896536784e+60, 3.114452310394384063e+64, 4.498555465873245751e+68, 1.205113215232800796e+73, 6.230864727145221322e+77, 6.487131248948465269e+82, 1.422810109167834249e+88, 6.897656089181724717e+93, 7.779163462756485195e+99, 2.155213251859555072e+106, 1.554347160152705281e+113, 3.103875072425192272e+120, 1.832673821557018634e+128, 3.431285951865278376e+136, 2.194542081542393530e+145, }, + { 2.363803632659058081e-160, 1.926835442612677686e-155, 1.109114905180506786e-150, 4.556759282087534164e-146, 1.350172241067816232e-141, 2.914359263635229435e-137, 4.627545976953585825e-133, 5.456508344460398758e-129, 4.821828861306345485e-125, 3.221779152402086241e-121, 1.641732102111619421e-117, 6.433569189921227126e-114, 1.954582672700428961e-110, 4.639912078942456372e-107, 8.671928891742699827e-104, 1.285485264305858782e-100, 1.522161801460927566e-97, 1.449767844425295085e-94, 1.118122255504445235e-91, 7.028344777398825069e-89, 3.623454064991238081e-86, 1.541513438874996543e-83, 5.443699502170284982e-81, 1.604913673768949456e-78, 3.972206240977317536e-76, 8.297975554162539562e-74, 1.470748835855054032e-71, 2.222935801472624670e-69, 2.879160361851977720e-67, 3.210837413250902178e-65, 3.097303984958235490e-63, 2.595974479763180595e-61, 1.898656799199089593e-59, 1.216865518398435626e-57, 6.862041810601184397e-56, 3.418134121780773218e-54, 1.509758535747580387e-52, 5.934924977563731784e-51, 2.083865009061241099e-49, 6.558128104492290092e-48, 1.856133016606468181e-46, 4.739964621828176249e-45, 1.095600459825324697e-43, 2.299177139060262518e-42, 4.393663812095906869e-41, 7.667728102142858487e-40, 1.225476279042445010e-38, 1.798526997315960782e-37, 2.430201154741018716e-36, 3.030993518975438712e-35, 3.497966609954172613e-34, 3.744308272796551045e-33, 3.726132797819332658e-32, 3.455018936399215381e-31, 2.991524108706319604e-30, 2.423818520801870809e-29, 1.841452809687011486e-28, 1.314419760826235421e-27, 8.831901010260867670e-27, 5.596660060604091621e-26, 3.350745417080507841e-25, 1.898675566025820409e-24, 1.019982287418197376e-23, 5.203315082978366918e-23, 2.524668746906057148e-22, 1.166904646009344233e-21, 5.145437675264868732e-21, 2.167677145279166596e-20, 8.736996911006110678e-20, 3.373776431076593266e-19, 1.249769727462160008e-18, 4.446913832647864892e-18, 1.521741180930875343e-17, 5.014158301377399707e-17, 1.592708205361177316e-16, 4.882536933653862982e-16, 1.446109387544416586e-15, 4.142510168443201880e-15, 1.148892083132325407e-14, 3.088024760858924214e-14, 8.051699653634442236e-14, 2.038478329249539199e-13, 5.015686309363884049e-13, 1.200444984849900298e-12, 2.797125428309156462e-12, 6.350357793399881333e-12, 1.405881744263466936e-11, 3.037391821635123795e-11, 6.408863411016101449e-11, 1.321618431565916164e-10, 2.665526566207284474e-10, 5.261497418654313068e-10, 1.017123184766088896e-09, 1.926882221639203388e-09, 3.579523428497157488e-09, 6.524486847652635035e-09, 1.167543991262942921e-08, 2.052356080018121741e-08, 3.545879678923676129e-08, 6.024472481556065885e-08, 1.007076869023518125e-07, 1.657191565891799652e-07, 2.685718943404479677e-07, 4.288752213761154116e-07, 6.751222405372943925e-07, 1.048111270324302884e-06, 1.605433960692314060e-06, 2.427271958412371013e-06, 3.623770645356477660e-06, 5.344280132492750309e-06, 7.788767891027678939e-06, 1.122171160022519082e-05, 1.598877254198599908e-05, 2.253652700952153115e-05, 3.143549403208496646e-05, 4.340664122305257288e-05, 5.935147653125578529e-05, 8.038574285450253209e-05, 1.078766266062957565e-04, 1.434832731669987826e-04, 1.892002753957224677e-04, 2.474036705329449166e-04, 3.208988510028906069e-04, 4.129696713145546995e-04, 5.274279220384250390e-04, 6.686622480794640482e-04, 8.416855170641220285e-04, 1.052179598744440400e-03, 1.306536501050643762e-03, 1.611894824798787196e-03, 1.976170547826080496e-03, 2.408081229927640721e-03, 2.917162840577481875e-03, 3.513778549028205519e-03, 4.209118976964403112e-03, 5.015193592567630665e-03, 5.944813116164644191e-03, 7.011563005746090924e-03, 8.229768289624073049e-03, 9.614450207543986041e-03, 1.118127530523730813e-02, 1.294649779580742160e-02, 1.492689615029751590e-02, 1.713970500593860526e-02, 1.960254358145296755e-02, 2.233334186285684056e-02, 2.535026586984720664e-02, 2.867164333232700310e-02, 3.231589109997912964e-02, 3.630144557680610965e-02, 4.064669741956638109e-02, 4.536993166688766414e-02, 5.048927437769432941e-02, 5.602264675683979161e-02, 6.198772763597769678e-02, 6.840192506222012774e-02, 7.528235762939712171e-02, 8.264584606994605986e-02, 9.050891551257121825e-02, 9.888780870447738360e-02, 1.077985103995250356e-01, 1.172567830270636607e-01, 1.272782136821146663e-01, 1.378782724173011162e-01, 1.490723817714478840e-01, 1.608759974398061173e-01, 1.733046999768424060e-01, 1.863742974247175786e-01, 2.001009387790379976e-01, 2.145012382381487190e-01, 2.295924102330349785e-01, 2.453924153016625057e-01, 2.619201169541956490e-01, 2.791954497739298773e-01, 2.972395991130188526e-01, 3.160751928723792943e-01, 3.357265060019327741e-01, 3.562196785212496373e-01, 3.775829480426418792e-01, 3.998468979800887046e-01, 4.230447228497335035e-01, 4.472125123131631074e-01, 4.723895558858634018e-01, 4.986186705332947608e-01, 5.259465537097384485e-01, 5.544241647649479754e-01, 5.841071380560416511e-01, 6.150562315632864018e-01, 6.473378153258308278e-01, 6.810244045956889952e-01, 7.161952432654565143e-01, 7.529369438691556459e-01, 7.913441913000366617e-01, 8.315205183502086596e-01, 8.735791622734589226e-01, 9.176440128265773576e-01, 9.638506636817484398e-01, 1.012347580753402101e+00, 1.063297402882930381e+00, 1.116878392515788506e+00, 1.173286056537125469e+00, 1.232734960362603918e+00, 1.295460761779549539e+00, 1.361722494981910846e+00, 1.431805139837984876e+00, 1.506022516788234345e+00, 1.584720554029819354e+00, 1.668280980969603645e+00, 1.757125510515793421e+00, 1.851720582866847453e+00, 1.952582755329533200e+00, 2.060284836698905963e+00, 2.175462881275503983e+00, 2.298824177179966629e+00, 2.431156386859774759e+00, 2.573338025304717222e+00, 2.726350494395667363e+00, 2.891291931102408784e+00, 3.069393174263124520e+00, 3.262036211067640944e+00, 3.470775532153801919e+00, 3.697362905908153155e+00, 3.943776181224350319e+00, 4.212252847439515687e+00, 4.505329225191826639e+00, 4.825886338442190807e+00, 5.177203733275742875e+00, 5.563022772612923373e+00, 5.987621259260909859e+00, 6.455901637501497370e+00, 6.973495514195020291e+00, 7.546887847708181032e+00, 8.183564906772872855e+00, 8.892191039842283431e+00, 9.682820467523296204e+00, 1.056715177903931837e+01, 1.155883465937652851e+01, 1.267384070151528947e+01, 1.393091310389918289e+01, 1.535211379418177923e+01, 1.696349128797309510e+01, 1.879589868990482198e+01, 2.088599907466058846e+01, 2.327750557804054323e+01, 2.602271658731131093e+01, 2.918442338619305962e+01, 3.283828974258811174e+01, 3.707583192189045823e+01, 4.200816575721451990e+01, 4.777073782243997224e+01, 5.452932468101429049e+01, 6.248767344468634478e+01, 7.189727649240108469e+01, 8.306993427631743111e+01, 9.639397813652482031e+01, 1.123553215857374919e+02, 1.315649140340119335e+02, 1.547947284376312334e+02, 1.830251850988715552e+02, 2.175079854175568113e+02, 2.598498278995140400e+02, 3.121245867818556035e+02, 3.770245173783702458e+02, 4.580653020257635092e+02, 5.598658426219653689e+02, 6.885324967857802403e+02, 8.521902266884453403e+02, 1.061721815114114004e+03, 1.331803836529085656e+03, 1.682368940494210217e+03, 2.140685129891926443e+03, 2.744334847491432747e+03, 3.545516659371773357e+03, 4.617306735234797694e+03, 6.062848530677391758e+03, 8.028955134017154634e+03, 1.072641999277462936e+04, 1.446061873485939411e+04, 1.967804579389513789e+04, 2.703776201447279367e+04, 3.752217148194723312e+04, 5.261052412010591097e+04, 7.455350923854624329e+04, 1.068125318497402759e+05, 1.547702528541975911e+05, 2.268930751685412563e+05, 3.366554971645478061e+05, 5.057644049026088560e+05, 7.696291826884134742e+05, 1.186761864945790800e+06, 1.855146094294667715e+06, 2.941132644236832276e+06, 4.731169740596920355e+06, 7.725765147199987935e+06, 1.281272565991955126e+07, 2.159151785284808339e+07, 3.699029448836502904e+07, 6.445902263727884020e+07, 1.143158678867853615e+08, 2.064425450996979446e+08, 3.798502995329785506e+08, 7.125329484929003007e+08, 1.363463294023391629e+09, 2.663196590686555077e+09, 5.313347815419462975e+09, 1.083506369700027396e+10, 2.259930737910197667e+10, 4.824707991473375387e+10, 1.055069002818752104e+11, 2.365138040635727209e+11, 5.439266129959972285e+11, 1.284356371641026839e+12, 3.116424654245920797e+12, 7.777312465656280419e+12, 1.997984843259596733e+13, 5.288649037339853118e+13, 1.443776937640548342e+14, 4.068967444890414804e+14, 1.185049702391501141e+15, 3.570348091883284324e+15, 1.113971254034978026e+16, 3.603374982229766184e+16, 1.209803708182151942e+17, 4.220890251904870611e+17, 1.532169872312865862e+18, 5.793890867821715890e+18, 2.285379920879842924e+19, 9.415714369232187727e+19, 4.057471211245170887e+20, 1.831405465804324767e+21, 8.671209773404504008e+21, 4.313209261217173994e+22, 2.257498454242656934e+23, 1.245267136898199709e+24, 7.251536499435180219e+24, 4.465573963364524765e+25, 2.913233420596266283e+26, 2.017063171206072979e+27, 1.485014353353330393e+28, 1.164811091759882662e+29, 9.753661264047912784e+29, 8.737124417851167566e+30, 8.390503265508677363e+31, 8.657362701430272680e+32, 9.619472292454361392e+33, 1.153735498483960294e+35, 1.497284701983562213e+36, 2.107816695320163748e+37, 3.227106623185610745e+38, 5.387696372515021985e+39, 9.835496017627849225e+40, 1.968904749086105300e+42, 4.334704147416758275e+43, 1.052717645113369473e+45, 2.829013521120326147e+46, 8.439656297525588822e+47, 2.804279894508234869e+49, 1.041383695988523864e+51, 4.337366591019718310e+52, 2.033523569151676725e+54, 1.077238847489773081e+56, 6.472891251891105455e+57, 4.429404678715878536e+59, 3.466135480828349864e+61, 3.114928656972704276e+63, 3.228947925415990689e+65, 3.878402486902381042e+67, 5.423187597439531197e+69, 8.870779393460412583e+71, 1.705832285076755970e+74, 3.876224350373120420e+76, 1.046359534886878004e+79, 3.373858809560757544e+81, 1.306762499786044015e+84, 6.115300889685679832e+86, 3.478550048884517349e+89, 2.420073578988056289e+92, 2.072453567501123129e+95, 2.199029867204449277e+98, 2.910868575802139983e+101, 4.840699137490951163e+104, 1.018669397739170369e+108, 2.733025017438095928e+111, 9.420797277586029837e+114, 4.205525105722885986e+118, 2.451352708852151939e+122, 1.881577053794165543e+126, 1.918506219134233785e+130, 2.622069659115564900e+134, 4.848463485415763756e+138, 1.224645005481997780e+143, 4.267387286482591954e+147, 2.072505613372582377e+152, }, + { 1.323228129684237783e-161, 4.129002973520822791e-159, 1.178655462569548882e-156, 3.082189008893206231e-154, 7.393542832199414487e-152, 1.629100644355328639e-149, 3.301545529059822941e-147, 6.162031390854241227e-145, 1.060528194470986309e-142, 1.685225757497235089e-140, 2.475534097582263629e-138, 3.365764749507587192e-136, 4.240562683924022383e-134, 4.956794227885611715e-132, 5.381716367914161520e-130, 5.433507172294988849e-128, 5.107031242794315420e-126, 4.473704932098646394e-124, 3.656376947377888629e-122, 2.791170022694259001e-120, 1.992200238692415032e-118, 1.330894359393789718e-116, 8.330356767359890503e-115, 4.890256639970245146e-113, 2.695128935451165447e-111, 1.395829605415630844e-109, 6.799997527188085942e-108, 3.119037767379032293e-106, 1.348260131419216291e-104, 5.497526018943990804e-103, 2.116384670251198533e-101, 7.699148714858061209e-100, 2.649065347250598345e-98, 8.628189263549727753e-97, 2.662520943248368922e-95, 7.790698623582886341e-94, 2.163354866683077281e-92, 5.705576739797220361e-91, 1.430338193028564913e-89, 3.411040781372328747e-88, 7.744268073516449037e-87, 1.675136564303435813e-85, 3.454795810595704816e-84, 6.798573137099477363e-83, 1.277474708033782661e-81, 2.293702139426309483e-80, 3.938021700015175030e-79, 6.469593934876300124e-78, 1.017725266990912471e-76, 1.534019529793324951e-75, 2.216999886838860916e-74, 3.074100747562803362e-73, 4.092295330837549092e-72, 5.233434175636538471e-71, 6.433506079763357418e-70, 7.607042677901362161e-69, 8.656714387163425357e-68, 9.486746058685489974e-67, 1.001756724248288397e-65, 1.019853943834854330e-64, 1.001591106610665630e-63, 9.494277822444263952e-63, 8.691422918891890649e-62, 7.687977047887448276e-61, 6.574408104196605248e-60, 5.438162502918425191e-59, 4.353340831363003212e-58, 3.374338762181243411e-57, 2.533770921173042330e-56, 1.844048925248616738e-55, 1.301410812308480184e-54, 8.910466744374470063e-54, 5.921538384124132331e-53, 3.821356134297705127e-52, 2.395780657353036891e-51, 1.459882187581820236e-50, 8.650105472076777327e-50, 4.985933550797199316e-49, 2.796911903237435916e-48, 1.527570118993503332e-47, 8.126314048196993302e-47, 4.212436363948578182e-46, 2.128604050242564662e-45, 1.048938356323431072e-44, 5.042753142653687842e-44, 2.365999225494165364e-43, 1.083813462091040325e-42, 4.848963367960316169e-42, 2.119612873737657277e-41, 9.055947139022002648e-41, 3.782987192192666650e-40, 1.545649846917574765e-39, 6.178909752126026357e-39, 2.417597558625940386e-38, 9.261305999966332746e-38, 3.474712971194656115e-37, 1.277215890629181345e-36, 4.600938133935473864e-36, 1.624804314773052044e-35, 5.626808103137929972e-35, 1.911442429947086471e-34, 6.371300415498187125e-34, 2.084444531309441237e-33, 6.695356060065574234e-33, 2.112038435637792931e-32, 6.544802906551512393e-32, 1.992864937623987114e-31, 5.964358817764151755e-31, 1.754973231464949500e-30, 5.078231558861773863e-30, 1.445447866528259475e-29, 4.048099759391660786e-29, 1.115752878927994221e-28, 3.027334168442338592e-28, 8.087868498106224788e-28, 2.128106544151858936e-27, 5.516210113930227985e-27, 1.408890921124863906e-26, 3.546520734326774807e-26, 8.800636481096360494e-26, 2.153319509043984465e-25, 5.196136544731926346e-25, 1.236869058422202190e-24, 2.904891674490918873e-24, 6.732707317563258763e-24, 1.540253603361391055e-23, 3.478765727687221019e-23, 7.758450079933031976e-23, 1.708939324269830276e-22, 3.718467010568811152e-22, 7.994094376769029920e-22, 1.698336774318343123e-21, 3.566214469724002275e-21, 7.402848534866351662e-21, 1.519411719755297549e-20, 3.083993994528608740e-20, 6.191388817974459809e-20, 1.229625987010589227e-19, 2.416245949308411084e-19, 4.698551818749419706e-19, 9.042992978848520439e-19, 1.722880198390020817e-18, 3.249832858354112322e-18, 6.070120594586457562e-18, 1.122871881646098441e-17, 2.057429235664205922e-17, 3.734613207742816399e-17, 6.716694369267842075e-17, 1.197063025055043952e-16, 2.114419661115663617e-16, 3.702017138231021853e-16, 6.425665498746337860e-16, 1.105830903726985419e-15, 1.887156051660563224e-15, 3.193979018679125833e-15, 5.361881977473204459e-15, 8.929318568606692809e-15, 1.475330560958586660e-14, 2.418708636765824964e-14, 3.935078350904051302e-14, 6.354047096308654479e-14, 1.018416666466509442e-13, 1.620423782999307693e-13, 2.559817517056126166e-13, 4.015273886294212810e-13, 6.254532358261761291e-13, 9.675981021394182858e-13, 1.486832112534566186e-12, 2.269557377760486879e-12, 3.441736008766365832e-12, 5.185793859860652413e-12, 7.764217889314004663e-12, 1.155228105746548036e-11, 1.708313121464262097e-11, 2.510951856086201897e-11, 3.668776978510952341e-11, 5.329131813941740314e-11, 7.696325397299480856e-11, 1.105200723643722855e-10, 1.578221843796034825e-10, 2.241309672940976766e-10, 3.165773201144956642e-10, 4.447730510871610704e-10, 6.216041661455164049e-10, 8.642544905395987868e-10, 1.195519306516659349e-09, 1.645482121417189823e-09, 2.253643612941620883e-09, 3.071610576496751310e-09, 4.166474690460445927e-09, 5.625036504185181035e-09, 7.559059638953998396e-09, 1.011177417876491092e-08, 1.346588701906267454e-08, 1.785340092957703350e-08, 2.356759364235337519e-08, 3.097756373337616088e-08, 4.054581171302714730e-08, 5.284939280085554173e-08, 6.860525247854168448e-08, 8.870043714076795346e-08, 1.142279599340281637e-07, 1.465291959965373757e-07, 1.872437814520259903e-07, 2.383680961705324062e-07, 3.023235208219232784e-07, 3.820357732606947876e-07, 4.810267467496160044e-07, 6.035203917139166314e-07, 7.545643021775656875e-07, 9.401687861337141280e-07, 1.167465314019272078e-06, 1.444886349199346242e-06, 1.782368666762205796e-06, 2.191582359683820240e-06, 2.686187812137005286e-06, 3.282122985909738110e-06, 3.997923415034129149e-06, 4.855077333283880469e-06, 5.878418366687560187e-06, 7.096558206229387964e-06, 8.542361632206236097e-06, 1.025346618920209381e-05, 1.227284870748632855e-05, 1.464944073127878202e-05, 1.743879474552002742e-05, 2.070380288967650755e-05, 2.451546960924430874e-05, 2.895373942298085844e-05, 3.410838067694928604e-05, 4.007992581615393488e-05, 4.698066833232878622e-05, 5.493571614427227251e-05, 6.408410073746518169e-05, 7.457994093551813828e-05, 8.659365970069775654e-05, 1.003132518682442285e-04, 1.159456002136906496e-04, 1.337178367385581674e-04, 1.538787455425709779e-04, 1.767002031351005554e-04, 2.024786515302844608e-04, 2.315365989746650402e-04, 2.642241426787982083e-04, 3.009205074706080013e-04, 3.420355938637258307e-04, 3.880115286439000550e-04, 4.393242107257947798e-04, 4.964848447258090522e-04, 5.600414544382562271e-04, 6.305803681962314437e-04, 7.087276679481586600e-04, 7.951505937892094439e-04, 8.905588956558126794e-04, 9.957061239230124343e-04, 1.111390850739538593e-03, 1.238457814094548688e-03, 1.377798976832850428e-03, 1.530354493121150144e-03, 1.697113575214988470e-03, 1.879115253782404405e-03, 2.077449025503311209e-03, 2.293255382179820056e-03, 2.527726216158548279e-03, 2.782105097477072741e-03, 3.057687418798497807e-03, 3.355820404885606963e-03, 3.677902984083964409e-03, 4.025385520026097270e-03, 4.399769402530814407e-03, 4.802606497446985045e-03, 5.235498455973840111e-03, 5.700095884774212336e-03, 6.198097378977308725e-03, 6.731248420937948614e-03, 7.301340148374219834e-03, 7.910207996239952125e-03, 8.559730217397303903e-03, 9.251826287833445298e-03, 9.988455202809488913e-03, 1.077161367093554544e-02, 1.160333421372954856e-02, 1.248568317873621646e-02, 1.342075867475355427e-02, 1.441068843813546585e-02, 1.545762763950860648e-02, 1.656375664055830135e-02, 1.773127871080136402e-02, 1.896241771447260382e-02, 2.025941577780677588e-02, 2.162453094709917839e-02, 2.306003484797691421e-02, 2.456821035631025318e-02, 2.615134929114115217e-02, 2.781175013990572523e-02, 2.955171582608151263e-02, 3.137355152920124081e-02, 3.327956256694509270e-02, 3.527205234875621605e-02, 3.735332041012234938e-02, 3.952566053633324126e-02, 4.179135898416228534e-02, 4.415269280953487221e-02, 4.661192830883879903e-02, 4.917131958110712872e-02, 5.183310721786459418e-02, 5.459951712697841302e-02, 5.747275949639657337e-02, 6.045502790319455825e-02, 6.354849857288828754e-02, 6.675532979350985865e-02, 7.007766148848641979e-02, 7.351761495191403887e-02, 7.707729274938041525e-02, 8.075877878706524317e-02, 8.456413855143733669e-02, 8.849541952147546057e-02, 9.255465175496720496e-02, 9.674384865008904765e-02, 1.010650078831426502e-01, 1.055201125230189472e-01, 1.101111323226840632e-01, 1.148400251877307103e-01, 1.197087388218165293e-01, 1.247192125486176994e-01, 1.298733793097628269e-01, 1.351731678380792159e-01, 1.406205050053816316e-01, 1.462173183439629526e-01, 1.519655387409069424e-01, 1.578671033043359383e-01, 1.639239584007306411e-01, 1.701380628625154331e-01, 1.765113913651907042e-01, 1.830459379734134606e-01, 1.897437198555789051e-01, 1.966067811666385690e-01, 2.036371970991047974e-01, 2.108370781024367852e-01, 2.182085742712797843e-01, 2.257538799033364379e-01, 2.334752382279873511e-01, 2.413749463071469410e-01, 2.494553601102403241e-01, 2.577188997656175820e-01, 2.661680549911833443e-01, 2.748053907075124803e-01, 2.836335528372471376e-01, 2.926552742951268547e-01, 3.018733811735925662e-01, 3.112907991295277084e-01, 3.209105599783561596e-01, 3.307358085024083972e-01, 3.407698094811951648e-01, 3.510159549519934555e-01, 3.614777717099542274e-01, 3.721589290577866932e-01, 3.830632468159621812e-01, 3.941947036053136035e-01, 4.055574454148868711e-01, 4.171557944689308074e-01, 4.289942584079951543e-01, 4.410775398002453309e-01, 4.534105460003012245e-01, 4.659983993741692944e-01, 4.788464479101668631e-01, 4.919602762371392109e-01, 5.053457170727489659e-01, 5.190088631261786795e-01, 5.329560794812372669e-01, 5.471940164876055195e-01, 5.617296231898020413e-01, 5.765701613254061793e-01, 5.917232199261468491e-01, 6.071967305576643327e-01, 6.229989832360855492e-01, 6.391386430620321596e-01, 6.556247676153161584e-01, 6.724668251563812272e-01, 6.896747136835329047e-01, 7.072587808981804764e-01, 7.252298451337033758e-01, 7.435992173071710726e-01, 7.623787239570054101e-01, 7.815807314337971290e-01, 8.012181713158943859e-01, 8.213045671260926392e-01, 8.418540624307963733e-01, 8.628814504084197628e-01, 8.844022049795737430e-01, 9.064325135977815717e-01, 9.289893118061069464e-01, 9.520903196722039764e-01, 9.757540802219457353e-01, 1.000000000000000000e+00, 1.024848391894543008e+00, 1.050320520372784475e+00, 1.076438649284173871e+00, 1.103226092399127978e+00, 1.130707266862927052e+00, 1.158907749757141229e+00, 1.187854337974646084e+00, 1.217575111629048984e+00, 1.248099501235266386e+00, 1.279458358915164500e+00, 1.311684033900709062e+00, 1.344810452627081143e+00, 1.378873203729832710e+00, 1.413909628283517352e+00, 1.449958915644490754e+00, 1.487062205287898607e+00, 1.525262695058439148e+00, 1.564605756286502811e+00, 1.605139056255971231e+00, 1.646912688547541313e+00, 1.689979311822189937e+00, 1.734394297653598793e+00, 1.780215888066332921e+00, 1.827505363488657555e+00, 1.876327221885466881e+00, 1.926749369898304239e+00, 1.978843326886336694e+00, 2.032684442834914613e+00, 2.088352131177556992e+00, 2.145930117663470432e+00, 2.205506706496711366e+00, 2.267175065075584681e+00, 2.331033528772661605e+00, 2.397185927317806037e+00, 2.465741934479827004e+00, 2.536817442887937264e+00, 2.610534965993323711e+00, 2.687024069345184956e+00, 2.766421833546071979e+00, 2.848873351459948781e+00, 2.934532262474922666e+00, 3.023561326873131923e+00, 3.116133043635102211e+00, 3.212430315307524598e+00, 3.312647163894682976e+00, 3.416989502097797957e+00, 3.525675964626843197e+00, 3.638938804749809967e+00, 3.757024861729272487e+00, 3.880196605330264341e+00, 4.008733264172298986e+00, 4.142932045347867609e+00, 4.283109453446644399e+00, 4.429602717916437040e+00, 4.582771338567048147e+00, 4.742998759991079249e+00, 4.910694186746867507e+00, 5.086294552335034437e+00, 5.270266656314831820e+00, 5.463109485364516396e+00, 5.665356735708146927e+00, 5.877579556128345480e+00, 6.100389532781943879e+00, 6.334441939256981670e+00, 6.580439277782222274e+00, 6.839135140254664526e+00, 7.111338420820842566e+00, 7.397917915172903763e+00, 7.699807345544508469e+00, 8.018010854664294474e+00, 8.353609016702406728e+00, 8.707765418592385473e+00, 9.081733871099147484e+00, 9.476866315716376006e+00, 9.894621501007146275e+00, 1.033657451045679019e+01, 1.080442723340841910e+01, 1.130001988133777781e+01, 1.182534366375335115e+01, 1.238255475156052427e+01, 1.297398967101161563e+01, 1.360218228861306245e+01, 1.426988256684760289e+01, 1.498007729260327644e+01, 1.573601300513857081e+01, 1.654122137866316500e+01, 1.739954734664685784e+01, 1.831518029132688981e+01, 1.929268866318984532e+01, 2.033705844217826172e+01, 2.145373590584482942e+01, 2.264867523060898736e+01, 2.392839152177298272e+01, 2.530001994731418268e+01, 2.677138174118011529e+01, 2.835105794560498805e+01, 3.004847188085487195e+01, 3.187398146713610639e+01, 3.383898267989664904e+01, 3.595602559959535672e+01, 3.823894472392493310e+01, 4.070300544879345396e+01, 4.336506889917953679e+01, 4.624377760823269784e+01, 4.935976490967979071e+01, 5.273589133292714765e+01, 5.639751178186770847e+01, 6.037277784867852275e+01, 6.469298027622754351e+01, 6.939293735292118365e+01, 7.451143592061966836e+01, 8.009173272176674066e+01, 8.618212503236856949e+01, 9.283660095406551480e+01, 1.001155814082968890e+02, 1.080867678325352448e+02, 1.168261118752949279e+02, 1.264189260858047240e+02, 1.369611577708331715e+02, 1.485608519349011866e+02, 1.613398336385932743e+02, 1.754356453320629017e+02, 1.910037809024609590e+02, 2.082202655019913565e+02, 2.272846389233001078e+02, 2.484234106336023257e+02, 2.718940668983047258e+02, 2.979897251188232016e+02, 3.270445480633676878e+02, 3.594400516741229885e+02, 3.956124653087335485e+02, 4.360613334959077953e+02, 4.813595846269808355e+02, 5.321653357808338203e+02, 5.892357556996862196e+02, 6.534433717775449045e+02, 7.257952842284018994e+02, 8.074558443729566627e+02, 8.997734679339701200e+02, 1.004312392957944252e+03, 1.122890361185594877e+03, 1.257623408459775530e+03, 1.410979202907522234e+03, 1.585840680166573460e+03, 1.785582106601447262e+03, 2.014160171499825914e+03, 2.276223289283167479e+03, 2.577243010007973485e+03, 2.923672325162804598e+03, 3.323136759290736047e+03, 3.784665511113575050e+03, 4.318971620160236406e+03, 4.938792274850918489e+03, 5.659303058273368331e+03, 6.498623292476395004e+03, 7.478433875318933386e+03, 8.624734342286166238e+03, 9.968772633484590145e+03, 1.154818959559393902e+04, 1.340843110702649390e+04, 1.560449453908580443e+04, 1.820309391023133793e+04, 2.128535066649680777e+04, 2.495014598048375046e+04, 2.931830770482188047e+04, 3.453785313845473397e+04, 4.079057084931056631e+04, 4.830030527863206410e+04, 5.734341246586992004e+04, 6.826199159022146453e+04, 8.148067525594191464e+04, 9.752799507478730867e+04, 1.170636462204808295e+05, 1.409133795481584143e+05, 1.701137853111825512e+05, 2.059699426710509940e+05, 2.501298539735692463e+05, 3.046808435555379486e+05, 3.722747886360361411e+05, 4.562913164460176067e+05, 5.610511554921845541e+05, 6.920959565810343691e+05, 8.565564972181198149e+05, 1.063638800552326000e+06, 1.325268101226286025e+06, 1.656944841847240121e+06, 2.078886479301160156e+06, 2.617555920130068069e+06, 3.307714852226224955e+06, 4.195192293202626259e+06, 5.340631300250745566e+06, 6.824578495767020734e+06, 8.754424053248831818e+06, 1.127390159772263517e+07, 1.457614342739689625e+07, 1.892169326841938100e+07, 2.466345986800667442e+07, 3.228142821711217588e+07, 4.243114571539869754e+07, 5.601173714434088431e+07, 7.426172509723072112e+07, 9.889461357830121731e+07, 1.322915875470427182e+08, 1.777766240727455981e+08, 2.400110583389834263e+08, 3.255621033641982742e+08, 4.437258820593761403e+08, 6.077246218504877165e+08, 8.364565879857375417e+08, 1.157066594326456169e+09, 1.608740826498742961e+09, 2.248337657948688269e+09, 3.158785978851336228e+09, 4.461677081363911380e+09, 6.336244831048209270e+09, 9.048130159588677560e+09, 1.299321362309972265e+10, 1.876478261212947929e+10, 2.725703976712888971e+10, 3.982553459064288940e+10, 5.853727794017415415e+10, 8.656299089553103385e+10, 1.287959733041898747e+11, 1.928345065430099883e+11, 2.905510467545806044e+11, 4.406145488098485809e+11, 6.725708918778493152e+11, 1.033486938212196930e+12, 1.598840557086695854e+12, 2.490490134218272825e+12, 3.906528466724583921e+12, 6.171225147961354244e+12, 9.819163736485109137e+12, 1.573800106991564475e+13, 2.541245461530031221e+13, 4.134437628407981776e+13, 6.778141973485971528e+13, 1.119906286595884492e+14, 1.865016806041768967e+14, 3.130890948724989738e+14, 5.298978847669068280e+14, 9.042973899804181753e+14, 1.556259036818991439e+15, 2.701230066368200812e+15, 4.729430105054711279e+15, 8.353779033096586530e+15, 1.488827606293191651e+16, 2.677653466031614956e+16, 4.860434481369499270e+16, 8.905735519300993312e+16, 1.647413728306871552e+17, 3.077081325673016377e+17, 5.804234101329097680e+17, 1.105828570628099614e+18, 2.128315358808074026e+18, 4.138651532085235581e+18, 8.132554212123920035e+18, 1.615146503312570855e+19, 3.242548467260718193e+19, 6.581494581080701321e+19, 1.350831366183090003e+20, 2.804093832520937396e+20, 5.888113683467563837e+20, 1.250923435312468276e+21, 2.689280279098215635e+21, 5.851582825664479700e+21, 1.288917231788944660e+22, 2.874582763768997631e+22, 6.492437335109217869e+22, 1.485286605867082177e+23, 3.442469159113307066e+23, 8.084930196860438207e+23, 1.924506778048094878e+24, 4.643992662491470729e+24, 1.136281452083591334e+25, 2.819664891060694571e+25, 7.097781559991856367e+25, 1.812838850127688486e+26, 4.699012851344539124e+26, 1.236419707162832951e+27, 3.303236261210411286e+27, 8.962558097638891218e+27, 2.470294852986226117e+28, 6.918270960555942883e+28, 1.969189447958411510e+29, 5.698092609453981289e+29, 1.676626156396922084e+30, 5.017901520171556970e+30, 1.527929892279834489e+31, 4.734762318366711949e+31, 1.493572546446777040e+32, 4.797441164681908184e+32, 1.569538296400998732e+33, 5.231651156910242454e+33, 1.777206511525290941e+34, 6.154587299576916134e+34, 2.173469781356604872e+35, 7.829529896526581616e+35, 2.877935554073076917e+36, 1.079761320923458592e+37, 4.136337730951207042e+37, 1.618408489711185844e+38, 6.469770640447824771e+38, 2.643413654859316358e+39, 1.104246728308525703e+40, 4.717842641881260665e+40, 2.062296462389327711e+41, 9.226680005161257219e+41, 4.226544071632731963e+42, 1.983043729707066518e+43, 9.533448690970155039e+43, 4.697914578740208606e+44, 2.373923101980436574e+45, 1.230570211868531753e+46, 6.546344338411695147e+46, 3.575371819335804914e+47, 2.005642453538335506e+48, 1.156055268028903078e+49, 6.849867807870312958e+49, 4.174004815218951121e+50, 2.616872034052857472e+51, 1.688750346837297725e+52, 1.122275666009684101e+53, 7.683968740248677071e+53, 5.422849612654278583e+54, 3.946686701799533415e+55, 2.963543587288132884e+56, 2.297086395798939516e+57, 1.838856414208555761e+58, 1.521049475711243996e+59, 1.300732291175071112e+60, 1.150559591141716740e+61, 1.053265997373725461e+62, 9.984114209879020836e+62, 9.805325615938694719e+63, 9.982463564199115995e+64, 1.054102211457911410e+66, 1.155172684780782463e+67, 1.314571302334116663e+68, 1.554362407685457310e+69, 1.910791206002645077e+70, 2.443616403890711206e+71, 3.252983822318823232e+72, 4.510600140020139737e+73, 6.518821831001902447e+74, 9.825834460774267633e+75, 1.545692063622722856e+77, 2.539346088408163253e+78, 4.359763993811836117e+79, 7.827943627464404744e+80, 1.470896877674301183e+82, 2.894527071420674290e+83, 5.969662541607915492e+84, 1.291277613981057357e+86, 2.931656535626877923e+87, 6.991353547531463135e+88, 1.752671194525972852e+90, 4.622450137056020715e+91, 1.283581933169566226e+93, 3.755839001138390788e+94, 1.158991729845978702e+96, 3.774916315438862678e+97, 1.298844894462381673e+99, 4.725038949943384889e+100, 1.819000031203286740e+102, 7.416966330876906188e+103, 3.206116996910598204e+105, 1.470588770071975193e+107, 7.164198238238641057e+108, 3.710397624567077270e+110, 2.044882454279709373e+112, 1.200428778654730225e+114, 7.513744370030172114e+115, 5.019575746343410636e+117, 3.582726927665698318e+119, 2.734947775877248560e+121, 2.235283764078944248e+123, 1.958084751118243323e+125, 1.840431913109305657e+127, 1.858143260692831108e+129, 2.017432949655777136e+131, 2.358177615888101494e+133, 2.971092974178603610e+135, 4.039532321435816302e+137, 5.933923069661132195e+139, 9.429263693444953240e+141, 1.622841456932873872e+144, 3.028884476067694180e+146, 6.138356175015339477e+148, 1.352531557191942648e+151, 3.244447362295582945e+153, }, + }; + m_weights = { + { 2.703640234162693583e-160, 3.100862940179668765e-58, 5.828334625665462970e-21, 1.628894422402653830e-07, 8.129907377394029252e-03, 2.851214447180802931e-01, 1.228894002317118650e+00, 9.374610761705565881e+00, 6.136846875218162167e+02, 8.367995944653844271e+06, 2.286032371256753845e+17, 9.029964022492184559e+44, 1.637973037681055808e+119, }, + { 1.029757744225565290e-96, 5.564174008086804112e-35, 1.534846576427062716e-12, 1.519539651119905182e-04, 7.878691652861874032e-02, 6.288072016384128612e-01, 2.842403831496369386e+00, 5.152309209026500589e+01, 2.554172947873109927e+04, 8.291547503290989754e+10, 6.794911791960761587e+27, 1.108995159102362663e+73, }, + { 1.545310485347377408e-124, 4.549745016271158113e-75, 3.781189989988588481e-45, 4.369440793304363176e-27, 3.253896178006708087e-16, 1.057239289288944987e-09, 7.826174663495492476e-06, 1.459783224353939263e-03, 2.972970552567852420e-02, 1.637950661613330541e-01, 4.392303913269138921e-01, 8.744243777287317807e-01, 1.804759465860974506e+00, 4.894937215283148383e+00, 2.036214502429748943e+01, 1.576549789679037479e+02, 3.249553828744194733e+03, 3.335686029489862584e+05, 4.858218914917275532e+08, 5.655171002571584464e+13, 9.084276291356790926e+21, 2.202757570781655071e+35, 1.851176020895552142e+57, 1.873046373612647920e+93, 3.113183070605141140e+152, }, + { 2.690380169654157101e-141, 9.388760099830475385e-110, 3.267856956418766261e-85, 4.012903562780032075e-66, 2.794595941054873674e-51, 9.598140333687791635e-40, 8.762766371925782803e-31, 7.896919977115783593e-24, 1.951680620313826776e-18, 2.931867534349928041e-14, 4.976350908135118762e-11, 1.546933241860617074e-08, 1.283189791774752963e-06, 3.809052946018782340e-05, 5.087526585392884730e-04, 3.656819625189471368e-03, 1.627679402690602992e-02, 5.011672130624018967e-02, 1.165913368715250324e-01, 2.201514148384271336e-01, 3.581909054968942386e-01, 5.288599003801643436e-01, 7.422823219366348741e-01, 1.032914080772662205e+00, 1.478415067523268199e+00, 2.242226697017918644e+00, 3.684755742578570582e+00, 6.677326887819023056e+00, 1.358063058433697357e+01, 3.171262375809110066e+01, 8.776338468947827779e+01, 3.006939713363920293e+02, 1.352196150715330628e+03, 8.616353573310419356e+03, 8.591849573350877359e+04, 1.523635814554291966e+06, 5.663834603448267056e+07, 5.450828629396188577e+09, 1.780881993484818221e+12, 2.797112703281894578e+15, 3.300887168363313931e+19, 5.192538272313512016e+24, 2.273085973059979872e+31, 7.124498195222272142e+39, 5.379592741425673874e+50, 4.647296508337283075e+64, 3.395147156494395571e+82, 2.736576372417856435e+105, 6.584825756536212781e+134, }, + { 1.692276285171240629e-150, 1.180420021590838281e-132, 6.494931071412232065e-117, 4.979673804239645358e-103, 8.790122245397054202e-91, 5.564311726870413043e-80, 1.867634664877268411e-70, 4.693767384843440310e-62, 1.197772698674604837e-54, 4.060530886983702887e-48, 2.318268710612758367e-42, 2.748088060676949794e-37, 8.136086869664039226e-33, 7.081491999860360593e-29, 2.092407629019781417e-25, 2.383020547076997517e-22, 1.170143938604536054e-19, 2.734857915002515580e-17, 3.319894174569245506e-15, 2.260825106530477104e-13, 9.244747974241858562e-12, 2.410325858091057071e-10, 4.224928060220423782e-09, 5.217223349652829804e-08, 4.730110697329046717e-07, 3.265522864288710545e-06, 1.772851678458610971e-05, 7.787346612077215804e-05, 2.838101678971546354e-04, 8.775026198694109646e-04, 2.347474744139291716e-03, 5.529174974874315725e-03, 1.164520226280038968e-02, 2.223487842904240574e-02, 3.896253311038730452e-02, 6.334975706136386464e-02, 9.651712033300261848e-02, 1.390236708907266445e-01, 1.908593745910709887e-01, 2.515965688234414960e-01, 3.206651646562737595e-01, 3.976974208167367099e-01, 4.828935799767836828e-01, 5.773826389735376677e-01, 6.835838865575605461e-01, 8.056083579298257627e-01, 9.497742078309479997e-01, 1.125351459431134254e+00, 1.345711576612114788e+00, 1.630156867495860456e+00, 2.006880650908830857e+00, 2.517828844916874130e+00, 3.226826819856410846e+00, 4.233461155863004269e+00, 5.697400323487776530e+00, 7.882247346334201378e+00, 1.123717929435969530e+01, 1.655437952523069781e+01, 2.528458931361129124e+01, 4.019700050163276117e+01, 6.682515670231120695e+01, 1.168022589948424530e+02, 2.160045684819153702e+02, 4.257255901158116698e+02, 9.017180693982791021e+02, 2.072151523320542727e+03, 5.222689557952776194e+03, 1.461663959276604441e+04, 4.606455611513396576e+04, 1.660950339384278845e+05, 6.976630616605097333e+05, 3.484240083705972727e+06, 2.117385064786894718e+07, 1.607368605379557548e+08, 1.570235957877638143e+09, 2.041619284762317483e+10, 3.670425964529826371e+11, 9.527196643411724126e+12, 3.749667772735766186e+14, 2.365380223523087981e+16, 2.546815287226970627e+18, 5.026010591299970789e+20, 1.970775914722195502e+23, 1.682531038342715298e+26, 3.469062187981719410e+29, 1.942614547946028081e+33, 3.375034694941022784e+37, 2.115298406181711256e+42, 5.673738540911562268e+47, 7.904099301170483654e+53, 7.121903115084356741e+60, 5.321820777644930491e+68, 4.370977753639010591e+77, 5.429657931755513797e+87, 1.464602226824232950e+99, 1.292445035662836561e+112, 5.936633203060705474e+126, 2.402419924621336913e+143, }, + { 2.552410363565288863e-155, 7.965872719315690060e-146, 6.586401422963018216e-137, 1.563673437419490296e-128, 1.149636272392214573e-120, 2.810189759625314580e-113, 2.441446149780773329e-106, 8.026292508555041710e-100, 1.059034284623927886e-93, 5.927259046205893861e-88, 1.482220909125121967e-82, 1.738946448501809732e-77, 1.002047910184021813e-72, 2.960929073720769637e-68, 4.671749731809402860e-64, 4.088398674807775827e-60, 2.056642628601930023e-56, 6.149878578966749305e-53, 1.128142221531950274e-49, 1.307702777646013040e-46, 9.848757125541659318e-44, 4.946847667192787369e-41, 1.698284656321589089e-38, 4.077947349805764486e-36, 6.998897321243266048e-34, 8.762183229651405846e-32, 8.156281709801700633e-30, 5.747366069381804213e-28, 3.117951907317865517e-26, 1.323052992594482858e-24, 4.457166057119926322e-23, 1.208896132634708032e-21, 2.674697849739340358e-20, 4.887394807742436672e-19, 7.461632083041868391e-18, 9.622230748739818989e-17, 1.058884510032627118e-15, 1.003988180288807180e-14, 8.276358838778374127e-14, 5.982281469656734375e-13, 3.821855766886203088e-12, 2.174279097299082001e-11, 1.109294120074848583e-10, 5.109055596902086022e-10, 2.137447956882816268e-09, 8.170468538364022161e-09, 2.869308592926374871e-08, 9.305185930419436742e-08, 2.800231592227134982e-07, 7.855263634214717091e-07, 2.062924236714395731e-06, 5.092224131071637441e-06, 1.185972357373608535e-05, 2.615333473470835518e-05, 5.479175746096322166e-05, 1.093962713107868416e-04, 2.087714243290528595e-04, 3.818797556417767457e-04, 6.712796918790164790e-04, 1.136760145626956604e-03, 1.858775505765622915e-03, 2.941191222579735746e-03, 4.512821350378020080e-03, 6.727293426938802892e-03, 9.760915371480980900e-03, 1.380842853102550981e-02, 1.907678055354397196e-02, 2.577730275571060412e-02, 3.411688991056810143e-02, 4.428892397843486143e-02, 5.646473816310556552e-02, 7.078637998740884103e-02, 8.736131246718460273e-02, 1.062595125372295046e-01, 1.275132133780278017e-01, 1.511193209351630349e-01, 1.770443400812491404e-01, 2.052314915777496186e-01, 2.356095985715091716e-01, 2.681032744853198083e-01, 3.026439500331752405e-01, 3.391813282438962329e-01, 3.776949427111484449e-01, 4.182056049753837852e-01, 4.607866519948383101e-01, 5.055750360563806155e-01, 5.527824318481410262e-01, 6.027066663808878454e-01, 6.557439076684384801e-01, 7.124021812071310501e-01, 7.733169258916167748e-01, 8.392694625821144443e-01, 9.112094418201526544e-01, 9.902825786957198607e-01, 1.077865293953107863e+00, 1.175608288920191064e+00, 1.285491624542001346e+00, 1.409894601042286311e+00, 1.551684711657329886e+00, 1.714331263928885829e+00, 1.902051053858215699e+00, 2.119995922515087770e+00, 2.374495377438728901e+00, 2.673372087884984440e+00, 3.026354489757871517e+00, 3.445619726158519068e+00, 3.946512819227006419e+00, 4.548505964859933724e+00, 5.276487613615791435e+00, 6.162508226184798743e+00, 7.248163842886806184e+00, 8.587878410768473380e+00, 1.025346434903602082e+01, 1.234051869120733230e+01, 1.497748183201988157e+01, 1.833859935862139637e+01, 2.266266859437541631e+01, 2.828045768298752298e+01, 3.565528397044830339e+01, 4.544381261232990127e+01, 5.858833744254070379e+01, 7.645876087681923606e+01, 1.010741758687003802e+02, 1.354538987141142977e+02, 1.841824059064608872e+02, 2.543337025162468240e+02, 3.570103970895535977e+02, 5.099537256432247190e+02, 7.420561390174965949e+02, 1.101323941193719451e+03, 1.669232910686306616e+03, 2.587203282090385703e+03, 4.106608602134535014e+03, 6.685657263550896700e+03, 1.118216368762133982e+04, 1.924811115485038079e+04, 3.416174865734933127e+04, 6.263882227839496242e+04, 1.189094418952240294e+05, 2.342262528110389793e+05, 4.798899889628646876e+05, 1.025279649144740527e+06, 2.290428015483177407e+06, 5.365618820221241118e+06, 1.322172034826883742e+07, 3.438296542047893623e+07, 9.468905314460992170e+07, 2.771843378168242512e+08, 8.658950437199969679e+08, 2.898779165825890846e+09, 1.044627762990198184e+10, 4.071673625087267154e+10, 1.725245696783106160e+11, 7.989856904303845909e+11, 4.067537100664303783e+12, 2.290253922913114847e+13, 1.435560574531699914e+14, 1.008680130601194048e+15, 8.003530334765274913e+15, 7.227937568629809266e+16, 7.491693576707361828e+17, 8.991671234614216799e+18, 1.261556024888540618e+20, 2.090038400033346091e+21, 4.132773073376509056e+22, 9.865671928781943336e+23, 2.877978132616007671e+25, 1.039303004928044064e+27, 4.710544722984128252e+28, 2.719194692980296464e+30, 2.030608169419634520e+32, 1.994536427964099457e+34, 2.622806931876485852e+36, 4.705142628855489738e+38, 1.174794916996875010e+41, 4.170574236544843559e+43, 2.153441953645800917e+46, 1.656794933445123415e+49, 1.948830907651317326e+52, 3.601980393005358786e+55, 1.077033440153993124e+59, 5.374188883861674378e+62, 4.625267105826449467e+66, 7.111646979020385006e+70, 2.027996051444846521e+75, 1.116168784120367146e+80, 1.237019821283735086e+85, 2.888108172342166477e+90, 1.490426937972460544e+96, 1.789306677271856318e+102, 5.276973875344766848e+108, 4.051217867886536330e+115, 8.611617868168979525e+122, 5.412634353380155695e+130, 1.078756609821147465e+139, 7.344353246966125053e+147, }, + { 8.688318611421924613e-158, 6.864317997043424201e-153, 3.829638174036322920e-148, 1.524985558970066863e-143, 4.379527631402474835e-139, 9.162408388991747001e-135, 1.410086556664696347e-130, 1.611529786006329005e-126, 1.380269212504431613e-122, 8.938739565456142404e-119, 4.414803004265274778e-115, 1.676831992534574674e-111, 4.937648515671545377e-108, 1.136068312653058895e-104, 2.057969760853201132e-101, 2.956779836249922681e-98, 3.393449014375824853e-95, 3.132619285740674842e-92, 2.341677665639346254e-89, 1.426656997926173190e-86, 7.128825597334931865e-84, 2.939485275517928205e-81, 1.006113300119903410e-78, 2.874969402023240560e-76, 6.896713338909433222e-74, 1.396405038640012785e-71, 2.398869799873387326e-69, 3.514180228970525006e-67, 4.411557600438730779e-65, 4.768408435763044172e-63, 4.458287229998440383e-61, 3.621710763086768959e-59, 2.567373174003034094e-57, 1.594829856885795944e-55, 8.716746897177859412e-54, 4.208424534880021226e-52, 1.801637343401221381e-50, 6.864432292330768862e-49, 2.336084584516383243e-47, 7.125716658075193173e-46, 1.954733295862350631e-44, 4.838195020814970471e-43, 1.083903033389729471e-41, 2.204655424309513426e-40, 4.083431629921110537e-39, 6.907095608064865023e-38, 1.069951518082577963e-36, 1.521972185061747284e-35, 1.993254198127980161e-34, 2.409552194902670884e-33, 2.695243589253751811e-32, 2.796309045342585624e-31, 2.697138787161831243e-30, 2.423968619042656074e-29, 2.034233848004972409e-28, 1.597498662808006882e-27, 1.176341105034547043e-26, 8.138404856556384931e-26, 5.300199402716282910e-25, 3.255367628680633536e-24, 1.889060856810273071e-23, 1.037502167741821871e-22, 5.402129194695882094e-22, 2.671080147950250592e-21, 1.256163163817414397e-20, 5.627458451375099018e-20, 2.405110192151924414e-19, 9.820723025892385774e-19, 3.836610965933493002e-18, 1.435949417965440387e-17, 5.155736116435221852e-17, 1.778106820243535736e-16, 5.897650538103448384e-16, 1.883545377386949394e-15, 5.799022727889041128e-15, 1.723080101027408120e-14, 4.946559668895564981e-14, 1.373437058883951037e-13, 3.692057356296675476e-13, 9.618669754374864080e-13, 2.430904641718059201e-12, 5.965319652795549281e-12, 1.422677541958913512e-11, 3.300412010407028696e-11, 7.453993539444124847e-11, 1.640317480539372495e-10, 3.519919455549922227e-10, 7.371241496931924727e-10, 1.507573517782825692e-09, 3.013444008176544118e-09, 5.891170930525923854e-09, 1.127175867596519203e-08, 2.112135943063526334e-08, 3.878572405868819131e-08, 6.984140168311147329e-08, 1.233979234102365865e-07, 2.140481233406505212e-07, 3.647293211756793211e-07, 6.108366265875129839e-07, 1.006020283089617901e-06, 1.630199379920459998e-06, 2.600430208375972125e-06, 4.085372746054298735e-06, 6.324194831966406940e-06, 9.650830226718535837e-06, 1.452455211307694488e-05, 2.156782506321975658e-05, 3.161234361554654466e-05, 4.575404320696170555e-05, 6.541767069965264068e-05, 9.243122234114186712e-05, 1.291101968446571125e-04, 1.783511762821284409e-04, 2.437337497712608884e-04, 3.296292528289701234e-04, 4.413142327104518440e-04, 5.850859955683163216e-04, 7.683770763700705263e-04, 9.998650298180469208e-04, 1.289573601590465490e-03, 1.648961132392222413e-03, 2.090991995585424661e-03, 2.630186988492201910e-03, 3.282648895332118799e-03, 4.066059914467245175e-03, 4.999648283080481820e-03, 6.104122218554241819e-03, 7.401570199659662364e-03, 8.915327597805008451e-03, 1.066981070009509413e-02, 1.269032020049755525e-02, 1.500281723149735994e-02, 1.763367592672867332e-02, 2.060941730962251417e-02, 2.395642996410886880e-02, 2.770068343772389725e-02, 3.186744063963193757e-02, 3.648097561865623097e-02, 4.156430303997019336e-02, 4.713892543167989540e-02, 5.322460385886412684e-02, 5.983915712308283792e-02, 6.699829390463281224e-02, 7.471548149065050122e-02, 8.300185389391494996e-02, 9.186616129460712899e-02, 1.013147618591979452e-01, 1.113516561340355690e-01, 1.219785634003157786e-01, 1.331950386328042665e-01, 1.449986280439946752e-01, 1.573850606313672716e-01, 1.703484726870446791e-01, 1.838816618814874884e-01, 1.979763672973498048e-01, 2.126235716643688402e-01, 2.278138220265254991e-01, 2.435375651517067386e-01, 2.597854941629632707e-01, 2.765489031191654411e-01, 2.938200465906351752e-01, 3.115925016510994851e-01, 3.298615301301230823e-01, 3.486244394295739435e-01, 3.678809406939879716e-01, 3.876335036292959599e-01, 4.078877077798518471e-01, 4.286525905940105684e-01, 4.499409931290513174e-01, 4.717699047639316286e-01, 4.941608088016098926e-01, 5.171400313514193966e-01, 5.407390963876342256e-01, 5.649950903858123945e-01, 5.899510404480374918e-01, 6.156563103475134535e-01, 6.421670194591982411e-01, 6.695464901047961714e-01, 6.978657294374126896e-01, 7.272039526349696447e-01, 7.576491548751669105e-01, 7.892987403432202489e-01, 8.222602173936578230e-01, 8.566519699682320391e-01, 8.926041164852169437e-01, 9.302594686857616145e-01, 9.697746043788558519e-01, 1.011321069700320644e+00, 1.055086728430498711e+00, 1.101277278143300224e+00, 1.150117955536247302e+00, 1.201855456275760449e+00, 1.256760098152647779e+00, 1.315128260359919236e+00, 1.377285136373095709e+00, 1.443587843343442141e+00, 1.514428937238563465e+00, 1.590240390338335337e+00, 1.671498096302065311e+00, 1.758726978084942299e+00, 1.852506785760205887e+00, 1.953478685110838140e+00, 2.062352754065132708e+00, 2.179916523112736371e+00, 2.307044718290330681e+00, 2.444710391817196957e+00, 2.593997656772008968e+00, 2.756116279277535182e+00, 2.932418425642610903e+00, 3.124417914187536020e+00, 3.333812383735923205e+00, 3.562508865047068391e+00, 3.812653330296280988e+00, 4.086664902155689132e+00, 4.387275531849634155e+00, 4.717576109385405085e+00, 5.081070154695596855e+00, 5.481736462718817995e+00, 5.924102347216244340e+00, 6.413329458204850426e+00, 6.955314549766230740e+00, 7.556808065486941215e+00, 8.225554008952760095e+00, 8.970455302965185036e+00, 9.801769746699598466e+00, 1.073134279679936208e+01, 1.177288477943655549e+01, 1.294230185297226511e+01, 1.425809217068106541e+01, 1.574182134943112610e+01, 1.741869467329444792e+01, 1.931824763074534781e+01, 2.147518163232618457e+01, 2.393037838236259586e+01, 2.673213477270754163e+01, 2.993767083537830673e+01, 3.361497689655818107e+01, 3.784508348524495401e+01, 4.272485990900652026e+01, 4.837047622725585887e+01, 5.492170063250241752e+01, 6.254725265973777743e+01, 7.145149574983117631e+01, 8.188283528217430591e+01, 9.414429671899321190e+01, 1.086069017070108772e+02, 1.257266497442910506e+02, 1.460661655727672308e+02, 1.703224100743601641e+02, 1.993623058409479084e+02, 2.342687403011957198e+02, 2.764002385528330658e+02, 3.274687277481591846e+02, 3.896413615832930151e+02, 4.656745019682919178e+02, 5.590908996105107215e+02, 6.744152109571297875e+02, 8.174887172033244140e+02, 9.958921680864290197e+02, 1.219517071629880108e+03, 1.501341972869855447e+03, 1.858493492282554856e+03, 2.313705362529768409e+03, 2.897337235279879262e+03, 3.650185874628374320e+03, 4.627425468074182920e+03, 5.904167858279871204e+03, 7.583363128219763259e+03, 9.807105719965428472e+03, 1.277293273832114230e+04, 1.675749596877978193e+04, 2.215121038263169759e+04, 2.950937349291504490e+04, 3.962820433513419525e+04, 5.365890489878942635e+04, 7.328024305737981431e+04, 1.009620167752942516e+05, 1.403709568321740997e+05, 1.970019955923188504e+05, 2.791695960502382133e+05, 3.995801250202947693e+05, 5.778515877588312220e+05, 8.445944401474017243e+05, 1.248092975135001687e+06, 1.865367859966950385e+06, 2.820705292493674480e+06, 4.317063433830483499e+06, 6.689961127164684387e+06, 1.050111601631327499e+07, 1.670327884792325766e+07, 2.693430470211696200e+07, 4.404906898054894166e+07, 7.309535640536363311e+07, 1.231306812701882145e+08, 2.106560568719367745e+08, 3.662073971851359192e+08, 6.472124787519330196e+08, 1.163486593592585616e+09, 2.128658395254150452e+09, 3.965732938755983605e+09, 7.527735928223242836e+09, 1.456757162128879538e+10, 2.875798636941021041e+10, 5.794999654160054887e+10, 1.192767536774485257e+11, 2.509334090779650360e+11, 5.399624414800303207e+11, 1.189276111740286910e+12, 2.683103883355551677e+12, 6.205255919751506427e+12, 1.472284072112162717e+13, 3.586628373992547853e+13, 8.978594107356889337e+13, 2.311710197091641250e+14, 6.127020712804348908e+14, 1.673232679378485978e+15, 4.712671499032329365e+15, 1.370275025680988289e+16, 4.117347054027612886e+16, 1.279822436878842710e+17, 4.119762767831332886e+17, 1.374888606936629814e+18, 4.762483833659790733e+18, 1.714288404980390540e+19, 6.420200704842635702e+19, 2.504808062315322558e+20, 1.019355251138167687e+21, 4.332952958521756932e+21, 1.926416464889827426e+22, 8.971059571108856501e+22, 4.382317748928748816e+23, 2.249003059943548727e+24, 1.214458587662725100e+25, 6.911683912813140938e+25, 4.152578123301633020e+26, 2.638346388179288086e+27, 1.775811490887700718e+28, 1.268552401544524965e+29, 9.635786341213661742e+29, 7.797939379813000783e+30, 6.736900087983560033e+31, 6.226288752443836475e+32, 6.169035287163451891e+33, 6.567250104576983172e+34, 7.528666735185428595e+35, 9.316271421365627344e+36, 1.247410737003664698e+38, 1.811787648043939987e+39, 2.861918583157116420e+40, 4.929657099622567574e+41, 9.284951278562156071e+42, 1.917687997037326435e+44, 4.355948096683946408e+45, 1.091453486585817118e+47, 3.026206402784023251e+48, 9.314478983991942688e+49, 3.193195693823940775e+51, 1.223447678968662613e+53, 5.257403184148516426e+54, 2.543108925126136766e+56, 1.389947584026783879e+58, 8.616987336205957549e+59, 6.083777056769299984e+61, 4.911841077800001710e+63, 4.554259483169784661e+65, 4.870815185962582259e+67, 6.036211886847067841e+69, 8.708377755587698026e+71, 1.469655296381977267e+74, 2.915822924489215887e+76, 6.836044306573246016e+78, 1.903917300559946782e+81, 6.333813341980360028e+83, 2.531082268773868753e+86, 1.222077360592898816e+89, 7.172167453276776330e+91, 5.148160232410244898e+94, 4.548619807672339638e+97, 4.979632843475864923e+100, 6.800802744782331957e+103, 1.166855497965918386e+107, 2.533457765534279043e+110, 7.012864641215147208e+113, 2.494083354169569414e+117, 1.148722178881219993e+121, 6.908313932158993510e+124, 5.470912484744367184e+128, 5.755359832684120769e+132, 8.115681923907451939e+136, 1.548304780334447081e+141, 4.034912159113614601e+145, 1.450632759611715526e+150, 7.268799665580789770e+154, }, + { 4.901759085947701448e-159, 1.505832423620814399e-156, 4.231872109262999523e-154, 1.089479701785106001e-151, 2.572922387150651649e-149, 5.581311054334156941e-147, 1.113575900126970040e-144, 2.046165051332286084e-142, 3.466994885004770636e-140, 5.423795404073501922e-138, 7.843833272402847010e-136, 1.049922957933194415e-133, 1.302301071957418603e-131, 1.498659737828393008e-129, 1.601906622414286282e-127, 1.592248618401983561e-125, 1.473375345916436274e-123, 1.270651551394009593e-121, 1.022408263525766209e-119, 7.683762602329562781e-118, 5.399268127233373186e-116, 3.551074274853494676e-114, 2.188235409519121010e-112, 1.264667515430816934e-110, 6.861807566737243712e-109, 3.498691686825209963e-107, 1.678016807398375157e-105, 7.577439431441931490e-104, 3.224703770159386809e-102, 1.294487090677705963e-100, 4.906133250963454139e-99, 1.757121317988153326e-97, 5.952042491454320383e-96, 1.908566653286417264e-94, 5.798224459236429212e-93, 1.670293239978334727e-91, 4.566236673398083038e-90, 1.185617342791547945e-88, 2.926160027801296929e-87, 6.870061134126707137e-86, 1.535565783500379945e-84, 3.270036736778401257e-83, 6.639558007206580362e-82, 1.286319750967398593e-80, 2.379566581139022958e-79, 4.206268231398883425e-78, 7.109719237833379433e-77, 1.149915104115372777e-75, 1.780876201255594220e-74, 2.642703796179329883e-73, 3.760085375941719327e-72, 5.132920951124251993e-71, 6.727100274601427696e-70, 8.469585621347697498e-69, 1.025032382672232848e-67, 1.193219127557863348e-66, 1.336816930381306582e-65, 1.442283479679798385e-64, 1.499374555004793991e-63, 1.502797203133501438e-62, 1.453005969318485303e-61, 1.355980448377862540e-60, 1.222072412212552127e-59, 1.064223180270520159e-58, 8.959667396075636845e-58, 7.296288808079294105e-57, 5.750255296190181158e-56, 4.388011664829013518e-55, 3.243852451291832398e-54, 2.324239357665538806e-53, 1.614869776203026446e-52, 1.088524605545274842e-51, 7.121755574192829045e-51, 4.524647662549067074e-50, 2.792730715818793035e-49, 1.675384879603864227e-48, 9.773114328777676091e-48, 5.545910766847627082e-47, 3.062809705627873645e-46, 1.646862118038266234e-45, 8.625108513887155847e-45, 4.401687663868890701e-44, 2.189755778847646746e-43, 1.062345336449265889e-42, 5.028036663485684049e-42, 2.322524635717249223e-41, 1.047406593898341306e-40, 4.613438388449698168e-40, 1.985397445118162005e-39, 8.351027367454628343e-39, 3.434440903484543389e-38, 1.381489131877196646e-37, 5.437051201310225224e-37, 2.094357548080647717e-36, 7.898676618592006902e-36, 2.917536870947471272e-35, 1.055788886022716597e-34, 3.744333812160330812e-34, 1.301801185251957290e-33, 4.438346216893387768e-33, 1.484348268951816542e-32, 4.871001129849836971e-32, 1.568903000742513942e-31, 4.961295315917935235e-31, 1.540773910027990821e-30, 4.700558022172014910e-30, 1.409115230718949596e-29, 4.151913103955692034e-29, 1.202737613715427748e-28, 3.426327374934496736e-28, 9.601405359397026012e-28, 2.647278642033773301e-27, 7.183442220565147103e-27, 1.918850545981494042e-26, 5.046974779455992494e-26, 1.307394799925911700e-25, 3.336342198236957082e-25, 8.389259581136262194e-25, 2.079051813513548608e-24, 5.079178967243765280e-24, 1.223501794357837278e-23, 2.906654911057549530e-23, 6.811668606095015470e-23, 1.574985938238025303e-22, 3.593796788969348326e-22, 8.094185411205212564e-22, 1.799796183237481721e-21, 3.951758901641017285e-21, 8.569580068050865775e-21, 1.835753486517298696e-20, 3.885414339966022317e-20, 8.126613972895021790e-20, 1.680007182889503141e-19, 3.433369351563962828e-19, 6.937695550399427499e-19, 1.386345631008981755e-18, 2.740087497759230881e-18, 5.357570288683386626e-18, 1.036464933022803784e-17, 1.984249442010084992e-17, 3.759788006060003409e-17, 7.052211261821684795e-17, 1.309635641529546221e-16, 2.408275496109180528e-16, 4.385898809611711552e-16, 7.911758686849121285e-16, 1.413883597877183873e-15, 2.503477536644680210e-15, 4.392637866550705827e-15, 7.638710306960574612e-15, 1.316703360377476041e-14, 2.250031027275448919e-14, 3.812239733412214953e-14, 6.405021660191363479e-14, 1.067250538270319484e-13, 1.763897493784721010e-13, 2.891987565334547756e-13, 4.704242520369958085e-13, 7.592878273512691990e-13, 1.216183338372525172e-12, 1.933388593436624879e-12, 3.050826852442290751e-12, 4.779080020017636657e-12, 7.432734713385425098e-12, 1.147833888125873666e-11, 1.760286160372422754e-11, 2.681071101623953168e-11, 4.056023754295965437e-11, 6.095443492241537222e-11, 9.100550129616064211e-11, 1.349993452136967652e-10, 1.989943912395156051e-10, 2.914996073619059788e-10, 4.243900781412219621e-10, 6.141353162671391082e-10, 8.834365795894798511e-10, 1.263395594025933170e-09, 1.796369250051716047e-09, 2.539704143326480862e-09, 3.570592498287890499e-09, 4.992348403150539107e-09, 6.942471870489931483e-09, 9.602949600164561371e-09, 1.321333712761666777e-08, 1.808727901635346390e-08, 2.463325364767791516e-08, 3.338047870136870496e-08, 4.501108426108505069e-08, 6.039985413333259594e-08, 8.066305374526097834e-08, 1.072181059018892614e-07, 1.418561443795353991e-07, 1.868297699836383305e-07, 2.449586539172972009e-07, 3.197559780442760832e-07, 4.155790690867544334e-07, 5.378079713325544678e-07, 6.930561064776686194e-07, 8.894175852502122454e-07, 1.136756157868726006e-06, 1.447041212534730898e-06, 1.834736645332833504e-06, 2.317248822354253644e-06, 2.915440225825303911e-06, 3.654215709863551870e-06, 4.563188576773760151e-06, 5.677433909482232878e-06, 7.038336747307571784e-06, 8.694542758083067228e-06, 1.070301902702759858e-05, 1.313023243937403750e-05, 1.605345286789073897e-05, 1.956218797728780449e-05, 2.375975591555218862e-05, 2.876500146954361208e-05, 3.471416041263076209e-05, 4.176287576185915239e-05, 5.008836848967403773e-05, 5.989176390181730373e-05, 7.140057340280213227e-05, 8.487132973049760036e-05, 1.005923719620999934e-04, 1.188867746885496973e-04, 1.401154137398069279e-04, 1.646801587388731249e-04, 1.930271805904271778e-04, 2.256503597954330556e-04, 2.630947792533707128e-04, 3.059602829980946180e-04, 3.549050801425155303e-04, 4.106493712131842727e-04, 4.739789720708565436e-04, 5.457489087697051069e-04, 6.268869550379884668e-04, 7.183970825975973673e-04, 8.213627933082928901e-04, 9.369503011517966364e-04, 1.066411531385725184e-03, 1.211086903819095417e-03, 1.372407867107646339e-03, 1.551899151252505624e-03, 1.751180706119547318e-03, 1.971969294784470944e-03, 2.216079711850908971e-03, 2.485425598581779636e-03, 2.782019828718993257e-03, 3.107974441230220176e-03, 3.465500098895993776e-03, 3.856905054613959619e-03, 4.284593610523639393e-03, 4.751064058515097225e-03, 5.258906094345618421e-03, 5.810797701414435799e-03, 6.409501504198915943e-03, 7.057860595396970186e-03, 7.758793844909123446e-03, 8.515290702888369372e-03, 9.330405513145299523e-03, 1.020725135717912572e-02, 1.114899345297222760e-02, 1.215884213639836574e-02, 1.324004545661629463e-02, 1.439588142011718850e-02, 1.562964992113485073e-02, 1.694466439888404584e-02, 1.834424326453982033e-02, 1.983170114298836870e-02, 2.141033997615067889e-02, 2.308344003609062690e-02, 2.485425089716015368e-02, 2.672598241710042669e-02, 2.870179577730820310e-02, 3.078479463239356953e-02, 3.297801641870515720e-02, 3.528442387069167064e-02, 3.770689679281728890e-02, 4.024822413326941635e-02, 4.291109640390936770e-02, 4.569809848884132640e-02, 4.861170288163592155e-02, 5.165426338866744454e-02, 5.482800933323496446e-02, 5.813504029216542680e-02, 6.157732139347005467e-02, 6.515667920037330165e-02, 6.887479820368566403e-02, 7.273321794107712090e-02, 7.673333075835566151e-02, 8.087638022439339824e-02, 8.516346020789830747e-02, 8.959551462082867423e-02, 9.417333782991444898e-02, 9.889757573450802477e-02, 1.037687275058577967e-01, 1.087871479799008567e-01, 1.139530506928239996e-01, 1.192665115459606141e-01, 1.247274730840887416e-01, 1.303357493688843496e-01, 1.360910314271734020e-01, 1.419928932517243620e-01, 1.480407983306351483e-01, 1.542341066798992024e-01, 1.605720823524863565e-01, 1.670539013962460335e-01, 1.736786602321317742e-01, 1.804453844236544912e-01, 1.873530378080931153e-01, 1.944005319598201097e-01, 2.015867359561292115e-01, 2.089104864161762672e-01, 2.163705977840528187e-01, 2.239658728275971045e-01, 2.316951133252986765e-01, 2.395571309145607347e-01, 2.475507580756380088e-01, 2.556748592267567912e-01, 2.639283419072366399e-01, 2.723101680268593668e-01, 2.808193651612593497e-01, 2.894550378747292326e-01, 2.982163790535362503e-01, 3.071026812346166036e-01, 3.161133479163487600e-01, 3.252479048399920142e-01, 3.345060112323053140e-01, 3.438874710018250777e-01, 3.533922438832718793e-01, 3.630204565265675291e-01, 3.727724135289699431e-01, 3.826486084108677024e-01, 3.926497345378144818e-01, 4.027766959934214472e-01, 4.130306184097598756e-01, 4.234128597639539906e-01, 4.339250211516634154e-01, 4.445689575501645526e-01, 4.553467885857401860e-01, 4.662609093220769612e-01, 4.773140010883521767e-01, 4.885090423676662636e-01, 4.998493197684479070e-01, 5.113384391034281429e-01, 5.229803366027518117e-01, 5.347792902897740156e-01, 5.467399315500809553e-01, 5.588672569262846167e-01, 5.711666401731758417e-01, 5.836438446098876156e-01, 5.963050358078278898e-01, 6.091567946552975691e-01, 6.222061308419237716e-01, 6.354604968083211637e-01, 6.489278022087558681e-01, 6.626164289370386795e-01, 6.765352467684294227e-01, 6.906936296730053994e-01, 7.051014728587479919e-01, 7.197692106055475377e-01, 7.347078349544334315e-01, 7.499289153196209421e-01, 7.654446190944464391e-01, 7.812677333259577661e-01, 7.974116875368567865e-01, 8.138905777776784362e-01, 8.307191919965581771e-01, 8.479130368187123741e-01, 8.654883658328603475e-01, 8.834622094872810766e-01, 9.018524067040521621e-01, 9.206776383262963142e-01, 9.399574625199963151e-01, 9.597123522591707284e-01, 9.799637350309700387e-01, 1.000734034905599933e+00, 1.022046717124952010e+00, 1.043926335373472893e+00, 1.066398581905185161e+00, 1.089490340711946628e+00, 1.113229743930062164e+00, 1.137646231695313314e+00, 1.162770615670420260e+00, 1.188635146483979071e+00, 1.215273585336112390e+00, 1.242721280043529050e+00, 1.271015245815510799e+00, 1.300194251072644711e+00, 1.330298908642019971e+00, 1.361371772686240192e+00, 1.393457441749111730e+00, 1.426602668328411758e+00, 1.460856475415888358e+00, 1.496270280476785338e+00, 1.532898027375920169e+00, 1.570796326794896619e+00, 1.610024605725646420e+00, 1.650645266669431435e+00, 1.692723857217988332e+00, 1.736329250744977731e+00, 1.781533838991654903e+00, 1.828413737391087381e+00, 1.877049004040720448e+00, 1.927523873304087635e+00, 1.979927005099477087e+00, 2.034351751016940433e+00, 2.090896438495766214e+00, 2.149664674393090421e+00, 2.210765669381402212e+00, 2.274314584729113927e+00, 2.340432903144970240e+00, 2.409248825504827076e+00, 2.480897695429288043e+00, 2.555522453844001656e+00, 2.633274125832370887e+00, 2.714312342284411608e+00, 2.798805899057066353e+00, 2.886933356592141886e+00, 2.978883683190077867e+00, 3.074856945413050211e+00, 3.175065049391765683e+00, 3.279732537139255280e+00, 3.389097442334834102e+00, 3.503412210435275865e+00, 3.622944688401595705e+00, 3.747979189802462585e+00, 3.878817641573403805e+00, 4.015780819279312670e+00, 4.159209678351536168e+00, 4.309466789455788368e+00, 4.466937886899736897e+00, 4.632033539816493591e+00, 4.805190956770360727e+00, 4.986875935432896972e+00, 5.177584970080537688e+00, 5.377847530880629761e+00, 5.588228530273088035e+00, 5.809330993233640059e+00, 6.041798949837089488e+00, 6.286320570342285919e+00, 6.543631565013652661e+00, 6.814518873098582608e+00, 7.099824667819718682e+00, 7.400450706942931008e+00, 7.717363061475788814e+00, 8.051597258371279584e+00, 8.404263876795383951e+00, 8.776554641607500109e+00, 9.169749062247565207e+00, 9.585221670276993889e+00, 1.002444991444300704e+01, 1.048902277839603856e+01, 1.098065019316492606e+01, 1.150117332427169985e+01, 1.205257582204547280e+01, 1.263699613338454324e+01, 1.325674098404332380e+01, 1.391430015262873368e+01, 1.461236267104086712e+01, 1.535383460126837531e+01, 1.614185855545811846e+01, 1.697983514525758524e+01, 1.787144656784601339e+01, 1.882068256013178484e+01, 1.983186897964764985e+01, 2.090969930111845450e+01, 2.205926935196095527e+01, 2.328611564861881683e+01, 2.459625773922860138e+01, 2.599624500732998276e+01, 2.749320844694889238e+01, 2.909491798228195984e+01, 3.080984597641076715e+01, 3.264723765414180400e+01, 3.461718925554321861e+01, 3.673073484057443067e+01, 3.899994278315456980e+01, 4.143802312713618427e+01, 4.405944712930142330e+01, 4.688008048840357439e+01, 4.991733195758662298e+01, 5.319031926387298369e+01, 5.672005451703465811e+01, 6.052965158594831140e+01, 6.464455825915836491e+01, 6.909281639443131774e+01, 7.390535370725211687e+01, 7.911631135942343489e+01, 8.476341209659472308e+01, 9.088837435982152722e+01, 9.753737857533253823e+01, 1.047615927251647361e+02, 1.126177653386554197e+02, 1.211688952437418817e+02, 1.304849888043593828e+02, 1.406439169773708701e+02, 1.517323863863765989e+02, 1.638470407739824279e+02, 1.770957117100033620e+02, 1.915988403612775885e+02, 2.074910955409497265e+02, 2.249232172361061194e+02, 2.440641194630869936e+02, 2.651032917390266964e+02, 2.882535448280364212e+02, 3.137541538897424513e+02, 3.418744609277612322e+02, 3.729180087461214321e+02, 4.072272907593818790e+02, 4.451892153103389878e+02, 4.872414000388630927e+02, 5.338794318098249932e+02, 5.856652513400113117e+02, 6.432368496766822816e+02, 7.073194969336578611e+02, 7.787387632221277236e+02, 8.584356387770406827e+02, 9.474841163944599543e+02, 1.047111666301969297e+03, 1.158723113719277435e+03, 1.283928525349707755e+03, 1.424575826189363437e+03, 1.582789006393775706e+03, 1.761012944445459235e+03, 1.962066073573121788e+03, 2.189202360708354222e+03, 2.446184360349559652e+03, 2.737369460761187093e+03, 3.067811870808767638e+03, 3.443383419509962754e+03, 3.870916878218207705e+03, 4.358376293464465508e+03, 4.915059769420260559e+03, 5.551841303216967404e+03, 6.281459704453426129e+03, 7.118864385205665710e+03, 8.081629967627799596e+03, 9.190454321738597280e+03, 1.046975794051835702e+04, 1.194840663946247320e+04, 1.366058463062104793e+04, 1.564685131637809273e+04, 1.795542299179967539e+04, 2.064373043744082514e+04, 2.378031563732670807e+04, 2.744714621995650953e+04, 3.174244552480722739e+04, 3.678416050731336226e+04, 4.271422037773508051e+04, 4.970377768100323981e+04, 5.795967273138576164e+04, 6.773242484608792593e+04, 7.932613346949942761e+04, 9.311077397156915450e+04, 1.095375030536372224e+05, 1.291577556735669526e+05, 1.526471301608741586e+05, 1.808353350969648289e+05, 2.147438294770164181e+05, 2.556332515573999948e+05, 3.050633345562097502e+05, 3.649687926665853954e+05, 4.377556866857485380e+05, 5.264241222943208736e+05, 6.347248990108319410e+05, 7.673600526542426466e+05, 9.302403050337502786e+05, 1.130816502666451845e+06, 1.378507531155523742e+06, 1.685254393964162275e+06, 2.066239770168639390e+06, 2.540825270229354918e+06, 3.133775962036416630e+06, 3.876865148275802393e+06, 4.810984054018349430e+06, 5.988924089534678664e+06, 7.479057929608060924e+06, 9.370225698693408867e+06, 1.177824230977510661e+07, 1.485459301432580619e+07, 1.879809270383398104e+07, 2.387057334436346400e+07, 3.041806552258603202e+07, 3.889950046843262151e+07, 4.992574374586696017e+07, 6.431287504495613210e+07, 8.315518519925858136e+07, 1.079255664704117961e+08, 1.406141073390035115e+08, 1.839201785677305607e+08, 2.415197116904975365e+08, 3.184386015381112281e+08, 4.215765018929686736e+08, 5.604446356915114550e+08, 7.482094398046911572e+08, 1.003175129668246151e+09, 1.350898918997482870e+09, 1.827222165053491590e+09, 2.482633480831760933e+09, 3.388577637234919719e+09, 4.646620065299105644e+09, 6.401821801566297122e+09, 8.862352038053251473e+09, 1.232838602859196811e+10, 1.723489297480180023e+10, 2.421530528469447376e+10, 3.419673813208063025e+10, 4.854312364622606540e+10, 6.927149043760342676e+10, 9.938049490186203616e+10, 1.433521424759854145e+11, 2.079221734483088227e+11, 3.032695241820108158e+11, 4.448631503727710431e+11, 6.563458646477901051e+11, 9.740635696398910980e+11, 1.454220520059656158e+12, 2.184250688898627320e+12, 3.300999104757560757e+12, 5.019970485022749012e+12, 7.682676299017607834e+12, 1.183376596003983872e+13, 1.834748853557035315e+13, 2.863639312458363586e+13, 4.499803892715039958e+13, 7.119486876989154498e+13, 1.134307017980122346e+14, 1.820065782363618395e+14, 2.941484500615394037e+14, 4.788707305890930382e+14, 7.854025036928623551e+14, 1.297894304619860251e+15, 2.161279954782425640e+15, 3.627102147035003834e+15, 6.135342933440950378e+15, 1.046170006362244506e+16, 1.798477357839665686e+16, 3.117473412332331475e+16, 5.449445073049184222e+16, 9.607515505017978212e+16, 1.708589224452677852e+17, 3.065429751110228665e+17, 5.549227437451149511e+17, 1.013730232778046314e+18, 1.869059895876405824e+18, 3.478549552381578424e+18, 6.535992245975463763e+18, 1.240019272261066308e+19, 2.375828866910936629e+19, 4.597682433604432625e+19, 8.988106816837128428e+19, 1.775302379393632263e+20, 3.543413304390973486e+20, 7.148061397675525327e+20, 1.457620510577186305e+21, 3.005137124879829797e+21, 6.265024861633250697e+21, 1.320979941090283816e+22, 2.817487535902146221e+22, 6.079933041429805231e+22, 1.327658853647212083e+23, 2.934311759183641318e+23, 6.565087216807130026e+23, 1.487212273437937650e+24, 3.411840196076788128e+24, 7.928189928797018762e+24, 1.866451877029704857e+25, 4.452521859886739549e+25, 1.076545435174977662e+26, 2.638685681190697586e+26, 6.557908470244186498e+26, 1.652952243735585721e+27, 4.226383395914916199e+27, 1.096450394268080148e+28, 2.886822082999286080e+28, 7.715480389344015925e+28, 2.093728789309964846e+29, 5.770275789447655037e+29, 1.615463845391781140e+30, 4.595470055795608691e+30, 1.328629392686523255e+31, 3.905079681530784219e+31, 1.167134024271997252e+32, 3.548058538654277403e+32, 1.097378059358046160e+33, 3.454102978064445595e+33, 1.106745393701652323e+34, 3.610899559139069994e+34, 1.199946999283670567e+35, 4.062687014190878792e+35, 1.401835223893224514e+36, 4.931085527333162173e+36, 1.768812393284919500e+37, 6.472148293945199961e+37, 2.416453721739211922e+38, 9.208944720398123862e+38, 3.583297028622126676e+39, 1.424097482596699440e+40, 5.782627833426411524e+40, 2.399862204084363183e+41, 1.018291572042305460e+42, 4.419105414822034531e+42, 1.962126117680499311e+43, 8.916742424061253707e+43, 4.148882478294757720e+44, 1.977256529558276930e+45, 9.655300233875401080e+45, 4.832878898335598922e+46, 2.480575878223098058e+47, 1.306102809757654706e+48, 7.057565717289569232e+48, 3.915276522229618618e+49, 2.230898980943393318e+50, 1.306141334496309306e+51, 7.861021286656392627e+51, 4.865583758538451107e+52, 3.098487425915704674e+53, 2.031037614862563901e+54, 1.370999647608260200e+55, 9.534736274325001528e+55, 6.834959923166415407e+56, 5.052733546324789020e+57, 3.853810997282159979e+58, 3.034183107853208298e+59, 2.467161926009838899e+60, 2.072901039813580593e+61, 1.800563980579615383e+62, 1.617764027895344257e+63, 1.504283028250688329e+64, 1.448393206525427172e+65, 1.444855510980115799e+66, 1.494120428855029243e+67, 1.602566566107015722e+68, 1.783880504153942988e+69, 2.061999240572760738e+70, 2.476521794698572715e+71, 3.092349914153497358e+72, 4.016927238305985810e+73, 5.431607545226497387e+74, 7.650086824042822759e+75, 1.123017984114349288e+77, 1.719382952966052004e+78, 2.747335718690686674e+79, 4.584545010557684123e+80, 7.995082041539250252e+81, 1.458119909365899044e+83, 2.783001178679600175e+84, 5.562812231966194628e+85, 1.165338768982404578e+87, 2.560399126432838224e+88, 5.904549641859098192e+89, 1.430278474749838710e+91, 3.642046122956932563e+92, 9.756698571206402300e+93, 2.751946044275883051e+95, 8.179164793643197279e+96, 2.563704735086825890e+98, 8.481656496128255880e+99, 2.964260254403981007e+101, 1.095342970031208886e+103, 4.283148547584870628e+104, 1.773954352944319744e+106, 7.788991081894224760e+107, 3.628931721056821352e+109, 1.795729272516020592e+111, 9.446685151482835339e+112, 5.288263179614488101e+114, 3.153311236741401362e+116, 2.004807079683827669e+118, 1.360407192665237716e+120, 9.862825609807810517e+121, 7.647551788591128099e+123, 6.348802224871730088e+125, 5.649062361980019098e+127, 5.393248003523784781e+129, 5.530897191915703916e+131, 6.099598644640894333e+133, 7.242098433491964504e+135, 9.268083053637375570e+137, 1.279942702416040582e+140, 1.909796626960621302e+142, 3.082540300669885040e+144, 5.388809732384179657e+146, 1.021610251056626535e+149, 2.103005440072790650e+151, 4.706753990348725570e+153, 1.146834128125248991e+156, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -6.164062500000000000; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#if LDBL_MAX_EXP == 16384 +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 1.02756529896290544244959196973059583e-2497L, 2.56737528671961581475200468317128232e-919L, 1.17417808941462434184174780056564573e-338L, 4.82182886130634548471358754377036370e-125L, 1.85613301660646818149136526457281019e-46L, 1.52174118093087534300657777272732001e-17L, 6.75122240537294392532710530940672267e-07L, 5.94481311616464419075825632567494453e-03L, 2.00100938779037997581424620542543429e-01L, 1.17328605653712546899681147538372171e+00L, 8.18356490677287285512063117929807241e+00L, 5.59865842621965368881982340891928481e+02L, 3.69902944883650290371636082450503730e+07L, 4.05747121124517088709477132072461878e+20L, 1.07723884748977308147226626407207905e+56L, 2.07250561337258237728923403163755392e+152L, 1.09889904624000153879292638133263171e+414L, 3.02463014753652876878705286965250144e+1125L, }, + { 3.16339947894004847541521297710937343e-1515L, 7.02786763812753004271170107158747593e-558L, 1.08465499866859733494552744914276656e-205L, 3.97220624097731753646493300738183748e-76L, 1.84145280968701148636501796762008815e-28L, 6.40886341101610144938011594904313817e-11L, 1.89200275395722467663251234615351291e-04L, 5.04892743776943294143478969573235061e-02L, 5.25946553709738448524487603870477588e-01L, 2.72635049439566736308739858009584752e+00L, 4.20081657572145199006060015525396829e+01L, 3.75221714819472331206969009243353365e+04L, 3.11642465424592079726559332629050577e+12L, 9.61947229245436139236957297153092319e+33L, 2.42007357898805628851519620917402234e+92L, 1.34351470989086331111432001407522043e+251L, 4.34937560839564995558174638985438726e+682L, 4.01820305474077838467315109614612109e+1855L, }, + { 2.20630426387562582340901270736066292e-1945L, 3.20902289525796097195876526710905754e-1180L, 3.99075419312896749376535004306952481e-716L, 1.22680463935505388461578092999320797e-434L, 6.60416836081631149205027836695167940e-264L, 2.36380363265905808053031227647927829e-160L, 1.52216180146092756550894692311532796e-97L, 1.89865679919908959317123677189779258e-59L, 2.43020115474101871630434504433731237e-36L, 2.52466874690605714759066961852641028e-22L, 8.05169965363444223580324196979926112e-14L, 1.16754399126294292055540155961164512e-08L, 1.59887725419859990767684898940272339e-05L, 1.30653650105064376247657363109776765e-03L, 1.96025435814529675467866513121889090e-02L, 1.07798510399525035644857486110150806e-01L, 3.35726506001932774135392168623644982e-01L, 7.91344191300036661743190713036639943e-01L, 1.75712551051579342077493249233109834e+00L, 4.50532922519182663928094313196688277e+00L, 1.69634912879730950991827009814964854e+01L, 1.31564914034011933527149556208430823e+02L, 3.54551665937177335700906931219692079e+03L, 7.69629182688413474235641078406238234e+05L, 5.31334781541946297455601223275400364e+09L, 1.11397125403497802554344014693570895e+16L, 2.91323342059626628322620905024841007e+26L, 4.33470414741675827465254900104887599e+43L, 8.87077939346041258291094819287939414e+71L, 4.20552510572288598564618972079522209e+118L, 3.78998758665619810759092788424597102e+195L, 2.85285821381079277498378752581228807e+322L, 4.35767992687500025738868152293904617e+531L, 3.35101732969916400190150631384628168e+876L, 1.39907636805339624393396738787997778e+1445L, 4.39310839133852761600954729262867435e+2382L, }, + { 2.60416027838200926634868701489352534e-2204L, 7.02786036162213986704884019362612079e-1717L, 2.87472449554862557122883045361480216e-1337L, 1.26052689335617094297502885256721406e-1041L, 2.22203737723769125613395083355625930e-811L, 4.59925691253299141912321586723335574e-632L, 2.06110387430222811031505778840893135e-492L, 1.18783333719310840737835079091916047e-383L, 5.99339963191580129696690680497340117e-299L, 5.55156577871295836646608994333019205e-233L, 1.31650343182343962237291034126486362e-181L, 1.35017224106781623208439493207058713e-141L, 1.95458267270042896122641878745090637e-110L, 3.62345406499123808121116200173051239e-86L, 2.87916036185197771976746396107338099e-67L, 1.50975853574758038650941626753584613e-52L, 4.39366381209590686916061999351406334e-41L, 3.72613279781933265810269222029431206e-32L, 3.35074541708050784063416140930256908e-25L, 8.73699691100611067810340427391712629e-20L, 1.44610938754441658588026566732900630e-15L, 2.79712542830915646153531586097835651e-12L, 1.01712318476608889609455916646557919e-09L, 1.00707686902351812525332969334486408e-07L, 3.62377064535647765957086044101238700e-06L, 5.93514765312557852887858990273347709e-05L, 5.27427922038425038994892508697801291e-04L, 2.91716284057748187538183216214780172e-03L, 1.11812753052373081344852811278990196e-02L, 3.23158910999791296389217134204252891e-02L, 7.52823576293971217140453145701166400e-02L, 1.49072381771447883955117212578891471e-01L, 2.61920116954195648982059938116700281e-01L, 4.23044722849733503488984642521144095e-01L, 6.47337815325830827783598163922905049e-01L, 9.63850663681748439752705317539095691e-01L, 1.43180513983798487645924505146418541e+00L, 2.17546288127550398262362304432746644e+00L, 3.47077553215380191942193887548951574e+00L, 5.98762125926090985873603940556086485e+00L, 1.15588346593765285104362265791852722e+01L, 2.60227165873113109321939526707132515e+01L, 7.18972764924010846908346544069757730e+01L, 2.59849827899514040038730358528910272e+02L, 1.33180383652908565595482681440747426e+03L, 1.07264199927746293597346233164919561e+04L, 1.54770252854197591129695964624494039e+05L, 4.73116974059692035499030617203501902e+06L, 3.79850299532978550624970142683299187e+08L, 1.05506900281875210383901752883017567e+11L, 1.44377693764054834189876938092028936e+14L, 1.53216987231286586179401429003390945e+18L, 2.25749845424265693444972830430363021e+23L, 9.75366126404791278425650801377275643e+29L, 3.22710662318561074542283240061745423e+38L, 2.80427989450823486864584373674252213e+49L, 3.11492865697270427645920832671970699e+63L, 3.37385880956075754428852062324609716e+81L, 4.84069913749095116306098688426537434e+104L, 2.62206965911556490036221731139595538e+134L, 3.95724512624896651389226023882699109e+172L, 4.16658233419696139622872515762144259e+221L, 3.67870997815873300310505495683155714e+284L, 2.45353561048417937411865685638919263e+365L, 1.47890836767899626666102902312593029e+469L, 2.66842264577698782467085710268227542e+602L, 3.39406520823137428862537121090858482e+773L, 1.71072929388916771882465310676448508e+993L, 2.17124413154098944294625847065193945e+1275L, 3.67108839134079465802181460380664133e+1637L, 4.72992162468569560939225829187204387e+2102L, }, + { 1.98007625288857013412122004727810624e-2346L, 8.39652992194258659266745309526472882e-2071L, 1.46030671151231956105710426802408027e-1827L, 6.65727248909208458885310717390128801e-1613L, 1.81581117219394388092797723844111009e-1423L, 2.72619674739250219990613941747932927e-1256L, 9.29590026994488020433315206443278096e-1109L, 1.46377917106366800430984793284730939e-978L, 1.15901956513202291149840314964756250e-863L, 2.89578802021929239619753606490350524e-762L, 8.80858736107764685086031513644364894e-673L, 8.19416690740938676449696497280686335e-594L, 4.00916745706227520865721440095991259e-524L, 1.27020033549323657895766092175564312e-462L, 2.38869695900235565316537719061693975e-408L, 1.88391475973801739487501436111488490e-360L, 3.49894275509125434733587030489899389e-318L, 7.01615886164307390146523314851863544e-281L, 5.82310443050787035609701710903434681e-248L, 6.54836166711216765944679142249433382e-219L, 2.84149263299034989667159925017962142e-193L, 1.19812648186130338854458247959762818e-170L, 1.10911490518050678588403791608480488e-150L, 4.62754597695358582538782054737574180e-133L, 1.64173210211161942076907089038989838e-117L, 8.67192889174269982709959745767681981e-104L, 1.11812225550444523531457194417899189e-91L, 5.44369950217028498211921027217139012e-81L, 1.47074883585505403248443957516006445e-71L, 3.09730398495823549037183157408809652e-63L, 6.86204181060118439675162432029019608e-56L, 2.08386500906124109876681630886775453e-49L, 1.09560045982532469724721792988430545e-43L, 1.22547627904244500951228300724497066e-38L, 3.49796660995417261286766404577301528e-34L, 2.99152410870631960427539566799345990e-30L, 8.83190101026086766963628794276374683e-27L, 1.01998228741819737621697177531967545e-23L, 5.14543767526486873178240241354085638e-21L, 1.24976972746216000788747786633668576e-18L, 1.59270820536117731616569419326771375e-16L, 1.14889208313232540746001768184091876e-14L, 5.01568630936388404881919116817433643e-13L, 1.40588174426346693556351457090253957e-11L, 2.66552656620728447371725338328298653e-10L, 3.57952342849715748848195322266581664e-09L, 3.54587967892367612935335788099896843e-08L, 2.68571894340447967655761437829800783e-07L, 1.60543396069231405992036918112042239e-06L, 7.78876789102767893920047052886009844e-06L, 3.14354940320849664611373818938001854e-05L, 1.07876626606295756489869617036039985e-04L, 3.20898851002890606916875803454736038e-04L, 8.41685517064122028463642895198591848e-04L, 1.97617054782608049591289962378898411e-03L, 4.20911897696440311235672067499450921e-03L, 8.22976828962407304914730770011736102e-03L, 1.49268961502975158975071505963565168e-02L, 2.53502658698472066372315325797964553e-02L, 4.06466974195663810865864410951160977e-02L, 6.19877276359776967830177840166714717e-02L, 9.05089155125712182450563511209635860e-02L, 1.27278213682114666289711516555196299e-01L, 1.73304699976842406023992088378438619e-01L, 2.29592410233034978491448000870038137e-01L, 2.97239599113018852567831136709176961e-01L, 3.77582948042641879160927817217899876e-01L, 4.72389555885863401785327685882008067e-01L, 5.84107138056041651067826639644019633e-01L, 7.16195243265456514286143145222900703e-01L, 8.73579162273458922635006193850777630e-01L, 1.06329740288293038148703202109279326e+00L, 1.29546076177954953883340629341283024e+00L, 1.58472055402981935372999954552668421e+00L, 1.95258275532953319986830507945836181e+00L, 2.43115638685977475925559253395572515e+00L, 3.06939317426312452000366876337463330e+00L, 3.94377618122435031881432297693345182e+00L, 5.17720373327574287465684980172077361e+00L, 6.97349551419502029130075958419090062e+00L, 9.68282046752329620408323930717367162e+00L, 1.39309131038991828857956159913232231e+01L, 2.08859990746605884557374483895633501e+01L, 3.28382897425881117409618357674054401e+01L, 5.45293246810142904942496502744410196e+01L, 9.63939781365248203122153852027923369e+01L, 1.83025185098871555179881958564576181e+02L, 3.77024517378370245776498953575447428e+02L, 8.52190226688445340278025693774183776e+02L, 2.14068512989192644263700461005007744e+03L, 6.06284853067739175777069687971114492e+03L, 1.96780457938951378915777196082473423e+04L, 7.45535092385462432927423608234859698e+04L, 3.36655497164547806089503954112397178e+05L, 1.85514609429466771541276069582993197e+06L, 1.28127256599195512602695379572162760e+07L, 1.14315867886785361488804976072737382e+08L, 1.36346329402339162906880444623714674e+09L, 2.25993073791019766670398383679728111e+10L, 5.43926612995997228479509745730508310e+11L, 1.99798484325959673290782033498623904e+13L, 1.18504970239150114123104110601445669e+15L, 1.20980370818215194207683618902723859e+17L, 2.28537992087984292439473774950290832e+19L, 8.67120977340450400779923403171032446e+21L, 7.25153649943518021867879355500893988e+24L, 1.48501435335333039333736586197814469e+28L, 8.39050326550867736343407650659898774e+31L, 1.49728470198356221256669260283197052e+36L, 9.83549601762784922530731490296260394e+40L, 2.82901352112032614706131527899887976e+46L, 4.33736659101971830974347248793299740e+52L, 4.42940467871587853569566546424045697e+59L, 3.87840248690238104186373399976301795e+67L, 3.87622435037312042010986878431609700e+76L, 6.11530088968567983241864570883470440e+86L, 2.19902986720444927672673080107769693e+98L, 2.73302501743809592753235404592828204e+111L, 1.88157705379416554346750034182897643e+126L, 1.22464500548199778033960287699262627e+143L, 1.38089682931886763280665214047107116e+162L, 5.35861724121451785967201429765672158e+183L, 1.55758090841089261682638940540906561e+208L, 8.18640878839858943416304034752205938e+235L, 2.11193471456685131226350980039759737e+267L, 8.29196100559631320106113784120111420e+302L, 1.78609329205356222554295903766141624e+343L, 9.02504022060557635111807879176244000e+388L, 5.55060710318615757165502584223064764e+440L, 2.68431690505806342057709029465018309e+499L, 8.45412788268345327632392585778624037e+565L, 1.90297947362180093404817251840979577e+641L, 4.62215189323912708971592873336189679e+726L, 2.62533210543270812917133055827838787e+823L, 1.13817822812561602537416032879617414e+933L, 1.95538622136936887385682087493096654e+1057L, 1.16937064578842112561072532780020718e+1198L, 3.88035117517281013054730623266703196e+1357L, 2.23743584154220985565150075331030128e+1538L, 1.50889533002797316376499137963913497e+1743L, 1.90641621776286179122749804749534564e+1975L, 1.93080249271305970633007359089743998e+2238L, }, + { 6.85586909881832886951451464772591878e-2421L, 2.92677267243682665120741515792112744e-2274L, 1.63242588944068781532732923861018809e-2136L, 4.10812064897186984969866413043968829e-2007L, 1.49435786878493820312929790405374745e-1885L, 2.34568268208591413691385316271709680e-1771L, 4.43925157300673395426635808699168955e-1664L, 2.65927633627471464278071651186161190e-1563L, 1.24859182507079754991269604284796564e-1468L, 1.07699173095552638424762549404812646e-1379L, 3.79889818022139862967145673157136925e-1296L, 1.16203657951916401289541501876509754e-1217L, 6.24572482158628957114104388658639197e-1144L, 1.14511680730607058597658427712436799e-1074L, 1.33557521045192075572641149916774170e-1009L, 1.77946124922921650079213398130306155e-948L, 4.69414096094237830969243170096712625e-891L, 4.11003931775404922019148615555751563e-837L, 1.94061218235885716000492708678051285e-786L, 7.79551077888128366830436599420622304e-739L, 4.08861993672760936738017704029701813e-694L, 4.18676490857955209780618740974196173e-652L, 1.22153592554301240722464717581112377e-612L, 1.44833892014264382948310395651753089e-575L, 9.74176764355703592877272264974985856e-541L, 5.08509650174353124708754662233746797e-508L, 2.76502760440391058924306176438285126e-477L, 2.06508450540542778211999232986493505e-448L, 2.74686348165461297466693117700925333e-421L, 8.30585680824802634886342521419101161e-396L, 7.18035163161661527310024383149797653e-372L, 2.20117367274887299835421816737413275e-349L, 2.92938701204713835430829657327314622e-328L, 2.04670856065666661814970623236244653e-308L, 8.97499107305077146284125789528155163e-290L, 2.92115595376553501154165826580135083e-272L, 8.26130614121671756652659688034185753e-256L, 2.35396777618554392325312768878283221e-240L, 7.76604519643439440768615254501273896e-226L, 3.38047616528897968517094694597452046e-212L, 2.19496817732884969215875687943120973e-199L, 2.38570033705332693932010529683394408e-187L, 4.83696042571616203283798802745975902e-176L, 2.02525789452808699182428060822541636e-165L, 1.92683544261267768613934270120773225e-155L, 4.55675928208753416426295293555087690e-146L, 2.91435926363522943509016642164959990e-137L, 5.45650834446039875776911937813876647e-129L, 3.22177915240208624055473617062236208e-121L, 6.43356918992122712617506763079342635e-114L, 4.63991207894245637238928734792612888e-107L, 1.28548526430585878202588260968441525e-100L, 1.44976784442529508497784801483631129e-94L, 7.02834477739882506904444529125607921e-89L, 1.54151343887499654318252629091310298e-83L, 1.60491367376894945627919582278915480e-78L, 8.29797555416253956153582009155421152e-74L, 2.22293580147262466985937857298017334e-69L, 3.21083741325090217758867273653191446e-65L, 2.59597447976318059491815288096285983e-61L, 1.21686551839843562559756380386148224e-57L, 3.41813412178077321753808876760492064e-54L, 5.93492497756373178397326564626159285e-51L, 6.55812810449229009165849681654564859e-48L, 4.73996462182817624913218344729897191e-45L, 2.29917713906026251753218108658989939e-42L, 7.66772810214285848709307613966489982e-40L, 1.79852699731596078211094021208953882e-37L, 3.03099351897543871174212829426305144e-35L, 3.74430827279655104510043134133803179e-33L, 3.45501893639921538125092697393537600e-31L, 2.42381852080187080923760278831274486e-29L, 1.31441976082623542058289755424927250e-27L, 5.59666006060409162050973561377317535e-26L, 1.89867556602582040862526655529336748e-24L, 5.20331508297836691753631952262461629e-23L, 1.16690464600934423260878649807673403e-21L, 2.16767714527916659623320357151600374e-20L, 3.37377643107659326572426331386135943e-19L, 4.44691383264786489190950322799097537e-18L, 5.01415830137739970673756811085508269e-17L, 4.88253693365386298188724591254681515e-16L, 4.14251016844320187955159569890123671e-15L, 3.08802476085892421415530065712870862e-14L, 2.03847832924953919920668690856932749e-13L, 1.20044498484990029827708442066317039e-12L, 6.35035779339988133329469515026722103e-12L, 3.03739182163512379493334464659410947e-11L, 1.32161843156591616383150953292325245e-10L, 5.26149741865431306798513845101472462e-10L, 1.92688222163920338777595529204662553e-09L, 6.52448684765263503483691364064710302e-09L, 2.05235608001812174069568432464532832e-08L, 6.02447248155606588490206026101601127e-08L, 1.65719156589179965185098196474263403e-07L, 4.28875221376115411615543853081272079e-07L, 1.04811127032430288440405169279023586e-06L, 2.42727195841237101271799656914039580e-06L, 5.34428013249275030874689017597357100e-06L, 1.12217116002251908227007056847369186e-05L, 2.25365270095215311537786875281660527e-05L, 4.34066412230525728790156860647261934e-05L, 8.03857428545025320920443714330221510e-05L, 1.43483273166998782632422720673552674e-04L, 2.47403670532944916561679376448099333e-04L, 4.12969671314554699465069528559056198e-04L, 6.68662248079464048176726608426967422e-04L, 1.05217959874444039957269021715673554e-03L, 1.61189482479878719591766861379534126e-03L, 2.40808122992764072147410965445120710e-03L, 3.51377854902820551940988678116833582e-03L, 5.01519359256763066459806052313013320e-03L, 7.01156300574609092374647377614547795e-03L, 9.61445020754398604050247376189537687e-03L, 1.29464977958074216006936641439568225e-02L, 1.71397050059386052582575161031849539e-02L, 2.23333418628568405596661137294311321e-02L, 2.86716433323270031012958633821643459e-02L, 3.63014455768061096476987670693482715e-02L, 4.53699316668876641396409342510559075e-02L, 5.60226467568397916052157799832294784e-02L, 6.84019250622201277408275217514564750e-02L, 8.26458460699460598611997466316916292e-02L, 9.88878087044773835985179298425629188e-02L, 1.17256783027063660721874825783310801e-01L, 1.37878272417301116163817842123251189e-01L, 1.60875997439806117261603052596128705e-01L, 1.86374297424717578638710069246872277e-01L, 2.14501238238148719030968730766268227e-01L, 2.45392415301662505713896222647369518e-01L, 2.79195449773929877272191161144448290e-01L, 3.16075192872379294294649481827620946e-01L, 3.56219678521249637323233310278349444e-01L, 3.99846897980088704601361036413251085e-01L, 4.47212512313163107391085998119621599e-01L, 4.98618670533294760818150011647972671e-01L, 5.54424164764947975414033158173924804e-01L, 6.15056231563286401803829984090534551e-01L, 6.81024404595688995229840589926798114e-01L, 7.52936943869155645889792590166619714e-01L, 8.31520518350208659550187071679434118e-01L, 9.17644012826577357641491486976575868e-01L, 1.01234758075340210126152790231895045e+00L, 1.11687839251578850642753265260268328e+00L, 1.23273496036260391788838218839806886e+00L, 1.36172249498191084612564077792923468e+00L, 1.50602251678823434544288956361434194e+00L, 1.66828098096960364511379075299209308e+00L, 1.85172058286684745279366828495999051e+00L, 2.06028483669890596285992438994232879e+00L, 2.29882417717996662881312374953444179e+00L, 2.57333802530471722160283306099247239e+00L, 2.89129193110240878387703249643229033e+00L, 3.26203621106764094357461881213752464e+00L, 3.69736290590815315504600654149629845e+00L, 4.21225284743951568672550404261498190e+00L, 4.82588633844219080687269426289849605e+00L, 5.56302277261292337309431040275971592e+00L, 6.45590163750149736955774273721315509e+00L, 7.54688784770818103174495320257408374e+00L, 8.89219103984228343085851433153285412e+00L, 1.05671517790393183669301386672470668e+01L, 1.26738407015152894733455767759949041e+01L, 1.53521137941817792315134763759132043e+01L, 1.87958986899048219790124225448671683e+01L, 2.32775055780405432294765542807163514e+01L, 2.91844233861930596156964126095351325e+01L, 3.70758319218904582325116346962442845e+01L, 4.77707378224399722392124081823831658e+01L, 6.24876734446863447811669818713989778e+01L, 8.30699342763174311126855611293197423e+01L, 1.12355321585737491915090874360361047e+02L, 1.54794728437631233369474093491065001e+02L, 2.17507985417556811263254275570301936e+02L, 3.12124586781855603508049115425717265e+02L, 4.58065302025763509177549206574829939e+02L, 6.88532496785780240326739257222869086e+02L, 1.06172181511411400423407908864360706e+03L, 1.68236894049421021674529061389284712e+03L, 2.74433484749143274695935635590635551e+03L, 4.61730673523479769409382001763470205e+03L, 8.02895513401715463422140861600391503e+03L, 1.44606187348593941052176609549649644e+04L, 2.70377620144727936743806059397776390e+04L, 5.26105241201059109738487092327866872e+04L, 1.06812531849740275922510876100737843e+05L, 2.26893075168541256271862004134549591e+05L, 5.05764404902608855969935895677933433e+05L, 1.18676186494579079987238943033223000e+06L, 2.94113264423683227561198247386975731e+06L, 7.72576514719998793452586494715302612e+06L, 2.15915178528480833880909472948132169e+07L, 6.44590226372788402030541979463995492e+07L, 2.06442545099697944602613003602586209e+08L, 7.12532948492900300739824830002676479e+08L, 2.66319659068655507734050368458244708e+09L, 1.08350636970002739580921292680640244e+10L, 4.82470799147337538737281851702596161e+10L, 2.36513804063572720852686335350104312e+11L, 1.28435637164102683934687705650167990e+12L, 7.77731246565628041938451985303773831e+12L, 5.28864903733985311795604320721713645e+13L, 4.06896744489041480369429188279659070e+14L, 3.57034809188328432417142254050169691e+15L, 3.60337498222976618360402297528737217e+16L, 4.22089025190487061069708630018503728e+17L, 5.79389086782171589014524617169039021e+18L, 9.41571436923218772663826142877596428e+19L, 1.83140546580432476725446560201754697e+21L, 4.31320926121717399384742067577025671e+22L, 1.24526713689819970862562132007699682e+24L, 4.46557396336452476527850690333252885e+25L, 2.01706317120607297931541128182425236e+27L, 1.16481109175988266234418168600383172e+29L, 8.73712441785116756599086490733480008e+30L, 8.65736270143027267976956887405444609e+32L, 1.15373549848396029384279199583578574e+35L, 2.10781669532016374773265262680619511e+37L, 5.38769637251502198497400987247791395e+39L, 1.96890474908610530032963280794536401e+42L, 1.05271764511336947295087542840771762e+45L, 8.43965629752558882239469624058575644e+47L, 1.04138369598852386365061187570128647e+51L, 2.03352356915167672502196854739506820e+54L, 6.47289125189110545523503523387311437e+57L, 3.46613548082834986367032599943319188e+61L, 3.22894792541599068853355143560944151e+65L, 5.42318759743953119742239523201238475e+69L, 1.70583228507675596981951702618714711e+74L, 1.04635953488687800354356406620895146e+79L, 1.30676249978604401490579288070545190e+84L, 3.47855004888451734894061507389280036e+89L, 2.07245356750112312931588098931095741e+95L, 2.91086857580213998298216107061151403e+101L, 1.01866939773917036897104863230086276e+108L, 9.42079727758602983661368103980660631e+114L, 2.45135270885215193905442997104007131e+122L, 1.91850621913423378510904034515156001e+130L, 4.84846348541576375648253727961523398e+138L, 4.26738728648259195430121429627940133e+147L, 1.41771213016857192102291892633345650e+157L, 1.93681124067818946208050336019146634e+167L, 1.19196764675833722929285298195873591e+178L, 3.64148488428297947856471515841164734e+189L, 6.12360784372861046853690882962104289e+201L, 6.32737167744109620998113270972893770e+214L, 4.51626866922887039378811138276232919e+228L, 2.52237535488279323839235752907864107e+243L, 1.25874430868722260548214869831621228e+259L, 6.46403890833514736730418683378673138e+275L, 3.97014109807165189460577113122885913e+293L, 3.42256445909004961984480518463414679e+312L, 4.91057220648194827953651882481242793e+332L, 1.40575745439889948649867992022706415e+354L, 9.73933590848593290516589462953654487e+376L, 2.00557619166308496177559022371882184e+401L, 1.52772859099735075822031580257311058e+427L, 5.43355654783039835976501066730115367e+454L, 1.15613726424969615026074606149058824e+484L, 1.91611396577413915548297095470351353e+515L, 3.27574835998524173295312535664414153e+548L, 7.78995993645646383749425447261756829e+583L, 3.54265432942533120234904548837850071e+621L, 4.32354359483087940297488323505450874e+661L, 2.03098786518797659659581103998046513e+704L, 5.39103916237599207670086450736143491e+749L, 1.21683151125684538902217928380735342e+798L, 3.60847574304211696962789044183995856e+849L, 2.23398800758266399217702784712099052e+904L, 4.72717380839903008268507408818545095e+962L, 5.77822208457179232925131147188581785e+1024L, 7.13289562956799416571309267253574621e+1090L, 1.61164858402955200792510210236524128e+1161L, 1.25521313739368945437360950048953572e+1236L, 6.61069623781251502357557332678377193e+1315L, 4.82362056335119095907952363185253207e+1400L, 1.04640496911016000942284610597050358e+1491L, 1.52131212817898241350510416765362487e+1587L, 3.52116090648535956154142297718505774e+1689L, 3.25907088535366768900129651211398670e+1798L, 3.21536840347133363006114569121938775e+1914L, 9.60165908424805663006527683476758652e+2037L, 2.63585872900260288034767508588870333e+2169L, 2.17048793513302111330851937361254536e+2309L, 1.88788443108195661060841368444711468e+2458L, }, + { 5.29693440729788041213142409892436291e-2459L, 2.27629257218329628557497350447858260e-2383L, 4.60725896612142987241524079465629916e-2310L, 5.17919364499500847985920034617781519e-2239L, 3.79383002964804382517930061580447157e-2170L, 2.11419993680434447426181517759297327e-2103L, 1.04148667561061807899012277964691785e-2038L, 5.24544425651958823988931435014729457e-1976L, 3.11006352777614281598465337503705373e-1915L, 2.48867462987012194623347147546568943e-1856L, 3.06835915872226280445223729961288427e-1799L, 6.62736493446143254705278263772087543e-1744L, 2.83997245953224047644578590378179268e-1690L, 2.72398780252406063855606534842103674e-1638L, 6.57327304158814917854156231336457877e-1588L, 4.46940189941144606938097964305720201e-1539L, 9.55652954181188776027715447963783638e-1492L, 7.14757266175076046071660887379600587e-1446L, 2.07313155515958333906901076011055929e-1401L, 2.57708633795358827890276221215294553e-1358L, 1.51269996990649935807792458579987758e-1316L, 4.60565435951356389119181468428252427e-1276L, 7.96677448800758121662225971905999717e-1237L, 8.55160853918795880988712436880140365e-1199L, 6.20482659749393290517542190337401836e-1162L, 3.30618935612498022733666989541183557e-1126L, 1.40195518332652973622801089378870590e-1091L, 5.11407919863367919558746085806786902e-1058L, 1.73063614614270605229830917360912415e-1025L, 5.84546019976429168954160400076820148e-994L, 2.11542888104356332114006186983662541e-963L, 8.78597020474401601699260325757052372e-934L, 4.47629976797445775500570938357786257e-905L, 2.98416839309444731431172458639558207e-877L, 2.77125321384854968458662765004085943e-850L, 3.80904190342493701536240175462301111e-824L, 8.21806462726393678491860107910281889e-799L, 2.94631935053803405188027155144659836e-774L, 1.85492994927395428856242032790235018e-750L, 2.16349445690590806097153640474491227e-727L, 4.92371233300030441739039250387920817e-705L, 2.29918059518632617935997695502963251e-683L, 2.31291758268743951509849171359112934e-662L, 5.25491742744220732604319355531444736e-642L, 2.82274223509188430651059911113688649e-622L, 3.74753227935082714244593814667510926e-603L, 1.28370364951438380618871579660566498e-584L, 1.18285412035024318029749091456416413e-566L, 3.05273754301598829645261576934311186e-549L, 2.29479910590203595225694928967822608e-532L, 5.21889625493118727969519850005753886e-516L, 3.72534255592436984201074827726301397e-500L, 8.64949198440528351465957047285602117e-485L, 6.76174414760667924982941341637985863e-470L, 1.84041518883114740241388396417281333e-455L, 1.80160472793323877219953443455302799e-441L, 6.54566528304067135832221898507534820e-428L, 9.10001699811829840956092860906810074e-415L, 4.98609828016939856686029944862830983e-402L, 1.10802830298400645391731986287163178e-389L, 1.02676405187821370308474571067658508e-377L, 4.07575091116228204031238856923140440e-366L, 7.11360268352693191010849541271753635e-355L, 5.59881168833151588006581688986986730e-344L, 2.03642255515559150564975951817039221e-333L, 3.50525657096789033370540964985470150e-323L, 2.92178573100086478331989127444273654e-313L, 1.20598734041934315977832234578459915e-303L, 2.51880216671823764300316483881856209e-294L, 2.71834421831894383133482530254389304e-285L, 1.54702039109098756507051056035620614e-276L, 4.73499485141563990358940703275480353e-268L, 7.94442519500188390796900278354012024e-260L, 7.44316376023327816606172273381802393e-252L, 3.96451700998508534828226048217863900e-244L, 1.22153684948784264379851755556819940e-236L, 2.21421725154084964507841507830563690e-229L, 2.40004857648572823842789487119416272e-222L, 1.58043505420313498164518700461984906e-215L, 6.42021223167302856767365812271085781e-209L, 1.63302423264111059580848381300534588e-202L, 2.63853106939137106330498547542524566e-196L, 2.74613250302397818664806479526069745e-190L, 1.86615306707995508392565990157579707e-184L, 8.38948945233194510175234920774873796e-179L, 2.52701050376399124391991347402621144e-173L, 5.16312575535157598596140018726440984e-168L, 7.24167062135448326922272784801743108e-163L, 7.05361814094865509813912299190351845e-158L, 4.82507740170943565549056875354725391e-153L, 2.34335421855805662819938218222415100e-148L, 8.16563163629951985655858859925168146e-144L, 2.06250908768935143871108361256064164e-139L, 3.81378121105029755974979453855090030e-135L, 5.21238862833226048821040688112783913e-131L, 5.31469066325781546457465599778122553e-127L, 4.07938032086884338695136986806703742e-123L, 2.37782434978024084372113156401306143e-119L, 1.06148128500673821430527965352560854e-115L, 3.65894930935314933069457000324241470e-112L, 9.81672760779301769095882197030988958e-109L, 2.06581729538829312212171371616525011e-105L, 3.43540071960972258090881112115251093e-102L, 4.54745983632894201410075262868047927e-99L, 4.82519857468149557373657687371350595e-96L, 4.13210577018135888633811621378125178e-93L, 2.87476099508953335771741680746804464e-90L, 1.63524251388290882625725240042223140e-87L, 7.65249997733887999623874860707951771e-85L, 2.96396516998940431058211305683891581e-82L, 9.55694449812711903241890069159516005e-80L, 2.57983003461536294556125432978470487e-77L, 5.86224102303822793749090237239965643e-75L, 1.12729666204663539107360352976065345e-72L, 1.84393400012961666333357387323541892e-70L, 2.57838118497774645351182154219344361e-68L, 3.09698398084623291081115732152399867e-66L, 3.21034639994569504125984658412826677e-64L, 2.88505745240234032993466930110171709e-62L, 2.25763973385675919792268556682148533e-60L, 1.54490468182644383657455478866541800e-58L, 9.28299236822216106223683331290050646e-57L, 4.91757270567151153434520348832876307e-55L, 2.30554641627582419897786323384840309e-53L, 9.60260856639165286607071389462405742e-52L, 3.56597785391661967741537394944785975e-50L, 1.18488237523747100855696221290216872e-48L, 3.53480106239996687790067585870262148e-47L, 9.49922331635571479300328969906674959e-46L, 2.30696251922047363681394459290289348e-44L, 5.07896585888252846067820035747838002e-43L, 1.01672554003146516218461940856820913e-41L, 1.85608083837358412341292426322275694e-40L, 3.09875103851653509802894724036653659e-39L, 4.74424556091727158516159565756659137e-38L, 6.67875654292885708009556323027970307e-37L, 8.66749789110265824007798499627002101e-36L, 1.03955806472296089132115323650013375e-34L, 1.15508617865206361238561969897526423e-33L, 1.19182362291753977427429758189318101e-32L, 1.14454132981883615336894355014782203e-31L, 1.02525602738123519983996836134381910e-30L, 8.58508308406581287405862446386142355e-30L, 6.73394164670453777712343530741256529e-29L, 4.95770293303240892202540668612526963e-28L, 3.43261200056988540268170912603591182e-27L, 2.23935379461627788150957730520597272e-26L, 1.37901808820501650857276186986911719e-25L, 8.03040544770876549232435915566049266e-25L, 4.42968188137908996064235843650469764e-24L, 2.31845927113168436195559586507393831e-23L, 1.15324161925721516540799043047625888e-22L, 5.46028729667908667672130073109459001e-22L, 2.46458926739523684644781998993375925e-21L, 1.06205430707170637462172218092564615e-20L, 4.37564008882607318443071720026076737e-20L, 1.72595587803323990868164488937090111e-19L, 6.52669144636334492287282783537910032e-19L, 2.36916844627434713681577417830597819e-18L, 8.26580372697482904251900693228762290e-18L, 2.77517606391661360182153963773908766e-17L, 8.97689232444592868369906653940499583e-17L, 2.80084735231662190309995026747244972e-16L, 8.43846463133099160645680685207593959e-16L, 2.45762595435789224473736552077118113e-15L, 6.92627769518345222522404766069340383e-15L, 1.89084205236464652796008005489924701e-14L, 5.00504297304156635993817971340426042e-14L, 1.28579120925883494201961228234875929e-13L, 3.20880531681575127155908954236910927e-13L, 7.78600100470787821926138878185058803e-13L, 1.83848331026111978204532135720140678e-12L, 4.22808302441074119355483439549639212e-12L, 9.47805306883598889922905503268261293e-12L, 2.07266429754356748908920713182886782e-11L, 4.42491437115776228499841800855357065e-11L, 9.22929507351999755945043065016679100e-11L, 1.88205258669115539986830146476840153e-10L, 3.75488615259231157512941964482754887e-10L, 7.33426418139309264953064008778652175e-10L, 1.40344387177481383433616336399570262e-09L, 2.63261606277390900911399983420396976e-09L, 4.84396275737187249536387241410506136e-09L, 8.74769197387686182490212973737486333e-09L, 1.55137319662316143322632050708021849e-08L, 2.70341183770391766500462033783635805e-08L, 4.63144836233962351361136455522914469e-08L, 7.80474058793106802102732603067941163e-08L, 1.29437017686516812026215434301661584e-07L, 2.11364219596533096486660492476571897e-07L, 3.40005066401716435610198303924157253e-07L, 5.39041104673862946543865026660608261e-07L, 8.42629030758144765430007132771995573e-07L, 1.29932702981307401261989221953085056e-06L, 1.97720517756199603296504985814152326e-06L, 2.97039557774168150435589567759708661e-06L, 4.40736236333866783037595222091818751e-06L, 6.46118993513603067322889724548764197e-06L, 9.36219732537340456332983881649283088e-06L, 1.34131848415120895981721422476655149e-05L, 1.90076038344927799241882635296823326e-05L, 2.66509095957072382671851701769041584e-05L, 3.69853096371186063639032612868033323e-05L, 5.08180543166657948433862427398171792e-05L, 6.91533341923576665290801314459185869e-05L, 9.32277498618928819410507284882673596e-05L, 1.24549207625185292746788896109936768e-04L, 1.64938971333376144939513069096604597e-04L, 2.16576471380809909291159455336007140e-04L, 2.82046340794006881311592802174739018e-04L, 3.64387021107897729238216699262593180e-04L, 4.67140162762043149791404714119969181e-04L, 5.94399941612237251611663813916878716e-04L, 7.50861330003505141341237132619730559e-04L, 9.41866302231455859084164368912569515e-04L, 1.17344692380002247672609547026883890e-03L, 1.45236427426188008347616119045966424e-03L, 1.78614218598655178612808460803997991e-03L, 2.18309484603519656221136749899809853e-03L, 2.65234740423109052289144172110269167e-03L, 3.20384885506921527761765779516587618e-03L, 3.84837661076576821141977260794172255e-03L, 4.59753235303186248996039969885789422e-03L, 5.46372893686621665171770797799402382e-03L, 6.46016831511747979221062326266402012e-03L, 7.60081065185419977059145624254178297e-03L, 8.90033498980204155946674089749748970e-03L, 1.03740920266168385556590451013464350e-02L, 1.20380497313706427480839156336456773e-02L, 1.39087326917827169960002061321148754e-02L, 1.60031562206455496475142539245814110e-02L, 1.83387563636593926316708603595489832e-02L, 2.09333170384958330449215168774593401e-02L, 2.38048955952869498234626954784270233e-02L, 2.69717481217077174816927863942958635e-02L, 3.04522558220532394622866431653207434e-02L, 3.42648537806332947261888782628446295e-02L, 3.84279633774899765386527022493279515e-02L, 4.29599295614980634381395647366200859e-02L, 4.78789641053477195533528647962166054e-02L, 5.32030958720316323100756360890520466e-02L, 5.89501290167188399227102430485391475e-02L, 6.51376099347951026087494855511522993e-02L, 7.17828036498272120091084808533476670e-02L, 7.89026802175633783409928711856568346e-02L, 8.65139116068936794825248092013403649e-02L, 9.46328794087702664882628072944679318e-02L, 1.03275693621920814402887268719345915e-01L, 1.12458222671938515285380933743314032e-01L, 1.22196134739810167085016527168685084e-01L, 1.32504950408621397326604347561435549e-01L, 1.43400106584199068783023171408440267e-01L, 1.54897031607657925984050586220533856e-01L, 1.67011231455784555526366713839660189e-01L, 1.79758386919258486031495958113778865e-01L, 1.93154461659030684603221234896514194e-01L, 2.07215821067763214460783254641335718e-01L, 2.21959361905993070139869913079334838e-01L, 2.37402652741481501585147220599178905e-01L, 2.53564085294908579555677649044302540e-01L, 2.70463036885576732351902861856168718e-01L, 2.88120044277091724111603906974976099e-01L, 3.06556989345224713687672375979413066e-01L, 3.25797297128632613090751563726807919e-01L, 3.45866146978355838846531059919780118e-01L, 3.66790697694818431455168590767201925e-01L, 3.88600327732532063221423261459050385e-01L, 4.11326891764317591973280272152569947e-01L, 4.35004995130479531888748830535836274e-01L, 4.59672287956338821101823148522366487e-01L, 4.85369781006713270719035870359289569e-01L, 5.12142185661796519744086646686900168e-01L, 5.40038280749567858894795821479236183e-01L, 5.69111309360283620800291297165821293e-01L, 5.99419409204557829271245298375247710e-01L, 6.31026080564853461281465428141943759e-01L, 6.64000696438865091754636398259527208e-01L, 6.98419060091622837940058120097784455e-01L, 7.34364015932103716685673325408458579e-01L, 7.71926120422450486565697123079450111e-01L, 8.11204380628463812996672518165491420e-01L, 8.52307069046258371120734338452652256e-01L, 8.95352624512219417238820469064741936e-01L, 9.40470650345508781665473144971561924e-01L, 9.87803022412309344664090567700404412e-01L, 1.03750512157160024916963789173178052e+00L, 1.08974720700214151578746902594297743e+00L, 1.14471594926501601899574650013187236e+00L, 1.20261614467922655880690394062840816e+00L, 1.26367263574296191533610775626416078e+00L, 1.32813246599542422597073187153380823e+00L, 1.39626730197278306832678497202104711e+00L, 1.46837615987297935465145703905241109e+00L, 1.54478848033412089590682530315276939e+00L, 1.62586760150092827681818702612923363e+00L, 1.71201468848349507792697792068680378e+00L, 1.80367318661869118602748089155898811e+00L, 1.90133387688644143294074965806611335e+00L, 2.00554062472320920559824403445004936e+00L, 2.11689692868996327728244730212683488e+00L, 2.23607339344688170923456651751668676e+00L, 2.36381627281331763524062140552607385e+00L, 2.50095725401825500385431630504625834e+00L, 2.64842468438767047986902883861439562e+00L, 2.80725647766353485711865991725063525e+00L, 2.97861498011790290399988989454287074e+00L, 3.16380412810114748721127771257562134e+00L, 3.36428929047159656773947338449998169e+00L, 3.58172026374255002938249218600614501e+00L, 3.81795797752670936449825238124466741e+00L, 4.07510557639156630320887778958143299e+00L, 4.35554467582358554514458856445852610e+00L, 4.66197774993613776113418481343338776e+00L, 4.99747780346124563910807301981274948e+00L, 5.36554671871496309147449064380266706e+00L, 5.77018396000583698718320188114380523e+00L, 6.21596767643453604333341399022283971e+00L, 6.70815068570623654464776592817234118e+00L, 7.25277436733040258314736650500251589e+00L, 7.85680416993879891697239876362854677e+00L, 8.52829127820429133135398118660851136e+00L, 9.27656603318338653224922387509018222e+00L, 1.01124700112272039114486606209390216e+01L, 1.10486353121876175190769261708382627e+01L, 1.20998216795271857764508697373482606e+01L, 1.32833246923912553882423938260725321e+01L, 1.46194715878299420711013972809323962e+01L, 1.61322254926408962729986594994585730e+01L, 1.78499242340404104179578536110600421e+01L, 1.98061868055245863949655128520558624e+01L, 2.20410294496835217815852679074305586e+01L, 2.46022447943980585927583897681190540e+01L, 2.75471123562893237374077750154320094e+01L, 3.09445280931970284883990775946651869e+01L, 3.48776660064165064038939228627010010e+01L, 3.94473180334351770794475603595764904e+01L, 4.47761023021425157569087608052893710e+01L, 5.10137878711900622533650986521384164e+01L, 5.83440613273984383402755554599355811e+01L, 6.69931638788863998843945524712655391e+01L, 7.72409663039404221632393248526916570e+01L, 8.94352363841359052286058140969269159e+01L, 1.04010107537438719134080196856970415e+02L, 1.21510103906665265646188258350644787e+02L, 1.42621552310160172951445448156836659e+02L, 1.68213866518508832477273582457732136e+02L, 1.99394097464546647941096853182355363e+02L, 2.37579409247584470819614691411159418e+02L, 2.84593916789823535562840880888980902e+02L, 3.42798827028127058717471147784029643e+02L, 4.15268383629255114718046929646589502e+02L, 5.06029199301683119404601716655559045e+02L, 6.20387871848170976858394304975149188e+02L, 7.65382367194376728088096731506729391e+02L, 9.50408087358179153450911943224019430e+02L, 1.18809220276011606595956628737466824e+03L, 1.49552334212407885347227350564427644e+03L, 1.89599366703067034325550411232806679e+03L, 2.42148532800683663374818194050951580e+03L, 3.11624674527423644655997407153581040e+03L, 4.04197721822739650017152639557046462e+03L, 5.28540456882764394198106919117899344e+03L, 6.96945349745478520211739265737692803e+03L, 9.26984863597541610825591719881066842e+03L, 1.24400169046144284609469034917486102e+04L, 1.68487804928219120974770366506141126e+04L, 2.30379493050689209894874317068326889e+04L, 3.18111749406368329678640732920395152e+04L, 4.43724092704038524997055436198884382e+04L, 6.25438880548229936896462817079707202e+04L, 8.91129656174671765721819893640615727e+04L, 1.28390011615567130356349325241374642e+05L, 1.87115939884978799395430373139032810e+05L, 2.75955654445572113231216194578725044e+05L, 4.11985149226574332956827494211875921e+05L, 6.22884543671150616939347176756608244e+05L, 9.54097172994412639791727921401626133e+05L, 1.48121323807100834515424707068495244e+06L, 2.33168052188078970586379639354686916e+06L, 3.72339779803011251388319470323527721e+06L, 6.03430539101169547235371451057106735e+06L, 9.92972861117960142404055815146657353e+06L, 1.65989636945226644757161242143615839e+07L, 2.82017465494921172861525124733558875e+07L, 4.87244883934161305263386031770533647e+07L, 8.56498776477185184074970634710495674e+07L, 1.53268758654909039217478083777958109e+08L, 2.79366798395238972059209786152271040e+08L, 5.18973079293501172198046128702649663e+08L, 9.83165082634482695230583899233702397e+08L, 1.90059962104050828804295224765625411e+09L, 3.75160395202091966289927262175925315e+09L, 7.56648043123273181762292360200563868e+09L, 1.56033907397856950198380769768232419e+10L, 3.29229832278164384876778685138061688e+10L, 7.11297379086385418813540334382875157e+10L, 1.57471442166507563544871664087516645e+11L, 3.57509888501672692207543566803978301e+11L, 8.33024430623979589172560805550927471e+11L, 1.99374509951525518357032637324282993e+12L, 4.90561996981418757143934103035069327e+12L, 1.24197379810188498181468317797399218e+13L, 3.23831600275722270184945604347174663e+13L, 8.70403769580874957196023586424815933e+13L, 2.41399528145469907607734183398259453e+14L, 6.91510620574880583944843529198735451e+14L, 2.04811558742607734304993874133785299e+15L, 6.27861397733698939186730156018167292e+15L, 1.99435267076689206564427715465056511e+16L, 6.57141971664513108413598657255436192e+16L, 2.24875056642273914367880154275296162e+17L, 8.00147401578245998412996372425512095e+17L, 2.96403754199235340052960592736049159e+18L, 1.14455803313869409862823561648962815e+19L, 4.61323311996821344548899222001480398e+19L, 1.94346926949906856258436939614621369e+20L, 8.56968050834200116120462221511753399e+20L, 3.96091566953282355348486677100761553e+21L, 1.92185171194284479900050386014427105e+22L, 9.80409181939054057802535035944011717e+22L, 5.26682924609986175842861032563925229e+23L, 2.98441055802829784200443452444088495e+24L, 1.78677995299228897649048545726173530e+25L, 1.13225906725879734647293567479653181e+26L, 7.60791970573697649080495794599946588e+26L, 5.43049485025884671542842347146701195e+27L, 4.12572142434645000681420526588413556e+28L, 3.34277767339287328803586493191472415e+29L, 2.89434014229221431295360965172883804e+30L, 2.68374761249850267614464943620131017e+31L, 2.67072026965642827232315722365639115e+32L, 2.85880373230063837155252556137517211e+33L, 3.29924822913520515079335032162581841e+34L, 4.11488570832552270061078474206882038e+35L, 5.56010558358231010262223361328066200e+36L, 8.16009266847150844693389287229450581e+37L, 1.30416726659952301962536120869903033e+39L, 2.27600481686142160023333409481863034e+40L, 4.34938214638271735275350443120721790e+41L, 9.12741493518023346499222172162825387e+42L, 2.10972038777434150864210644015160107e+44L, 5.38754491759583324556444810556121661e+45L, 1.52482535270240332398284822085798536e+47L, 4.79877533166358652838909903087275144e+48L, 1.68494126510508458862564987284302025e+50L, 6.62357573295543230261174696442002813e+51L, 2.92557273755841342556692584369563440e+53L, 1.45729219902900863678006319195819802e+55L, 8.21783496105748128055143975755446008e+56L, 5.26688130483523933792268242131450300e+58L, 3.85211799189653678380768112270880793e+60L, 3.22861432024885393800430464301385615e+62L, 3.11445231039438406261213455773274485e+64L, 3.47323481265477220985448691064609690e+66L, 4.49855546587324575105781665091655708e+68L, 6.79925746409737423822172568281133860e+70L, 1.20511321523280079626937861818322431e+73L, 2.51749264598597737693408358183917414e+75L, 6.23086472714522132176542446806460931e+77L, 1.83698604157213615145607828551975305e+80L, 6.48713124894846526923286444858655243e+82L, 2.75979764628924062898267004292796591e+85L, 1.42281010916783424894495664030511266e+88L, 8.94356583170635560730657498907040019e+90L, 6.89765608918172471716339680473639534e+93L, 6.56960382950241207669696237814704407e+96L, 7.77916346275648519460667580565807164e+99L, 1.15314598687748380372708686918514146e+103L, 2.15521325185955507170865064451154694e+106L, 5.11618164822064799451529384134754077e+109L, 1.55434716015270528126967279870385072e+113L, 6.09112777117402790869661219995564436e+116L, 3.10387507242519227183111245931080882e+120L, 2.07390189233940742293442790510784430e+124L, 1.83267382155701863417862737648022763e+128L, 2.16097258672364775058232219739796364e+132L, 3.43128595186527837599814654188046354e+136L, 7.40646244666625583794129098263179729e+140L, 2.19454208154239352969892199569722442e+145L, 9.01619836979155465535468945047889426e+149L, 5.18985678737597694246477524117862598e+154L, 4.23046985030263912409378392183252421e+159L, 4.93764276985086773495452256391816235e+164L, 8.34636422063293684495534346523864357e+169L, 2.06741406169751668845974997770098232e+175L, 7.59587841419400960682004001784651511e+180L, 4.19164127392101407920200382533221559e+186L, 3.51927711650483149002609005453729140e+192L, 4.55587470619707394753414927965798200e+198L, 9.21952142596023196043927688149872532e+204L, 2.95816314360706369484966684111893238e+211L, 1.52709952631709289803811134371908265e+218L, 1.28765668330017907582554622529315931e+225L, 1.80129361672056777447357282869624658e+232L, 4.24814651295030396772649227180907798e+239L, 1.71729703963558073111114105671039088e+247L, 1.21046234446012300929891454835993254e+255L, 1.51419519516367160890801105849993081e+263L, 3.42330233588160029564511697140750743e+271L, 1.42528129667493838632765543616342364e+280L, 1.11420723637564670686340338390175118e+289L, 1.66850212135837193821657370527462903e+298L, 4.88589347415031911318629107633374545e+307L, 2.85800617499362161237161192858659000e+317L, 3.41368346308455763011375953918857639e+327L, 8.51659564264685587821018369835222946e+337L, 4.54303089474615832686354150019925596e+348L, 5.30809578740740306246018975605923943e+359L, 1.39268945492416740550127311639881773e+371L, 8.41868946331338761333876333129653244e+382L, 1.20396970846759916705111332553270569e+395L, 4.18638285711073253556696402015828229e+407L, 3.64051583443686661335653674614037576e+420L, 8.15125707810912875910267388062325131e+433L, 4.84241684726444145079336201568928602e+447L, 7.87277386139003022204421580245435912e+461L, 3.61660042166407854517352456605683269e+476L, 4.85176905670774504900384645174873943e+491L, 1.96653101796028683463909850095858046e+507L, 2.49428344091357019569533852688763620e+523L, 1.02650775155921036180043655136824490e+540L, 1.42290670725613581153914997322741401e+557L, 6.90446128383757111350399979478971290e+574L, 1.22038031602184356762554212370154951e+593L, 8.18641498043102997149775477320992897e+611L, 2.17426427576810603662782427977182733e+631L, 2.38847898517251831173924452396821302e+651L, 1.13525581232092079165478024625033648e+672L, 2.44581305055310563196277332943189236e+693L, 2.50579201726264634501291514398286907e+715L, 1.28278958026597426545698815500879845e+738L, 3.45329144611998202962794722592107008e+761L, 5.15301310117757693898843758843439768e+785L, 4.50037434223155300664502702852727419e+810L, 2.43306674872992411217032796443919144e+836L, 8.62798204693025064663883932656343701e+862L, 2.13031523407691556211779361127399737e+890L, 3.89502853428849118703235846476912848e+918L, 5.61967843038535141183624496528991236e+947L, 6.83163157235897275355324461890504612e+977L, 7.48741060910847824069581635250382582e+1008L, 7.93319051954128205327740081284490051e+1040L, 8.73273358333231337767980404927541807e+1073L, 1.07574303828662898687276828597901159e+1108L, 1.60109519481842931883372467310550530e+1143L, 3.11621335415749303163841998134612826e+1179L, 8.60558107743722927550014656572137529e+1216L, 3.66811383278356514418007625117425117e+1255L, 2.63234220176367112942815907184016908e+1295L, 3.47859421502287448304146808910623408e+1336L, 9.28512235755776936781681374078562947e+1378L, 5.50718056653300293052467960576840696e+1422L, 8.00902248373521173018720630861185040e+1467L, 3.16115623922106492070773163357582495e+1514L, 3.76042153408120168432167355515647590e+1562L, 1.50211667261404150161306978400073837e+1612L, 2.25263196634448337432840054986261153e+1663L, 1.42290818050514650710172541634086053e+1716L, 4.26315122517229508281635793163851999e+1770L, 6.84787649140078417523090257285629098e+1826L, 6.69183748343427005004387693124220507e+1884L, 4.53246642529433183363157301179103704e+1944L, 2.43420309539903059914673692609144617e+2006L, 1.19096818482919681799422553000433899e+2070L, 6.12585236774593416353267428912127386e+2135L, 3.84000941993213246405245986391372004e+2203L, 3.41673273574541565248480628561887880e+2273L, 5.05031055516767284204610907378751985e+2345L, 1.45860427844568831785920214989842347e+2420L, }, + { 2.77668375956040189946826811680384390e-2478L, 7.15287685954868211386033128907477031e-2440L, 4.67658088132803463412188029644470498e-2402L, 7.92687480429971819654882242916691373e-2365L, 3.55705626445534513670485482702241051e-2328L, 4.31363186281767249198550472192046640e-2292L, 1.44267570824010102564476209762038016e-2256L, 1.35750289529472083929076668071298865e-2221L, 3.66520151899825097802289209374933991e-2187L, 2.89498463671553268274047707590333923e-2153L, 6.81807725541668247816231315716744273e-2120L, 4.87856900336985600073857171641568070e-2087L, 1.08033682307899983904972807875490412e-2054L, 7.53978658799448170922270322982561647e-2023L, 1.68836600150778453318616795534542245e-1991L, 1.23462709610862382392789185979644933e-1960L, 2.99986697918589103634446685042416531e-1930L, 2.46367649797140140439024370548377672e-1900L, 6.95479514251903643444688832919306991e-1871L, 6.86110776725256744693425828768272774e-1842L, 2.40431940102692787285034949159539178e-1813L, 3.04121511300162701514429163779115709e-1785L, 1.41065291642406553832784938505501922e-1757L, 2.43705806703985396362343530158481976e-1730L, 1.59233397078886467474093245165420794e-1703L, 3.99458646512746569553991304016076066e-1677L, 3.90502825544924862516415029425091730e-1651L, 1.50951212222311306420066585908781007e-1625L, 2.34075577961021270449149847209864885e-1600L, 1.47683791355252947630371426518876483e-1575L, 3.84433827968748974568829430827411882e-1551L, 4.18584678137447017460210584041562890e-1527L, 1.93235335361456340539919561054923147e-1503L, 3.83273493158460886555652388105220442e-1480L, 3.30931424971841824136873930746170663e-1457L, 1.26001001743526741988366704934436124e-1434L, 2.14254382108136960073063000869254434e-1412L, 1.64752740569760866428499059885288678e-1390L, 5.79997534765464443335232132612089697e-1369L, 9.46173366850636035136459393339314051e-1348L, 7.23844554700889711120024618879438753e-1327L, 2.62753543705293236920590575888507321e-1306L, 4.57825670343966465596419576070363442e-1286L, 3.87294895920776670416027972176834657e-1266L, 1.60856514992623900565886618371043785e-1246L, 3.31650403849378163469754348545840043e-1227L, 3.43149117215084179247503681795855710e-1208L, 1.80089379614922388608625914511562841e-1189L, 4.84469660937728881846012977552474102e-1171L, 6.75021934282781912062862469597524256e-1153L, 4.92120879530819746165015110941962755e-1135L, 1.89622303139680815547453480860411409e-1117L, 3.89999690124553358779083557357143651e-1100L, 4.32337852652349730363515343553956403e-1083L, 2.60812148992852188438485836891607672e-1066L, 8.64320507307309471921069873497971138e-1050L, 1.58817234955465364327662145482119776e-1033L, 1.63292822332387428570727069490856970e-1017L, 9.47965403932768371077126663738787002e-1002L, 3.13489123036525936535865202633924346e-986L, 5.95725324626422679969355089398557051e-971L, 6.56135449619885064132736333035718110e-956L, 4.22412947622465431737740854731813869e-941L, 1.60284936502012533605395043475391797e-926L, 3.61426009581007446214636991266185477e-912L, 4.88226731291038533672727194690523707e-898L, 3.98243859045531426665602764668150557e-884L, 1.97696254579881780215274246825324592e-870L, 6.01884829406232602469720991349044932e-857L, 1.13236358528056083157892195864287071e-843L, 1.32634602112101849951006383738692278e-830L, 9.74354258615429475261032804502093079e-818L, 4.52175713954583830576111594951110560e-805L, 1.33512020097306090853791018618669252e-792L, 2.52581092493362086952359277189983609e-780L, 3.08280454280630114861769351743791880e-768L, 2.44403095665612216421741893390173529e-756L, 1.26703351146649868905932200644776032e-744L, 4.32364746058654184636712625519962546e-733L, 9.77482453681545274501227529587168230e-722L, 1.47345296987795364063826018729590588e-710L, 1.49025749519107052339924056423862408e-699L, 1.01758543742056270682348949473524139e-688L, 4.71965368684349520914049336410150458e-678L, 1.49583331955342167906773277357310899e-667L, 3.25877112957152479296585133409409173e-657L, 4.90846979890405909332298369271733953e-647L, 5.14096775171769223933971053266547990e-637L, 3.76527319345060607553853872315139069e-627L, 1.93914103642113548742773247369930873e-617L, 7.06081267960685321695216552061682039e-608L, 1.82753922477698812695612565052211519e-598L, 3.38020931062714080731736679298776434e-589L, 4.49104974727379533831457784467988803e-580L, 4.30831017202845455490779426657646708e-571L, 2.99925774499663529105464847801180013e-562L, 1.52274525111081863903256031902733405e-553L, 5.66595073105051388454002533447155475e-545L, 1.55254034318111114885985765214004285e-536L, 3.14773091677700441775450360300498865e-528L, 4.74422214535871848463366092395468719e-520L, 5.34000677409012855851843363768904621e-512L, 4.50913961542719498094454101135511353e-504L, 2.86916730093441295609899413107663763e-496L, 1.38176315596895654455580263526098670e-488L, 5.05827668288972660188294275444103716e-481L, 1.41354423391013787396132813520577665e-473L, 3.02811286218415761503816814918528786e-466L, 4.99321587478833584968780076440597278e-459L, 6.36350378784780643105814130227578114e-452L, 6.29295581774659679570380847201393083e-445L, 4.84800776366962427166614895670077970e-438L, 2.92081155862662548270928062619807743e-431L, 1.38143568676341254642463548681208773e-424L, 5.14842432351503290408078410534655737e-418L, 1.51753560889290027005627901927469983e-411L, 3.55061704489050704368494163406172279e-405L, 6.61796042955880547227964893320004528e-399L, 9.86122308014976296151434619809887336e-393L, 1.17877481135241077171765329651013943e-386L, 1.13424833803992349974759003704486622e-380L, 8.81502377306393355822212968439637791e-375L, 5.55155950590484925963715579436840823e-369L, 2.84248729913659406224316552722434334e-363L, 1.18704719186027282879490304441234572e-357L, 4.05597847694543335354139081149132852e-352L, 1.13745052103435347539610354499759843e-346L, 2.62608432267715211136705119144544958e-341L, 5.00649221900861773230008659070798254e-336L, 7.90489841299351390278476450028383484e-331L, 1.03673095771954987567298480275353471e-325L, 1.13264118291164663653569719276217293e-320L, 1.03372554114991613828759256440083793e-315L, 7.90343344978986920403039115230438646e-311L, 5.07593758357543835739913968923721419e-306L, 2.74587297706393183600196990448758755e-301L, 1.25448043297991919976296583184269934e-296L, 4.85293287864597257977432400607091472e-292L, 1.59375532748424261820313240836566102e-287L, 4.45470192712163297279675529941780532e-283L, 1.06238236699788796015140463431038408e-278L, 2.16709025689586849941731617555370390e-274L, 3.79017494148388392555292862630176094e-270L, 5.69722642026139785964263462216321432e-266L, 7.37750423818818484376423187717037465e-262L, 8.24899816234186348122208308733670706e-258L, 7.98228295613681065404000331301407417e-254L, 6.69977627078532550007479609463315785e-250L, 4.88831026337525670264792775582398754e-246L, 3.10717465030331182564914656973440633e-242L, 1.72428695582194286916259157368370433e-238L, 8.37152419508690266695542791416172637e-235L, 3.56328545617913642798317603893755984e-231L, 1.33239745308069123170741398284986139e-227L, 4.38557307471736323357712547586541243e-224L, 1.27317190092247560042567075437905721e-220L, 3.26633944706575228492861971563886982e-217L, 7.41961719235926788479176390701225966e-214L, 1.49508892701036107375575902806187267e-210L, 2.67747004659594255579164687433346539e-207L, 4.26921971680475266131733781176106392e-204L, 6.07184376271449065521795822572065912e-201L, 7.71632746256793762696505755410742573e-198L, 8.77761527570739954686084893442788334e-195L, 8.95291300378341203683641755088969233e-192L, 8.20179011370862828929882403579221646e-189L, 6.75977978662441271172788792155811852e-186L, 5.02051176570061397957717306624573193e-183L, 3.36554863928813190587746679952307259e-180L, 2.03960573952427530884860135637723107e-177L, 1.11917598852847666035205866531172342e-174L, 5.56905039413988338846998023185739233e-172L, 2.51682459319287628531543936384778284e-169L, 1.03457507608575432785228105631849600e-166L, 3.87388309025221395194171192891040522e-164L, 1.32322812968423778281527114220160831e-161L, 4.12900297352082279106292344371557207e-159L, 1.17865546256954888181796214775388038e-156L, 3.08218900889320623074522540652758709e-154L, 7.39354283219941448656677403739458341e-152L, 1.62910064435532863938332952898952690e-149L, 3.30154552905982294134609461204752294e-147L, 6.16203139085424122701291732112343081e-145L, 1.06052819447098630885771547158633382e-142L, 1.68522575749723508863020213808775829e-140L, 2.47553409758226362888052187337950144e-138L, 3.36576474950758719210258297005317849e-136L, 4.24056268392402238294912126586145782e-134L, 4.95679422788561171460024764665358982e-132L, 5.38171636791416151987580045952962687e-130L, 5.43350717229498884938353606822409483e-128L, 5.10703124279431542010303665040364840e-126L, 4.47370493209864639350813176634174273e-124L, 3.65637694737788862889473248524269217e-122L, 2.79117002269425900051588497263773104e-120L, 1.99220023869241503219258818787712929e-118L, 1.33089435939378971755299967553769684e-116L, 8.33035676735989050287962245538521119e-115L, 4.89025663997024514599039877971897448e-113L, 2.69512893545116544669129054438916450e-111L, 1.39582960541563084355183973360376419e-109L, 6.79999752718808594213315829447961814e-108L, 3.11903776737903229329061449549842670e-106L, 1.34826013141921629130407145750369350e-104L, 5.49752601894399080415833353152482494e-103L, 2.11638467025119853304622111522504730e-101L, 7.69914871485806120880436816954565416e-100L, 2.64906534725059834511552809323827260e-98L, 8.62818926354972775334178389390317975e-97L, 2.66252094324836892217545797407595895e-95L, 7.79069862358288634135952568964046431e-94L, 2.16335486668307728100344975621110455e-92L, 5.70557673979722036138381850123515391e-91L, 1.43033819302856491333403076823625576e-89L, 3.41104078137232874664267449214467490e-88L, 7.74426807351644903668383259880558649e-87L, 1.67513656430343581317253830008450619e-85L, 3.45479581059570481569225182340141781e-84L, 6.79857313709947736278888732144820603e-83L, 1.27747470803378266136497077558029564e-81L, 2.29370213942630948295519765524670121e-80L, 3.93802170001517503024981641969166523e-79L, 6.46959393487630012362523872090477425e-78L, 1.01772526699091247125279301878345328e-76L, 1.53401952979332495111639447956817637e-75L, 2.21699988683886091607827589036641130e-74L, 3.07410074756280336185727691291524915e-73L, 4.09229533083754909228682061184080234e-72L, 5.23343417563653847061479912948387465e-71L, 6.43350607976335741808585356397544551e-70L, 7.60704267790136216066341175717356605e-69L, 8.65671438716342535748325493579430488e-68L, 9.48674605868548997400346985395655480e-67L, 1.00175672424828839701939548888991483e-65L, 1.01985394383485432972080334959114676e-64L, 1.00159110661066563005593773053264872e-63L, 9.49427782244426395210838765944495599e-63L, 8.69142291889189064854075883690819022e-62L, 7.68797704788744827616631661309525244e-61L, 6.57440810419660524782417308561229212e-60L, 5.43816250291842519145575247702512746e-59L, 4.35334083136300321175659843267140387e-58L, 3.37433876218124341053665144604385146e-57L, 2.53377092117304232961472206140287465e-56L, 1.84404892524861673828316906508664460e-55L, 1.30141081230848018402542829366785560e-54L, 8.91046674437447006307015773182167698e-54L, 5.92153838412413233143345637093941679e-53L, 3.82135613429770512672309553535220252e-52L, 2.39578065735303689149259651605329745e-51L, 1.45988218758182023631230626004517631e-50L, 8.65010547207677732721948607063784916e-50L, 4.98593355079719931559980617333925476e-49L, 2.79691190323743591605512918548961454e-48L, 1.52757011899350333194123701418929652e-47L, 8.12631404819699330158401537112269973e-47L, 4.21243636394857818219784558381591723e-46L, 2.12860405024256466240923390999711474e-45L, 1.04893835632343107182205383744844780e-44L, 5.04275314265368784163135845797922992e-44L, 2.36599922549416536405636377221603052e-43L, 1.08381346209104032486272733428199249e-42L, 4.84896336796031616924505606902108385e-42L, 2.11961287373765727720156892217888941e-41L, 9.05594713902200264778664561627827336e-41L, 3.78298719219266665046394564391309006e-40L, 1.54564984691757476458462458129485585e-39L, 6.17890975212602635731338783415082506e-39L, 2.41759755862594038624882497707942985e-38L, 9.26130599996633274587378852134765724e-38L, 3.47471297119465611529279266980333841e-37L, 1.27721589062918134522531144355249981e-36L, 4.60093813393547386396189442938777048e-36L, 1.62480431477305204386750726891935535e-35L, 5.62680810313792997206232926753677840e-35L, 1.91144242994708647057868821934329247e-34L, 6.37130041549818712538060098629118750e-34L, 2.08444453130944123746087664312229902e-33L, 6.69535606006557423430835320939136513e-33L, 2.11203843563779293148946583571749480e-32L, 6.54480290655151239305039275670085965e-32L, 1.99286493762398711426295964156611288e-31L, 5.96435881776415175461953820911435643e-31L, 1.75497323146494950021419641534165307e-30L, 5.07823155886177386317817053950871430e-30L, 1.44544786652825947518140437679267760e-29L, 4.04809975939166078604969666043969110e-29L, 1.11575287892799422088984788434321808e-28L, 3.02733416844233859190251989588495462e-28L, 8.08786849810622478767566085355596476e-28L, 2.12810654415185893615787768003277562e-27L, 5.51621011393022798460545237305226697e-27L, 1.40889092112486390607440977505465003e-26L, 3.54652073432677480700798349650597512e-26L, 8.80063648109636049392437478276758980e-26L, 2.15331950904398446525184217737998611e-25L, 5.19613654473192634598878003489200027e-25L, 1.23686905842220219027076147492586511e-24L, 2.90489167449091887312162206507161675e-24L, 6.73270731756325876275561922583341148e-24L, 1.54025360336139105521086193967934171e-23L, 3.47876572768722101871596015971992779e-23L, 7.75845007993303197586197585003227682e-23L, 1.70893932426983027624683633350310787e-22L, 3.71846701056881115177897268795618277e-22L, 7.99409437676902992032878645322876456e-22L, 1.69833677431834312305384300763198925e-21L, 3.56621446972400227479906082231485065e-21L, 7.40284853486635166159906810215851685e-21L, 1.51941171975529754933443555359007838e-20L, 3.08399399452860874024652960034823534e-20L, 6.19138881797445980861805317656851788e-20L, 1.22962598701058922677441904835003634e-19L, 2.41624594930841108357336910436255182e-19L, 4.69855181874941970642420918335722321e-19L, 9.04299297884852043932311013611381641e-19L, 1.72288019839002081694998146770641182e-18L, 3.24983285835411232229770728918949423e-18L, 6.07012059458645756189773861988245818e-18L, 1.12287188164609844099198470626937240e-17L, 2.05742923566420592156922015953543702e-17L, 3.73461320774281639944361675972781502e-17L, 6.71669436926784207473111220730444193e-17L, 1.19706302505504395186947411747310186e-16L, 2.11441966111566361680483324148539475e-16L, 3.70201713823102185303168392234499685e-16L, 6.42566549874633786044656050804228769e-16L, 1.10583090372698541886807277008925137e-15L, 1.88715605166056322365232100161599762e-15L, 3.19397901867912583303235022260119744e-15L, 5.36188197747320445907706025927166858e-15L, 8.92931856860669280901808059459161448e-15L, 1.47533056095858665971377793523064186e-14L, 2.41870863676582496406573146120828803e-14L, 3.93507835090405130222724885910838729e-14L, 6.35404709630865447857089142202307170e-14L, 1.01841666646650944181450881700329392e-13L, 1.62042378299930769318560924447489642e-13L, 2.55981751705612616590139075734652273e-13L, 4.01527388629421281039816262827476156e-13L, 6.25453235826176129082121714446163184e-13L, 9.67598102139418285827447083279565919e-13L, 1.48683211253456618620643979203627482e-12L, 2.26955737776048687888315587634986337e-12L, 3.44173600876636583230784574560493186e-12L, 5.18579385986065241250884484837407551e-12L, 7.76421788931400466314739807932612879e-12L, 1.15522810574654803550770552217628934e-11L, 1.70831312146426209744016210099566072e-11L, 2.51095185608620189710869551132160955e-11L, 3.66877697851095234075891821003426570e-11L, 5.32913181394174031371781017456930198e-11L, 7.69632539729948085558352466099257329e-11L, 1.10520072364372285498114055238330020e-10L, 1.57822184379603482492805668832205965e-10L, 2.24130967294097676646756319917307649e-10L, 3.16577320114495664158493107630920887e-10L, 4.44773051087161070439507137569795222e-10L, 6.21604166145516404864589081218699790e-10L, 8.64254490539598786804804563578215933e-10L, 1.19551930651665934901247256485043253e-09L, 1.64548212141718982285430677462884054e-09L, 2.25364361294162088274171207920306355e-09L, 3.07161057649675130982867546470369013e-09L, 4.16647469046044592666212503776391905e-09L, 5.62503650418518103546622761014447205e-09L, 7.55905963895399839577230243791284335e-09L, 1.01117741787649109183519733871956784e-08L, 1.34658870190626745425612716113453914e-08L, 1.78534009295770335027325069409745001e-08L, 2.35675936423533751929780865973963492e-08L, 3.09775637333761608808718626586210342e-08L, 4.05458117130271472976754716443074815e-08L, 5.28493928008555417314519862662075002e-08L, 6.86052524785416844753739601495847428e-08L, 8.87004371407679534565262439555179668e-08L, 1.14227959934028163656084297163993474e-07L, 1.46529195996537375677477289744322135e-07L, 1.87243781452025990276419175076674860e-07L, 2.38368096170532406236914962927186340e-07L, 3.02323520821923278406510621336929642e-07L, 3.82035773260694787625549171519571981e-07L, 4.81026746749616004418812011672214969e-07L, 6.03520391713916631448186742261762126e-07L, 7.54564302177565687477041747448625764e-07L, 9.40168786133714127970401442799808303e-07L, 1.16746531401927207818183968119629644e-06L, 1.44488634919934624164636989185786720e-06L, 1.78236866676220579646941432400191756e-06L, 2.19158235968382023977800841196782357e-06L, 2.68618781213700528587671678902632939e-06L, 3.28212298590973811003340670234049833e-06L, 3.99792341503412914858164425580814066e-06L, 4.85507733328388046876150511289283628e-06L, 5.87841836668756018708322083288294132e-06L, 7.09655820622938796350022322477138609e-06L, 8.54236163220623609743157219064928822e-06L, 1.02534661892020938105973895830986033e-05L, 1.22728487074863285519290054710280426e-05L, 1.46494407312787820235069142302801116e-05L, 1.74387947455200274155445197262654991e-05L, 2.07038028896765075538771239781158806e-05L, 2.45154696092443087426053206140339263e-05L, 2.89537394229808584415606234281235237e-05L, 3.41083806769492860360664819345743796e-05L, 4.00799258161539348751926239815464572e-05L, 4.69806683323287862163878784706404376e-05L, 5.49357161442722725101184470856795070e-05L, 6.40841007374651816919514989779193660e-05L, 7.45799409355181382811997812036059565e-05L, 8.65936597006977565440049012882777955e-05L, 1.00313251868244228486845169918522419e-04L, 1.15945600213690649557974183508671660e-04L, 1.33717836738558167374082301113276138e-04L, 1.53878745542570977882656611663357910e-04L, 1.76700203135100555424143059190915095e-04L, 2.02478651530284460762520573567302864e-04L, 2.31536598974665040190979221162493510e-04L, 2.64224142678798208257632362853594384e-04L, 3.00920507470608001324163745800874977e-04L, 3.42035593863725830721435182160899216e-04L, 3.88011528643900055031892572065609775e-04L, 4.39324210725794779827016989314436073e-04L, 4.96484844725809052233768108298280237e-04L, 5.60041454438256227059209260385185510e-04L, 6.30580368196231443658525282679749066e-04L, 7.08727667948158660008974296844527949e-04L, 7.95150593789209443880323604776955146e-04L, 8.90558895655812679363260602821822057e-04L, 9.95706123923012434268721813542918011e-04L, 1.11139085073953859292031598702982886e-03L, 1.23845781409454868818512091763619876e-03L, 1.37779897683285042761735605405503089e-03L, 1.53035449312115014435580213674818791e-03L, 1.69711357521498846993912286538919474e-03L, 1.87911525378240440542796943910703787e-03L, 2.07744902550331120940589303741307914e-03L, 2.29325538217982005624763697091003995e-03L, 2.52772621615854827916639591227331912e-03L, 2.78210509747707274118095565348853401e-03L, 3.05768741879849780665835354304288470e-03L, 3.35582040488560696306610399114125004e-03L, 3.67790298408396440888192232818825231e-03L, 4.02538552002609726985152127212337675e-03L, 4.39976940253081440732383904779371772e-03L, 4.80260649744698504497144153794077709e-03L, 5.23549845597384011114251649759318761e-03L, 5.70009588477421233645539752147845015e-03L, 6.19809737897730872540802302573847437e-03L, 6.73124842093794861403414763375789954e-03L, 7.30134014837421983438805473382268060e-03L, 7.91020799623995212524470914365122922e-03L, 8.55973021739730390294556694387596169e-03L, 9.25182628783344529797384941938652911e-03L, 9.98845520280948891334775899197118662e-03L, 1.07716136709355454400393298774895433e-02L, 1.16033342137295485601573254130151715e-02L, 1.24856831787362164573968971563345559e-02L, 1.34207586747535542664119568732591706e-02L, 1.44106884381354658508301066473916456e-02L, 1.54576276395086064771405090469805654e-02L, 1.65637566405583013536386920486874088e-02L, 1.77312787108013640215572254554956350e-02L, 1.89624177144726038238696005618612010e-02L, 2.02594157778067758841208537767709612e-02L, 2.16245309470991783928580857382458621e-02L, 2.30600348479769142051214039575544903e-02L, 2.45682103563102531782599654851478334e-02L, 2.61513492911411521698129655317611847e-02L, 2.78117501399057252267505437298152555e-02L, 2.95517158260815126327011961248970821e-02L, 3.13735515292012408141424535463840985e-02L, 3.32795625669450926962877709780283664e-02L, 3.52720523487562160472278601135978908e-02L, 3.73533204101223493795063079870277644e-02L, 3.95256605363332412560750462340568604e-02L, 4.17913589841622853414796289201462570e-02L, 4.41526928095348722137611194180899765e-02L, 4.66119283088387990349053837529086301e-02L, 4.91713195811071287202299070345370512e-02L, 5.18331072178645941782756741967663201e-02L, 5.45995171269784130156535121811973661e-02L, 5.74727594963965733729390200663376457e-02L, 6.04550279031945582526756917103894992e-02L, 6.35484985728882875351754365961380466e-02L, 6.67553297935098586459427868785125518e-02L, 7.00776614884864197850796119077335695e-02L, 7.35176149519140388651301532758182494e-02L, 7.70772927493804152471705586229649727e-02L, 8.07587787870652431694028348485017861e-02L, 8.45641385514373366852999925423097546e-02L, 8.84954195214754605679505353644207668e-02L, 9.25546517549672049628688665169818439e-02L, 9.67438486500890476543279055502732567e-02L, 1.01065007883142650157999494215339249e-01L, 1.05520112523018947242782060692540634e-01L, 1.10111132322684063185699908950501089e-01L, 1.14840025187730710332047574671488736e-01L, 1.19708738821816529269842068051324872e-01L, 1.24719212548617699381893630778769370e-01L, 1.29873379309762826940592292027774350e-01L, 1.35173167838079215925316604016895877e-01L, 1.40620505005381631636575206950501568e-01L, 1.46217318343962952595269565777364191e-01L, 1.51965538740906942447303428154167210e-01L, 1.57867103304335938296117505727756989e-01L, 1.63923958400730641095309983504562072e-01L, 1.70138062862515433149015694041321523e-01L, 1.76511391365190704205555387802167839e-01L, 1.83045937973413460592324819248629329e-01L, 1.89743719855578905138540205901925041e-01L, 1.96606781166638569017145529907938222e-01L, 2.03637197099104797388960830732662422e-01L, 2.10837078102436785186096324004787346e-01L, 2.18208574271279784343490287100076472e-01L, 2.25753879903336437885194071240289887e-01L, 2.33475238227987351081778389476348222e-01L, 2.41374946307146941036852686683657608e-01L, 2.49455360110240324117132946908862256e-01L, 2.57718899765617581970697551365699803e-01L, 2.66168054991183344330456451077482845e-01L, 2.74805390707512480349974276871498222e-01L, 2.83633552837247137560986852113493320e-01L, 2.92655274295126854671240651245542162e-01L, 3.01873381173592566247581847444990310e-01L, 3.11290799129527708372244037377423071e-01L, 3.20910559978356159579257040371157487e-01L, 3.30735808502408397196150346208941643e-01L, 3.40769809481195164806575214000604739e-01L, 3.51015954951993455453034437018576899e-01L, 3.61477771709954227353934951808660907e-01L, 3.72158929057786693176355712369457666e-01L, 3.83063246815962181179662085907016341e-01L, 3.94194703605313603549231284148895684e-01L, 4.05557445414886871112481166359816563e-01L, 4.17155794468930807411520974095114834e-01L, 4.28994258407995154251335647089270309e-01L, 4.41077539800245330879960121109734359e-01L, 4.53410546000301224452886670053661009e-01L, 4.65998399374169294389180835005701951e-01L, 4.78846447910166863084991969300289662e-01L, 4.91960276237139210883303640625007935e-01L, 5.05345717072748965861316155618037977e-01L, 5.19008863126178679451085258491885813e-01L, 5.32956079481237266942061435303847022e-01L, 5.47194016487605519485083198030599369e-01L, 5.61729623189802041293777914000548030e-01L, 5.76570161325406179304747155047028479e-01L, 5.91723219926146849096660434528676034e-01L, 6.07196730557664332661777342118343230e-01L, 6.22998983236085549221918733111272834e-01L, 6.39138643062032159550125999965534073e-01L, 6.55624767615316158435211030870214346e-01L, 6.72466825156381227156528472165863186e-01L, 6.89674713683532904728192023160169670e-01L, 7.07258780898180476422511449104598714e-01L, 7.25229845133703375815759935882969711e-01L, 7.43599217307171072603779249870503705e-01L, 7.62378723957005410057715275736188342e-01L, 7.81580731433797129025240842779308298e-01L, 8.01218171315894385869574690877526536e-01L, 8.21304567126092639185776756157030964e-01L, 8.41854062430796373280836243276360497e-01L, 8.62881450408419762754617604609421022e-01L, 8.84402204979573743001129336964073261e-01L, 9.06432513597781571704880022546834535e-01L, 9.28989311806106946360784332676954119e-01L, 9.52090319672203976394493741712123982e-01L, 9.75754080221945735296148718924093021e-01L, 1.00000000000000000000000000000000000e+00L, 1.02484839189454300830993201809676807e+00L, 1.05032052037278447499546563674080434e+00L, 1.07643864928417387084533130337621185e+00L, 1.10322609239912797847732993345442148e+00L, 1.13070726686292705163871994441376389e+00L, 1.15890774975714122929598339522250570e+00L, 1.18785433797464608445948646027899515e+00L, 1.21757511162904898441624819295410761e+00L, 1.24809950123526638608045628896113726e+00L, 1.27945835891516450038384515634984238e+00L, 1.31168403390070906172271785633240954e+00L, 1.34481045262708114284870961989593531e+00L, 1.37887320372983270957282413312613361e+00L, 1.41390962828351735195133854106565322e+00L, 1.44995891564449075379247910337230275e+00L, 1.48706220528789860745767637311307254e+00L, 1.52526269505843914812343336632313553e+00L, 1.56460575628650281139860620478932861e+00L, 1.60513905625597123057624111991440169e+00L, 1.64691268854754131266306691391994313e+00L, 1.68997931182218993728102497644674194e+00L, 1.73439429765359879279739907195277543e+00L, 1.78021588806633292063608039095887334e+00L, 1.82750536348865755482665463985323837e+00L, 1.87632722188546688075368971900486300e+00L, 1.92674936989830423931126850366320158e+00L, 1.97884332688633669446426238525349115e+00L, 2.03268444283491461260047065213162138e+00L, 2.08835213117755699197923733656794571e+00L, 2.14593011766347043193461156899167303e+00L, 2.20550670649671136552919447649838551e+00L, 2.26717506507558468055611786100163107e+00L, 2.33103352877266160486316503843066293e+00L, 2.39718592731780603672335804074417192e+00L, 2.46574193447982700411979376412836737e+00L, 2.53681744288793726408585573416385695e+00L, 2.61053496599332371109890452901649940e+00L, 2.68702406934518495604136651525501878e+00L, 2.76642183354607197859959809591833922e+00L, 2.84887335145994878054909245340497664e+00L, 2.93453226247492266642719969961850934e+00L, 3.02356132687313192268979888413460939e+00L, 3.11613304363510221142689168603250629e+00L, 3.21243031530752459841477997957148726e+00L, 3.31264716389468297553121493594219218e+00L, 3.41698950209779795665404010466511538e+00L, 3.52567596462684319748110900008331556e+00L, 3.63893880474980996700862087872826533e+00L, 3.75702486172927248744324880848351753e+00L, 3.88019660533026434144487775885161751e+00L, 4.00873326417229898631367723395410172e+00L, 4.14293204534786760904278361346846386e+00L, 4.28310945344664439881789918389859821e+00L, 4.42960271791643703960803985590050978e+00L, 4.58277133856704814714568853892203278e+00L, 4.74299875999107924880685634942448809e+00L, 4.91069418674686750664370967067014440e+00L, 5.08629455233503443708376995130700228e+00L, 5.27026665631483182008254527988202911e+00L, 5.46310948536451639599392689767712196e+00L, 5.66535673570814692696549699934052267e+00L, 5.87757955612834548026155780285696226e+00L, 6.10038953278194387910748891481975603e+00L, 6.33444193925698167042406747055218470e+00L, 6.58043927778222227422530564217212955e+00L, 6.83913514025466452585283059757581636e+00L, 7.11133842082084256614010724304296860e+00L, 7.39791791517290376256435527130893558e+00L, 7.69980734554450846886947561889535387e+00L, 8.01801085466429447369362846417322143e+00L, 8.35360901670240672837408029297072392e+00L, 8.70776541859238547329480193384508847e+00L, 9.08173387109914748403941266390886970e+00L, 9.47686631571637600605881026375055671e+00L, 9.89462150100714627457776733266750735e+00L, 1.03365745104567901877248523564151283e+01L, 1.08044272334084191011529376038077113e+01L, 1.13000198813377778114411160555843168e+01L, 1.18253436637533511507143176436936036e+01L, 1.23825547515605242739627815508172524e+01L, 1.29739896710116156250639129682527238e+01L, 1.36021822886130624460500072703793332e+01L, 1.42698825668476028925550536958145770e+01L, 1.49800772926032764371676872413981972e+01L, 1.57360130051385708102009640040308534e+01L, 1.65412213786631649993077912938609934e+01L, 1.73995473466468578424134221353716244e+01L, 1.83151802913268898058518900530921820e+01L, 1.92926886631898453200253754020840677e+01L, 2.03370584421782617230641820877704224e+01L, 2.14537359058448294184882229567324528e+01L, 2.26486752306089873609060295600452917e+01L, 2.39283915217729827153789982621787140e+01L, 2.53000199473141826806593837999123741e+01L, 2.67713817411801152928733734963681048e+01L, 2.83510579456049880498903420268116163e+01L, 3.00484718808548719519487088002485537e+01L, 3.18739814671361063943508266371074277e+01L, 3.38389826798966490384466465437407911e+01L, 3.59560255995953567185453470776520193e+01L, 3.82389447239249331007247241110692191e+01L, 4.07030054487934539563244342845687403e+01L, 4.33650688991795367943193597150736221e+01L, 4.62437776082326978417918860128324332e+01L, 4.93597649096797907147762266234322051e+01L, 5.27358913329271476516365756663547356e+01L, 5.63975117818677084656045931084727554e+01L, 6.03727778486785227486990377756623302e+01L, 6.46929802762275435095300960911126288e+01L, 6.93929373529211836464995846228029413e+01L, 7.45114359206196683576202953920800440e+01L, 8.00917327217667406576253702254103983e+01L, 8.61821250323685694884618177226323948e+01L, 9.28366009540655148012445479790749067e+01L, 1.00115581408296888990404128808417666e+02L, 1.08086767832535244787263306357432758e+02L, 1.16826111875294927859522500437909465e+02L, 1.26418926085804724017089848087642554e+02L, 1.36961157770833171464154963091055755e+02L, 1.48560851934901186551056930429681893e+02L, 1.61339833638593274264805190552029918e+02L, 1.75435645332062901686076817427004926e+02L, 1.91003780902460959044883635552383857e+02L, 2.08220265501991356519964932798160160e+02L, 2.27284638923300107785084254230641145e+02L, 2.48423410633602325676190041300652816e+02L, 2.71894066898304725754664440871201054e+02L, 2.97989725118823201634188484455430791e+02L, 3.27044548063367687799351246625873367e+02L, 3.59440051674122988480906333522906174e+02L, 3.95612465308733548542080237354845984e+02L, 4.36061333495907795272034066341690570e+02L, 4.81359584626980835451438312811051118e+02L, 5.32165335780833820345250001609436065e+02L, 5.89235755699686219555872484606593438e+02L, 6.53443371777544904545726289396026874e+02L, 7.25795284228401899442052568196334372e+02L, 8.07455844372956662653935015669559504e+02L, 8.99773467933970120032100931203892228e+02L, 1.00431239295794425220145278602443696e+03L, 1.12289036118559487702348487348886695e+03L, 1.25762340845977552983926843880669836e+03L, 1.41097920290752223402430410334039052e+03L, 1.58584068016657346033724860162595503e+03L, 1.78558210660144726153863412855453166e+03L, 2.01416017149982591387363180452914622e+03L, 2.27622328928316747879110750486628791e+03L, 2.57724301000797348481178480414602978e+03L, 2.92367232516280459791647074886201195e+03L, 3.32313675929073604672388801848045153e+03L, 3.78466551111357505023764578327774171e+03L, 4.31897162016023640570560918832525773e+03L, 4.93879227485091848874762796864624098e+03L, 5.65930305827336833061655557231992410e+03L, 6.49862329247639500380687922515090074e+03L, 7.47843387531893338609063539714339383e+03L, 8.62473434228616623771753210405507751e+03L, 9.96877263348459014531785309952890789e+03L, 1.15481895955939390229775103785535678e+04L, 1.34084311070264939001405447133999516e+04L, 1.56044945390858044276508880692505176e+04L, 1.82030939102313379306065080413190777e+04L, 2.12853506664968077681001285108385025e+04L, 2.49501459804837504640469288880047968e+04L, 2.93183077048218804714595369958899209e+04L, 3.45378531384547339729721217099269346e+04L, 4.07905708493105663079713795820150418e+04L, 4.83003052786320640972382415932704632e+04L, 5.73434124658699200382652517134835469e+04L, 6.82619915902214645340692561470062070e+04L, 8.14806752559419146429293810910586320e+04L, 9.75279950747873086720735652227979263e+04L, 1.17063646220480829492981340691767948e+05L, 1.40913379548158414250243653370073176e+05L, 1.70113785311182551164819299122255310e+05L, 2.05969942671050993972655988038600318e+05L, 2.50129853973569246335608225835338567e+05L, 3.04680843555537948624554921830727349e+05L, 3.72274788636036141079112881438654547e+05L, 4.56291316446017606669036491868612297e+05L, 5.61051155492184554128598135519314736e+05L, 6.92095956581034369089275407099645880e+05L, 8.56556497218119814922783780052161157e+05L, 1.06363880055232600043867227938165842e+06L, 1.32526810122628602501044472769613140e+06L, 1.65694484184724012086108587753064923e+06L, 2.07888647930116015575144959412983113e+06L, 2.61755592013006806905408032351706035e+06L, 3.30771485222622495472503881888885584e+06L, 4.19519229320262625923561042278599896e+06L, 5.34063130025074556576550111959530826e+06L, 6.82457849576702073415053978191461581e+06L, 8.75442405324883181776310371883173248e+06L, 1.12739015977226351727931535875936998e+07L, 1.45761434273968962478096940509724237e+07L, 1.89216932684193810033543675766077150e+07L, 2.46634598680066744212983509402346013e+07L, 3.22814282171121758797754478348568006e+07L, 4.24311457153986975423657329267444940e+07L, 5.60117371443408843149644877281459637e+07L, 7.42617250972307211179134697728146644e+07L, 9.88946135783012173106461237736151683e+07L, 1.32291587547042718239491966847893521e+08L, 1.77776624072745598074170059515038266e+08L, 2.40011058338983426258122648845724399e+08L, 3.25562103364198274177076500687162156e+08L, 4.43725882059376140276746390832793801e+08L, 6.07724621850487716521348005200021505e+08L, 8.36456587985737541719041767923031690e+08L, 1.15706659432645616854021468641216152e+09L, 1.60874082649874296139935339596050162e+09L, 2.24833765794868826938828602052210087e+09L, 3.15878597885133622780330724633488102e+09L, 4.46167708136391137964792211498946984e+09L, 6.33624483104820926953501466923377042e+09L, 9.04813015958867755955007060963155039e+09L, 1.29932136230997226464299124717687605e+10L, 1.87647826121294792855983490567276630e+10L, 2.72570397671288897105662591436709544e+10L, 3.98255345906428893971269386370983030e+10L, 5.85372779401741541532402802418687327e+10L, 8.65629908955310338465751817097315538e+10L, 1.28795973304189874698643530406628864e+11L, 1.92834506543009988305207298557577307e+11L, 2.90551046754580604436065170645660613e+11L, 4.40614548809848580878194871514169088e+11L, 6.72570891877849315226112306772636026e+11L, 1.03348693821219692992886708382137863e+12L, 1.59884055708669585428974649723976740e+12L, 2.49049013421827282502410713540807461e+12L, 3.90652846672458392086943060796482254e+12L, 6.17122514796135424360349149730712054e+12L, 9.81916373648510913725273324679675423e+12L, 1.57380010699156447495769482655375521e+13L, 2.54124546153003122065528612181733881e+13L, 4.13443762840798177552480089332110759e+13L, 6.77814197348597152801493367496981491e+13L, 1.11990628659588449226309821338662554e+14L, 1.86501680604176896658450602560601490e+14L, 3.13089094872498973827438463058389098e+14L, 5.29897884766906828009755247847186245e+14L, 9.04297389980418175348985287558326633e+14L, 1.55625903681899143890977078931637702e+15L, 2.70123006636820081209540843148166787e+15L, 4.72943010505471127882390119991674115e+15L, 8.35377903309658653016536824399814765e+15L, 1.48882760629319165095592517030838223e+16L, 2.67765346603161495578266855417246317e+16L, 4.86043448136949927032370428281054854e+16L, 8.90573551930099331171397006211491165e+16L, 1.64741372830687155232163226493215628e+17L, 3.07708132567301637697547718557883369e+17L, 5.80423410132909767997152626617023549e+17L, 1.10582857062809961361827765317796937e+18L, 2.12831535880807402614537212551250197e+18L, 4.13865153208523558147805437822414497e+18L, 8.13255421212392003487525754214292826e+18L, 1.61514650331257085505245767762340125e+19L, 3.24254846726071819306305572744455009e+19L, 6.58149458108070132105640205170170346e+19L, 1.35083136618309000260400853464983546e+20L, 2.80409383252093739584477712160125327e+20L, 5.88811368346756383731750279395970839e+20L, 1.25092343531246827629449550883330451e+21L, 2.68928027909821563456325160060548474e+21L, 5.85158282566447970019894650702188721e+21L, 1.28891723178894465997393609758461271e+22L, 2.87458276376899763123926200401593262e+22L, 6.49243733510921786856841605747277893e+22L, 1.48528660586708217722481671351080137e+23L, 3.44246915911330706635229848078895385e+23L, 8.08493019686043820711319325430367342e+23L, 1.92450677804809487818429003209217169e+24L, 4.64399266249147072865108838294493471e+24L, 1.13628145208359133428909996372167656e+25L, 2.81966489106069457125481864485455314e+25L, 7.09778155999185636739332722019170506e+25L, 1.81283885012768848640687277115301054e+26L, 4.69901285134453912350857508188703800e+26L, 1.23641970716283295078972799846710910e+27L, 3.30323626121041128601791088120844416e+27L, 8.96255809763889121781104645394017356e+27L, 2.47029485298622611738479511793982193e+28L, 6.91827096055594288255981089299725583e+28L, 1.96918944795841151009270119290336857e+29L, 5.69809260945398128927937198565189507e+29L, 1.67662615639692208356086898776485724e+30L, 5.01790152017155697028174057139776321e+30L, 1.52792989227983448898308499437330165e+31L, 4.73476231836671194909529913837515959e+31L, 1.49357254644677704024642645900767165e+32L, 4.79744116468190818427448048047019508e+32L, 1.56953829640099873205260260372105814e+33L, 5.23165115691024245360777615947271007e+33L, 1.77720651152529094086938101558873583e+34L, 6.15458729957691613373022022121395673e+34L, 2.17346978135660487165909974321640569e+35L, 7.82952989652658161590959525826590591e+35L, 2.87793555407307691688503613867678361e+36L, 1.07976132092345859199417272983750960e+37L, 4.13633773095120704247204289059445522e+37L, 1.61840848971118584374440265082561208e+38L, 6.46977064044782477057521822447781556e+38L, 2.64341365485931635830069155722471865e+39L, 1.10424672830852570286491286394819018e+40L, 4.71784264188126066477442678013103229e+40L, 2.06229646238932771079246843113076062e+41L, 9.22668000516125721911884540275100330e+41L, 4.22654407163273196344404760642122190e+42L, 1.98304372970706651824186968975247346e+43L, 9.53344869097015503904308238124562564e+43L, 4.69791457874020860581396665191487360e+44L, 2.37392310198043657407434802189623818e+45L, 1.23057021186853175270406146048991232e+46L, 6.54634433841169514665337805691594822e+46L, 3.57537181933580491356588477879121785e+47L, 2.00564245353833550563491221890112961e+48L, 1.15605526802890307768061561905701576e+49L, 6.84986780787031295787489135284280640e+49L, 4.17400481521895112076613271616259486e+50L, 2.61687203405285747164128861362318936e+51L, 1.68875034683729772513757434403804400e+52L, 1.12227566600968410062529607944214843e+53L, 7.68396874024867707105114297890426357e+53L, 5.42284961265427858271262866960101842e+54L, 3.94668670179953341522351651523862327e+55L, 2.96354358728813288396379337565903477e+56L, 2.29708639579893951580254665307105346e+57L, 1.83885641420855576075627699143076709e+58L, 1.52104947571124399594694864621286492e+59L, 1.30073229117507111236343155772481130e+60L, 1.15055959114171674001974091149754682e+61L, 1.05326599737372546052564481925643420e+62L, 9.98411420987902083614726789220470599e+62L, 9.80532561593869471877040903652671478e+63L, 9.98246356419911599549241472274732206e+64L, 1.05410221145791141007800297806625299e+66L, 1.15517268478078246328479789979967959e+67L, 1.31457130233411666326872185958326427e+68L, 1.55436240768545731029836466857749970e+69L, 1.91079120600264507732475085854133289e+70L, 2.44361640389071120608105036496582382e+71L, 3.25298382231882323170055543487798304e+72L, 4.51060014002013973693091388809534590e+73L, 6.51882183100190244682597556816883900e+74L, 9.82583446077426763261011103909194169e+75L, 1.54569206362272285597219332482212685e+77L, 2.53934608840816325270469005344260713e+78L, 4.35976399381183611739718946785420143e+79L, 7.82794362746440474440241447663834683e+80L, 1.47089687767430118295343594318257369e+82L, 2.89452707142067428998158759253431372e+83L, 5.96966254160791549191064067088778403e+84L, 1.29127761398105735746114390466172354e+86L, 2.93165653562687792342264563025180130e+87L, 6.99135354753146313546505095265922672e+88L, 1.75267119452597285220967300845626556e+90L, 4.62245013705602071519123099756702996e+91L, 1.28358193316956622609422743295635868e+93L, 3.75583900113839078839602923077406673e+94L, 1.15899172984597870198690174300625365e+96L, 3.77491631543886267838503954431054828e+97L, 1.29884489446238167309781708169537790e+99L, 4.72503894994338488909389270574194659e+100L, 1.81900003120328673954815570724729852e+102L, 7.41696633087690618810014849262359799e+103L, 3.20611699691059820440544154944066069e+105L, 1.47058877007197519318900335321912402e+107L, 7.16419823823864105738627712719272912e+108L, 3.71039762456707726983380527316097819e+110L, 2.04488245427970937306347337109290828e+112L, 1.20042877865473022461473385597117568e+114L, 7.51374437003017211432960701498996352e+115L, 5.01957574634341063561427626174780847e+117L, 3.58272692766569831842277681502801710e+119L, 2.73494777587724855953563379276564479e+121L, 2.23528376407894424768162839028330791e+123L, 1.95808475111824332331314972422066776e+125L, 1.84043191310930565706137359879906765e+127L, 1.85814326069283110784535066904520512e+129L, 2.01743294965577713629069559518257063e+131L, 2.35817761588810149418319514273035811e+133L, 2.97109297417860360975602176456436124e+135L, 4.03953232143581630156016504419988399e+137L, 5.93392306966113219484352196331202218e+139L, 9.42926369344495323976110371737768721e+141L, 1.62284145693287387206611282820134815e+144L, 3.02888447606769418009867639216690630e+146L, 6.13835617501533947725917198648160556e+148L, 1.35253155719194264809220346207577825e+151L, 3.24444736229558294520810049145898860e+153L, 8.48424354492815185029440589500302573e+155L, 2.42189217690801196639615731788461939e+158L, 7.55727585868832926111996462541955391e+160L, 2.58138920742415528768470662656564452e+163L, 9.66580408821980500452620634685578942e+165L, 3.97326060268422220330874023543806264e+168L, 1.79563826725695454978311213353995983e+171L, 8.93514523408268859940137248520982995e+173L, 4.90290834459626229428863642680474223e+176L, 2.97128375542216561281658377940574510e+179L, 1.99182881480698947977101116086872463e+182L, 1.47933813166325570382207702423402678e+185L, 1.21924602572867713843112063103440147e+188L, 1.11695489454371994985095225835122915e+191L, 1.13926159735841086544690160419235263e+194L, 1.29595329494635946555823051599904183e+197L, 1.64694619802426865078234124605721432e+200L, 2.34234840634634342775071057533872554e+203L, 3.73486904651415569743903039850576755e+206L, 6.68856535510325485878978796153529680e+209L, 1.34777842855531871957592541417095863e+213L, 3.06153116112389690978003658017819254e+216L, 7.85439891718825136093879357578783886e+219L, 2.28020371103825909996341632353690860e+223L, 7.50526802410090668256555773098038714e+226L, 2.80639879206390242816779047164860586e+230L, 1.19452560453314111686916354242681346e+234L, 5.79949872394246778903337432628166035e+237L, 3.21835787345388969294352208047085465e+241L, 2.04569666433064103875712173825120783e+245L, 1.49258715453013675730747996991557044e+249L, 1.25277443244629163588528004740184593e+253L, 1.21226842377681326200203984685187270e+257L, 1.35547194242695069046025865235623225e+261L, 1.75524005232377336464776480479935346e+265L, 2.63840064228932918271533450220126376e+269L, 4.61448246937529975889164745570586249e+273L, 9.41280682985947960778964419634581143e+277L, 2.24481910655275049981565977905948653e+282L, 6.27448882996682532882323387040658757e+286L, 2.06060958394918535923518047482752655e+291L, 7.97142764215603564227622164969231434e+295L, 3.64182905892925111147897309560503282e+300L, 1.97007938638916489488880184999451702e+305L, 1.26527287963256941162906241681573766e+310L, 9.67374762635351109418734649102546799e+314L, 8.82892141913231571338896445110187498e+319L, 9.64570405228039780469604907885256630e+324L, 1.26503839487205882730553259131731653e+330L, 1.99740647993660386944495280559643123e+335L, 3.80795083906732148311558637535145760e+340L, 8.79159120777085501704319293452205335e+345L, 2.46549631780369377584312978131661447e+351L, 8.42426490586997547506062762517991909e+356L, 3.51804562259170040261749407236406336e+362L, 1.80129565203500398450083781286924107e+368L, 1.13442688952887433720702641069844446e+374L, 8.81641141946113920681847478154293508e+379L, 8.48338453086470297056624825970987040e+385L, 1.01407299264221993702531525534230006e+392L, 1.51103955764611037180263766796269076e+398L, 2.81641187251957701963969414170240418e+404L, 6.58963120298401361748098859356824253e+410L, 1.94234184512060662929742463444500478e+417L, 7.23884585856411287896767410403126131e+423L, 3.42370598009480301692521696476539260e+430L, 2.06270296737946127496845017607144670e+437L, 1.58907837423540569213464552634511445e+444L, 1.57146131021351822368954401625918115e+451L, 2.00271733703560402612457677241115831e+458L, 3.30238681816736073809946856032462582e+465L, 7.07441603885154545912376402781538965e+472L, 1.97695789038711346120868489115303627e+480L, 7.23713029747673018134344413894888363e+487L, 3.48533178833568221019229567888827162e+495L, 2.21771798011905249239941207476859498e+503L, 1.87265680045956064211817379705948563e+511L, 2.10782709864946331624669282953979957e+519L, 3.17689162904658562291907841456392867e+527L, 6.44105645558316603786838285606330189e+535L, 1.76492886625329297926588753856751673e+544L, 6.56708664348495439553998825816543384e+552L, 3.33415826521812264992257180271069504e+561L, 2.32109565019822213867641474306217000e+570L, 2.22665090852540791532492989207079877e+579L, 2.95839667933009412312396349376762019e+588L, 5.47183877884770709370953901555429409e+597L, 1.41626756773793934414234479620392920e+607L, 5.15692247865370682523431517094128585e+616L, 2.65584978465684945355727442801669402e+626L, 1.94515906011252752522390088574648572e+636L, 2.03729480055734573550624444975610288e+646L, 3.06864139959250122576234946830893261e+656L, 6.68523683038794846390318553081110530e+666L, 2.11879952715090010307995150421897875e+677L, 9.82718465915609660920397095265955939e+687L, 6.71024976037303477285708646634894987e+698L, 6.78677922161865926117102990656018413e+709L, 1.02303626651674990928162545434962304e+721L, 2.31286202012488077377232576408525763e+732L, 7.89245107528823830762373616398932534e+743L, 4.09160120200842896534230185492282146e+755L, 3.24379955366775267129216830328274275e+767L, 3.95912453354472811300573118431549283e+779L, 7.48996232152866120855530906466249236e+791L, 2.21152965349315333956435853596087911e+804L, 1.02632075670404876010930426472294612e+817L, 7.53951068632005171876747821502928323e+829L, 8.83108581906785992138514068848879898e+842L, 1.66144742506056069516088714981068146e+856L, 5.05826477150550571129779691932628665e+869L, 2.51102428144577988853257771418346819e+883L, 2.04822869357369644800523164159313000e+897L, 2.76681803049890115118755008828029448e+911L, 6.23888945414058934548223953019542236e+925L, 2.36735167714072318956060511661796446e+940L, 1.52407555570930344049434626852406921e+955L, 1.67862596848152559342541655995681177e+970L, 3.18990333799710745664618509349355327e+985L, 1.05489081758823555970428507172122908e+1001L, 6.12396788613568122227472934597131896e+1016L, 6.29654583950170379780496166626637403e+1032L, 1.15697821762367329197002183707451842e+1049L, 3.83417721859040383986075244204614475e+1065L, 2.31300589079836393970996707559294268e+1082L, 2.56410460141809897241834340099170971e+1099L, 5.27364125127925215166604640933456487e+1116L, 2.03202107773477151599346823269715856e+1134L, 1.48143334195874803524122054239589157e+1152L, 2.06411274147574456351269054783640404e+1170L, 5.55279829459270893053136130201212587e+1188L, 2.91418497041682586483964699073577480e+1207L, 3.01522322419410790036838054063732694e+1226L, 6.21672053535323172221442203567173233e+1245L, 2.58201182234158741299570291718541207e+1265L, 2.18423750518116545391544630374143187e+1285L, 3.80584781426053416091532316078175593e+1305L, 1.38151208502663182821551093570287278e+1326L, 1.05688876376696945875455031156325640e+1347L, 1.72414525934903045436623350959611871e+1368L, 6.06970176363513871871663291361433633e+1389L, 4.66734911165218107635353767855185961e+1411L, 7.93644483902981870648608149469983212e+1433L, 3.02177407323915414129348065742188333e+1456L, 2.60910294567790325670373269654248928e+1479L, 5.17503694719938298503446121278113303e+1502L, 2.38900287619137048290055040441414741e+1526L, 2.60122790255932170291515511953064757e+1550L, 6.77122378037074355003811222286996596e+1574L, 4.27212445104598645308010594377100889e+1599L, 6.62465696881760614600007097777440709e+1624L, 2.56080093301387999855187759148833996e+1650L, 2.50338804461975863168260136920269977e+1676L, 6.28008959392222170902165204120090502e+1702L, 4.10330805623617785960247879181409818e+1729L, 7.08891597895639626581466081525369401e+1756L, 3.28815937986385053022460003637061243e+1784L, 4.15918117856089374793600707142802802e+1812L, 1.45749058887095094990047184214707565e+1841L, 1.43785687357830444275837543949503093e+1870L, 4.05897446691318032347020269164975282e+1899L, 3.33348114079172166390364845912603682e+1929L, 8.09961164105229487950427444532606992e+1959L, 5.92288638308847934616085992236628536e+1990L, 1.32629748644648493533560071181408206e+2022L, 9.25637244456745511366766862807596139e+2053L, 2.04978139964660371723728495327865680e+2086L, 1.46668915962420498068615471735159780e+2119L, 3.45424976463618489443831684054473314e+2152L, 2.72836294216453749285575709798797945e+2186L, 7.36646679330208627221413509790840381e+2220L, 6.93156469113828331566714060809446921e+2255L, 2.31823213431754954747032929849642953e+2291L, 2.81131341663812436900512315439163404e+2327L, 1.26153121461887745230804891576437417e+2364L, 2.13831434840067269117435765818454673e+2401L, 1.39803888650069112961026818896691495e+2439L, }, + }; + m_weights = { + { 5.90801545776726515999184015930013435e-2494L, 5.43034121836882538817369981204760444e-916L, 9.13645323997978810837635266947225189e-336L, 1.38026921250443161275979571515063966e-122L, 1.95473329586235063070470724741264116e-44L, 5.89765053810344838395474502424100508e-16L, 9.65083022671853583721482039321815318e-06L, 3.18674406396319375693901804428127016e-02L, 4.49940993129051317388425885244478941e-01L, 1.85250678576020588686470383628874232e+00L, 2.14751816323261845650556006802974073e+01L, 3.65018587462837432006103692095515092e+03L, 6.47212478751933019554592655468556643e+08L, 1.92641646488982742563851849719109881e+22L, 1.38994758402678387868517621844463411e+58L, 7.26879966558078977021348471744247141e+154L, 1.04765280279857897745141662958802655e+417L, 7.83837589244484743057347089777048838e+1128L, }, + { 1.10316126712058491420201654940763610e-1511L, 9.01600613495532057799091391040663772e-555L, 5.11904332497495239643103179971390500e-203L, 6.89671333890943322248923557636362424e-74L, 1.17634110503454704251022002576839267e-26L, 1.50757351778282569234155861289206864e-09L, 1.64896113239222241299157252910603817e-03L, 1.70348472687044679146785418051347199e-01L, 8.92604116485216943737039962090086924e-01L, 5.08107015469559685466563888116585167e+00L, 1.70322410074360164066883311173278799e+02L, 3.99580125020294769314748785515084392e+05L, 8.97859410735688933722745437703783632e+13L, 7.52866673518542859464441779223888455e+35L, 5.14816023241024489763203760058639816e+94L, 7.76882384415261869036597544471920535e+253L, 6.83649581024319385239349778375109740e+685L, 1.71685218299087881635674367971803808e+1859L, }, + { 9.87925015299918398144785423598176370e-1942L, 8.71533681693018261767494097538810486e-1177L, 6.57384046217461429576867660255037671e-713L, 1.22572352048272001483240603010122094e-431L, 4.00210488905354704066065300402901994e-261L, 8.68831861142192461329723188826285819e-158L, 3.39344901437582485256542967096807177e-95L, 2.56737317400303409399563341354938201e-57L, 1.99325419812798016097936249998766075e-34L, 1.25616316381741439662336351160566326e-20L, 2.43090464171805920109733890177176767e-12L, 2.14048123340650521217897512392567060e-07L, 1.78351176282128440930436365965135303e-04L, 8.91532759780500845110690795259481658e-03L, 8.30018538939149499579790988285111688e-02L, 2.93820046590635175209882488313404811e-01L, 6.42167019459198241099164736507367056e-01L, 1.25676009815264777866804196778444950e+00L, 2.93241842564261090318837326991751597e+00L, 9.80176974669959846616864231368773370e+00L, 5.49217006325024175243162209529224299e+01L, 6.74415210957129787494085872629636299e+02L, 2.95093734929150449033134748913572566e+04L, 1.05011160163132749880805450719595372e+07L, 1.19276753677448525725842377258604019e+11L, 4.11976276783133288599595346140932524e+17L, 1.77581149088770071821845041850345600e+28L, 4.35594809668394640823177135833505819e+45L, 1.46965529638197726713059781629071505e+74L, 1.14872217888121999297587395528584026e+121L, 1.70677996026663975507589457654701634e+198L, 2.11819696469088836247505505584030188e+325L, 5.33443484802698043954530255107399872e+534L, 6.76327254647744376095801434158695958e+879L, 4.65552684789936854337398747780741866e+1448L, 2.41016379900581970812596189341460931e+2386L, }, + { 1.32133547680717018679108130408012819e-2200L, 2.77712159414975738481258376000179218e-1713L, 8.84696668578869367896605187021695554e-1334L, 3.02118052104884375490712624043751719e-1038L, 4.14765218378536031502305059306013033e-808L, 6.68597993758855914851785488336018106e-629L, 2.33347816130102648013054297856813910e-489L, 1.04733564854277330060008344877597147e-380L, 4.11557211597596026781639255888321135e-296L, 2.96892493585484037081544967750602740e-230L, 5.48318261457236849627593775240447695e-179L, 4.37952763140247483545256113532792419e-139L, 4.93764851567154537678682785150822008e-108L, 7.12882559733493186476365592485215882e-84L, 4.41155760043873077928273281441139888e-65L, 1.80163734340122138141929999274331671e-50L, 4.08343162992111053691005442960554881e-39L, 2.69713878716183124254075973537323621e-30L, 1.88906085681027307067677306620940234e-23L, 3.83661096593349300206254286709601564e-18L, 4.94655966889556498072463502849060578e-14L, 7.45399353944412484667368844933083088e-11L, 2.11213594306352633431635806968088815e-08L, 1.63019937992045999824523554635197574e-06L, 4.57540432069617055539176306478504351e-05L, 5.85085995568316321646161156635372880e-04L, 4.06605991446724517473851752061784970e-03L, 1.76336759267286733236155605055701792e-02L, 5.32246038588641268382381208383524691e-02L, 1.21978563400315778588175663550724559e-01L, 2.27813822026525499121180105863893077e-01L, 3.67880940693987971581072989565083693e-01L, 5.40739096387634225611080390746760034e-01L, 7.57649154875166910544734982341932295e-01L, 1.05508672843049871100505526038205526e+00L, 1.51442893723856346518379289394390563e+00L, 2.30704471829033068051765367243404246e+00L, 3.81265333029628098807578829102732392e+00L, 6.95531454976623073962406546394064472e+00L, 1.42580921706810654107345317832413199e+01L, 3.36149768965581810654207836598212633e+01L, 9.41442967189932119013509095554254321e+01L, 3.27468727748159184559404098660493044e+02L, 1.50134197286985544688570624625182907e+03L, 9.80710571996542847233767661790386013e+03L, 1.00962016775294251580231030319396563e+05L, 1.86536785996695038528848904417900709e+06L, 7.30953564053636331147337800282574617e+07L, 7.52773592822324283583724791889200862e+09L, 2.68310388335555167663870380176682102e+12L, 4.71267149903232936486329698993101877e+15L, 6.42020070484263570170339986066376457e+19L, 1.21445858766272510022421711137530603e+25L, 6.73690008798356003301023318149224184e+31L, 2.86191858315711641955678894569568040e+40L, 3.19319569382394077525802448772198805e+51L, 4.55425948316978466116193749735949380e+65L, 6.33381334198036002776230152386194807e+83L, 1.16685549796591838612114357506921339e+107L, 8.11568192390745193863805331868574764e+136L, 1.57270137093366013936347867540038862e+175L, 2.12621037868720966375758237292361135e+224L, 2.41043281776111273672384537919910315e+287L, 2.06426392024598778796244702435819107e+368L, 1.59767188945824373238194899871319514e+472L, 3.70147206080013271017541277477470426e+605L, 6.04524081068361649977908949693985827e+776L, 3.91244551907499740549590413818514135e+996L, 6.37601410091330839292544093678958764e+1278L, 1.38423256121282951104859278958281990e+1641L, 2.29003319158044389177689218691755697e+2106L, }, + { 1.06947516637266850888077780365944975e-2342L, 4.00222795925000100954191256688394740e-2067L, 6.14269929806784835508930822317395965e-1824L, 2.47129563578700314331274388349812780e-1609L, 5.94856549925636496124140508697277691e-1420L, 7.88155582901689454838569820447222612e-1253L, 2.37169815411747688234160253328737061e-1105L, 3.29576869517934854144272957025066495e-975L, 2.30295331039392476672974731888405196e-860L, 5.07778539549297920546786995561355024e-759L, 1.36309792114536681315299788580123700e-669L, 1.11902249499811588919802641601624761e-590L, 4.83171643219834730998170916090452646e-521L, 1.35092956692688343220060283908963635e-459L, 2.24199581450623280210827812157346751e-405L, 1.56044428013608715771945922727966521e-357L, 2.55762668699602425668170610426828633e-315L, 4.52598451420085229059456309653543845e-278L, 3.31498525601312348031091223503291312e-245L, 3.28982733272263633196035888826313749e-216L, 1.25979671796942324763554469354410763e-190L, 4.68781195667796137227478889031902638e-168L, 3.82963817403632291960149514795452273e-148L, 1.41008655666469634743601323447962987e-130L, 4.41480300426527477757453266178330825e-115L, 2.05796976085320113157119878898298467e-101L, 2.34167766563934625382241547560196138e-89L, 1.00611330011990340950410787621048434e-78L, 2.39886979987338732623660845760149501e-69L, 4.45828722999844038302160563656015401e-61L, 8.71674689717785941226626165471518297e-54L, 2.33608458451638324303027615256535578e-47L, 1.08390303338972947113853753614820116e-41L, 1.06995151808257796332112367831607337e-36L, 2.69524358925375181073032551986305924e-32L, 2.03423384800497240894806821496090050e-28L, 5.30019940271628291011490416486872002e-25L, 5.40212919469588209381281396175343198e-22L, 2.40511019215192441365347431063245533e-19L, 5.15573611643522185168933155470786681e-17L, 5.79902272788904112815174301897601165e-15L, 3.69205735629667547626167545850806392e-13L, 1.42267754195891351150562998109337966e-11L, 3.51991945554992222676432065045765653e-10L, 5.89117093052592385410771587163177426e-09L, 6.98414016831114732860587596174055273e-08L, 6.10836626587512983932161479872803914e-07L, 4.08537274605429873510095058624689151e-06L, 2.15678250632197565791431535444473324e-05L, 9.24312223411418671168580362381399190e-05L, 3.29629252828970123413244980995397823e-04L, 9.99865029818046920794114062146177746e-04L, 2.63018698849220190957883149658594289e-03L, 6.10412221855424181881652487802655548e-03L, 1.26903202004975552477255319538074005e-02L, 2.39564299641088688046037610330961560e-02L, 4.15643030399701933649627965940349917e-02L, 6.69982939046328122378009075425825174e-02L, 1.01314761859197945164098555651429523e-01L, 1.44998628043994675224702383164439509e-01L, 1.97976367297349804840344474368395293e-01L, 2.59785494162963270697436696871054011e-01L, 3.29861530130123082323166204892104315e-01L, 4.07887707779851847083967462215852975e-01L, 4.94160808801609892592520472039421040e-01L, 5.89951040448037491768065148251882226e-01L, 6.97865729437412689560491745121349024e-01L, 8.22260217393657822959055682985146030e-01L, 9.69774604378855851935565350832453271e-01L, 1.15011795553624730201138456447827419e+00L, 1.37728513637309570900453193107529701e+00L, 1.67149809630206531099733950813918712e+00L, 2.06235275406513270776777022052056344e+00L, 2.59399765677200896819549138553557629e+00L, 3.33381238373592320485907218391630985e+00L, 4.38727553184963415451944389447389070e+00L, 5.92410234721624433989387409845478071e+00L, 8.22555400895276009470529071921123608e+00L, 1.17728847794365554942833299884164414e+01L, 1.74186946732944479219083797984245546e+01L, 2.67321347727075416316453470949013980e+01L, 4.27248599090065202592682231550667436e+01L, 7.14514957498311763066605425195361350e+01L, 1.25726649744291050649669245834238885e+02L, 2.34268740301195719755233273502547873e+02L, 4.65674501968291917847819643280019736e+02L, 9.95892168086429019721630255623709337e+02L, 2.31370536252976840857940169336286210e+03L, 5.90416785827987120394897587933071506e+03L, 1.67574959687797819327588127121232764e+04L, 5.36589048987894263464971617898730248e+04L, 1.97001995592318850388501435517959975e+05L, 8.44594440147401724253246450884183480e+05L, 4.31706343383048349864263584742746589e+06L, 2.69343047021169619975848244859698568e+07L, 2.10656056871936774519731164741615606e+08L, 2.12865839525415045164207708849921266e+09L, 2.87579863694102104115679841861873156e+10L, 5.39962441480030320721171298079837788e+11L, 1.47228407211216271679535227733468003e+13L, 6.12702071280434890818621133461421119e+14L, 4.11734705402761288562221821245591184e+16L, 4.76248383365979073253985584808588348e+18L, 1.01935525113816768714253607040570786e+21L, 4.38231774892874881629281035002570378e+23L, 4.15257812330163302032181919338837514e+26L, 9.63578634121366174238646117049249945e+29L, 6.16903528716345189143890155825118447e+33L, 1.24741073700366469803472774007991980e+38L, 9.28495127856215607061013544719468024e+42L, 3.02620640278402325128627613072607942e+48L, 5.25740318414851642612290423653366751e+54L, 6.08377705676929998408087326671143748e+61L, 6.03621188684706784050917948535663342e+69L, 6.83604430657324601596912909835543184e+78L, 1.22207736059289881632444543839493409e+89L, 4.97963284347586492335598341460012283e+100L, 7.01286464121514720750130754209620950e+113L, 5.47091248474436718447273702781160082e+128L, 4.03491215911361460129480089373280294e+145L, 5.15550681905479930138211789209766809e+164L, 2.26698817812971993667638253759384337e+186L, 7.46678442214100282100191345089453705e+210L, 4.44695748246229233245164503407419774e+238L, 1.29997993210113625215904908209705899e+270L, 5.78362417210637255304620183172670719e+305L, 1.41167148054040165920786770540444441e+346L, 8.08286570061195033556699134866983755e+391L, 5.63304784971987527997364020512160855e+443L, 3.08690662195072763023845781932813249e+502L, 1.10165417416868743288711300669064477e+569L, 2.80994196635775688984524212097397961e+644L, 7.73382325928152223721046490397169922e+729L, 4.97761231747547736253787393388911251e+826L, 2.44530978920516083381477794744261645e+936L, 4.76039467365174741738996705683688855e+1060L, 3.22588883912409917905940907837482370e+1201L, 1.21298392121243707893541014829026239e+1361L, 7.92540396126882607375372502759559361e+1541L, 6.05643048475311304903673843949239315e+1746L, 8.67085957383156175019676264069447501e+1978L, 9.95105409544177778456070528537389733e+2241L, }, + { 3.82052466785182332086738926018596976e-2417L, 1.53216690964008904863800245911834695e-2270L, 8.02799618255145245433991916259679940e-2133L, 1.89790062782857972828467648673787073e-2003L, 6.48547054333991583933133337347105329e-1882L, 9.56340910858469468709935501045338939e-1768L, 1.70023842699605420504066989530814298e-1660L, 9.56797730413407205631782708332785103e-1560L, 4.22020698781412857368210883093245672e-1465L, 3.41965451589094380116779072034053750e-1376L, 1.13314142099471085666864638284317139e-1292L, 3.25613842818879565325184054056113549e-1214L, 1.64407833236659941146136019432680305e-1140L, 2.83169222847758408789499219075138705e-1071L, 3.10256729477751738834780026930224437e-1006L, 3.88327366035249790364432313659702349e-945L, 9.62325937366412073215674752789621450e-888L, 7.91532304589191166500084311712723764e-834L, 3.51089649105332123383908279313304145e-783L, 1.32489192907121558509586493733802170e-735L, 6.52783588426344440105254553576625446e-691L, 6.27953766456679638940801082204333268e-649L, 1.72112316179301192237697323835800001e-609L, 1.91704593421434794371085034440245942e-572L, 1.21131389706331685590249812201530647e-537L, 5.93984004695174374389288417212720344e-505L, 3.03411224655952005849867823710301306e-474L, 2.12875962525689396085894169728448953e-445L, 2.66000529174336615171418420545198600e-418L, 7.55590515004675433995195831838744150e-393L, 6.13626926542527991664012204881781789e-369L, 1.76713467741974813886350949888126351e-346L, 2.20926972666826146585381131914638666e-325L, 1.45005559535857920730397373363607727e-305L, 5.97336892939272666152938174641382891e-287L, 1.82640350668529645297131829899777179e-269L, 4.85229717585781075750778298691866187e-253L, 1.29884069259764069953465811099712413e-237L, 4.02542740473423831131996110176920188e-223L, 1.64606390223494048083381164318527223e-209L, 1.00404640707773475495017963404550319e-196L, 1.02517549226209525963922466256750740e-184L, 1.95259262992798399878532201786889482e-173L, 7.68026595299128847616027073204274409e-163L, 6.86431799704342420135947045710241387e-153L, 1.52498555897006686273111644122247925e-143L, 9.16240838899174700108797638312124662e-135L, 1.61152978600632900525315532785259119e-126L, 8.93873956545614240431663830324423008e-119L, 1.67683199253457467411487735035598912e-111L, 1.13606831265305889540738444180574550e-104L, 2.95677983624992268135074874283992128e-98L, 3.13261928574067484199912376683710488e-92L, 1.42665699792617318967988994714464344e-86L, 2.93948527551792820481373266955543872e-81L, 2.87496940202324055984269030763057181e-76L, 1.39640503864001278539518135367012235e-71L, 3.51418022897052500616248358954553443e-67L, 4.76840843576304417158706032926840904e-63L, 3.62171076308676895946675701059866747e-59L, 1.59482985688579594373676029076259231e-55L, 4.20842453488002122572360942178919587e-52L, 6.86443229233076886165541867675398494e-49L, 7.12571665807519317291983672203309613e-46L, 4.83819502081497047116760866720006226e-43L, 2.20465542430951342610708115485440884e-40L, 6.90709560806486502312714752170868272e-38L, 1.52197218506174728353062647705743598e-35L, 2.40955219490267088425869662208370235e-33L, 2.79630904534258562440727543829590381e-31L, 2.42396861904265607424793591553560695e-29L, 1.59749866280800688175296781099864391e-27L, 8.13840485655638493122774039812902482e-26L, 3.25536762868063353648331484818545825e-24L, 1.03750216774182187079375467840556085e-22L, 2.67108014795025059201469276708831348e-21L, 5.62745845137509901846677188959226735e-20L, 9.82072302589238577426509279192638536e-19L, 1.43594941796544038692542800708134381e-17L, 1.77810682024353573557752337941414159e-16L, 1.88354537738694939365287613122504842e-15L, 1.72308010102740811988992770129939744e-14L, 1.37343705888395103661321882765344100e-13L, 9.61866975437486408023966746429500914e-13L, 5.96531965279554928068743818930854269e-12L, 3.30041201040702869600996143071210790e-11L, 1.64031748053937249488182380342568737e-10L, 7.37124149693192472685858181626175497e-10L, 3.01344400817654411848957462000254023e-09L, 1.12717586759651920251576226824261590e-08L, 3.87857240586881913126338809706852880e-08L, 1.23397923410236586482402725064781148e-07L, 3.64729321175679321144258676923993113e-07L, 1.00602028308961790056200899477538690e-06L, 2.60043020837597212496425152713721292e-06L, 6.32419483196640694034831908133223537e-06L, 1.45245521130769448827445571183003177e-05L, 3.16123436155465446648693209598810124e-05L, 6.54176706996526406822348966226430775e-05L, 1.29110196844657112529538619169285993e-04L, 2.43733749771260888436783011892865212e-04L, 4.41314232710451843972392755372463603e-04L, 7.68377076370070526296257588743541811e-04L, 1.28957360159046548970572233319638690e-03L, 2.09099199558542466132447951593809118e-03L, 3.28264889533211879885382599961585359e-03L, 4.99964828308048181967481389975237633e-03L, 7.40157019965966236427260197490815304e-03L, 1.06698107000950941317328124490909795e-02L, 1.50028172314973599445873815719412949e-02L, 2.06094173096225141746698709598883056e-02L, 2.77006834377238972506888931261097291e-02L, 3.64809756186562309685025492261970114e-02L, 4.71389254316798953989957737554750583e-02L, 5.98391571230828379216832783213494747e-02L, 7.47154814906505012222514984217472816e-02L, 9.18661612946071289937159187843364627e-02L, 1.11351656134035569001793372114249223e-01L, 1.33195038632804266520840073116724199e-01L, 1.57385060631367271607409153973946866e-01L, 1.83881661881487488373471043449811640e-01L, 2.12623571664368840241407884037664753e-01L, 2.43537565151706738569000265542366947e-01L, 2.76548903119165441078310983457425711e-01L, 3.11592501651099485071285279910294521e-01L, 3.48624439429573943493094167043683901e-01L, 3.87633503629295959856799538075546008e-01L, 4.28652590594010568395685064250714546e-01L, 4.71769904763931628640496795425394984e-01L, 5.17140031351419396580841715288928105e-01L, 5.64995090385812394527782017926592446e-01L, 6.15656310347513453519162300561374394e-01L, 6.69546490104796171397630195486014552e-01L, 7.27203952634969644713241799501762825e-01L, 7.89298740343220248874987146571520149e-01L, 8.56651969968232039115451358927023892e-01L, 9.30259468685761614462731685806948992e-01L, 1.01132106970032064396659635282297935e+00L, 1.10127727814330022383089577768540741e+00L, 1.20185545627576044892754956074556492e+00L, 1.31512826035991923618357153643853889e+00L, 1.44358784334344214073911010244139658e+00L, 1.59024039033833533691274024525328135e+00L, 1.75872697808494229887678505228447105e+00L, 1.95347868511083813992081514830258545e+00L, 2.17991652311273637078595706271805585e+00L, 2.44471039181719695746189348680321367e+00L, 2.75611627927753518177812012686624980e+00L, 3.12441791418753602036992277268322970e+00L, 3.56250886504706839116501560040688156e+00L, 4.08666490215568913223544572173213403e+00L, 4.71757610938540508471197077535051869e+00L, 5.48173646271881799502596740262131127e+00L, 6.41332945820485042568468273867868285e+00L, 7.55680806548694121454415120092330575e+00L, 8.97045530296518503588356381213781124e+00L, 1.07313427967993620782556935698599286e+01L, 1.29423018529722651121181556330024768e+01L, 1.57418213494311260952898800974816324e+01L, 1.93182476307453478113061967921720372e+01L, 2.39303783823625958630927317369382100e+01L, 2.99376708353783067254755016259184880e+01L, 3.78450834852449540061461594823397372e+01L, 4.83704762272558588741438572877597086e+01L, 6.25472526597377774327448466299291048e+01L, 8.18828352821743059070051234981039846e+01L, 1.08606901707010877244713106575898588e+02L, 1.46066165572767230787668444759129144e+02L, 1.99362305840947908376533577788614663e+02L, 2.76400238552833065835531188582929358e+02L, 3.89641361583293015149089847924625396e+02L, 5.59090899610510721528958323850657754e+02L, 8.17488717203324414010281686447524861e+02L, 1.21951707162988010780952106506178041e+03L, 1.85849349228255485567535180727353270e+03L, 2.89733723527987926224598061281533634e+03L, 4.62742546807418291953673117361684539e+03L, 7.58336312821976325886140349375631572e+03L, 1.27729327383211423049145373221610484e+04L, 2.21512103826316975884795094360035657e+04L, 3.96282043351341952537133210137390141e+04L, 7.32802430573798143066819092764851057e+04L, 1.40370956832174099704802040273767653e+05L, 2.79169596050238213326100612230710484e+05L, 5.77851587758831222006931720166846758e+05L, 1.24809297513500168708148829224766608e+06L, 2.82070529249367448006501528915158547e+06L, 6.68996112716468438709724989481100128e+06L, 1.67032788479232576626369550400657265e+07L, 4.40490689805489416603930530460183080e+07L, 1.23130681270188214533524272282450985e+08L, 3.66207397185135919222246119544674802e+08L, 1.16348659359258561581772655083768774e+09L, 3.96573293875598360514367483348534276e+09L, 1.45675716212887953801924286655056170e+10L, 5.79499965416005488651946885694232582e+10L, 2.50933409077965035999243371354527615e+11L, 1.18927611174028691004735513584719908e+12L, 6.20525591975150642720259081452168385e+12L, 3.58662837399254785268923887857175768e+13L, 2.31171019709164125040709702173384790e+14L, 1.67323267937848597801576240028274938e+15L, 1.37027502568098828908714302508292741e+16L, 1.27982243687884271019103805104886411e+17L, 1.37488860693662981360604951513000987e+18L, 1.71428840498039054019366079813545633e+19L, 2.50480806231532255799256901000499530e+20L, 4.33295295852175693203040531656862705e+21L, 8.97105957110885650118812876460940777e+22L, 2.24900305994354872692347113786351015e+24L, 6.91168391281314093810281357471213740e+25L, 2.63834638817928808592115398804015843e+27L, 1.26855240154452496477895137567276885e+29L, 7.79793937981300078349411089481829644e+30L, 6.22628875244383647460445596438511369e+32L, 6.56725010457698317225350638943220187e+34L, 9.31627142136562734426709726532855891e+36L, 1.81178764804393998725363596058882739e+39L, 4.92965709962256757369004572197380439e+41L, 1.91768799703732643541855471608092309e+44L, 1.09145348658581711775073448931123050e+47L, 9.31447898399194268806130290915959528e+49L, 1.22344767896866261290498650189275522e+53L, 2.54310892512613676637994972961780173e+56L, 8.61698733620595754888079045068786616e+59L, 4.91184107780000171015313299477683427e+63L, 4.87081518596258225878777239561036595e+67L, 8.70837775558769802630502082888045797e+71L, 2.91582292448921588681558819522688100e+76L, 1.90391730055994678151666350663451590e+81L, 2.53108226877386875309925515429807108e+86L, 7.17216745327677632991407821508792163e+91L, 4.54861980767233963821254711174889633e+97L, 6.80080274478233195724672872122891978e+103L, 2.53345776553427904264312812304869400e+110L, 2.49408335416956941404546574182091219e+117L, 6.90831393215899350999406217643925461e+124L, 5.75535983268412076946168827231484587e+132L, 1.54830478033444708124258729693098368e+141L, 1.45063275961171552593742069490051326e+150L, 5.13010920252030309322157027524520131e+159L, 7.46051857949218271625227134136784373e+169L, 4.88752936708905952864518859469811383e+180L, 1.58944916201304126296752123375100638e+192L, 2.84523891966215233479427916942262824e+204L, 3.12952175960493682046861415263020503e+217L, 2.37781288259852734112773228061886887e+231L, 1.41367934226264567696479785830917722e+246L, 7.50969021632501856297416076380790606e+261L, 4.10517599617698914085666788248374635e+278L, 2.68396648103470580650904518179723689e+296L, 2.46300967872463438914762759549033346e+315L, 3.76174998591379278617806685202641214e+335L, 1.14633505463399943022299924904504898e+357L, 8.45422653379120782973725460577460520e+379L, 1.85322036769366179986950823638998209e+404L, 1.50271794914844405931928670543344206e+430L, 5.68929995100375677797682848265066614e+457L, 1.28862756145762463302669091988538860e+487L, 2.27343599851542201859662096966470860e+518L, 4.13728378647859018626664278751490836e+551L, 1.04732962553987345589103224110962753e+587L, 5.07014442635227334186619020470235649e+624L, 6.58680466182542570069097938912153401e+664L, 3.29371230247950075139843014589562364e+707L, 9.30666782392729638823808617314515754e+752L, 2.23612238313938342458217832467289997e+801L, 7.05882324392654993625063412318352329e+852L, 4.65192550274585790446586136162724180e+907L, 1.04784460655109112066824552095698697e+966L, 1.36343029663707923380723270729436320e+1028L, 1.79162856963805080764174564008589158e+1094L, 4.30919215868732016052648412277675057e+1164L, 3.57261639332919274471338835639300206e+1239L, 2.00290113950626521919894557483624467e+1319L, 1.55571074565195195355910058210877816e+1404L, 3.59251763773431142332284400696144078e+1494L, 5.55982146221013438636549073847422510e+1590L, 1.36984614652427999087777938149635656e+1693L, 1.34965612662661283517635152647662065e+1802L, 1.41743602676194002368496649429520279e+1918L, 4.50570145843130891260063218260174869e+2041L, 1.31668432261399763150332726270146708e+2173L, 1.15414484031205360166874295729734758e+2313L, 1.06861618403043050305720276519487893e+2462L, }, + { 2.99827136671822203139659705254947108e-2455L, 1.24882827026046387418324170521821293e-2379L, 2.44988423001973909940876922057761351e-2306L, 2.66927540888423924256197676379835451e-2235L, 1.89512300782142727523964560129359997e-2166L, 1.02360851047736978252291085443458258e-2099L, 4.88730957021167285814599122540648196e-2035L, 2.38575973739960063984613176811112623e-1972L, 1.37101430897591401677957283544539320e-1911L, 1.06333264218828160158212770967007648e-1852L, 1.27067801926958817891969964688113127e-1795L, 2.66010333678426336904594890897508436e-1740L, 1.10484167956085896672647638913688653e-1686L, 1.02711572445228877679664077673865962e-1634L, 2.40228312498468537472913439313888633e-1584L, 1.58314329557188545251248547330891601e-1535L, 3.28094781159949863603124081342946968e-1488L, 2.37840601013012306745513950331950428e-1442L, 6.68624945754691841776166731458196006e-1398L, 8.05587986859135128455444199209469004e-1355L, 4.58316096287519065423952255855034306e-1313L, 1.35248343166964409448147921555689922e-1272L, 2.26752160966952001157168922897574770e-1233L, 2.35909278572023604645731071940961914e-1195L, 1.65903351294385543451470844717805067e-1158L, 8.56804094411838080986008744972959423e-1123L, 3.52140713988280887124946897137042691e-1088L, 1.24502439015653832112887580419259567e-1054L, 4.08361208615792538039018647193947162e-1022L, 1.33685935274460284904788097419890160e-990L, 4.68914584779066055505548198640894341e-960L, 1.88761464755010821415650640440428715e-930L, 9.32118389977759099804089947706407268e-902L, 6.02287072293155834327191570771930380e-874L, 5.42106639858656175956621834625906078e-847L, 7.22191826970524227339284882890548040e-821L, 1.51020072122639353372149509671977024e-795L, 5.24775126181523166368024963040824842e-771L, 3.20220580014087429159629013136223785e-747L, 3.61997704502523196516304924921584345e-724L, 7.98492800624004092804929885145612391e-702L, 3.61392988815279171930655913638563273e-680L, 3.52366894930304180660437805611575996e-659L, 7.75941790954346674475792064117877807e-639L, 4.03982705605992279012386676527754690e-619L, 5.19834669028776461984659088482903679e-600L, 1.72588931588477933787290173538689408e-581L, 1.54137268468058258004178745033532316e-563L, 3.85562019823508006565291873935904091e-546L, 2.80916830174896024691081755907263354e-529L, 6.19212992045820718698085583700822639e-513L, 4.28406369726641450642830646435371014e-497L, 9.64070107276137860266813577293097959e-482L, 7.30474502980487251348070249880206420e-467L, 1.92703875472217605577664104239882285e-452L, 1.82836317722867439282495454446115074e-438L, 6.43850535226391166629598797094394826e-425L, 8.67564527079512826366041439069686406e-412L, 4.60732378382987117665981750506044471e-399L, 9.92355019653945096209219622811507181e-387L, 8.91282113369599082908019662526444168e-375L, 3.42910268669860807072991706793596262e-363L, 5.80083861220020883214825204353252963e-352L, 4.42512315593917892307328787082985460e-341L, 1.56000404760553377203351190297454435e-330L, 2.60259125151860978088621742839596354e-320L, 2.10262994916038774260354592873630300e-310L, 8.41173460487346663387701675407432002e-301L, 1.70280612724644563266907394311476267e-291L, 1.78116409086610297225917597830385624e-282L, 9.82480313804105048460709403983300504e-274L, 2.91457791899830525764575140294420231e-265L, 4.73965774855838520901565109021450612e-257L, 4.30398176296336788976377718753404885e-249L, 2.22193567988028967419035853512154624e-241L, 6.63553772275767193165934337486647504e-234L, 1.16578412206922730540647811503608703e-226L, 1.22474675486304476176402962758102117e-219L, 7.81684108965031293490823429466674471e-213L, 3.07774321188900147460180897292349446e-206L, 7.58759251414243265302591311385078772e-200L, 1.18823395876906229284835410783359514e-193L, 1.19864235179097517931485807315756884e-187L, 7.89484815058732018316693655376229205e-182L, 3.44001585820470930356951346759790116e-176L, 1.00429282413458278190733306028479555e-170L, 1.98881516262612704197372631141044676e-165L, 2.70364023416269358290386889178454878e-160L, 2.55241036356528886321774073237366662e-155L, 1.69227628517124062919375344585284149e-150L, 7.96587271931569005985245219884752131e-146L, 2.69038016965415710141558028398178580e-141L, 6.58640142296301821553052201959182941e-137L, 1.18042002159083828066729019346791192e-132L, 1.56367343741949029569249898774237153e-128L, 1.54531048534737740803236941099285613e-124L, 1.14963627239221457328345144952502533e-120L, 6.49493107141223206477306791588740146e-117L, 2.81018975962531457950258683552245790e-113L, 9.38876009983047538463236277234608306e-110L, 2.44144614978077332940218030178369234e-106L, 4.97967380423964535764132428105410190e-103L, 8.02629250855504170950085275141889693e-100L, 1.02975774422556528975197839046564511e-96L, 1.05903428462392788554333849690582167e-93L, 8.79012224539705420215807394822091933e-91L, 5.92725904620589386119574720007659266e-88L, 3.26785695641876626125438772016710733e-85L, 1.48222090912512196733576972776187035e-82L, 5.56431172687041304333655416134228735e-80L, 1.73894644850180973193834439393406052e-77L, 4.54974501627115811330277659341709811e-75L, 1.00204791018402181301004224966380115e-72L, 1.86763466487726841127561204857118883e-70L, 2.96092907372076963741238677845263773e-68L, 4.01290356278003207547213477434374557e-66L, 4.67174973180940285995675266523420122e-64L, 4.69376738484344030975102668254954324e-62L, 4.08839867480777582716177965835471551e-60L, 3.10086294017966876521788239138705860e-58L, 2.05664262860193002265928563040484563e-56L, 1.19777269867460483717671801459380654e-54L, 6.14987857896674930479991965502306936e-53L, 2.79459594105487367405294144558243202e-51L, 1.12814222153195027375952194262805170e-49L, 4.06053088698370288660361299969573584e-48L, 1.30770277764601303984357205166621959e-46L, 3.78118998998858848129267831928491324e-45L, 9.84875712554165931773609676827898732e-44L, 2.31826871061275836674260034702071180e-42L, 4.94684766719278736886703293137447413e-41L, 9.59814033368779163526953048426266162e-40L, 1.69828465632158908850726775955673984e-38L, 2.74808806067694979431131601699073400e-37L, 4.07794734980576448596813627579221148e-36L, 5.56417400808680411162969051547065270e-35L, 6.99889732124326604821939972498753725e-34L, 8.13608686966403922600365716655177400e-33L, 8.76218322965140584555660990677761542e-32L, 8.76276637192578280309577248461260176e-31L, 8.15628170980170063345810303188191933e-30L, 7.08149199986036059275640615879247609e-29L, 5.74736606938180421303095720610698091e-28L, 4.36944079330436317602800446372377792e-27L, 3.11795190731786551713306066746724497e-26L, 2.09240762901978141675541589343048983e-25L, 1.32305299259448285811442078319939693e-24L, 7.89691997711578359267081292526106870e-24L, 4.45716605711992632203887297614028920e-23L, 2.38302054707699751676620265710858837e-22L, 1.20889613263470803214753580918237251e-21L, 5.82833462566546297036431040060608322e-21L, 2.67469784973934035752489871481337927e-20L, 1.17014393860453605367131279149462226e-19L, 4.88739480774243667158625429475089610e-19L, 1.95168062031382677617975635339602042e-18L, 7.46163208304186839076058133462415646e-18L, 2.73485791500251557979443670181385630e-17L, 9.62223074873981898938153222962813147e-17L, 3.25389617800670808719193210653774700e-16L, 1.05888451003262711834291997535706834e-15L, 3.31989417456924550647348023471492055e-15L, 1.00398818028880718004903688096398433e-14L, 2.93186753434992804142094819281287207e-14L, 8.27635883877837412701034478711895464e-14L, 2.26082510653047710401828799240495861e-13L, 5.98228146965673437508140635644104873e-13L, 1.53484657642706271558550260287175188e-12L, 3.82185576688620308819449258941130914e-12L, 9.24474797424185856221360345157220406e-12L, 2.17427909729908200066806520833424743e-11L, 4.97635090813511876195380613765617708e-11L, 1.10929412007484858271399815868498117e-10L, 2.41032585809105707126681740366639425e-10L, 5.10905559690208602233885434283852003e-10L, 1.05723928928894498681155298267174319e-09L, 2.13744795688281626795384543565327267e-09L, 4.22492806022042378177884800843897317e-09L, 8.17046853836402216132200964074977087e-09L, 1.54693324186061707441588930749976281e-08L, 2.86930859292637487108510416894642893e-08L, 5.21722334965282980403485300265738444e-08L, 9.30518593041943674159836371480799295e-08L, 1.62889442240265382985512933741863589e-07L, 2.80023159222713498193152226335713707e-07L, 4.73011069732904671695491353591017402e-07L, 7.85526363421471709139200654941264315e-07L, 1.28318979177475296348420727772184965e-06L, 2.06292423671439573062357518920248604e-06L, 3.26552286428871054459476770292453844e-06L, 5.09222413107163744070769490625113325e-06L, 7.82617466349549247600633222001776503e-06L, 1.18597235737360853531010814128200937e-05L, 1.77285167845861097132511756107809923e-05L, 2.61533347347083551795448324767635695e-05L, 3.80905294601878233958593851046717171e-05L, 5.47917574609632216617322114415284106e-05L, 7.78734661207721580410532787755478685e-05L, 1.09396271310786841597436260479638662e-04L, 1.51953965111990518244589142984584154e-04L, 2.08771424329052859462812228725402767e-04L, 2.83810167897154635400111152886276561e-04L, 3.81879755641776745662197699923565149e-04L, 5.08752658539288473040921063606067979e-04L, 6.71279691879016478989727452815073290e-04L, 8.77502619869410964596211481799673429e-04L, 1.13676014562695660388935295197579588e-03L, 1.45978322435393926290231969328136083e-03L, 1.85877550576562291461373383997358853e-03L, 2.34747474413929171623192976971642926e-03L, 2.94119122257973574562047404684570218e-03L, 3.65681962518947136825693675506580632e-03L, 4.51282135037802008049500003706382224e-03L, 5.52917497487431572466643627095469859e-03L, 6.72729342693880289247231232743320046e-03L, 8.12990737739402925191380506695287882e-03L, 9.76091537148098089988167779205704956e-03L, 1.16452022628003896766716791241908478e-02L, 1.38084285310255098081489577923406060e-02L, 1.62767940269060299249627834088541599e-02L, 1.90767805535439719611430291452241110e-02L, 2.22348784290424057418829018676115193e-02L, 2.57773027557106041232220835190089403e-02L, 2.97297055256785242037107379259364943e-02L, 3.41168899105681014303940274877700652e-02L, 3.89625331103873045168982262850032695e-02L, 4.42889239784348614272085648656341809e-02L, 5.01167213062401896725837060595306942e-02L, 5.64647381631055655160905842942135176e-02L, 6.33497570613638646379858081046281019e-02L, 7.07863799874088410337603891340254733e-02L, 7.87869165286187403201277486249691639e-02L, 8.73613124671846027274852311959507760e-02L, 9.65171203330026184766273626679604986e-02L, 1.06259512537229504582581766840088037e-01L, 1.16591336871525032405196867775170242e-01L, 1.27513213378027801743713746335418149e-01L, 1.39023670890726644461647310110564995e-01L, 1.51119320935163034926767802526948718e-01L, 1.63795066161333054101624624583286900e-01L, 1.77044340081249140375155906842322507e-01L, 1.90859374591070988709995096163492901e-01L, 2.05231491577749618625157075644473454e-01L, 2.20151414838427133582099008248376327e-01L, 2.35609598571509171617873703655361587e-01L, 2.51596568823441496049692748064095951e-01L, 2.68103274485319808338763876413696112e-01L, 2.85121444718080293120944366000785895e-01L, 3.02643950033175240463650928525241062e-01L, 3.20665164656273759511495325736015581e-01L, 3.39181328243896232934423095526947639e-01L, 3.58190905496894238632513262989320923e-01L, 3.77694942711148444854921008885136613e-01L, 3.97697420816736709936441112125746846e-01L, 4.18205604975383785180004107895309545e-01L, 4.39230391326913892071217294036947977e-01L, 4.60786651994838310108569244001462874e-01L, 4.82893579976783682783259082280697090e-01L, 5.05575036056380615456191240843198089e-01L, 5.28859900380164343616138823034844308e-01L, 5.52782431848141026163801711629569094e-01L, 5.77382638973537667728623589540847426e-01L, 6.02706666380887845415163251209767664e-01L, 6.28807201638412861233038059400000985e-01L, 6.55743907668438480076422889144751851e-01L, 6.83583886557560546105565188637319809e-01L, 7.12402181207131050122140520074497354e-01L, 7.42282321936634874071712163942668772e-01L, 7.73316925891616774766609626518222875e-01L, 8.05608357929825762678392686079844024e-01L, 8.39269462582114444255866071824225817e-01L, 8.74424377728731780655872302934188327e-01L, 9.11209441820152654384317758539800255e-01L, 9.49774207830947999703385257169606442e-01L, 9.90282578695719860661750084965348602e-01L, 1.03291408077266220499949941381670461e+00L, 1.07786529395310786342015831094913754e+00L, 1.12535145943113425409772316889306152e+00L, 1.17560828892019106387681852443264510e+00L, 1.22889400231711865029290591255755794e+00L, 1.28549162454200134646596760738351906e+00L, 1.34571157661211478758710729669915294e+00L, 1.40989460104228631141154693756330089e+00L, 1.47841506752326819907071392253335661e+00L, 1.55168471165732988584072993312632620e+00L, 1.63015686749586045646523839878119043e+00L, 1.71433126392888582869445858515841385e+00L, 1.80475946586097450583979351681595524e+00L, 1.90205105385821569910651758727035418e+00L, 2.00688065090883085704250790253631297e+00L, 2.11999592251508776978462701922381176e+00L, 2.24222669701791864392841075957133612e+00L, 2.37449537743872890090165532424204567e+00L, 2.51782884491687412950125924770996677e+00L, 2.67337208788498443977901451698681543e+00L, 2.84240383149636938582597352632467033e+00L, 3.02635448975787151687626271616744396e+00L, 3.22682681985641084640836568780538092e+00L, 3.44561972615851906798292101239468486e+00L, 3.68475574257857058166416238846674883e+00L, 3.94651281922700641882215705186324970e+00L, 4.23346115586300426882702466682124288e+00L, 4.54850596485993372358839139642384894e+00L, 4.89493721528314838282250644869812537e+00L, 5.27648761361579143482640951008870741e+00L, 5.69740032348777653019331418706396336e+00L, 6.16250822618479874280298612217822529e+00L, 6.67732688781902305621720870171254858e+00L, 7.24816384288680618425673773908490765e+00L, 7.88224734633420137754997440176783259e+00L, 8.58787841076847338040196250304371454e+00L, 9.37461076170556588083589376387132811e+00L, 1.02534643490360208202755813725095827e+01L, 1.12371792943596952958405098972799626e+01L, 1.23405186912073323038589589843390563e+01L, 1.35806305843369735705552654775963352e+01L, 1.49774818320198815684165550755584428e+01L, 1.65543795252306978072060668000283508e+01L, 1.83385993586213963662082373601202455e+01L, 2.03621450242974894275535474068497776e+01L, 2.26626685943754163096516986406459795e+01L, 2.52845893136112912405786286347442878e+01L, 2.82804576829875229843082739941801350e+01L, 3.17126237580911006574531329780573620e+01L, 3.56552839704483033860162655552985983e+01L, 4.01970005016327611735412627281826315e+01L, 4.54438126123299012690083228854751285e+01L, 5.15230920902650058925899224137885947e+01L, 5.85883374425407037894686827319101058e+01L, 6.68251567023112069515824430636222454e+01L, 7.64587608768192360600680527705062884e+01L, 8.77633846894782777864438965135974549e+01L, 1.01074175868700380244224060820937268e+02L, 1.16802258994842453002226105258170771e+02L, 1.35453898714114297683765730207366657e+02L, 1.57654978967903747896778920825912898e+02L, 1.84182405906460887204718250035971904e+02L, 2.16004568481915370203941996632993398e+02L, 2.54333702516246823953928460722661707e+02L, 3.00693971336392029288524445812313026e+02L, 3.57010397089553597741305454749296236e+02L, 4.25725590115811669827894375931285872e+02L, 5.09953725643224718975881101989299450e+02L, 6.13684687521816216675628323432708789e+02L, 7.42056139017496594867562213902074498e+02L, 9.01718069398279102081695287947885045e+02L, 1.10132394119371945146169423670051948e+03L, 1.35219615071533062822615520086342752e+03L, 1.66923291068630661586092129359067647e+03L, 2.07215152332054272741081984137877196e+03L, 2.58720328209038570262408045410782795e+03L, 3.24955382874419473343636700904469745e+03L, 4.10660860213453501373964026030452875e+03L, 5.22268955795277619388623264624171874e+03L, 6.68565726355089669998707553230747827e+03L, 8.61635357331041935557199135249564277e+03L, 1.11821636876213398227716019227207708e+04L, 1.46166395927660444135310088609126834e+04L, 1.92481111548503807855046302083949422e+04L, 2.55417294787310992653570084425920733e+04L, 3.41617486573493312682855974958999477e+04L, 4.60645561151339657587241032816274431e+04L, 6.26388222783949624156629031841856307e+04L, 8.59184957335087735876745002390386986e+04L, 1.18909441895224029432207119296169161e+05L, 1.66095033938427884484826987675525104e+05L, 2.34226252811038979343276539537003434e+05L, 3.33568602948986258437654580586715228e+05L, 4.79889988962864687601246140266254885e+05L, 6.97663061660509733330079420786394691e+05L, 1.02527964914474052697145671441285507e+06L, 1.52363581455429196593138247075709981e+06L, 2.29042801548317740734746692037333714e+06L, 3.48424008370597272699707163872949391e+06L, 5.36561882022124111785765119998290944e+06L, 8.36799594465384427071057649003523823e+06L, 1.32217203482688374239659605009398927e+07L, 2.11738506478689471767346755297403608e+07L, 3.43829654204789362343598103327212044e+07L, 5.66383460344826705635075490736605924e+07L, 9.46890531446099216978642309212033877e+07L, 1.60736860537955754766368401888105613e+08L, 2.77184337816824251216810756452423932e+08L, 4.85821891491727553231947839400706241e+08L, 8.65895043719996967916785083318862010e+08L, 1.57023595787763814315717820663521931e+09L, 2.89877916582589084595240112564380085e+09L, 5.45082862939618857716273065316347458e+09L, 1.04462776299019818355322697028773431e+10L, 2.04161928476231748290058801874576093e+10L, 4.07167362508726715447348035164126587e+10L, 8.29154750329098975446073110291771593e+10L, 1.72524569678310615987347680670953976e+11L, 3.67042596452982637114653516749325639e+11L, 7.98985690430384590881851382687868095e+11L, 1.78088199348481822130071407591775159e+12L, 4.06753710066430378340194042741373814e+12L, 9.52719664341172412580158176782396629e+12L, 2.29025392291311484677517351429897325e+13L, 5.65517100257158446400477892790807623e+13L, 1.43556057453169991412842468344287817e+14L, 3.74966777273576618576956864828262686e+14L, 1.00868013060119404846072345341681988e+15L, 2.79711270328189457750729359218050034e+15L, 8.00353033476527491290557180677857043e+15L, 2.36538022352308798092653239020367364e+16L, 7.22793756862980926623333746953184515e+16L, 2.28603237125675384523138361921766753e+17L, 7.49169357670736182787260118136384206e+17L, 2.54681528722697062733706069581540403e+18L, 8.99167123461421679854681325569917778e+18L, 3.30088716836331393064955543786333400e+19L, 1.26155602488854061815298573346753948e+20L, 5.02601059129997078887664234449072840e+20L, 2.09003840003334609133024432910535654e+21L, 9.08427629135679092557541630988833736e+21L, 4.13277307337650905633261831455054852e+22L, 1.97077591472219550165099701845426740e+23L, 9.86567192878194333593095251120628263e+23L, 5.19253827231351201624600034890440225e+24L, 2.87797813261600767124658244003026900e+25L, 1.68253103834271529795445964171621893e+26L, 1.03930300492804406447430223922613789e+27L, 6.79491179196076158722692150701779494e+27L, 4.71054472298412825215699352759734253e+28L, 3.46906218798171940969795067049186910e+29L, 2.71919469298029646397308102518695120e+30L, 2.27308597305997987201797057125811269e+31L, 2.03060816941963451979890589753656719e+32L, 1.94261454794602808054773809715560372e+33L, 1.99453642796409945684693816457728868e+34L, 2.20275757078165507105373401305070760e+35L, 2.62280693187648585243154230451397289e+36L, 3.37503469494102278406378324431267258e+37L, 4.70514262885548973786602859197635105e+38L, 7.12449819522227214155183099218285736e+39L, 1.17479491699687500984526531336188586e+41L, 2.11529840618171125644793575486664802e+42L, 4.17057423654484355854313046574264130e+43L, 9.02996402249218455912158145716517353e+44L, 2.15344195364580091650722699472214395e+46L, 5.67373854091156226750041136308702235e+47L, 1.65679493344512341491651081156308385e+49L, 5.37959274142567387437479000715431452e+50L, 1.94883090765131732574822421459033340e+52L, 7.90409930117048365355172083360408902e+53L, 3.60198039300535878643618051284879761e+55L, 1.85117602089555214211892984185617326e+57L, 1.07703344015399312416171835284404207e+59L, 7.12190311508435674119313111798381629e+60L, 5.37418888386167437844586074702336014e+62L, 4.64729650833728307491157079699691435e+64L, 4.62526710582644946748054017004844382e+66L, 5.32182077764493049141810605179622557e+68L, 7.11164697902038500579051989777466680e+70L, 1.10899515910236266304919828966923200e+73L, 2.02799605144484652148788128416483129e+75L, 4.37097775363901059074163853783972656e+77L, 1.11616878412036714566047843287003825e+80L, 3.39514715649439557125494531010505893e+82L, 1.23701982128373508607730444611285161e+85L, 5.42965793175551379743384549971838572e+87L, 2.88810817234216647705316265060164148e+90L, 1.87304637361264791993354548498385904e+93L, 1.49042693797246054384025095285834884e+96L, 1.46460222682423294988692623274219021e+99L, 1.78930667727185631768641895397399502e+102L, 2.73657637241785643461962451320315667e+105L, 5.27697387534476684848681508483720442e+108L, 1.29244503566283656061209233007634805e+112L, 4.05121786788653633019340698712667656e+115L, 1.63797303768105580759099639209855651e+119L, 8.61161786816897952522273022842847467e+122L, 5.93663320306070547376727413186770748e+126L, 5.41263435338015569490052234550484999e+130L, 6.58482575653621278094067557171475624e+134L, 1.07875660982114746476517100137547561e+139L, 2.40241992462133691284825971033750350e+143L, 7.34435324696612505273925787730222850e+147L, 3.11318307060514113999896732347290570e+152L, 1.84887752009365552806348833513339683e+157L, 1.55493753489569904210242587934359215e+162L, 1.87247311840034398087857290386878308e+167L, 3.26561398822344966034897508874934342e+172L, 8.34577318106206521818843721578177275e+177L, 3.16365209967032443701802479913075857e+183L, 1.80121863573431611955949232303314972e+189L, 1.56029746814154042157436181814468250e+195L, 2.08399815409632719398233238905315693e+201L, 4.35116508686695844690078637651674080e+207L, 1.44042594283375698824917457557971547e+214L, 7.67198578340176495038072549202750984e+220L, 6.67439909212164301008970795489093574e+227L, 9.63314810388083227111873828289832687e+234L, 2.34398517046722427869034729305744960e+242L, 9.77625325893464652861772945740140456e+249L, 7.10967843958998030041427991161778060e+257L, 9.17597441867286774623146964891772219e+265L, 2.14036206544827332284805812358315196e+274L, 9.19420612380519250234059644495148895e+282L, 7.41568524413971300723452081581189161e+291L, 1.14573384520235218510170025456065061e+301L, 3.46156619789802557007367290577360329e+310L, 2.08912045049233012342096277237544009e+320L, 2.57451388307699184873778115477509299e+330L, 6.62688893229567984520960366416649465e+340L, 3.64721218233974203748299012650543732e+351L, 4.39668921699312866048896359512324981e+362L, 1.19018091828589034728575506532863164e+374L, 7.42292147631996488193728378356566879e+385L, 1.09526098640141261390128648437627728e+398L, 3.92927734436557751277903528467662194e+410L, 3.52539958718458390412925405124992174e+423L, 8.14407380085561132671651242382158564e+436L, 4.99172864167925991508434677916290384e+450L, 8.37313822543668537823480408319630674e+464L, 3.96855771450749046728173847477197045e+479L, 5.49292894873452993989300213358944271e+494L, 2.29708122354182613470710687416853220e+510L, 3.00602816347641813806476628260504686e+526L, 1.27638345565474398023933739505382139e+543L, 1.82543785151714558753981850731109273e+560L, 9.13886193903951047182967076404934097e+577L, 1.66659166393902754183225415655293639e+596L, 1.15345182570915755941253059732455874e+615L, 3.16074696483848527092291852149349249e+634L, 3.58237065512849118228300807716046934e+654L, 1.75676845140981179589000705343726870e+675L, 3.90495239094757591264933748015965848e+696L, 4.12771024114613858596256966986824636e+718L, 2.18017473107123494465764845328386818e+741L, 6.05537171542030830962660182644895823e+764L, 9.32267445280349135813949292533678488e+788L, 8.40039310752404384099688064836067109e+813L, 4.68572386284109286448290494678984852e+839L, 1.71436621216433181556756205470621080e+866L, 4.36726894564208691170045669145775062e+893L, 8.23850494545149522733960578619372006e+921L, 1.22636833130359811940229369518492693e+951L, 1.53817446772510796133546119401337038e+981L, 1.73934010579080275675622752667739992e+1012L, 1.90139542390828308944919910797818652e+1044L, 2.15946649839694693874583032395369802e+1077L, 2.74458385322614086037916005350795661e+1111L, 4.21460437827726866824631065747020388e+1146L, 8.46327678591246014474308263680903354e+1182L, 2.41136671056709946500959023526115708e+1220L, 1.06046799402590770086828664893536628e+1259L, 7.85179239227989671195411257856609735e+1298L, 1.07053761782523090834371225181245647e+1340L, 2.94820375013014518743449818159813519e+1382L, 1.80414267837505733123417059421507186e+1426L, 2.70702818749460407693598763878577805e+1471L, 1.10237898995725987663697548890315962e+1518L, 1.35298567513553498909522877321159185e+1566L, 5.57611902405430874175886881037679558e+1615L, 8.62760618106732185887902244008862925e+1666L, 5.62274836328861658358184936480919820e+1719L, 1.73809780706704538846353037945373733e+1774L, 2.88052131688282318513745853191288493e+1830L, 2.90423838801873888374451692095277096e+1888L, 2.02951924440811805047282880080209219e+1948L, 1.12457154445459099155545223242406413e+2010L, 5.67678101812548596682420412619518564e+2073L, 3.01259124479996611916817067093268060e+2139L, 1.94839799990442184578594656275869899e+2207L, 1.78866123976568468449541367729975757e+2277L, 2.72776450570640988722564402903756955e+2349L, 8.12826724972980545013533499964424395e+2423L, }, + { 1.58403833597397609272337637131715304e-2474L, 4.01729907956437307269377706375953438e-2436L, 2.58580645701935131155084366864422406e-2398L, 4.31502895023559220093536948165386274e-2361L, 1.90627959218882483095663188951084330e-2324L, 2.27589955667507909301636117518932802e-2288L, 7.49364095876812027654477175001110624e-2253L, 6.94191154236392933887288062436725643e-2218L, 1.84522919671267474043685120983334524e-2183L, 1.43487104640347241520251346864979221e-2149L, 3.32692243646438795745471365264644590e-2116L, 2.34362088307498827836613435573448115e-2083L, 5.10938037262713942693655713913568198e-2051L, 3.51060735754549615330960873223686009e-2019L, 7.73934046950102664330281533900661264e-1988L, 5.57169465236073520583741860201801676e-1957L, 1.33280818206626290524674045358563098e-1926L, 1.07761463878385909143899244627194248e-1896L, 2.99487219016399829947920738111566372e-1867L, 2.90872283894068508271645083240599458e-1838L, 1.00349314519658897817146360011284604e-1809L, 1.24963603019269210233323055704536134e-1781L, 5.70651178926661193581089363715896182e-1754L, 9.70578293043209307574192077696195294e-1727L, 6.24328278846472954410732505740796953e-1700L, 1.54193058035632514209035337344023300e-1673L, 1.48399119945730121895709095048379728e-1647L, 5.64752158032889554103477750567193685e-1622L, 8.62167301557505164690437370018957398e-1597L, 5.35528299764763984143338000418037832e-1572L, 1.37241462764951847155586335894427418e-1547L, 1.47116444020541724843474277134735959e-1523L, 6.68618803692998895772448346916660911e-1500L, 1.30561453192449212967328116730742424e-1476L, 1.10983482751594629837009226116529299e-1453L, 4.16014518377810797736243906294304347e-1431L, 6.96431413050131379947014047903616964e-1409L, 5.27224320695995707920555229340409925e-1387L, 1.82727152085917578757399986780345619e-1365L, 2.93468712490571136931409720092296819e-1344L, 2.21029656493081556265677595112314098e-1323L, 7.89892460822856456312620943162424218e-1303L, 1.35498246922475851477828612647429926e-1282L, 1.12846854910106323887966343965144914e-1262L, 4.61424330893765402182473137993848704e-1243L, 9.36605095127672178405946589653781928e-1224L, 9.54054141854710811663726016692763275e-1205L, 4.92938100391460828476769674596652859e-1186L, 1.30552448174985025504800286655378847e-1167L, 1.79081395504489298673122868237542862e-1149L, 1.28534148947828407343141932678878641e-1131L, 4.87584961151572559819046616829450419e-1114L, 9.87277629967922144952427945151885497e-1097L, 1.07748800964228010206356572218732211e-1079L, 6.39928058051557015650179754550910965e-1063L, 2.08781638937389821580749246439535224e-1046L, 3.77684590339710704264469235045684970e-1030L, 3.82307555361237861173188661605677525e-1014L, 2.18500494285229212661260038960152445e-998L, 7.11371665672211288079530438419393765e-983L, 1.33086590459456967821090511427946680e-967L, 1.44309821421378874919204882407008472e-952L, 9.14647515187060050796469146648366553e-938L, 3.41683020290309632448426799765730462e-923L, 7.58515118221027874504569883083804726e-909L, 1.00874302140725085602226074835782694e-894L, 8.10069400524047548461447004237480370e-881L, 3.95900210017885619699714022194103898e-867L, 1.18662867376446832171113003401601030e-853L, 2.19786739893484213511853337557279548e-840L, 2.53446665772094387684997171428381901e-827L, 1.83299289701163579779687245566728015e-814L, 8.37462324951323786164578010773011160e-802L, 2.43440349985894963165438833576050630e-789L, 4.53405919015746926984345204895280285e-777L, 5.44811780296147933680587250736719556e-765L, 4.25227509910246244055269284525208521e-753L, 2.17028567518979939311612851867355063e-741L, 7.29110293097611082922276966606966112e-730L, 1.62280402409213923291155004693280799e-718L, 2.40828308813354260030814303685712546e-707L, 2.39798644647022706006083856285038692e-696L, 1.61202006993232554271262188260349029e-685L, 7.36078014307223356522361505691981658e-675L, 2.29673595120013740585571409952171287e-664L, 4.92601668045549547120303143586093867e-654L, 7.30469847326532782734592211727680659e-644L, 7.53208483045812497621524949105624661e-634L, 5.43101457218649885434844485451114112e-624L, 2.75364547737132169841544376328974616e-614L, 9.87114363624257039419731807833639141e-605L, 2.51532230246971379761137727536103954e-595L, 4.58020252011364324634687161502454437e-586L, 5.99105224430269595047395967421408836e-577L, 5.65817475729598864582006398104320790e-568L, 3.87790653215945353008449656152626419e-559L, 1.93831767408426944576894121111160849e-550L, 7.10042999124518145073529096418920675e-542L, 1.91544155185588660392537613901890409e-533L, 3.82329460613706944718834058784982843e-525L, 5.67308558344799642959861077485254353e-517L, 6.28651971015047054176370541889652534e-509L, 5.22608309691007325295015732741277330e-501L, 3.27380385796518526996963624688451015e-493L, 1.55218880567110686358214096387337744e-485L, 5.59406715134492552797785887998506288e-478L, 1.53903555561583129370612427064103671e-470L, 3.24582771097869247388161880434215690e-463L, 5.26923908371102477241383694074670819e-456L, 6.61116543964979170247326465662672578e-449L, 6.43651161747399650924315876123367361e-442L, 4.88172530890739153159755873311503383e-435L, 2.89552772291014307121494513337008901e-428L, 1.34824561713159645449381177450374044e-421L, 4.94682830703508395886779775564904786e-415L, 1.43550778574773554814450699757551163e-408L, 3.30662278156545301906789072182270217e-402L, 6.06763076341882342375981845143813941e-396L, 8.90102295078976467641802004915383639e-390L, 1.04750026993369008379812665328207076e-383L, 9.92305977697594285442750520712185343e-378L, 7.59233047709729007268137313555513461e-372L, 4.70739644774061079459196244467224618e-366L, 2.37289471679140773116577190541471766e-360L, 9.75578189470698031776059091702014024e-355L, 3.28173795958592945075990020191630023e-349L, 9.06055778471501819614486253220513415e-344L, 2.05942153439035557149195606898627504e-338L, 3.86530964740245225250791387282901296e-333L, 6.00843270324960642367292431619041056e-328L, 7.75791717613089963209182313649669073e-323L, 8.34421688870272754369905134347321346e-318L, 7.49743392110895125137984446953806518e-313L, 5.64335493091932417079632230402715339e-308L, 3.56822312364224796215751885944182157e-303L, 1.90033575264131712027297219010231489e-298L, 8.54728045366493643486236298588028833e-294L, 3.25523625801393911932111212124054975e-289L, 1.05248047241632062076489482718979111e-284L, 2.89617776712893256185087414745466351e-280L, 6.79988531580997322799099912957691248e-276L, 1.36556351036663137564575797911341140e-271L, 2.35130154856703817933308580165070895e-267L, 3.47957918602140446743207712996488528e-263L, 4.43595246742156897562714682208015764e-259L, 4.88306826050902558584812739817346803e-255L, 4.65192688318894071322199120456680912e-251L, 3.84397217698170104458131412518090261e-247L, 2.76116826189849718252009792299798034e-243L, 1.72788148193695597819524956747708857e-239L, 9.44000021446169518374327174980091189e-236L, 4.51212554821909958969480138145008725e-232L, 1.89078188020015147413152497967774898e-228L, 6.96047357819953940988624584998189879e-225L, 2.25551400000095886908107215813083451e-221L, 6.44644677476230409449870129589571800e-218L, 1.62820413693305623578289570883910133e-214L, 3.64118898140332008867604954881435445e-211L, 7.22342104300488240353501601432620632e-208L, 1.27354621995150979542739771832851778e-204L, 1.99918407175965223164864543465886820e-201L, 2.79923301669228713128194864334595626e-198L, 3.50221902155243103789141550909762023e-195L, 3.92214264392110857739154085058742459e-192L, 3.93845056335503285763060194710496279e-189L, 3.55208932101704820479562248595366349e-186L, 2.88218576501349132033303488025583146e-183L, 2.10742246561673617325867420889217990e-180L, 1.39082883056909297835969428096996258e-177L, 8.29809184041509702782403322046680024e-175L, 4.48275079028324875908925844854947607e-172L, 2.19604664947993546897548946859268970e-169L, 9.77074245531826439290686011595488065e-167L, 3.95412900034836577575737163397063382e-164L, 1.45763752143522946134851229157315125e-161L, 4.90175908594770144816169627656347413e-159L, 1.50583242362081439890282730822964005e-156L, 4.23187210926299952258468916772463829e-154L, 1.08947970178510600143883902241342972e-151L, 2.57292238715065164920970933548863818e-149L, 5.58131105433415694107142145348480095e-147L, 1.11357590012697004029170524556205260e-144L, 2.04616505133228608383036998688279538e-142L, 3.46699488500477063569923373366652510e-140L, 5.42379540407350192206120227447952764e-138L, 7.84383327240284700975116490839187822e-136L, 1.04992295793319441478934809931921214e-133L, 1.30230107195741860304672567525213181e-131L, 1.49865973782839300796909511415792928e-129L, 1.60190662241428628230308870106117967e-127L, 1.59224861840198356125270425396669689e-125L, 1.47337534591643627391632824044256382e-123L, 1.27065155139400959289502878067800521e-121L, 1.02240826352576620907328663762929630e-119L, 7.68376260232956278119400404906698852e-118L, 5.39926812723337318582425048609813182e-116L, 3.55107427485349467569160645183534302e-114L, 2.18823540951912101048500342930263842e-112L, 1.26466751543081693428147968135946762e-110L, 6.86180756673724371219029573988488620e-109L, 3.49869168682520996337772693940273721e-107L, 1.67801680739837515692197356611469711e-105L, 7.57743943144193148982405002124429739e-104L, 3.22470377015938680899710533122019572e-102L, 1.29448709067770596337952427228314258e-100L, 4.90613325096345413914934529363944533e-99L, 1.75712131798815332550332783841135938e-97L, 5.95204249145432038279376449394263726e-96L, 1.90856665328641726356485393831448064e-94L, 5.79822445923642921233565089484060205e-93L, 1.67029323997833472695510332615399040e-91L, 4.56623667339808303761814383193281614e-90L, 1.18561734279154794522720467403607684e-88L, 2.92616002780129692916694825399426567e-87L, 6.87006113412670713749912656047162470e-86L, 1.53556578350037994526862611062995548e-84L, 3.27003673677840125658578850353789865e-83L, 6.63955800720658036202444029681088661e-82L, 1.28631975096739859347518450406626244e-80L, 2.37956658113902295790875474474928153e-79L, 4.20626823139888342521923162463424944e-78L, 7.10971923783337943250783648529172174e-77L, 1.14991510411537277718541841100610582e-75L, 1.78087620125559422021122815240864113e-74L, 2.64270379617932988289762938432353092e-73L, 3.76008537594171932684988546369276565e-72L, 5.13292095112425199264463076393673633e-71L, 6.72710027460142769581137467118289653e-70L, 8.46958562134769749810317782657268756e-69L, 1.02503238267223284787859415412841523e-67L, 1.19321912755786334798650299344282298e-66L, 1.33681693038130658171632078204446788e-65L, 1.44228347967979838541089585366023007e-64L, 1.49937455500479399063651651865716553e-63L, 1.50279720313350143765006477517598013e-62L, 1.45300596931848530329429215240805653e-61L, 1.35598044837786253974814702268132430e-60L, 1.22207241221255212718220407758970979e-59L, 1.06422318027052015901612579353436284e-58L, 8.95966739607563684498250506056071091e-58L, 7.29628880807929410507791279851435148e-57L, 5.75025529619018115782221236649660618e-56L, 4.38801166482901351758297994035262224e-55L, 3.24385245129183239778054564241318804e-54L, 2.32423935766553880551312730791561599e-53L, 1.61486977620302644603098163288002715e-52L, 1.08852460554527484166896264813585652e-51L, 7.12175557419282904469498440847683331e-51L, 4.52464766254906707378983948806266105e-50L, 2.79273071581879303547665803856393705e-49L, 1.67538487960386422664995380528599268e-48L, 9.77311432877767609128920687351148833e-48L, 5.54591076684762708155258243373876422e-47L, 3.06280970562787364526087771025696151e-46L, 1.64686211803826623376300968100335938e-45L, 8.62510851388715584666563483664725226e-45L, 4.40168766386889070104410967553191993e-44L, 2.18975577884764674623829698191429056e-43L, 1.06234533644926588892221744026505121e-42L, 5.02803666348568404922856964957017674e-42L, 2.32252463571724922291588384046952088e-41L, 1.04740659389834130621977678673036650e-40L, 4.61343838844969816849890851044847674e-40L, 1.98539744511816200515536891243051363e-39L, 8.35102736745462834322783293199882340e-39L, 3.43444090348454338873945310910863585e-38L, 1.38148913187719664577281415801326678e-37L, 5.43705120131022522415564030011104834e-37L, 2.09435754808064771674030165617400032e-36L, 7.89867661859200690211003183623252601e-36L, 2.91753687094747127218152557081492503e-35L, 1.05578888602271659701510267800456427e-34L, 3.74433381216033081152946793044225824e-34L, 1.30180118525195729018565371931285108e-33L, 4.43834621689338776826444391843192077e-33L, 1.48434826895181654234585115302567433e-32L, 4.87100112984983697071424260901079389e-32L, 1.56890300074251394167498791840311009e-31L, 4.96129531591793523529868958902224169e-31L, 1.54077391002799082070667599670892752e-30L, 4.70055802217201491012415527477898338e-30L, 1.40911523071894959581827729743208189e-29L, 4.15191310395569203370171887252329295e-29L, 1.20273761371542774812275721780834541e-28L, 3.42632737493449673556641936029297478e-28L, 9.60140535939702601155477307042148556e-28L, 2.64727864203377330130778700812469317e-27L, 7.18344222056514710304108009603342664e-27L, 1.91885054598149404233254994607045127e-26L, 5.04697477945599249407828848720385551e-26L, 1.30739479992591170007499101639277446e-25L, 3.33634219823695708156517864262133521e-25L, 8.38925958113626219399750986165640649e-25L, 2.07905181351354860827899559955891196e-24L, 5.07917896724376528007260946058158296e-24L, 1.22350179435783727784530143589061714e-23L, 2.90665491105754953014975765085018324e-23L, 6.81166860609501546977145188171063268e-23L, 1.57498593823802530267320052674032470e-22L, 3.59379678896934832551131875550134077e-22L, 8.09418541120521256436201968800902213e-22L, 1.79979618323748172103553749785052354e-21L, 3.95175890164101728455789689950582204e-21L, 8.56958006805086577463240518925283894e-21L, 1.83575348651729869648335347322858802e-20L, 3.88541433996602231722399876322981769e-20L, 8.12661397289502178971121801417655470e-20L, 1.68000718288950314093575786904308274e-19L, 3.43336935156396282804714345750464903e-19L, 6.93769555039942749928599832442683686e-19L, 1.38634563100898175510110455954156138e-18L, 2.74008749775923088060873199170519103e-18L, 5.35757028868338662612872498580241047e-18L, 1.03646493302280378406673184005440162e-17L, 1.98424944201008499240310250250687800e-17L, 3.75978800606000340899396301904932318e-17L, 7.05221126182168479511704811938887205e-17L, 1.30963564152954622082996853685780292e-16L, 2.40827549610918052797562865726934570e-16L, 4.38589880961171155211843738902302126e-16L, 7.91175868684912128549216604428547791e-16L, 1.41388359787718387270571947224924145e-15L, 2.50347753664468021020115723250325879e-15L, 4.39263786655070582741822344903139686e-15L, 7.63871030696057461236914444427999640e-15L, 1.31670336037747604093705380830550144e-14L, 2.25003102727544891850217684727399098e-14L, 3.81223973341221495282227985716493129e-14L, 6.40502166019136347918960755019998163e-14L, 1.06725053827031948353711195948826425e-13L, 1.76389749378472101040375240485184047e-13L, 2.89198756533454775599767608849931393e-13L, 4.70424252036995808470327107927435060e-13L, 7.59287827351269198973041796516049688e-13L, 1.21618333837252517178450702971971531e-12L, 1.93338859343662487903047794738683986e-12L, 3.05082685244229075126272877890267121e-12L, 4.77908002001763665704541557372044375e-12L, 7.43273471338542509759247990082208445e-12L, 1.14783388812587366578078714999164060e-11L, 1.76028616037242275427822154657272751e-11L, 2.68107110162395316788540367212924769e-11L, 4.05602375429596543728262134893310443e-11L, 6.09544349224153722159236648112669209e-11L, 9.10055012961606421079182569690846497e-11L, 1.34999345213696765153127846451643325e-10L, 1.98994391239515605127817880646635584e-10L, 2.91499607361905978799020781323598840e-10L, 4.24390078141221962088655373293736779e-10L, 6.14135316267139108184909214050184662e-10L, 8.83436579589479851125156253066831718e-10L, 1.26339559402593316965102282486280599e-09L, 1.79636925005171604673781604814805685e-09L, 2.53970414332648086166213535713251755e-09L, 3.57059249828789049877331667413514712e-09L, 4.99234840315053910682137402914672922e-09L, 6.94247187048993148295924434414634261e-09L, 9.60294960016456137105057353194608309e-09L, 1.32133371276166677672139906194961059e-08L, 1.80872790163534638977965561238944112e-08L, 2.46332536476779151638500763225429049e-08L, 3.33804787013687049574791297244907192e-08L, 4.50110842610850506871431532628603516e-08L, 6.03998541333325959410060827223996830e-08L, 8.06630537452609783391065479881400036e-08L, 1.07218105901889261435737857618298194e-07L, 1.41856144379535399139351236825663488e-07L, 1.86829769983638330491745888879438028e-07L, 2.44958653917297200861483891225150109e-07L, 3.19755978044276083153634882857883309e-07L, 4.15579069086754433405340505039048729e-07L, 5.37807971332554467827633744547482376e-07L, 6.93056106477668619385798002644561466e-07L, 8.89417585250212245375810218669817408e-07L, 1.13675615786872600638029106996132895e-06L, 1.44704121253473089806789252868181132e-06L, 1.83473664533283350419063698449974520e-06L, 2.31724882235425364363184937796552995e-06L, 2.91544022582530391094107183656707013e-06L, 3.65421570986355186992807571629053921e-06L, 4.56318857677376015133362727471956847e-06L, 5.67743390948223287752620793591929613e-06L, 7.03833674730757178417069911600525632e-06L, 8.69454275808306722839276847105496531e-06L, 1.07030190270275985848630609511672890e-05L, 1.31302324393740374972736712543053054e-05L, 1.60534528678907389671161995891497537e-05L, 1.95621879772878044903047444244351033e-05L, 2.37597559155521886172243888058434365e-05L, 2.87650014695436120790473222143336354e-05L, 3.47141604126307620878569429267584729e-05L, 4.17628757618591523872557240511914786e-05L, 5.00883684896740377264076716570754303e-05L, 5.98917639018173037280503906445049523e-05L, 7.14005734028021322676450426011314791e-05L, 8.48713297304976003620620060812799411e-05L, 1.00592371962099993408798498455907607e-04L, 1.18886774688549697317681023800631139e-04L, 1.40115413739806927896468824589692520e-04L, 1.64680158738873124934815777767252928e-04L, 1.93027180590427177790609959505517465e-04L, 2.25650359795433055575151925625868196e-04L, 2.63094779253370712822446127059315509e-04L, 3.05960282998094618038061759727754321e-04L, 3.54905080142515530273890819014315333e-04L, 4.10649371213184272695586730470455583e-04L, 4.73978972070856543596623702324547537e-04L, 5.45748908769705106925744948564871657e-04L, 6.26886955037988466777589811218012335e-04L, 7.18397082597597367255394668144143647e-04L, 8.21362793308292890121036733909194916e-04L, 9.36950301151796636389593916360605611e-04L, 1.06641153138572518429387087881256567e-03L, 1.21108690381909541715522898126065244e-03L, 1.37240786710764633931488483556773354e-03L, 1.55189915125250562428574475103346186e-03L, 1.75118070611954731846143391024982058e-03L, 1.97196929478447094442182021751059029e-03L, 2.21607971185090897097885205424488147e-03L, 2.48542559858177963603431553204765315e-03L, 2.78201982871899325746660736300345366e-03L, 3.10797444123022017600460098808123935e-03L, 3.46550009889599377554207066240202628e-03L, 3.85690505461395961880575720620871256e-03L, 4.28459361052363939313848682793859897e-03L, 4.75106405851509722505038175681427297e-03L, 5.25890609434561842084606413815284753e-03L, 5.81079770141443579933464319447926318e-03L, 6.40950150419891594280210549702450453e-03L, 7.05786059539697018633739598386855559e-03L, 7.75879384490912344645900750924930976e-03L, 8.51529070288836937235862937785994511e-03L, 9.33040551314529952303815524992440065e-03L, 1.02072513571791257196870650265821749e-02L, 1.11489934529722276019901656254303012e-02L, 1.21588421363983657377673415921445027e-02L, 1.32400454566162946339651246079183099e-02L, 1.43958814201171884975897081297216705e-02L, 1.56296499211348507284307663166667625e-02L, 1.69446643988840458394481431193257832e-02L, 1.83442432645398203334614155955590374e-02L, 1.98317011429883687012533532738687781e-02L, 2.14103399761506788853091011534572156e-02L, 2.30834400360906269037251797223442256e-02L, 2.48542508971601536767883257823339293e-02L, 2.67259824171004266947925047187844041e-02L, 2.87017957773082030971446046374914401e-02L, 3.07847946323935695276863138190467659e-02L, 3.29780164187051571955970986393933287e-02L, 3.52844238706916706398930809090405599e-02L, 3.77068967928172889046621767464058045e-02L, 4.02482241332694163505581270228186661e-02L, 4.29110964039093677010619866631701642e-02L, 4.56980984888413264034413616112869595e-02L, 4.86117028816359215545912812117182378e-02L, 5.16542633886674445449455067720287452e-02L, 5.48280093332349644585895096278308003e-02L, 5.81350402921654268021994051667911914e-02L, 6.15773213934700546744487567673172633e-02L, 6.51566792003733016470332458328988615e-02L, 6.88747982036856640340840950741077307e-02L, 7.27332179410771208959941663503595393e-02L, 7.67333307583556615050326531083587939e-02L, 8.08763802243933982425303227000944183e-02L, 8.51634602078983074689360505021182257e-02L, 8.95955146208286742294968393977769930e-02L, 9.41733378299144489750576704343915921e-02L, 9.88975757345080247656478735188449399e-02L, 1.03768727505857796722978821461546404e-01L, 1.08787147979900856678514246787241454e-01L, 1.13953050692823999603416543952272158e-01L, 1.19266511545960614110252460361458099e-01L, 1.24727473084088741556780346524879069e-01L, 1.30335749368884349581460099687500407e-01L, 1.36091031427173401966757170543046798e-01L, 1.41992893251724361991875167825655695e-01L, 1.48040798330635148304426193810368709e-01L, 1.54234106679899202351157467338543629e-01L, 1.60572082352486356465237071613156643e-01L, 1.67053901396246033471214692284653203e-01L, 1.73678660232131774208044201415508905e-01L, 1.80445384423654491197811595430697492e-01L, 1.87353037808093115326776430258837481e-01L, 1.94400531959820109714578533182084599e-01L, 2.01586735956129211498107459964096125e-01L, 2.08910486416176267158329341893267875e-01L, 2.16370597784052818695266702661187610e-01L, 2.23965872827597104489240738884195628e-01L, 2.31695113325298676464455224512869174e-01L, 2.39557130914560734720290079897448420e-01L, 2.47550758075638008786996132954185789e-01L, 2.55674859226756791227887436442350007e-01L, 2.63928341907236639931045094151784107e-01L, 2.72310168026859366788753574972476498e-01L, 2.80819365161259349748148678323641718e-01L, 2.89455037874729232565423711864655899e-01L, 2.98216379053536250342702367445487260e-01L, 3.07102681234616603556790972526892770e-01L, 3.16113347916348760019249138447488231e-01L, 3.25247904839992014226666657864488014e-01L, 3.34506011232305314043635112310304911e-01L, 3.43887471001825077739424147442217492e-01L, 3.53392243883271879333889785572599272e-01L, 3.63020456526567529072712529376719554e-01L, 3.72772413528969943076239230990758849e-01L, 3.82648608410867702369280704118517439e-01L, 3.92649734537814481801171047048544340e-01L, 4.02776695993421447225756159687866121e-01L, 4.13030618409759875566958499890031988e-01L, 4.23412859763953990585030832527434639e-01L, 4.33925021151663415382683548295156320e-01L, 4.44568957550164552554831720660662401e-01L, 4.55346788585740186021655771168112611e-01L, 4.66260909322076961243786064631384911e-01L, 4.77314001088352176735947056292312804e-01L, 4.88509042367666263602229097070513234e-01L, 4.99849319768447906973686731056178972e-01L, 5.11338439103428142948352352152044385e-01L, 5.22980336602751811729499672944460101e-01L, 5.34779290289774015573364455286468490e-01L, 5.46739931550080955287380242064660003e-01L, 5.58867256926284616744877484869191055e-01L, 5.71166640173175841717312971842336611e-01L, 5.83643844609887615578228626088462787e-01L, 5.96305035807827889758567710635182685e-01L, 6.09156794655297569062821736349343099e-01L, 6.22206130841923771587050175584017347e-01L, 6.35460496808321163697317796410781296e-01L, 6.48927802208755868138883757264025330e-01L, 6.62616428937038679525110869491604161e-01L, 6.76535246768429422677267756666823087e-01L, 6.90693629673005399383708050292572666e-01L, 7.05101472858747991895757442966727674e-01L, 7.19769210605547537680146085503476253e-01L, 7.34707834954433431482100014962668745e-01L, 7.49928915319620942104629439591963551e-01L, 7.65444619094446439133009723643838630e-01L, 7.81267733325957766141060146767846541e-01L, 7.97411687536856786535849810135961905e-01L, 8.13890577777678436208431256995493454e-01L, 8.30719191996558177068293937598919209e-01L, 8.47913036818712374055336621201445842e-01L, 8.65488365832860347537655780480228440e-01L, 8.83462209487281076620051655836621909e-01L, 9.01852406704052162112602532863159232e-01L, 9.20677638326296314246112109641174382e-01L, 9.39957462519996315051517977272639457e-01L, 9.59712352259170728365681565566195274e-01L, 9.79963735030970038685207606899372777e-01L, 1.00073403490559993309000835270230984e+00L, 1.02204671712495200986974494164817378e+00L, 1.04392633537347289336664619627296763e+00L, 1.06639858190518516071876464455235265e+00L, 1.08949034071194662751500934725633506e+00L, 1.11322974393006216402411430386892104e+00L, 1.13764623169531331372630723630321340e+00L, 1.16277061567042026013306680494416940e+00L, 1.18863514648397907083703649648730714e+00L, 1.21527358533611238960293477132347556e+00L, 1.24272128004352904999786719958821158e+00L, 1.27101524581551079885511358011134290e+00L, 1.30019425107264471110982901454765895e+00L, 1.33029890864201997125110745686528366e+00L, 1.36137177268624019179654148863686280e+00L, 1.39345744174911173037014751038646328e+00L, 1.42660266832841175766232711333173310e+00L, 1.46085647541588835802048454309412779e+00L, 1.49627028047678533760134362560179034e+00L, 1.53289802737592016874439144914426210e+00L, 1.57079632679489661923132169163975144e+00L, 1.61002460572564642000849608863176067e+00L, 1.65064526666943143532240244567555108e+00L, 1.69272385721798833166204038375277879e+00L, 1.73632925074497773069781144176863796e+00L, 1.78153383899165490255124499430464714e+00L, 1.82841373739108738124596203605065226e+00L, 1.87704900404072044775471792428672248e+00L, 1.92752387330408763463712892863710673e+00L, 1.97992700509947708650365975965257989e+00L, 2.03435175101694043322616088522632134e+00L, 2.09089643849576621383396167595935906e+00L, 2.14966467439309042108153883973067514e+00L, 2.21076566938140221236799358744093376e+00L, 2.27431458472911392711904220601704565e+00L, 2.34043290314497023966214961240421096e+00L, 2.40924882550482707578395780381837657e+00L, 2.48089769542928804270777308901824137e+00L, 2.55552245384400165592583716337259322e+00L, 2.63327412583237088656291310907475315e+00L, 2.71431234228441160768610076838330351e+00L, 2.79880589905706635256578441640292763e+00L, 2.88693335659214188612865513175227518e+00L, 2.97888368319007786718164917079966461e+00L, 3.07485694541305021056656397487876403e+00L, 3.17506504939176568339259231884822943e+00L, 3.27973253713925527986226523992226922e+00L, 3.38909744233483410200034132396842728e+00L, 3.50341221043527586541966899038246748e+00L, 3.62294468840159570502872359754361586e+00L, 3.74797918980246258518386393043115941e+00L, 3.87881764157340380510220562013091253e+00L, 4.01578081927931267029397913978942025e+00L, 4.15920967835153616848634566919310171e+00L, 4.30946678945578836835486232808829311e+00L, 4.46693788689973689723986043138805888e+00L, 4.63203353981649359057533901265089751e+00L, 4.80519095677036072684883899803335247e+00L, 4.98687593543289697160079921623416533e+00L, 5.17758497008053768765855285400689531e+00L, 5.37784753088062976076034128768012631e+00L, 5.58822853027308803485444007033170411e+00L, 5.80933099323364005938466841106588229e+00L, 6.04179894983708948784718604678234941e+00L, 6.28632057034228591922334730387683243e+00L, 6.54363156501365266125399451934329088e+00L, 6.81451887309858260791767579514605499e+00L, 7.09982466781971868191373433617700078e+00L, 7.40045070694293100845796745008949286e+00L, 7.71736306147578881407568826714170705e+00L, 8.05159725837127958401987584151171259e+00L, 8.40426387679538395058384455428283593e+00L, 8.77655464160750010892022612040926275e+00L, 9.16974906224756520705691589269677116e+00L, 9.58522167027699388874228356777329920e+00L, 1.00244499144430070386099274885141050e+01L, 1.04890227783960385614814296197680936e+01L, 1.09806501931649260624015170997236345e+01L, 1.15011733242716998455210622743445835e+01L, 1.20525758220454727952816341992419823e+01L, 1.26369961333845432419384699684768677e+01L, 1.32567409840433238017603739136360460e+01L, 1.39143001526287336814820956823084828e+01L, 1.46123626710408671221171338391349055e+01L, 1.53538346012683753120053442509520620e+01L, 1.61418585554581184591279187098492208e+01L, 1.69798351452575852400510409025135738e+01L, 1.78714465678460133882677098961576727e+01L, 1.88206825601317848442892749807248071e+01L, 1.98318689796476498521560439791262319e+01L, 2.09096993011184544989073368255312499e+01L, 2.20592693519609552724995680207860407e+01L, 2.32861156486188168325833440616926330e+01L, 2.45962577392286013760094208279475314e+01L, 2.59962450073299827601794849672397508e+01L, 2.74932084469488923833030086627802945e+01L, 2.90949179822819598429999086944366938e+01L, 3.08098459764107671506384842333391345e+01L, 3.26472376541418040006352140116179211e+01L, 3.46171892555432186128355184008936311e+01L, 3.67307348405744306653537849794079228e+01L, 3.89999427831545697992227880433189487e+01L, 4.14380231271361842696931290595974334e+01L, 4.40594471293014233018696008435982161e+01L, 4.68800804884035743932352319123055757e+01L, 4.99173319575866229822636583993237381e+01L, 5.31903192638729836914160122380617184e+01L, 5.67200545170346581087003708738282234e+01L, 6.05296515859483113978235132985845589e+01L, 6.46445582591583649124780712968047055e+01L, 6.90928163944313177415529394071665670e+01L, 7.39053537072521168719419511314839173e+01L, 7.91163113594234348927381617490387462e+01L, 8.47634120965947230809397578710282148e+01L, 9.08883743598215272174601093484125344e+01L, 9.75373785753325382322893051705294986e+01L, 1.04761592725164736089639534479074532e+02L, 1.12617765338655419662606911403899284e+02L, 1.21168895243741881709481972315918511e+02L, 1.30484988804359382802013970413388238e+02L, 1.40643916977370870089294791135734370e+02L, 1.51732386386376598946153144686407135e+02L, 1.63847040773982427929709267988083986e+02L, 1.77095711710003361983546853982729852e+02L, 1.91598840361277588527216638598210664e+02L, 2.07491095540949726522855395012839290e+02L, 2.24923217236106119394568010864647153e+02L, 2.44064119463086993590008673999888577e+02L, 2.65103291739026696423162894476095053e+02L, 2.88253544828036421249450783362468048e+02L, 3.13754153889742451327114437895012151e+02L, 3.41874460927761232190324931320648150e+02L, 3.72918008746121432097478949634992228e+02L, 4.07227290759381879033987273956073881e+02L, 4.45189215310338987815842929936219157e+02L, 4.87241400038863092710563840938907565e+02L, 5.33879431809824993154116113611340152e+02L, 5.85665251340011311718653543776253641e+02L, 6.43236849676682281579530292235801252e+02L, 7.07319496933657861116096423723089184e+02L, 7.78738763222127723625961426334336958e+02L, 8.58435638777040682657342340030579928e+02L, 9.47484116394459954294416631122613257e+02L, 1.04711166630196929712820316594777632e+03L, 1.15872311371927743485840786701904690e+03L, 1.28392852534970775486315470390457819e+03L, 1.42457582618936343671625036189352836e+03L, 1.58278900639377570598543689683858411e+03L, 1.76101294444545923486104598108258215e+03L, 1.96206607357312178755673700966218336e+03L, 2.18920236070835422209657734442941355e+03L, 2.44618436034955965177471357752869960e+03L, 2.73736946076118709316717034422700237e+03L, 3.06781187080876763823587584403262657e+03L, 3.44338341950996275353420062305895100e+03L, 3.87091687821820770548262640961099474e+03L, 4.35837629346446550811483742251576785e+03L, 4.91505976942026055884439891778599977e+03L, 5.55184130321696740425893724460092414e+03L, 6.28145970445342612877221303833900020e+03L, 7.11886438520566571043900024525721790e+03L, 8.08162996762779959609851789890726579e+03L, 9.19045432173859727983153055486718404e+03L, 1.04697579405183570171054706781681133e+04L, 1.19484066394624731955974446656465043e+04L, 1.36605846306210479280006137726608390e+04L, 1.56468513163780927299848865296760921e+04L, 1.79554229917996753910020302361418910e+04L, 2.06437304374408251386790990436920728e+04L, 2.37803156373267080705808819875316658e+04L, 2.74471462199565095258711815725505419e+04L, 3.17424455248072273922403695999752070e+04L, 3.67841605073133622632674187774059283e+04L, 4.27142203777350805091608476572382608e+04L, 4.97037776810032398127125994364568099e+04L, 5.79596727313857616360132420453444344e+04L, 6.77324248460879259253530791773167141e+04L, 7.93261334694994276050922426242412735e+04L, 9.31107739715691545023768199956003639e+04L, 1.09537503053637222429417759669716212e+05L, 1.29157755673566952599086463851912376e+05L, 1.52647130160874158565239969760504587e+05L, 1.80835335096964828910095096138515211e+05L, 2.14743829477016418053483721316277484e+05L, 2.55633251557399994754680946686048161e+05L, 3.05063334556209750218324509503461449e+05L, 3.64968792666585395419705030588899790e+05L, 4.37755686685748537981529230100717254e+05L, 5.26424122294320873553623779329790816e+05L, 6.34724899010831940960718793968560727e+05L, 7.67360052654242646579956157559309383e+05L, 9.30240305033750278572545038832724621e+05L, 1.13081650266645184495081585123306969e+06L, 1.37850753115552374245055838415718322e+06L, 1.68525439396416227539607702063253047e+06L, 2.06623977016863939032179814240740936e+06L, 2.54082527022935491763036651163297626e+06L, 3.13377596203641663047341272710642846e+06L, 3.87686514827580239293595658539782774e+06L, 4.81098405401834942973721071475737211e+06L, 5.98892408953467866424875864774796159e+06L, 7.47905792960806092396497010475870265e+06L, 9.37022569869340886743682668142431718e+06L, 1.17782423097751066120254539266241595e+07L, 1.48545930143258061872721569284540776e+07L, 1.87980927038339810411221199415802492e+07L, 2.38705733443634639976678131975655720e+07L, 3.04180655225860320213756009749555241e+07L, 3.88995004684326215069338023547372206e+07L, 4.99257437458669601662091946924574592e+07L, 6.43128750449561321017861557895848463e+07L, 8.31551851992585813643149605060553440e+07L, 1.07925566470411796107305712037505869e+08L, 1.40614107339003511498586442587195365e+08L, 1.83920178567730560673713663331917338e+08L, 2.41519711690497536458569405379734816e+08L, 3.18438601538111228132801183275722771e+08L, 4.21576501892968673592102667497462836e+08L, 5.60444635691511454953230090792878868e+08L, 7.48209439804691157215633476755723997e+08L, 1.00317512966824615144294234414110893e+09L, 1.35089891899748286951692285814894218e+09L, 1.82722216505349159044967968934424570e+09L, 2.48263348083176093300905605774694855e+09L, 3.38857763723491971892999484076543171e+09L, 4.64662006529910564426883234085294096e+09L, 6.40182180156629712154379147661940269e+09L, 8.86235203805325147258573091932997831e+09L, 1.23283860285919681076337828978766266e+10L, 1.72348929748018002343932808836953853e+10L, 2.42153052846944737603768649152219024e+10L, 3.41967381320806302529104945578396652e+10L, 4.85431236462260654032773006433818623e+10L, 6.92714904376034267631798991329824532e+10L, 9.93804949018620361644641133903513098e+10L, 1.43352142475985414523266188918663249e+11L, 2.07922173448308822669953899424734201e+11L, 3.03269524182010815814751345567548609e+11L, 4.44863150372771043146060595057040363e+11L, 6.56345864647790105139454816812312939e+11L, 9.74063569639891097956397109813490533e+11L, 1.45422052005965615789962842879352220e+12L, 2.18425068889862732017431485970855335e+12L, 3.30099910475756075681442440083420253e+12L, 5.01997048502274901150163921982195024e+12L, 7.68267629901760783371009641842522603e+12L, 1.18337659600398387182686793240868246e+13L, 1.83474885355703531496992152648661997e+13L, 2.86363931245836358559523100954017414e+13L, 4.49980389271503995761664922194406313e+13L, 7.11948687698915449751693845544920647e+13L, 1.13430701798012234619458399048221594e+14L, 1.82006578236361839541514524597276231e+14L, 2.94148450061539403705926461420998342e+14L, 4.78870730589093038221910605812495108e+14L, 7.85402503692862355090784993078672085e+14L, 1.29789430461986025113447366376693514e+15L, 2.16127995478242564041665605678872071e+15L, 3.62710214703500383377916061381597850e+15L, 6.13534293344095037788551479051826967e+15L, 1.04617000636224450596060724147477482e+16L, 1.79847735783966568554234927670508824e+16L, 3.11747341233233147536151972501734499e+16L, 5.44944507304918422218082921598846642e+16L, 9.60751550501797821243248841373822216e+16L, 1.70858922445267785163471612163490444e+17L, 3.06542975111022866531582625971692938e+17L, 5.54922743745114951066953816028814728e+17L, 1.01373023277804631428305560194491190e+18L, 1.86905989587640582429259395332686294e+18L, 3.47854955238157842413369108802590798e+18L, 6.53599224597546376326701108631484361e+18L, 1.24001927226106630812645719537154550e+19L, 2.37582886691093662903464587039857427e+19L, 4.59768243360443262528520790447211677e+19L, 8.98810681683712842794124622629411311e+19L, 1.77530237939363226330723906827319437e+20L, 3.54341330439097348610370779591666976e+20L, 7.14806139767552532748817894789979543e+20L, 1.45762051057718630539520752847120279e+21L, 3.00513712487982979744944726506420716e+21L, 6.26502486163325069730377264873611059e+21L, 1.32097994109028381590144585332181800e+22L, 2.81748753590214622077676014001554368e+22L, 6.07993304142980523101356268020373032e+22L, 1.32765885364721208288263553578233241e+23L, 2.93431175918364131820516218129002628e+23L, 6.56508721680713002578214496043109168e+23L, 1.48721227343793765013154051597710086e+24L, 3.41184019607678812819334291291332010e+24L, 7.92818992879701876208212761012395842e+24L, 1.86645187702970485690987148720542546e+25L, 4.45252185988673954885155645168863932e+25L, 1.07654543517497766241465472692681594e+26L, 2.63868568119069758552386276646714408e+26L, 6.55790847024418649820013325410592483e+26L, 1.65295224373558572055534033842757998e+27L, 4.22638339591491619855432610245411904e+27L, 1.09645039426808014848951068590561771e+28L, 2.88682208299928608019375692651426610e+28L, 7.71548038934401592468282155249032740e+28L, 2.09372878930996484632394470400138705e+29L, 5.77027578944765503685743525710220950e+29L, 1.61546384539178114004658391605197219e+30L, 4.59547005579560869055708560274363012e+30L, 1.32862939268652325541488091880021431e+31L, 3.90507968153078421921910800039715306e+31L, 1.16713402427199725201363486127342874e+32L, 3.54805853865427740256789009746696294e+32L, 1.09737805935804615955239963430188272e+33L, 3.45410297806444559459316674852385198e+33L, 1.10674539370165232283645935543266144e+34L, 3.61089955913906999391756229494586894e+34L, 1.19994699928367056689901878605794596e+35L, 4.06268701419087879160332452792716198e+35L, 1.40183522389322451388311239745912475e+36L, 4.93108552733316217324966630695184171e+36L, 1.76881239328491949973951925349674313e+37L, 6.47214829394519996070845864216337266e+37L, 2.41645372173921192231147151489004683e+38L, 9.20894472039812386191245000342688835e+38L, 3.58329702862212667598998865894252598e+39L, 1.42409748259669944005518449916929857e+40L, 5.78262783342641152433806724533524027e+40L, 2.39986220408436318313990705343752378e+41L, 1.01829157204230545960231903208713235e+42L, 4.41910541482203453093956062976933998e+42L, 1.96212611768049931065065590432043620e+43L, 8.91674242406125370712417447773466783e+43L, 4.14888247829475772044491476179936724e+44L, 1.97725652955827692966670149947470575e+45L, 9.65530023387540108044378286001152781e+45L, 4.83287889833559892166961276593618835e+46L, 2.48057587822309805808523773881299449e+47L, 1.30610280975765470571043683527277027e+48L, 7.05756571728956923233902004974509542e+48L, 3.91527652222961861840270351783060925e+49L, 2.23089898094339331762072829615745302e+50L, 1.30614133449630930559423540813368509e+51L, 7.86102128665639262739828585146248224e+51L, 4.86558375853845110678814792824481696e+52L, 3.09848742591570467373735298285106117e+53L, 2.03103761486256390140847277681645261e+54L, 1.37099964760826020030246335833308722e+55L, 9.53473627432500152782873935909970826e+55L, 6.83495992316641540715754654005899263e+56L, 5.05273354632478901960113633106144814e+57L, 3.85381099728215997914445000026608173e+58L, 3.03418310785320829824308157124864982e+59L, 2.46716192600983889917114272951924381e+60L, 2.07290103981358059329932171745274528e+61L, 1.80056398057961538305615630314631614e+62L, 1.61776402789534425695658193709805813e+63L, 1.50428302825068832904492692640561694e+64L, 1.44839320652542717214779500803249160e+65L, 1.44485551098011579855868939330990133e+66L, 1.49412042885502924277326734308483245e+67L, 1.60256656610701572194891345599497651e+68L, 1.78388050415394298763315503064430164e+69L, 2.06199924057276073839995264039101124e+70L, 2.47652179469857271457600275335452230e+71L, 3.09234991415349735847967247784284417e+72L, 4.01692723830598581004567643058591262e+73L, 5.43160754522649738742682321649737815e+74L, 7.65008682404282275932608294522372170e+75L, 1.12301798411434928750045233045701052e+77L, 1.71938295296605200401018803799684912e+78L, 2.74733571869068667385885336550518795e+79L, 4.58454501055768412308971248876333874e+80L, 7.99508204153925025226317876728470146e+81L, 1.45811990936589904392804782726885652e+83L, 2.78300117867960017490532778932474629e+84L, 5.56281223196619462795860275879049153e+85L, 1.16533876898240457849831832137567995e+87L, 2.56039912643283822420817604614012086e+88L, 5.90454964185909819164533268125527979e+89L, 1.43027847474983870988836419822056214e+91L, 3.64204612295693256305339371887263313e+92L, 9.75669857120640229967783787120452211e+93L, 2.75194604427588305129487979774984195e+95L, 8.17916479364319727936284803066665955e+96L, 2.56370473508682589047202009616066313e+98L, 8.48165649612825587957771293185197099e+99L, 2.96426025440398100674466172613133159e+101L, 1.09534297003120888620652471421812455e+103L, 4.28314854758487062838465336068295133e+104L, 1.77395435294431974409395342323139198e+106L, 7.78899108189422475969140390458031321e+107L, 3.62893172105682135159715800277136586e+109L, 1.79572927251602059220958063790243562e+111L, 9.44668515148283533862523011302496150e+112L, 5.28826317961448810089554134850695191e+114L, 3.15331123674140136231493452577546350e+116L, 2.00480707968382766860514611914082879e+118L, 1.36040719266523771611516008331762962e+120L, 9.86282560980781051743602195410395887e+121L, 7.64755178859112809938428139017982021e+123L, 6.34880222487173008841344329862213996e+125L, 5.64906236198001909791959175488227229e+127L, 5.39324800352378478055022039572371179e+129L, 5.53089719191570391565414448432944942e+131L, 6.09959864464089433289271654904908851e+133L, 7.24209843349196450391058906977712497e+135L, 9.26808305363737556950784175210077690e+137L, 1.27994270241604058214925694813276489e+140L, 1.90979662696062130244831484512150929e+142L, 3.08254030066988503957988563764712878e+144L, 5.38880973238417965706179354197373928e+146L, 1.02161025105662653467101460483765248e+149L, 2.10300544007279065014421211807768152e+151L, 4.70675399034872557015773705065650223e+153L, 1.14683412812524899101968167573148610e+156L, 3.04620262376779901134561159740015427e+158L, 8.83255301555740088857655282843830654e+160L, 2.79951315833790052768515917244690507e+163L, 9.71307000884329724595836237775132776e+165L, 3.69425449543187541186652254254454177e+168L, 1.54248755204034481247092284401752383e+171L, 7.08075007659653083674442572183052884e+173L, 3.57888569536270290704774796012385631e+176L, 1.99473765641034107285413476042860568e+179L, 1.22789700989638770500092926180435793e+182L, 8.36095001442791620159284429240141671e+184L, 6.30749438488829733664127973626729614e+187L, 5.28039699582730274851611343025005913e+190L, 4.91356459266260178144685151251583280e+193L, 5.09061556382806163145943155929283695e+196L, 5.88195913486315120755496558081929324e+199L, 7.59272859182451584412681161192886089e+202L, 1.09687154447604565252927157604063023e+206L, 1.77650105264457177914887205035954057e+209L, 3.23153511879574325299022213712900198e+212L, 6.61424415330008555964088497876375007e+215L, 1.52611134962392865764465743843181152e+219L, 3.97691502072254861067816109956158434e+222L, 1.17271592685350180601663411607927347e+226L, 3.92076851079784438154800269803529292e+229L, 1.48915601904650135853122181753421959e+233L, 6.43831323019893638007682069747894997e+236L, 3.17506717851901774760997889290937204e+240L, 1.78970981603629426034165602936202663e+244L, 1.15551435950001094003467361479483663e+248L, 8.56366431033316582912879348191377839e+251L, 7.30093770528170061921940254565023758e+255L, 7.17613138815551609337504025522760569e+259L, 8.15019404042552378087870259624107791e+263L, 1.07201229194901841245742935320285314e+268L, 1.63677814658507005123653360340510968e+272L, 2.90775562270833690431514296460636317e+276L, 6.02476179304325236422526103127046739e+280L, 1.45944561364291559252990517774206937e+285L, 4.14353248208966528107409825739318649e+289L, 1.38220972739972368321976302536673924e+294L, 5.43125471568796436605394023488404770e+298L, 2.52039989595272682474151246524004609e+303L, 1.38490332203279628724542169932072504e+308L, 9.03453415480179250943103381623811201e+312L, 7.01620311300324094081813342355630834e+317L, 6.50430483422567669743617206850738485e+322L, 7.21793562600493199951776097195343971e+327L, 9.61542788471746566451160668498411528e+332L, 1.54211655565340209996546117001243607e+338L, 2.98626205265198316430063943341329432e+343L, 7.00309320577422492544778192980108604e+348L, 1.99486089518136492496460973366880635e+354L, 6.92350663128275446878446973158773950e+359L, 2.93684755383592258491626945473185368e+365L, 1.52739293250863294426010436780725812e+371L, 9.77075509850276765943058812672579852e+376L, 7.71310608088780517993569363011828070e+382L, 7.53863036472313339350939561575995488e+388L, 9.15331385155864163687518059055937567e+394L, 1.38538605697398143363179835422022577e+401L, 2.62287133256068615930266548676255190e+407L, 6.23343982286571042809890547122705804e+413L, 1.86628588041890755929921756251934723e+420L, 7.06492694188791912037300528166794228e+426L, 3.39406886800977749230458579824930803e+433L, 2.07704891812976483907563047536681219e+440L, 1.62532865525590176989706193358042030e+447L, 1.63262112354994112352218911327913750e+454L, 2.11342684365334123128646755974119857e+461L, 3.53982137873383101244091847412793714e+468L, 7.70246700302666062188915359100825615e+475L, 2.18636422788338230254129077405708124e+483L, 8.12975261672049081897166938196495657e+490L, 3.97686557044826916151646962242652853e+498L, 2.57033035969007091507617008526033295e+506L, 2.20458407348036235529376715504150602e+514L, 2.52051509380683369529400145083533353e+522L, 3.85871376898138292734730034828559871e+530L, 7.94663225793828689108907007781152553e+538L, 2.21176541223395827472447113026924253e+547L, 8.35931033048630497134082029598865726e+555L, 4.31091797212556485985662056018893390e+564L, 3.04833317305882254988404372326531988e+573L, 2.97034828681146526635277450855709161e+582L, 4.00864404566992526097179834506253327e+591L, 7.53113144131492631353410204171028663e+600L, 1.97996763586022811207860344830247407e+610L, 7.32300332662100885299893727481183608e+619L, 3.83078680906847773947984890776183687e+629L, 2.84987258373806149506606754536239806e+639L, 3.03186631046306534459943952897407369e+649L, 4.63861318260680959360747724936035922e+659L, 1.02646622253495677529633262335412306e+670L, 3.30448344760519942319105428211388701e+680L, 1.55678514244926540491694986676104766e+691L, 1.07975219247204914347510266773073325e+702L, 1.10926415409608640204268413223928121e+713L, 1.69843188882084389205231670587156933e+724L, 3.90025209215096037836224226547246383e+735L, 1.35188796159061122898267917047667153e+747L, 7.11881895741722013661309086794573765e+758L, 5.73263787962641176699015570741387791e+770L, 7.10698682909851371094390920546530663e+782L, 1.36568905751347705631533710470350932e+795L, 4.09591384091714486453161283605440034e+807L, 1.93075428208975454032168180693618424e+820L, 1.44069783794868490577087909226154603e+833L, 1.71407451380697883211569548277738601e+846L, 3.27557874564463748685767424892341420e+859L, 1.01295195987435253561137255728975319e+873L, 5.10768437019276174029340754351596177e+886L, 4.23191986113702770379280941046346950e+900L, 5.80664714178397794019307157189161329e+914L, 1.32995815980583547946711112525038194e+929L, 5.12600842672542100652183507817331030e+943L, 3.35203762278831767267193293263751763e+958L, 3.75009417204153826893896307870937057e+973L, 7.23855050824188975713471018223024339e+988L, 2.43146178229439003194650931378387467e+1004L, 1.43376736234835679429446577737976919e+1020L, 1.49738681485939897351147361037410278e+1036L, 2.79474808763788045317059787958854766e+1052L, 9.40752795141195895210630116566470676e+1068L, 5.76455681194134988563523968421696548e+1085L, 6.49098750070655215612470119412325218e+1102L, 1.35603677524062211064037225514112165e+1120L, 5.30731596106421482379267500594247426e+1137L, 3.93020043869734370491941322540535807e+1155L, 5.56226722613029149136813618379760709e+1173L, 1.51990408820680241841102181882025951e+1192L, 8.10228003417607034858018290055212984e+1210L, 8.51521180721994744419289716417963237e+1229L, 1.78329495296502824223674285976432097e+1249L, 7.52325725334531880022021234450122858e+1268L, 6.46447702663797449769360764507187142e+1288L, 1.14411796435953528891736478925455547e+1309L, 4.21851818337788742448241659152628519e+1329L, 3.27808619028067308419286053048979085e+1350L, 5.43188779501763188996015031600338462e+1371L, 1.94236185576822902995555282219996135e+1393L, 1.51711647857248503907031482339088565e+1415L, 2.62035716514505778741231466041668281e+1437L, 1.01340333806343444348385264050569250e+1460L, 8.88786410219005270769408353397020687e+1482L, 1.79062851327433476234422894649930707e+1506L, 8.39642792144232596950658702528918677e+1529L, 9.28628794761707451127390451820966789e+1553L, 2.45536895088636462839367313490581387e+1578L, 1.57354562229875356978426356241845302e+1603L, 2.47847583619098850454983740131691503e+1628L, 9.73157119375940175602769413110414643e+1653L, 9.66320447484532719750186034583884499e+1679L, 2.46232109538721189753853963925622165e+1706L, 1.63417596934387293040006746046570718e+1733L, 2.86767794799456586471233013913198039e+1760L, 1.35110548955493375904544893914917995e+1788L, 1.73592152545700077097814839827674920e+1816L, 6.17893831026015926230407301367680801e+1844L, 6.19169576655007716364858612984691562e+1873L, 1.77539961419331109157892833779912252e+1903L, 1.48102931564535770775910220632570312e+1933L, 3.65523833138677287346435504279580939e+1963L, 2.71500576533505130343548298805675281e+1994L, 6.17538661057993294979124427622665421e+2025L, 4.37773911614056336228335278244614535e+2057L, 9.84696637606677900175890481086698860e+2089L, 7.15679932872021171306956409599896671e+2122L, 1.71206538074954819527676482193571839e+2156L, 1.37358203471630226464631105286036694e+2190L, 3.76701670663930120912543386433302245e+2224L, 3.60043887764831236838085599723119708e+2259L, 1.22311399177140229476034440208616729e+2295L, 1.50662485913882109231872682750679813e+2331L, 6.86720031172136555587682118613084257e+2367L, 1.18233110675109495729851537371527994e+2405L, 7.85186218386652904615339091354671418e+2442L, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -8.8984375000000L; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif +#ifdef BOOST_HAS_FLOAT128 +template +void exp_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 2.239451308457907276646263599248028318747e-2543Q, 4.087883914826209167187520163938786544603e-936Q, 7.764136408896555253208502557716060646316e-345Q, 2.569416154701911093162209102345213640613e-127Q, 2.705458070464053854934121429341356913371e-47Q, 7.491188348021113917760090371440516887521e-18Q, 5.198294603582515693057809058359470253018e-07Q, 0.005389922804577577496651910020276229582764Q, 0.1920600417448513371971708155403009636026Q, 1.140219687292143805081229623729334820659Q, 7.806184141505854070922571674663437423603Q, 497.9910059199034049204308876883447088185Q, 27016042.73379639480428530637021605662451Q, 172966369043668599418.5877957471751383371Q, 1.061675373362961296862509492541522509127e+55Q, 3.811736521949348274993846910907815663725e+149Q, 4.031589783270233530756613072386084762687e+406Q, 1.857591496578858801010210685679553673527e+1105Q, }, + { 6.38192460297577997296130116084380488004e-1543Q, 4.553284218142424152191512347101108073691e-568Q, 1.937062162895195937060002998269756423851e-209Q, 1.660126625033739077374114876720390220712e-77Q, 5.725718222547734673080418904622339594753e-29Q, 4.168381624810496871907721134250128161942e-11Q, 0.0001613301975005046953323705477328478299103Q, 0.0474713399587676291203429066086137662056Q, 0.5099627601758401314316521881645115690603Q, 2.636240582466121690921186199130019570689Q, 39.05613529229837860979125052359555007623Q, 30990.22477506600812220045610450185310364Q, 1857609984963.014390268032888333743476748Q, 2359106700485891760372588191034580.237445Q, 5.305502438164240038024865289303441329929e+90Q, 4.153264547632969989660655052675878016131e+246Q, 2.39549808558050342461418974153843135261e+670Q, 1.907821628968714220362207148967088886146e+1822Q, }, + { 6.057903324174675880054786918700573277193e-1981Q, 8.656190904067090962653034260124195755274e-1202Q, 3.301911576596318022491539142850442018161e-729Q, 1.425485029898429297758878823810205941516e-442Q, 1.016496544573331920304016689793414356743e-268Q, 2.848036810989534605128535426330975462895e-163Q, 2.581928872313165828368701686010678577144e-99Q, 1.601590227152633400640250804848713890905e-60Q, 5.423190544363659530944338243992687682219e-37Q, 1.016381761828840448285257216929561921503e-22Q, 4.635725075794601084424604353869125707077e-14Q, 8.3498615886950739967156481568160331201e-09Q, 1.303868885475613415062833232828648525669e-05Q, 0.001153300807253218344728159062725073079949Q, 0.01814288911244882236930497812936819917973Q, 0.1025656071886267491128524112054469619388Q, 0.3242301173345578897587341005053281543043Q, 0.7688636442387784234265303257286061242944Q, 1.704936145319479582718350104944998619577Q, 4.332223509891009397137256165478273534279Q, 16.00424777396788542203662195209964219854Q, 119.9894477197320344196270723637925628186Q, 3053.206094606356294417950881488718170062Q, 602365.2553559583292243897621777047334194Q, 3550455773.201059364690484967711333425091Q, 5733723619916794.008354021149856937812556Q, 97490164875869638451560588.97182161070984Q, 7.132097466952214251618865223622602893458e+42Q, 4.527309308592487932893086561010303870042e+70Q, 3.115319987396348432317683626917454615693e+116Q, 1.165082263946878699920850154957972424971e+192Q, 4.61868993445541953416660351754288757642e+316Q, 1.235693446874006572643670815583618997533e+522Q, 6.085142451732094001360716852852249745666e+860Q, 1.561268268167538223129534325473369675815e+1419Q, 7.15416720524977809484490807341332912337e+2339Q, }, + { 1.316397640984446973307154953464589633275e-2244Q, 2.91103714441677346374884778987181929964e-1748Q, 1.041515112823364264288004198932170597134e-1361Q, 1.163952866111770553035180609992941917098e-1060Q, 3.331010008037941781256743115855292034324e-826Q, 1.311012824977050544924978303237678019851e-643Q, 2.102714428828884821953890862683078649826e-501Q, 1.181154283940326231672292577754503055478e-390Q, 2.109394497146605580650701202262455040085e-304Q, 3.142026651033038465813811858591067955951e-237Q, 6.481721750272378322539690406725748230209e-185Q, 3.583598691717140876356841025821167196821e-144Q, 1.92664353411734602269656833786034601971e-112Q, 9.922976982058019429687317584840590274898e-88Q, 1.74739966510164583390419990770953521763e-68Q, 1.70290143918426077776224230568679054616e-53Q, 8.030136878691961276301034231071221582072e-42Q, 9.917365028053524354476145352392235487451e-33Q, 1.195101660603996715429218637550950454647e-25Q, 3.914005753291886226833591030642884022779e-20Q, 7.736530260670029404731999770065344717989e-16Q, 1.718208187412490487060798651160186368903e-12Q, 6.957606467986766668781610852908826758303e-10Q, 7.490494532575157167666978009034915042833e-08Q, 2.876694179706214244895454007509365858007e-06Q, 4.95621623915248246930633393189624651192e-05Q, 0.0004580885614011081480136084266758386238991Q, 0.002611973650987327972015238352563580017097Q, 0.01024958074171405301707965287545674192198Q, 0.03016224300141855969532721437631887510999Q, 0.07123470770339354612512733126593011802245Q, 0.1425077997714610113981393440866519718873Q, 0.2522461348260661654197754128666648295859Q, 0.4094768120120717375909393632502588445701Q, 0.6284517616579117758312487536756803604881Q, 0.9367868281384272374009925574604673700344Q, 1.390682216155298525280673341216151282237Q, 2.107722788359705067834932911785748508994Q, 3.347673174455422472577549274497972709551Q, 5.736410541438001909256000925370163885819Q, 10.96982957507422942804757729955529934671Q, 24.38435887010115093181364909323819215825Q, 66.24753699117985966148476651092908482621Q, 234.2315029073004369735419071058951676162Q, 1166.800705234530212373324266823192926477Q, 9058.072807556345123303399558638850050032Q, 124646.6048080201712485538680062639558529Q, 3584819.86746951378682172637961966062923Q, 266100993.7796082691768128807430671558536Q, 66825052601.51570420440082629824643725379Q, 80338167537283.97995953411028754151943899Q, 721934731984192713.8330181471216700501392Q, 85912332322414837303920.66199595232277841Q, 282145179878388664670389842403.4386259681Q, 65637349877520123390370406122266056686.38Q, 3.628585210946194380811829731899355186227e+48Q, 2.255004287064249520310520131039130736102e+62Q, 1.15869387156744556281317453901581151608e+80Q, 6.381237955604791946525597400340497294869e+102Q, 1.010840568769200528470714372039635841864e+132Q, 3.146392870507528140666504475776071670543e+169Q, 4.36361765578710599110918832751720492273e+217Q, 2.853414836089672424680428668400813268807e+279Q, 6.729793209488189821208480033926845423686e+358Q, 5.551856590995612599330193819104783525931e+460Q, 4.052255999971348848790422668447727946207e+591Q, 4.359321017798455720139540978196326313327e+759Q, 2.491143253847753891477290704847758735118e+975Q, 2.715360792058091922045750051250504657e+1252Q, 1.435205921116767351962933143664802808424e+1608Q, 8.210855869756939741458957539090139842153e+2064Q, }, + { 2.5206619423030582050540170122224114428e-2389Q, 1.172863116157072894734245940044946298728e-2108Q, 5.723395259249713010169313313952092349583e-1861Q, 2.197389499531280825740095933047095895838e-1642Q, 1.745161518126606205352284095182052308004e-1449Q, 2.988322581168499697535468502285209728217e-1279Q, 5.082152338298280900263082030896703594299e-1129Q, 1.923568771941791888696041505006148197297e-996Q, 1.922376701708619531115877054556550086857e-879Q, 3.43354234203261313677968607194090162681e-776Q, 4.520976144958693723499608471428644204377e-685Q, 1.16924290517103592239484417171431040132e-604Q, 1.076080723321413327903675953550818303011e-533Q, 4.542643147897936251189382845876349248208e-471Q, 8.39641135188984130629872933142091374729e-416Q, 4.975865312177024229863027999897167556333e-367Q, 5.478993165227465768218836546574553849014e-324Q, 5.284390536217028049162677728277890870188e-286Q, 1.753997013998162369603538709409426038521e-252Q, 6.702720150152123722417807613786063904275e-223Q, 8.560241294360251079054160391146097054699e-197Q, 9.357825403471029128412705980972206582797e-174Q, 2.008012274394970040775210542988145301135e-153Q, 1.759362217490417244193766476411245146585e-135Q, 1.201323068157632801024303577546837842597e-119Q, 1.130871751114348441263036859622267361614e-105Q, 2.427952702329304891356334984001160462099e-93Q, 1.853857010064827708666752242673457462783e-82Q, 7.450531057316733181973526587285947355417e-73Q, 2.227578113196083858417625605575495347595e-64Q, 6.723847629738657283145680261671783557431e-57Q, 2.682661571058473846237236792137934196058e-50Q, 1.79453195451344128721262062986439838442e-44Q, 2.482641507616913094034333751341582768753e-39Q, 8.548433311573474998083868427676274583188e-35Q, 8.62683103876914985130407106643678050193e-31Q, 2.947486044786180737441798148453414409162e-27Q, 3.872329992960205091594692590987101453023e-24Q, 2.188786812967355018227938536553422999502e-21Q, 5.877663279328016310239105745938007253203e-19Q, 8.184245820130904480351031879568469982524e-17Q, 6.383596940050023404498310185052683420494e-15Q, 2.985846320564205038037745987061543784625e-13Q, 8.894313235339439363097219119871323774239e-12Q, 1.779353851443023403734921943727167209889e-10Q, 2.505382916672247087749339155220756062847e-09Q, 2.587725630426792604401006002267344237741e-08Q, 2.033572921227284576438445719455687616491e-07Q, 1.25575991824042977482635039643574244403e-06Q, 6.269440412694030058863353111989674862175e-06Q, 2.595085881599872954251937862499883118425e-05Q, 9.105996179813948353400602282697524464869e-05Q, 0.0002762392802117902551874788776118764135082Q, 0.0007371672770779048357858142458553279273489Q, 0.001757270507480588460625943761648134470357Q, 0.003793199741311863237629531234477439491776Q, 0.007504045999882254423903408991718678739289Q, 0.01375129203357108795095672207425737042887Q, 0.0235648806669815705789256424396565511416Q, 0.03808206546757287312410400667727321525232Q, 0.0584750515250823575509888778022876539008Q, 0.08588741816168257779870858476342798002897Q, 0.1213974127142878083976184138280395303104Q, 0.1660203958235870922656132735987314987822Q, 0.2207560463670208437118557853737734158601Q, 0.2866810915284543028513192158997575835338Q, 0.3650869474810520258950775181589457153731Q, 0.4576643646397673926152716166562185990355Q, 0.5667441269218995998913739139298550489509Q, 0.6956144754295223366640533077595837863928Q, 0.8489536783030172130335775282473784663229Q, 1.033443510885548859219360552937381026851Q, 1.25867327784678000729733451594597097337Q, 1.538517555075041016346761652863952793208Q, 1.89329890876468636135161330299058554312Q, 2.353277301351851558487347974576485001412Q, 2.964435360444065702141420592598446485362Q, 3.798346361008385380944705678431124418709Q, 4.969527598464384372784681410687225436954Q, 6.666989125776029897025551678183749955099Q, 9.213721071361445027221262415929619540222Q, 13.18345690989291972865182826932610004922Q, 19.64024062230142947772459448354624698294Q, 30.65462770756782675694978623368074494086Q, 50.4779893046794926285039124793115175055Q, 88.37993660346673602047366921902538163011Q, 165.9803667059984169730050649489153421943Q, 337.6706631615823036132897955161926139609Q, 752.4698775446966859930160294870547655096Q, 1859.895753721088275783900471462382585879Q, 5171.784242569678351544419777453466412916Q, 16439.68224920392428255829998472244941314Q, 60828.28772762458714202245676717324350873Q, 267403.3214912122110256002506355191499137Q, 1429347.933351015204306617447897972413452Q, 9536926.621626306980484309643305423208196Q, 81822783.86938234780551399066229800198692Q, 933554751.5321686629929819185460517560829Q, 14714528933.55367564194257696642197219325Q, 334526819004.1342316058283621780777931756Q, 11519120972470.51332962127585805147042226Q, 634977429513554.5866778047103885859990833Q, 59661154851781618.71469833139627374808833Q, 10258566668268483666.87233774788273411671Q, 3498782351548458269054.698064372699628001Q, 2593041167054462009490911.107406772475519Q, 4630891728517314272789671037.133056823687Q, 22405725198422081640863565993885.01556046Q, 335382887519057371346768487572597807.0471Q, 1.805229891096869056758012265512553255292e+40Q, 4.143352671969591623813814524116221876304e+45Q, 4.918933828381959415593488120823071981949e+51Q, 3.759479884167637531775066458674648098607e+58Q, 2.370354252414880186596684665159418630029e+66Q, 1.632887662723346042746203904027271808135e+75Q, 1.689790288382573271901196765672215169737e+85Q, 3.768157678554177644154419456918439518135e+96Q, 2.725167569380753976402510741556225451742e+109Q, 1.01581121689650812980198251914622703178e+124Q, 3.298856991576337284158560413886137181497e+140Q, 1.691896320782650875076203269043188495403e+159Q, 2.688862164597444111407738620805399395688e+180Q, 2.842157259124605697187795386218677216391e+204Q, 4.747639199403024362447283672125852826296e+231Q, 3.341705701165246712607275760771067534333e+262Q, 3.011199583815608630823405186037102754549e+297Q, 1.223690427483633883424913552261079866419e+337Q, 9.342435130798085441244782123257085986706e+381Q, 6.75013277944506940788764281864974376778e+432Q, 2.883587060602951466391472557821367572471e+490Q, 5.807295241013203323828534467621397444726e+555Q, 5.796152105409012013566864143195753032862e+629Q, 4.122626017834653186081615813053037582347e+713Q, 4.285202011931086479539142857463076440052e+808Q, 1.99573761404250032069947440682788052405e+916Q, 2.014079397178923658633495910333688587014e+1038Q, 3.570148522918403340320830841666908310066e+1176Q, 1.617637477295168349967593280814302779633e+1333Q, 5.291797544280981679311029646634340608003e+1510Q, 7.48399182023635266336559154483155451479e+1711Q, 6.420118348194716283591292220766712713315e+1939Q, 1.230075220167288536615919838362095973387e+2198Q, }, + { 3.795390672070017300753231208972661157463e-2465Q, 7.779777553755136439657877267977245651568e-2316Q, 1.433306323222013275209083063019716735198e-2175Q, 8.384206893282840565983221028480116073658e-2044Q, 5.095877570390321573443926231967674337647e-1920Q, 9.801617117780997982789217759593347992677e-1804Q, 1.698559621973235103207681863307358445538e-1694Q, 7.086325399079152707198289787557526167382e-1592Q, 1.791883740278245862466944715145415778126e-1495Q, 6.537977048684207893536199493437969077762e-1405Q, 7.774908468832649847178339204899627179575e-1320Q, 6.478864602726321305200912515898143930486e-1240Q, 7.765090574678907306134193726947577898876e-1165Q, 2.630326119433748477458706343770434986992e-1094Q, 4.749906839546177165095241119597567665718e-1028Q, 8.299891364005248930752542816259554461453e-966Q, 2.456886121616923290433040931702106673987e-907Q, 2.084975105306165421720621792298451738582e-852Q, 8.314863021917642918260981455060899893804e-801Q, 2.479012812294721526368945086473772161421e-752Q, 8.54646964556090357402612014431012525116e-707Q, 5.132368733352036821103684616515224808065e-664Q, 7.889147927418897398294379021877366424811e-624Q, 4.456089988888074476694572824088806782629e-586Q, 1.298990194919558378495326736351729403923e-550Q, 2.688838750505892128510794226187763931399e-517Q, 5.333514036446538787793518253409262489744e-486Q, 1.343530053903156890860347423384825206649e-456Q, 5.599542549782115166174708028896712747121e-429Q, 4.950559812998042896188584647263206419909e-403Q, 1.172571121690289764179956681265097018287e-378Q, 9.265119487981539529767577305990761378789e-356Q, 3.000980062420973867973818880845860478641e-334Q, 4.835349309746179020153748142870208251803e-314Q, 4.648418165203187459537829054831654604148e-295Q, 3.162795591358865058002374567318379344286e-277Q, 1.78816495446662412891655575761768850823e-260Q, 9.767303242094807115508406532983731924042e-245Q, 5.938359770701310949887981802571491225734e-230Q, 4.590409820668175251596766385949902266971e-216Q, 5.112083272880275136834520713890140902382e-203Q, 9.223299886181076841150224911038916132471e-191Q, 3.010290465213103549498805131683068042409e-179Q, 1.971306978618734683067074267607013989575e-168Q, 2.854882401768039470681434737764403097782e-158Q, 1.001876004164187257589222479116755961481e-148Q, 9.28388368884304519736248927049010830097e-140Q, 2.462486108028708927260440395734488837617e-131Q, 2.016795400360833462215017065421366863426e-123Q, 5.476652622966367615032292053884484336876e-116Q, 5.272077566455494451788521546425408136695e-109Q, 1.915797835762559722934275003970166064824e-102Q, 2.787748791718769345895186833164681898523e-96Q, 1.717019969783925469381392688568931486586e-90Q, 4.715605767411004441260107716554911215983e-85Q, 6.064460188117978272108174292717305809528e-80Q, 3.823876411447123854401459917711732557741e-75Q, 1.234319419865795919459380852955199024887e-70Q, 2.124134488829505900467360579059303439811e-66Q, 2.024503330684819834315108532844110559563e-62Q, 1.107606713747660145231851458239388162059e-58Q, 3.597409197676984675677984057726546424488e-55Q, 7.159009669672532506246206967901639058717e-52Q, 8.992186046439948861475628942520087991718e-49Q, 7.330545657183168686891287840557389031978e-46Q, 3.981455458584870683744497436520506933176e-43Q, 1.476619713772285254431130454584176200133e-40Q, 3.826978431809928214389355447519902726264e-38Q, 7.083290668359386861447966477541586360608e-36Q, 9.555768999319788426431775086087349112968e-34Q, 9.577913087935460160539269489276067690914e-32Q, 7.262226384946935038838885698096620016918e-30Q, 4.236504491274396853110321383504675317874e-28Q, 1.931901576598121874499773676395841031276e-26Q, 6.990113865391778138743200448969517839792e-25Q, 2.035144735566841718413904303195536680396e-23Q, 4.831023993941522980447473400007455319995e-22Q, 9.466523297160036536447434637997160469953e-21Q, 1.549167405525432140925565313051159250563e-19Q, 2.14045496241922041961398056320914332322e-18Q, 2.52272497168145963445164392470656925743e-17Q, 2.560802965559051560381760195943725944933e-16Q, 2.259216301270926387212069708862804061239e-15Q, 1.747067697308661614911229837784633703426e-14Q, 1.193721953493877730136777069023115375804e-13Q, 7.261048647211436110012409981162064070343e-13Q, 3.959698354015994423003203648219445875559e-12Q, 1.948812140821042423838293141200645234893e-11Q, 8.710185284512708238528405205689273543106e-11Q, 3.556110511389215106439363864587680913673e-10Q, 1.333523995015433973303869945509054883231e-09Q, 4.61686492197482306467363712069697375051e-09Q, 1.482933777652652086397921165904176062922e-08Q, 4.439201256433602926738671445859281174894e-08Q, 1.243818740024104315795359265865889061391e-07Q, 3.275118138216200625243866640518155922026e-07Q, 8.134998048703182572861795938492429107642e-07Q, 1.912901137346598024841188094682606222964e-06Q, 4.272510974451733112955668057488366672288e-06Q, 9.092705525753037851717167450560202933918e-06Q, 1.849285862719977729368018635153610374012e-05Q, 3.604297979179478770170349465262021708134e-05Q, 6.749560699636067367111827124793672270975e-05Q, 0.0001217399530093589052755709255552137501214Q, 0.0002119798092857219716784092724070184838165Q, 0.0003571089874396016314441647628669192562085Q, 0.0005832262433970766235214764926219826111953Q, 0.0009252003173231862125410074191993584583236Q, 0.001428170271956024371431271278148622938591Q, 0.002148851705929752880377989456676968462357Q, 0.00315651924059648003003554910164669437379Q, 0.004533551347666632228987100190172196497749Q, 0.00637545404570481802455455747608672403478Q, 0.008790321915333871574458792947941344568964Q, 0.01189774328782595914086895004343189328045Q, 0.01582720561441695890844807688765959236837Q, 0.0207161013778195777697553686569837390476Q, 0.02670746991923049288761134463020449829739Q, 0.03394763323356885770625642676679074309901Q, 0.04258389292974886627325746268496237602011Q, 0.05276245167659283110092436309489567698917Q, 0.0646267074882549485198639150918873184786Q, 0.07831604604644478869244426161876162156255Q, 0.09396522829516283795223827995446661844768Q, 0.1117044411973961766270728271802225526835Q, 0.1316600519131492902561052263967199098344Q, 0.1539560822924166257732329883435248756687Q, 0.1787164033620456734893640543344657244889Q, 0.2060676396490745147451195395209975563699Q, 0.2361427713798308598187043784963620082981Q, 0.2690854290511355532204052693921342602242Q, 0.305054889564183700169683815016292291199Q, 0.3442318059586820108521538706833283481062Q, 0.3868247338279828413933661340378205138754Q, 0.4330775570906081008567360156110456811268Q, 0.4832779647893183186516132108214191589339Q, 0.5377671905201770169268895537332680002311Q, 0.5969512993956263711392546315972859565671Q, 0.6613143977169219977516694158659088783811Q, 0.7314342528824741733839807656432757716107Q, 0.8080009525815161840183243326671240353006Q, 0.8918394127469408385488364196441967124333Q, 0.9839367763604760603196459906151607884336Q, 1.085476048188192123075453739251218510212Q, 1.197877708796906199452119329245639014272Q, 1.322851579124039222603672663798567463376Q, 1.462461912120810364685968380183335243894Q, 1.619209637172122692401303406940860411898Q, 1.796136969870131896910672473813146944781Q, 1.996961357255571143394600289831227589373Q, 2.226248146939811707460599481581870837544Q, 2.489634721575354120682362651699549592949Q, 2.794123526213803146198014666678951074308Q, 3.148468019138963709501537343168779075746Q, 3.563684960811185116871444598190714785818Q, 4.053739911052914262319668034399529246027Q, 4.636472277732791639643132400229354301411Q, 5.334854715994749316640865062595471476959Q, 6.17872368062665629230474100549748115302Q, 7.207180591667347287378567828702938758294Q, 8.471957573781362650788882585164992019564Q, 10.04218590197794227217933794419470785519Q, 12.01122789383119269588876734679450310228Q, 14.50658104373764159548493669863074310088Q, 17.70441458362279065247583672815995486735Q, 21.85118425006810320690011043664488062523Q, 27.29621402684115092380778363288585647847Q, 34.54152056424679099285119102536330748543Q, 44.31916726839142090610996062523724345462Q, 57.71328886751774892234123495651961475509Q, 76.35584358152632016598443699081343758881Q, 102.7462505675411480105538524612024044409Q, 140.7831585666643225193757393741867278968Q, 196.6667474964623927249971506170398178841Q, 280.4619631485236195196797451233228262752Q, 408.8670610980933975199031744038678580601Q, 610.2321623589824189265508610689128858198Q, 933.8829465748849223717127266358476602503Q, 1467.899351682072654265261818303420805692Q, 2373.963552496782925146643131635919487713Q, 3957.687993737630371024277051314012548134Q, 6815.00440544869246329167423844268111282Q, 12147.029345299389687784126723105779578Q, 22461.26315451801667607728249765542982297Q, 43191.82899503864990448351842350310452323Q, 86592.83261029074596023553700403258785224Q, 181491.2182721628267997397771678482115802Q, 398821.3304282950694957160947337961449181Q, 921693.0297755253718437997165579403685837Q, 2247506.617072129871513449059675893778703Q, 5802766.090658016747854717427934875572966Q, 15922021.31523087692433670991497122820894Q, 46612597.19331592874262340584944675431461Q, 146208710.2792678645398232830462812342502Q, 493569143.2307066662432772490674353132498Q, 1801740337.558116631147349810980444999904Q, 7148307411.399254959232794464956561182284Q, 30989869934.39066958068626939662791860663Q, 147649151381.9059927972205500145326440175Q, 777832651058.2373318671672047663996869845Q, 4560424603708.565710249815401144391564815Q, 29963305946767.56842972520633089879873266Q, 222246149150518.6507762919150981008140173Q, 1875596126838825.642644233007895386015597Q, 18160363350835773.74516009756645868880786Q, 203536650090248516.625043706634545368859Q, 2665597720841305548.302450333304699400882Q, 41204608037903156475.39985932734062136376Q, 759876113857935028362.6764948416534507389Q, 16909538504875626556689.12599202687620857Q, 459597465298806307001750.7749444248692729Q, 15455560145468796199738255.29643411074339Q, 651956726139185886059458642.6456024667082Q, 35004988031596951754619312735.98599420651Q, 2429841273655890598216891207245.641906802Q, 221696165758096369653709633056729.8232721Q, 27060150789216850631109638704372698.78322Q, 4502433645750365138830615513311327089.375Q, 1041810120339429976002448865021784801526.0Q, 3.424464587101762111451481470694312381625e+41Q, 1.635664057519152851238683474567057668695e+44Q, 1.162951256027565131290956161943290374314e+47Q, 1.262811761284799086503405611252635233656e+50Q, 2.15222560299770182282455885090384256002e+53Q, 5.927019921206890317429173453836477496214e+56Q, 2.720358070414621904927945205493061176651e+60Q, 2.150628379545567079384298592862480655326e+64Q, 3.033091903463971517881841788307963107317e+68Q, 7.921368611331628081248063379573761382456e+72Q, 3.986286626077744941375852361406984714748e+77Q, 4.032391864691712851313014198621042119742e+82Q, 8.577090029838120212166000022366079871587e+87Q, 4.024562204594671053503828454684257308668e+93Q, 4.383891452457096911537927453770180399861e+99Q, 1.17045217400342154196646591119629085978e+106Q, 8.115437734907537955622095521768803987323e+112Q, 1.554052969362240408421903236953148739051e+120Q, 8.775471287453444844276638439036590213222e+127Q, 1.566809482709748107234370921913935232618e+136Q, 9.526797160697136847557977555249000344472e+144Q, 2.134941756221901106176576424675977193162e+154Q, 1.918097035157483285449977841564367744648e+164Q, 7.556035740310529929570454851394128435238e+174Q, 1.43568170802240136103830216945338188904e+186Q, 1.456247124841402286711771880936055458401e+198Q, 8.784946928360920634616223064741925447928e+210Q, 3.535985278478868333807046739582226641175e+224Q, 1.073272343888237444965783157773143482544e+239Q, 2.798511671365241100069292950756398438599e+254Q, 7.201139159763991347976972479464073241141e+270Q, 2.119612470693949634980452377127889982788e+288Q, 8.35127608501017199036945672484210550293e+306Q, 5.206581076471599138927368603976642437135e+326Q, 6.137683072504159519093566380150676073848e+347Q, 1.65365713226976909024057251840993190236e+370Q, 1.246014506033140843421606944264692466847e+394Q, 3.254899241867217111629780947123555165675e+419Q, 3.705154796788819306114372374954229956351e+446Q, 2.344512109211865118416887254717997725603e+475Q, 1.068605521510729219385296658425410620874e+506Q, 4.622755758626722510337274875488262765949e+538Q, 2.545829350236663337500678416947756636394e+573Q, 2.439795178088938120765822649335193091201e+610Q, 5.675175497466395228662107439123139188123e+649Q, 4.565969620548043353061100880184463647516e+691Q, 1.852513557834463914074257089792125292744e+736Q, 5.66202849023276763425686777537095814147e+783Q, 1.99854750515263372338536180455239032501e+834Q, 1.28382276856928079108725410000686060447e+888Q, 2.435560683565767075089527065866036912278e+945Q, 2.284607066895124809009946752542339634883e+1006Q, 1.83397327367455896295290053298361055471e+1071Q, 2.259224958362616651797923330046896261405e+1140Q, 7.952136569405401937718403408277221799385e+1213Q, 1.550067830025464501251949158102360769822e+1292Q, 3.384382591693685484610769271259590877811e+1375Q, 1.751941236491613044496278886964352885248e+1464Q, 4.776645267343470319209453110650570993652e+1558Q, 1.604349526201221298891650145582936076751e+1659Q, 1.640044957411376610973353671546593593977e+1766Q, 1.336396861851325699943323623799172110962e+1880Q, 2.41906808317407675203923811685143697444e+2001Q, 2.896081860693974086066933470505539001816e+2130Q, 7.324861191361713354256739989104536795154e+2267Q, 1.347469525914335579372969347338829120074e+2414Q, }, + { 5.892170517318086666953925258259606259061e-2504Q, 6.117305974456569837115715631749111865698e-2427Q, 2.712084481257778798750223761957629870515e-2352Q, 6.073058710711633857519284698655949914024e-2280Q, 8.082266197142077119564887639840911869565e-2210Q, 7.484561995997071530501984781691501485529e-2142Q, 5.619352370681200188347816270904791694455e-2076Q, 3.966702009117964995668129237954360954774e-2012Q, 3.039160829008980709281446092761564330808e-1950Q, 2.904674120638887918188905017568583344857e-1890Q, 3.963146206792477443213856482805096904006e-1832Q, 8.797489265002916895750145490206360737566e-1776Q, 3.606480170760138398954756486565543243608e-1721Q, 3.087106294302307871196417216617493649868e-1668Q, 6.215254538498038663143380180158422424065e-1617Q, 3.303019263067666624863250674838244790295e-1567Q, 5.181698126897362137508517547147366721192e-1519Q, 2.67430990687042667343737270909643193877e-1472Q, 5.04372736336949773835965501524190461252e-1427Q, 3.848661455852432413566576255164564523954e-1383Q, 1.31142543929451988746108502161155545923e-1340Q, 2.19579728467028106786956369019004703621e-1299Q, 1.982058966544355958671442714446925470899e-1259Q, 1.055209826978095633677671490164298051898e-1220Q, 3.614769981710764510469969660128911079744e-1183Q, 8.669620657522813613476248440368886020077e-1147Q, 1.579891518706792342061627603531973101382e-1111Q, 2.368095394608974529044007666148227296087e-1077Q, 3.152777809486329357349922837512146182733e-1044Q, 4.016616422152767475043768845311040445394e-1012Q, 5.26326734348874427867160923756135577274e-981Q, 7.607975954101774669220742789343028025992e-951Q, 1.29824601484856651321515822364389494584e-921Q, 2.792983144744856624041340061025572588357e-893Q, 8.073725811606752551798005890821023071973e-866Q, 3.335750915317738167215040711158938700374e-839Q, 2.091325277547992586470359739628205949321e-813Q, 2.108397879487823636845683679666452461287e-788Q, 3.615813848673697494437203912271165602689e-764Q, 1.113910390544133206836910834129616648114e-740Q, 6.4986798192866207556531928681508001505e-718Q, 7.557269790334208193064600070845678835738e-696Q, 1.840855696857568526152225936524612005631e-674Q, 9.855455540318692459000160450736088444298e-654Q, 1.215011181806807883503024417928187082906e-633Q, 3.608710810907620387125789818961584561518e-614Q, 2.697801843128551517722534747566806678326e-595Q, 5.296475656590678792057661014274729741598e-577Q, 2.845434351853293221694274145766127034931e-559Q, 4.353222210388104546768744275969919162466e-542Q, 1.971319605306481685459990202413649319882e-525Q, 2.743178579713549537232332748108356050045e-509Q, 1.216377484217057669321200590511760772754e-493Q, 1.780251054144349041585891833770135353931e-478Q, 8.898235527618745551411874254333308519164e-464Q, 1.569971597631697176571270982246834173433e-449Q, 1.009621902698559076723839592135830897456e-435Q, 2.441127896800545725696080663751581711874e-422Q, 2.286956623983843351692168480046548829067e-409Q, 8.547313231231952263389158526373469384726e-397Q, 1.310945121043115854537489288344750585315e-384Q, 8.480544215952584120219210061556976886891e-373Q, 2.376195750145011407949988906500690280959e-361Q, 2.958966552359701613946778776076028444187e-350Q, 1.678932905454870490485103352086229292909e-339Q, 4.446975873193618582040505313291817509065e-329Q, 5.628775440009246798411151001673301275784e-319Q, 3.482949423243256460469329466445523169403e-309Q, 1.077028836057387184891418032453579279292e-299Q, 1.7002900687661497411099945611064888079e-290Q, 1.398999859111998929669400205107302068455e-281Q, 6.120943065868598204199619385636695886373e-273Q, 1.451991886477035314124154356864543161856e-264Q, 1.902982255891018605439736483173910116321e-256Q, 1.403323668038955827632944226103034802753e-248Q, 5.926761782297548008111802847112709911628e-241Q, 1.458347909530007582053409207558183402751e-233Q, 2.125725921886845166902485753056081233894e-226Q, 1.865314922085840081035788849150941346294e-219Q, 1.000868211285321086917874293102058243002e-212Q, 3.333910189116025062392204887682742425462e-206Q, 6.996057797661723564465529622684508232394e-200Q, 9.381010137682393061723297183966641053728e-194Q, 8.149422206570198614671737034056664431133e-188Q, 4.648204050438648295729958742208519419602e-182Q, 1.763382028599735618950597430260750127679e-176Q, 4.505668549509372875334714365466121837689e-171Q, 7.848827451015741343516636376339472039698e-166Q, 9.43195366733317557432496852652751112836e-161Q, 7.908807675712522422612568989783146337138e-156Q, 4.678874056808388547490695440890043150363e-151Q, 1.9740277150406416393472265914784118132e-146Q, 6.001555992890612428801571487780317935966e-142Q, 1.328163079397065385327925289264731361735e-137Q, 2.16052535040165176442153814630687031217e-133Q, 2.607958591114470705414120473406600483036e-129Q, 2.357554701561926760029134769773337306267e-125Q, 1.610298469201024515879430894257744042905e-121Q, 8.382612222355548760233942491367020639525e-118Q, 3.353593586452915832569674072223525081046e-114Q, 1.039483344045928327813782782292714015733e-110Q, 2.515998899367231336786588220014789800163e-107Q, 4.791748526296684859820071480335168052638e-104Q, 7.233882041344577328694643371681697761091e-101Q, 8.718610699523506537449879798515202197214e-98Q, 8.447548935303423092983492501963432028328e-95Q, 6.624273312846416599106412803691377974126e-92Q, 4.231522609903937390394156663719438122666e-89Q, 2.215877847430570570445630383685921708396e-86Q, 9.570645508139853996549884935016352405711e-84Q, 3.429704850295633161024952993937464831207e-81Q, 1.025621270026085677651647893549391716655e-78Q, 2.573652733661275222317639633213733692478e-76Q, 5.448651668530820565916001089395037924061e-74Q, 9.783082745893052744363715374110441645141e-72Q, 1.497309317676946956551112800447843381192e-69Q, 1.963044966272704772659454700492703707982e-67Q, 2.215134209071674982471098815066195747706e-65Q, 2.161351710643442010301494126693960145476e-63Q, 1.831678748421095089762102375383001016554e-61Q, 1.354112410172168136765883516840229885915e-59Q, 8.769338472449643538158092836793899993759e-58Q, 4.995220388929997584669700704804630257962e-56Q, 2.512654423616951714204235999520576210629e-54Q, 1.120373918708649945843283688366357025889e-52Q, 4.444839111284013899725922216127704158823e-51Q, 1.574610283663527272755009024582427877567e-49Q, 4.998356543932294904480136169985894236427e-48Q, 1.426543666359685133441221136496707150912e-46Q, 3.672552882913553274555845097712520647132e-45Q, 8.555668106587513479048141229067260955288e-44Q, 1.809164391396441253762162140556144646538e-42Q, 3.482848907447103497527032821217257422686e-41Q, 6.121786687311889688191400930566012176179e-40Q, 9.852003787026362774618836477823750001228e-39Q, 1.455634124991238896963167344925482788243e-37Q, 1.97971820691572088676655895385912176617e-36Q, 2.484763679339334966581765721767085024748e-35Q, 2.885163212704360732431320706076695613523e-34Q, 3.106699707341279253390630094501492545923e-33Q, 3.109422822659254173295015828730415582971e-32Q, 2.89927169617384850488285791262825714268e-31Q, 2.523908691785325135732629051255895540275e-30Q, 2.055662367454969045111364012501147940831e-29Q, 1.569686619252582684425332361542007327513e-28Q, 1.125950740133316431064044128614537744957e-27Q, 7.601631416668137779752584924274136228738e-27Q, 4.839329824239351623300558838123321724376e-26Q, 2.910313243115431255504236289416347158316e-25Q, 1.656270635728607887892216630334576640507e-24Q, 8.935060024907100301565336660347629000551e-24Q, 4.576707115860143299317717947737094283786e-23Q, 2.229416062319399778753562461794880093428e-22Q, 1.034387027477115751926852078057580744105e-21Q, 4.578042956879664176157371046309566421989e-21Q, 1.935585802011138180920578591072504780355e-20Q, 7.82874713340001580345661045705345964109e-20Q, 3.033277065605609148877308443530255995764e-19Q, 1.127317776163823415957278474207966592424e-18Q, 4.023943777604203957468025053851953375997e-18Q, 1.381237707255244482658044701824585586376e-17Q, 4.564771324569693089113904466531252814338e-17Q, 1.454155094221294167906504269767636729648e-16Q, 4.470282536710471999548738623982417075368e-16Q, 1.327602585336672326909513613982506297883e-15Q, 3.813043588615643039554788734257898537102e-15Q, 1.060213952169345190463001465764618351972e-14Q, 2.856716038659232860437047136982049015392e-14Q, 7.466427670055988494705277475545414724545e-14Q, 1.894690957825474964952696780154361710946e-13Q, 4.672384910216859631300636349537565265528e-13Q, 1.12071812756145590573088420248213396768e-12Q, 2.61687402991139925388375152212065210662e-12Q, 5.953297123549162859512430130852786699602e-12Q, 1.320593807517838934275904504842136211828e-11Q, 2.858616138334039461868692599012329142624e-11Q, 6.042892454052515960778598669683992803927e-11Q, 1.248400183635724584150334059943405909833e-10Q, 2.522263563011319493898997487611481739084e-10Q, 4.987157614461502802573237722321997830104e-10Q, 9.656747028650146543937534093622969648656e-10Q, 1.832331394688612391225223960799760892905e-09Q, 3.409135584469323144465616190250392759698e-09Q, 6.223217073156115395989075884572438588064e-09Q, 1.115247649492127150742015804014106309015e-08Q, 1.963183124650189164476211317711594899641e-08Q, 3.396434861673153782630952753806077604247e-08Q, 5.778182457384419293379609496198444309124e-08Q, 9.671416228982645764923638776870390962876e-08Q, 1.593449237146444753348807411708714457653e-07Q, 2.585517662865383112572981730106266058425e-07Q, 4.133550070951521580893927841763124264506e-07Q, 6.514248621964041568573631795492153402393e-07Q, 1.012427229350996242277648936990123957075e-06Q, 1.552418076257223144547466550986390138311e-06Q, 2.34952602641015445771098161766731932897e-06Q, 3.511189688643888344939790080074685439225e-06Q, 5.183238423526162260514143683960468112835e-06Q, 7.561120127800534234406303171206800351833e-06Q, 1.090358470741065211245882025263310466461e-05Q, 1.554912473916646049717055292677270916341e-05Q, 2.193545319541190180132126849766958008055e-05Q, 3.06222602906776706081463783690640463254e-05Q, 4.231743641829304472292855191854823789729e-05Q, 5.790687550406990902565521591693920007089e-05Q, 7.848788357413748318766982611145815627101e-05Q, 0.00010540611257998968044433245343227694598Q, 0.0001402958222219341832876712273516369371858Q, 0.0001851231462878728337021449981301377043921Q, 0.0002422319093235441278154323469294950222567Q, 0.0003143914093490438255880506656627154706713Q, 0.0004048454583005453349179317740247669036001Q, 0.0005173618594864548959363227919828100894997Q, 0.0006562814060075758768591696157433266343571Q, 0.000826565410738786554070676706609189056012Q, 0.001033840731308778310338356140134352910286Q, 0.001284441235784871207845599117337491899893Q, 0.001585444668572432724602460096818027294236Q, 0.001944703922220064726230693092127144593237Q, 0.002370871798930369738140358404690161441277Q, 0.002873418453883568229680512273971543105615Q, 0.003462640848071487344380174768378455826004Q, 0.004149663697254268694341620803700341750894Q, 0.004946431581083455931123013841676887080885Q, 0.005865692066950994853071296376232848181214Q, 0.006920969900914144932733040132020845317402Q, 0.008126532517174807372490261340953247192729Q, 0.009497347312238993901379897831447122259424Q, 0.01104903131457044980845293838495748749764Q, 0.01279779405034133941458833907237333363064Q, 0.01476037455652850932760949389411325141064Q, 0.01695397362067762139688900226735864675142Q, 0.01939618242962242870635025934401096038724Q, 0.0221049088856914002071081720488716917237Q, 0.02509830289776780112805635044533390468242Q, 0.02839468197618069143809622830333154887549Q, 0.0320124584557903256913655927231054414679Q, 0.0359700696425036189719041085926788664321Q, 0.04028591212712788918860989829800630773938Q, 0.04497828143973876450915029065019924359699Q, 0.05006531813074977860516026316034857684728Q, 0.05556496126500436200205406716017085842229Q, 0.06149491020595281000433614073726129327576Q, 0.06787259545181476041214035595974238651884Q, 0.07471515916795304445597861763291341835026Q, 0.08203944594271127811857339386627258498639Q, 0.08986200418066622980078648563566282224339Q, 0.09819909844029617176185091362429719527247Q, 0.1070667329248230597757363001969375241841Q, 0.1164806862474626034039483986386441378342Q, 0.1264565575171798280651520372849367286188Q, 0.1370098237296297712334750378458162735435Q, 0.1481559084012775089077514714455506672378Q, 0.1599102613534637261518838984992924699938Q, 0.1722884495378824340287769605961068745877Q, 0.1853062587958232506234706761849695009517Q, 0.1989798064606889145314525019971032049343Q, 0.2133256647466923920312841051185874306084Q, 0.2283609949161532287902785133781001020772Q, 0.2441036922833063452109012049830089929543Q, 0.2605725421938823788428344541510908353441Q, 0.2777873872168545776842997093342357199644Q, 0.2957693058977194666949060616013919036907Q, 0.314540803551686309784195942257876965052Q, 0.3341260157205896645805580249519520659416Q, 0.3545509250798462409040234122490482411371Q, 0.3758435927622725725468195175697635639615Q, 0.398034405265314932316721128862444377758Q, 0.4211563383288478074934410968315399023713Q, 0.4452452394142342112037530159184743482082Q, 0.4703401306843622192334129067026336438633Q, 0.4964835346819850264796402305352446730944Q, 0.5237218252336346706380944300907573589031Q, 0.5521056064731078009809290745112694671355Q, 0.5816901232873094490876115456900045021105Q, 0.6125357069442992091785758987915348842459Q, 0.6447082601760031328793606429195360515171Q, 0.6782797865647680362323450787747425231422Q, 0.713328969733718924338199106505237313316Q, 0.7499418085773880637774140766639953164695Q, 0.788212315604926068652626105954826754308Q, 0.8282432864192821691838855987970085475654Q, 0.8701471494406427668515580696378217925631Q, 0.9140469062229000024305084421371343630326Q, 0.9600771741334760715452351166072128160259Q, 1.00838534479936281872807209462051762564Q, 1.059132873600894629208311701835194786588Q, 1.112496717660920861077933361693898250256Q, 1.16867094227945066816119751095978153848Q, 1.227868518660106499246607081659705290566Q, 1.290323339132992663775546769881462628908Q, 1.356292479979645252281439522534913259788Q, 1.426058746505517983625962591713495225332Q, 1.499933540298130677282755870691604857096Q, 1.578260094790658487921066515100833894383Q, 1.661417132483943299505861369104724515305Q, 1.749823005659253477628797946998754744417Q, 1.843940392372990799011473838158344835204Q, 1.944281631243440140888093759695373064805Q, 2.051414792356401944565998126314287654597Q, 2.165970597938875077463390429124692046136Q, 2.288650325771052401031013101683478825601Q, 2.420234851224610202981214703922557385267Q, 2.561595011055991143556009719659165225042Q, 2.713703504531639625308909178993926233509Q, 2.877648586197607034469946831006043902893Q, 3.054649850949549132212265433115461142545Q, 3.246076467630962399436086307607401933516Q, 3.453468284179391156036568854332710135444Q, 3.678560307807365503436950354477030229407Q, 3.923311160880828226841460125907452693619Q, 4.189936230801589469617865272423738708942Q, 4.480946374981393187300478594675727821553Q, 4.799193215730075888059881716590645860452Q, 5.147922271834676155907768264245273184096Q, 5.53083543288162221496812953064514469904Q, 5.952164600404323232077176105485527849396Q, 6.416758711130580646140459867054801191736Q, 6.930186840165860423056959159766792880846Q, 7.498860678961496459112702551699237411072Q, 8.130180423734335306085749550103992889195Q, 8.832709032074082300727064239431431565972Q, 9.616380956728658660414523916466345275065Q, 10.49275290755319395568272810318760233957Q, 11.47530600467060827560328905529268264146Q, 12.57981097060251303632608403301195351732Q, 13.82477089961782960432916836171863837498Q, 15.23195981221925849222231128916108185324Q, 16.82707987825682774784083335591634330807Q, 18.64056617116082598920083983139151178565Q, 20.70857549023794489237616151245562272887Q, 23.07420567642830393820713431967151913949Q, 25.78900463811922691101083889080485274776Q, 28.9148449161628874745824798436978904724Q, 32.52626128158058523332927382231420046858Q, 36.71337723086835603588917836258932717836Q, 41.58558355922287803881354300264233692755Q, 47.27618148799234762359952749427981866286Q, 53.94826824081686119518439858327130711346Q, 61.80223017903425916505790434588652768438Q, 71.08532543748765375968161551984797388555Q, 82.10399526567024554009049181822069349031Q, 95.23975602759407986028496155380257658111Q, 110.9698130973400470540296126193574357698Q, 129.8939333056630349651209392273740185622Q, 152.7696559979070753474928332485084782731Q, 180.5586736654304805091404612770078232022Q, 214.4882566244919977674795470939882573586Q, 256.1330547928231665447618178646818628868Q, 307.5246605111580416738693948713410626594Q, 371.2992177645933210815236774130885421247Q, 450.8974935685650228046078237680058220481Q, 550.8377451977232828330837131651153630988Q, 677.0902520413471880139625478638325464736Q, 837.5947742574322093884729471574161023545Q, 1042.980321750999312487850573606895531864Q, 1307.5733034982828412757582490221559987Q, 1650.819716406337706482714876001490076974Q, 2099.30620694485704616911531094921965624Q, 2689.653973155598437822589731884479684238Q, 3472.694809575007863005294222892497677728Q, 4519.545764387058601035451090692543677268Q, 5930.518674537505346737826216472633987045Q, 7848.298777884479316137628839872663776205Q, 10477.60880021856385719693056500458608465Q, 14114.81490684772176680780085987142294843Q, 19192.91511707047090505808670817300989283Q, 26350.55658560455766181799432059631325487Q, 36538.95917947214240512662756429322004361Q, 51189.24577374136230581311094854349469585Q, 72477.04375863379234457839995727856619466Q, 103745.4088649592973810191411342407199099Q, 150188.3023295660326508494811677648122358Q, 219967.7689573534473575008039486504545042Q, 326061.5312826027320414954398576839826327Q, 489355.6392353288320496416362546119688476Q, 743885.9518644993361121112473990653166511Q, 1145836.036325291912608215672199749248507Q, 1789188.875939868458022703843462472987756Q, 2833325.749624631317608641966061077100245Q, 4552379.001085143560456970771255583862215Q, 7424770.417957557824591303777367273905285Q, 12298095.03339192649792224192475818198456Q, 20697452.44203504870297806084701641515662Q, 35411226.8516228589720639754465162495418Q, 61622293.99369810009557886781288436597997Q, 109129592.8013237346517088038973951906807Q, 196787450.7962188394120339001790074555393Q, 361536817.7448103880188348963209149691119Q, 677120423.3172777856818760349805677342992Q, 1293610983.587362779559465518324962563345Q, 2522553846.524246174668941309214199618138Q, 5024113345.110335633272773596127448087986Q, 10227108739.74671955289688604133172938803Q, 21292284646.64136897396446520065098915002Q, 45371028957.31826747857852788334895849181Q, 99024543993.49841576792491248942076110007Q, 221536850748.6098276622557044178585207827Q, 508428097361.1528634995551255940374716653Q, 1197969892671.581974824369525928975612373Q, 2900404573426.685665196180358330599181008Q, 7221752811472.8261452649181134184825247Q, 18509084887192.97335916615093951559742913Q, 48874773784843.78193151762381145841529246Q, 133092599678780.7333556849381274648911595Q, 374125489089124.7353802139430677423910378Q, 1086709109057297.928444101014041776257313Q, 3265082931979987.87258453753276410350238Q, 10158431261326011.13015097449733816116137Q, 32763630132737586.73603276260407811351189Q, 109669789016956903.4218400551929290532534Q, 381438095770944157.1825584777350889364541Q, 1380167765463284502.013487398318939323096Q, 5201827105102251430.265183068342299790134Q, 20448381076785180341.12205914023728031402Q, 83950163624094898393.20723287617699714777Q, 360448148933858058712.8780057010771531487Q, 1620842171484886876913.030704922900840775Q, 7644568543274003707654.86412953245584887Q, 37873673540062878009627.31905351817669446Q, 197411676069663987218840.0240738763140198Q, 1084325020587868871264672.520110031271041Q, 6286658480253412511287686.688273773230383Q, 38538910676114933268850065.09568308686941Q, 250246069563561293270298335.428341967445Q, 1724315963019082925322914110.810919837136Q, 12631846969813248447320347615.40596832151Q, 98573898949291986323285198444.06078824566Q, 821057436212784005347211084495.6470514358Q, 7314771694696635838311419333295.781697573Q, 69850784256841570597712958391316.64699117Q, 716542825316038193448406387231039.7325133Q, 7914087099643693963542803664017844.382529Q, 94333533130664349347695260353580343.22749Q, 1216435546693629689320962786816870882.161Q, 17011958605833866533697726617718628547.07Q, 258690600784654078952220563714511508113.2Q, 4288668870669264476726242241367007368436.0Q, 7.772683277942945071659438262429071791914e+40Q, 1.544382512235139127663329049916790285448e+42Q, 3.373976769284500300734994475431045918708e+43Q, 8.129067158063592169546241812179625219138e+44Q, 2.166707895024819458966336780455558086535e+46Q, 6.409342911265172948192363235629813592865e+47Q, 2.11113881388279400077857147982308514427e+49Q, 7.769489188265480790835175082006376830908e+50Q, 3.206046642709239701586971551086164010033e+52Q, 1.488767022066119144919510543596148902267e+54Q, 7.808922278980110020262281481276188465084e+55Q, 4.644537901374006010236471698605630713765e+57Q, 3.144950967272856447107269590955178110167e+59Q, 2.434406581339142831982748698038217920141e+61Q, 2.163340477883997759822400087483427153e+63Q, 2.21672786608733211115932677066290250184e+65Q, 2.630990323276199330190674194077357004804e+67Q, 3.633887175234243651387984912585415628364e+69Q, 5.868933738481309220339956552275711759159e+71Q, 1.113881935382029622721131804445852357116e+74Q, 2.497102482962287596897815758971572470222e+76Q, 6.647318918269159316328027335371301086625e+78Q, 2.112701640474565422443496783512143837923e+81Q, 8.062227970535759114418981877150220612432e+83Q, 3.715510945470852711992858932101873544354e+86Q, 2.080318971829832954182086119453113044697e+89Q, 1.423879211015686994319095889875168247666e+92Q, 1.198994853251729786241539016492183220468e+95Q, 1.250315031722350913764230284966245816961e+98Q, 1.625650765546514480342676962699164400174e+101Q, 2.653884334781796076676164446838709276364e+104Q, 5.479254529900215518677997546263114530318e+107Q, 1.441395352908079823636049242510235987341e+111Q, 4.86863361476434656481400139271483745093e+114Q, 2.12833312729333131375593175762872072427e+118Q, 1.21404908713874757399814333397205765557e+122Q, 9.113086201114220747023518622031943166454e+125Q, 9.080551093105764581019426693667161701282e+129Q, 1.211941011117902121307375621265384771229e+134Q, 2.186766004105621881376552252876808934254e+138Q, 5.38556910852742084096067183800770753047e+142Q, 1.828345237093990030193445995904159522714e+147Q, 8.643847849099259259500488986422077930261e+151Q, 5.751005573557285468834049974868214789523e+156Q, 5.443504786034121401705823847908344635578e+161Q, 7.412615573089797094999326113074735280293e+166Q, 1.469049957199636824011402378332059557857e+172Q, 4.287925258882100461704570569455556092359e+177Q, 1.86612597273239616433526329447208163512e+183Q, 1.226379273064859017878285487689272510739e+189Q, 1.233049565517510525925233460318642472664e+195Q, 1.922517526428740240240358644220410694808e+201Q, 4.713487477409130845748812106854860817482e+207Q, 1.843473550328897809072120079994782769412e+214Q, 1.167326323244523228495462028700671117392e+221Q, 1.215209473429451036393049722893853863007e+228Q, 2.112842179547585374156273626907120728937e+235Q, 6.236071889607844243851741551378727798154e+242Q, 3.177451055527403166573000715118191400606e+250Q, 2.843789662251339660082577053201078673614e+258Q, 4.551274163789384572783760421480072175954e+266Q, 1.326777353683208009714512167729125836305e+275Q, 7.180580831932836542699287247744355850507e+283Q, 7.357782423625700430160947985743321252389e+292Q, 1.456666945043501567602541946073259416498e+302Q, 5.689564305935835027168129397847037147749e+311Q, 4.479926117516288195408691178143032272192e+321Q, 7.271111854603264703485967993610910737998e+331Q, 2.489090968193354380548052924828358593712e+342Q, 1.840259455673651866750330218300534783335e+353Q, 3.011137976393141155355678072396774678908e+364Q, 1.118272080174129693400170486739725992216e+376Q, 9.674512812796990597042138943041164545638e+387Q, 2.002782451702786557677729337022040139776e+400Q, 1.019975709385264179139063366965306494318e+413Q, 1.314944448797276383473642068489831668351e+426Q, 4.419677641026319174030519840041897734792e+439Q, 3.99254597036251358494799314361445177128e+453Q, 1.000265470725239760396725325941353640132e+468Q, 7.178755898102847579865186247347092072963e+482Q, 1.526021248325894848024962737690774582006e+498Q, 9.945324366407757254373767427512829534744e+513Q, 2.059059865446383839574552066851830041917e+530Q, 1.404900555375285454167524041392893443542e+547Q, 3.28087400282783259859618499821459956325e+564Q, 2.726864333586723754092688809912622716001e+582Q, 8.397859952756530445475213030730928168291e+600Q, 9.989908058973658294250311845442889852856e+619Q, 4.791505060970806776913551234159590878002e+639Q, 9.685481388431718626736865995988280327726e+659Q, 8.636556526427388714908536450441882235051e+680Q, 3.561156350974507459594142999610151752871e+702Q, 7.128248594017258005827215297412602656911e+724Q, 7.282768106798628819284639720336581389678e+747Q, 3.999482831186451968486716727260797908428e+771Q, 1.245346192388408435509525415668547227356e+796Q, 2.323145626677791462828372939022836177037e+821Q, 2.748168511226474189368586386876360779693e+847Q, 2.186023493982995850536763861857306300187e+874Q, 1.242175899551683170518300129644162776195e+902Q, 5.367034878872921573200381477952443794382e+930Q, 1.880509201665102918165168525840432579628e+960Q, 5.71032298577717938785953523302892142655e+990Q, 1.609386767501025736187596845183892280095e+1022Q, 4.518456557906832340328523403801389575925e+1054Q, 1.359377662008135474569503940329073679828e+1088Q, 4.725054714693428263295803139291895421729e+1122Q, 2.050805649400987593085939745846976951509e+1158Q, 1.204198867740810318663452249425780180773e+1195Q, 1.039053471866655386979552860107322907703e+1233Q, 1.434806667444463356971054485869624191903e+1272Q, 3.462506506934504077751858039898243011211e+1312Q, 1.599075147408129408091474499525357970819e+1354Q, 1.552099255551750227826769263306876457274e+1397Q, 3.487589868124137333898596626836045551213e+1441Q, 2.004482475545019114512171871841999807838e+1487Q, 3.266184291106132543681912795564641088147e+1534Q, 1.67783763526057060563518018773882643864e+1583Q, 3.031816590403436442474526312463549597677e+1633Q, 2.157658535793961571985216784676001134821e+1685Q, 6.795640821072482146198361520303941544851e+1738Q, 1.068303525733467960295743735204898069971e+1794Q, 9.49035887175352239368277676528910660383e+1850Q, 5.415177775755778852952005549339515155762e+1909Q, 2.265003149514209136521685690794152242451e+1970Q, 7.958960851406909431550138661401662745318e+2032Q, 2.704333418922120675152324269895601692782e+2097Q, 1.027316567877779588221212575606512955238e+2164Q, 5.067724711353594001952616900450932235233e+2232Q, 3.788567045328638236731381566671647412124e+2303Q, 5.033943905367906070883711379852229702017e+2376Q, 1.401291904868944410529538867922103039787e+2452Q, }, + { 1.371514866891850860580147671247114055774e-2523Q, 1.78059151397248974751721161286837911487e-2484Q, 5.721785888758699069103456365589770844687e-2446Q, 4.65054375815005991582966268522321514424e-2408Q, 9.766439188577561460790237859691768982479e-2371Q, 5.411793370039458455354990385284371780101e-2334Q, 8.077731109845845920201388563994532085669e-2298Q, 3.314457987808662239136747203944447166213e-2262Q, 3.814216774420151193012892981499696410824e-2227Q, 1.25553244197497295620771570706808273245e-2192Q, 1.205334248405440130028736096195044170071e-2158Q, 3.439859219242599171410929107063382097289e-2125Q, 2.973688352410262055813011490243478241374e-2092Q, 7.932557138399171381451724757235015551226e-2060Q, 6.64983139985567616753784650800300435522e-2028Q, 1.783535197590152574181620799985394198187e-1996Q, 1.557756177066760347798671232037746675342e-1965Q, 4.50835586041040533232716428603770260743e-1935Q, 4.398198753548687358528653536680048897554e-1905Q, 1.470927315235637240331266456192550898399e-1875Q, 1.71465008838880964348190523555111145902e-1846Q, 7.081482877179836131442059969229644646902e-1818Q, 1.052988868679756641461550070454780113115e-1789Q, 5.727332034022694687284947570371705183098e-1762Q, 1.15739462236578863659656148034953454216e-1734Q, 8.824245880938427131911655080026958855498e-1708Q, 2.576937902674734058187379364472798379884e-1681Q, 2.925647070385438309955468564014371260538e-1655Q, 1.310366516627749970196906908155253601244e-1629Q, 2.348978983105517007632719018468710632253e-1604Q, 1.709410997728098633816935547350434401855e-1579Q, 5.121118377662292204023170356055225918098e-1555Q, 6.403389635343425663631591782183715749097e-1531Q, 3.387388606361687519127880900479628129084e-1507Q, 7.682845028338649121205296292580122279028e-1484Q, 7.5697800616719066342183600003671550179e-1461Q, 3.282179766587278495544847128493743606877e-1438Q, 6.342874576272782317964383704289390519493e-1416Q, 5.532171052437858139242350241105314679303e-1394Q, 2.204689812211625778588319899320164116602e-1372Q, 4.063642231251649808970064588651411033634e-1351Q, 3.505834447518969518509518528849945942891e-1330Q, 1.432473887091513447150492126342839296652e-1309Q, 2.804358628632567232199952351415702630343e-1289Q, 2.66063964253518984171287821553517135124e-1269Q, 1.237147739109782914114766326315518993064e-1249Q, 2.850636185934696156243405262161503937397e-1230Q, 3.290591833059237434920108388995870213671e-1211Q, 1.923411531080387875303980530941562752132e-1192Q, 5.753315949676429219782768882380932643224e-1174Q, 8.898623641056617385925239335507072432457e-1156Q, 7.189967416446551570306795185549101380576e-1138Q, 3.065508239134858139768522765991406123598e-1120Q, 6.965523591486903308426760175908956871108e-1103Q, 8.517620034923183484809399729544114465539e-1086Q, 5.659365953962467848177766816717617097698e-1069Q, 2.062573530337046406767250567348179248901e-1052Q, 4.161852659707982830572968592800051957069e-1036Q, 4.692241159119044484191107448210417118604e-1020Q, 2.982698522097636407260213300060948041181e-1004Q, 1.078529659466679650148712953327103511679e-988Q, 2.237932571204419329079179415438119299158e-973Q, 2.687779604401946022373571466662866987864e-958Q, 1.884315707424963927641532671833587240912e-943Q, 7.775916115101539973101721787430845628126e-929Q, 1.904389083833778231092894380474362030062e-914Q, 2.790480743212439217722761443513185676356e-900Q, 2.465926648913378827209569812194001932794e-886Q, 1.32453666225889852923448237001268368176e-872Q, 4.357954169067029764588892111614304541975e-859Q, 8.849858929503900331905076375159876230295e-846Q, 1.11756825414017856890835286188725247492e-832Q, 8.840858072027483686200027831373682346404e-820Q, 4.413127527092704801352846086655418413121e-807Q, 1.400007801030484767570446402553494180345e-794Q, 2.842487154347560114907190046795915809722e-782Q, 3.719250938565689181624101685057377159049e-770Q, 3.157618225591420085512645965965929848638e-758Q, 1.75114987148442787873596419431088305131e-746Q, 6.385777873090946474243531008881328150137e-735Q, 1.541181822234902334916632441949848277437e-723Q, 2.477550690731270781011321116596617085026e-712Q, 2.669658787248566306163138309021034924058e-701Q, 1.940202333546917439202686680187380693786e-690Q, 9.568593524722134826709740856677698073001e-680Q, 3.221585461382583247710139618437253490996e-669Q, 7.44872342769648167389430455225675065663e-659Q, 1.189638501771902231424740243250726099567e-648Q, 1.319958393938916343886322409809694440374e-638Q, 1.023222353884721296290441353639395656224e-628Q, 5.572611912350442469781066985285379073621e-619Q, 2.143895457167286509138836925702305298852e-609Q, 5.857935768286961997593913967879706360256e-600Q, 1.1428406852843012490910945546556940254e-590Q, 1.600276538368249091681352691119548348521e-581Q, 1.616611439295194955625093231898724105017e-572Q, 1.184175055644738174748521286561285618321e-563Q, 6.321063094448832167707046445620734055392e-555Q, 2.470922066459568011770971566970048936919e-546Q, 7.107557665424030425852285003920836370767e-538Q, 1.511608590010936014341479674633899001101e-529Q, 2.388081265694744511448096326055442541688e-521Q, 2.815472550702340688172542879041232967279e-513Q, 2.48837919000401445219744804980784920927e-505Q, 1.656093914015468497737181055575250483141e-497Q, 8.336168624615487443627885419612364814439e-490Q, 3.18743641956695605041303086533386108674e-482Q, 9.297395544527448592830333338764436959721e-475Q, 2.07753500427579145364603881525582257654e-467Q, 3.571058202658373821694558210889151485115e-460Q, 4.74103867173240490413388040526375091844e-453Q, 4.881093482481361236762660159636286975458e-446Q, 3.912369974092201956975825460350308122387e-439Q, 2.450910406106052551255344761044302587528e-432Q, 1.204589604960650973911895984080791492458e-425Q, 4.662390512096548320130183079581954524186e-419Q, 1.426410136108239271628869933927485152397e-412Q, 3.462022295520875568887679396389873321599e-406Q, 6.689965361959539507296200940776906225983e-400Q, 1.032906866888844460363965234571578480766e-393Q, 1.278652922107423854922242620018460855558e-387Q, 1.27346175112717053239090655930858052069e-381Q, 1.023823977719212384301250664189673152317e-375Q, 6.666725705084252678150326635220070780096e-370Q, 3.527501141911259771256602680376156110087e-364Q, 1.521550619725659440989624157338581448637e-358Q, 5.367178386399065173689709539892711842253e-353Q, 1.553103594884899144778901074836122484754e-347Q, 3.698136866653946571267914019652083161444e-342Q, 7.267857666274321583558053878456127222792e-337Q, 1.182396378403029271255116700338342272541e-331Q, 1.597075112277586427731638320619803585259e-326Q, 1.79616310417311168251812691532499891895e-321Q, 1.686776580430614870136341368549220295438e-316Q, 1.326400820923694839828868126921386634198e-311Q, 8.757752605603787086889457335226509690784e-307Q, 4.868418990945228081453886254928167861293e-302Q, 2.284646841932174244279967147270918463565e-297Q, 9.074580740097597152261098447164420165217e-293Q, 3.058674426405965026102952238688104005e-288Q, 8.770907787988163743413755834970410859751e-284Q, 2.145105864999992209688483122610527442958e-279Q, 4.485565646931315043637211169200810850942e-275Q, 8.039051377155100634170607610838242458239e-271Q, 1.237798459140634245394855702707316430846e-266Q, 1.641250849228685733321328948635354163602e-262Q, 1.878392643839145475948645114851275314888e-258Q, 1.859837819346807234979384520727903936856e-254Q, 1.596675206199588015266237522224100758227e-250Q, 1.191163300889329440492988307548134854255e-246Q, 7.738998457363138650763594103272910530358e-243Q, 4.388214066152685197969849610034490383905e-239Q, 2.176190276775343886183543527108804962112e-235Q, 9.458323390405043573268776062741642547043e-232Q, 3.610172183979709423096064193965398866308e-228Q, 1.212586127555234921919768098823882915843e-224Q, 3.59111324401453575527963023293455049051e-221Q, 9.395610112642259280459967294233090545081e-218Q, 2.175878640712952864616203692811262231176e-214Q, 4.468683812013515731337379575375451666765e-211Q, 8.153960491495333836272380517373862616232e-208Q, 1.324334834118382614778205714074964422865e-204Q, 1.918010969227594967076007862060402474386e-201Q, 2.481419344431850431832642008478325717022e-198Q, 2.872795934722793405682347917373434018734e-195Q, 2.981349523066067914025266431304396865241e-192Q, 2.778183214184428719494018536521280699548e-189Q, 2.328486353991385450908858723725291527882e-186Q, 1.758186943224971219517752327685010699026e-183Q, 1.197946966638678929592039684664547722208e-180Q, 7.377055951967901897864941596001292223249e-178Q, 4.112278669973440702181315578462285064667e-175Q, 2.078291415365407917218825890865740908413e-172Q, 9.537067910130183878871726206163401272743e-170Q, 3.979767266831748046536551531606993002857e-167Q, 1.51242767258917389289465209587647895879e-164Q, 5.241982224408838742535027808527238690516e-162Q, 1.659359739042905225047790447024360734017e-159Q, 4.804189190171438209477354610578302798335e-157Q, 1.273899629641974768294696288314250406176e-154Q, 3.097972570039967409381197695536388439631e-152Q, 6.918782676203354501696541281574674135727e-150Q, 1.420905061393621836184825537780939096116e-147Q, 2.686880053196812186383269222572644952966e-145Q, 4.684197364933578819900414372355690019325e-143Q, 7.538292842090449394366060991929379034132e-141Q, 1.121244892108977725124030722189671879955e-138Q, 1.543291602455658629065990737883115515276e-136Q, 1.968057200151723062214416934507209947162e-134Q, 2.328003983334060978647728261009904175111e-132Q, 2.557361370195688062969068207425233275233e-130Q, 2.611927488619706964609586759095304201419e-128Q, 2.483026158243640437503808965978985775636e-126Q, 2.199558726962169679083120552270215159747e-124Q, 1.817604357772346797279295638966528051203e-122Q, 1.402622308618408240781121273710706375183e-120Q, 1.011860243749717496597643469830115242708e-118Q, 6.831127536515730097540183118129885433187e-117Q, 4.320191100696367801967874719856844820374e-115Q, 2.562075564358016827111173141097650600476e-113Q, 1.426238694588568870687238604039093177163e-111Q, 7.459848026168321089493030639864685607272e-110Q, 3.669651340262246286048534626216288397075e-108Q, 1.699377066420368081652375575263230646377e-106Q, 7.415347269378738772554757519265950805265e-105Q, 3.051760076915455100351083762051342894307e-103Q, 1.185606536701726646160124184282201673383e-101Q, 4.352012462292932218666289630132342719673e-100Q, 1.510709811312352716016896845640521276349e-98Q, 4.96351624265344783282463142301615005161e-97Q, 1.544847436576855907745798135714872919059e-95Q, 4.558626702124257235752569024006245964769e-94Q, 1.27642008479453751639667439563273882791e-92Q, 3.394045905392319665569519214098169750653e-91Q, 8.577369478664050327841008779377881642778e-90Q, 2.061794113305408627205942105505921160903e-88Q, 4.717678942214176175585291907504765989603e-87Q, 1.028336592244877396499367499530170373412e-85Q, 2.136942248611699065366375204560555442768e-84Q, 4.236649816605452806608538404381400553183e-83Q, 8.019390326869837302318803327925687368548e-82Q, 1.450310328118094376720023212297234378891e-80Q, 2.507773447443639285811131422971779815463e-79Q, 4.148830024850719085252858854502549378537e-78Q, 6.571590494079647834460655487488465170869e-77Q, 9.972769081433910894391809784387965744944e-76Q, 1.450941240511938754819526746862952160298e-74Q, 2.025147121753812973462197585271955311494e-73Q, 2.713410648449319341394062293702880697709e-72Q, 3.492221881468832071574769247806205619972e-71Q, 4.320026314957986074471025977887938831804e-70Q, 5.139678044302121691257432248649865135314e-69Q, 5.88454602498027835646853308660089711635e-68Q, 6.487480038582780094962826210870660500257e-67Q, 6.890958196370926220424217725022443833687e-66Q, 7.056254711010837638169942940084550044742e-65Q, 6.969579804750282059291393905862236832069e-64Q, 6.643844951482205349397989109640847868486e-63Q, 6.115782049052550927522596994851724693213e-62Q, 5.439255920241588910635386169168650069713e-61Q, 4.676421881589679071462973437280331165559e-60Q, 3.888684381216725595659573659632893641487e-59Q, 3.129184103756304830587115921877252345851e-58Q, 2.437923355425183366110025852517458902153e-57Q, 1.839870139530736605717536567889553740685e-56Q, 1.34569546099067802857678564027627409864e-55Q, 9.543548354590505654408042421857208818407e-55Q, 6.565747142552830887480211819288562501447e-54Q, 4.384035908945419864942715257281219621436e-53Q, 2.842372851943162821895168269638503020572e-52Q, 1.790206722551992369372815691219096572315e-51Q, 1.095810962565634873096014895603262248904e-50Q, 6.521845700716095054692872802045308924929e-50Q, 3.775695339986648388305396192552307067105e-49Q, 2.12716464152594887189778742590835609859e-48Q, 1.16671910540040391992253760579220008166e-47Q, 6.23265403559085987542213498720205905273e-47Q, 3.244134896678645746059576473240602899384e-46Q, 1.645958473231714974889173810016645441791e-45Q, 8.143388031734858419182189130653533970639e-45Q, 3.930313582465246907302843363611600709482e-44Q, 1.851194263290435234938417283137103119568e-43Q, 8.512239336793202359069241917584798017519e-43Q, 3.822649348695211790804635671865758360444e-42Q, 1.677154859408228776678271851575940954557e-41Q, 7.191619924152852038442032565761535379094e-41Q, 3.014945807169869323963767145635796967345e-40Q, 1.236185040650714236792933080415503535797e-39Q, 4.958933233628030587234303679158088010029e-39Q, 1.946888752775509918760428023552746596113e-38Q, 7.483195996266222208010017837398543174827e-38Q, 2.816884085832008440862888918858326739866e-37Q, 1.038788790311983532626498647875866074014e-36Q, 3.754052366421776972298304402899627666075e-36Q, 1.329916636449442293929331165948166178563e-35Q, 4.619911398476589889287822018098556733235e-35Q, 1.574200500535886072240446156960489377595e-34Q, 5.263002870105818624051575346548509593314e-34Q, 1.726960099078857779289991292495256114725e-33Q, 5.563295479027593276363106515909903530738e-33Q, 1.759977498646924128925619156060635503779e-32Q, 5.469270261898178500979414281790390666607e-32Q, 1.670010326740456896177958676237975226683e-31Q, 5.011812229140459292937572098984863834087e-31Q, 1.478675283612228924576755629362483876746e-30Q, 4.290105197670639434248708745588052583008e-30Q, 1.224314847204857214288128441827892216884e-29Q, 3.437633138669099008098353177172696586855e-29Q, 9.498972745536045125708605102671240382972e-29Q, 2.583760349139748372190785203361264056883e-28Q, 6.919781634353028415062110558967966606871e-28Q, 1.825162674340331350492593059731827245464e-27Q, 4.742230202003700799981525062649235524325e-27Q, 1.21405061359099326936056130057580569356e-26Q, 3.063118047519658846943846604881668640376e-26Q, 7.618361643983062409286968372813904975471e-26Q, 1.868215421385976931437156399023912819061e-25Q, 4.518090735445957461893059448531246001478e-25Q, 1.077802555101032018001573196795959603137e-24Q, 2.536716415287025987243332057261521203556e-24Q, 5.891743572611456938581645671099702613624e-24Q, 1.350654629696238651479692262614635184919e-23Q, 3.056759774717924539419358796200729285625e-23Q, 6.830955143743892705466065819320427714946e-23Q, 1.507613243104685126205368805198220832115e-22Q, 3.286781089426561469078764502160043788401e-22Q, 7.079565101495153315614280736442313671788e-22Q, 1.506880116178374539920205157221361054724e-21Q, 3.170058264327805606367536705343862141049e-21Q, 6.59251402755243003297452378499013462071e-21Q, 1.35552580917224613064763906748000530126e-20Q, 2.756219881083391006714632017605268608876e-20Q, 5.542995422751507991815595112925511099095e-20Q, 1.102741830357026668509228710940474564193e-19Q, 2.170574924791608623404819767053535761174e-19Q, 4.22784562521684419969566703381613825383e-19Q, 8.150374391610149393088547569573938943941e-19Q, 1.555319761370903112941040411557418768911e-18Q, 2.938421091239191486965897394716220785884e-18Q, 5.49702918186578726899982577419496597386e-18Q, 1.018422840283521980646891608411447224077e-17Q, 1.868872525702349874003525110232409264092e-17Q, 3.397402939502888626915671597580544282826e-17Q, 6.119185785264468750269400946381512507862e-17Q, 1.09214879924426987627392659888533333755e-16Q, 1.931848224257484115187021666194486246113e-16Q, 3.38709738113457021746601978090966428654e-16Q, 5.887153893766801191455922107519234664868e-16Q, 1.0145296263318078248737176573311390616e-15Q, 1.733657986531008282841829763437819666348e-15Q, 2.938043850581996177822909658510042042154e-15Q, 4.938615471781692605915992715954874017254e-15Q, 8.234918562531385917858203857862277957338e-15Q, 1.362306331265371396596294694423173800976e-14Q, 2.236170869424733841320751737542100923557e-14Q, 3.642524554580435163120663045083577493864e-14Q, 5.888694392313571271396174247706099778175e-14Q, 9.449427618501157548166373911244332310801e-14Q, 1.505261978665752624561018591391102066314e-13Q, 2.380609441526787810264512243714771106257e-13Q, 3.738370022433227086384575475381090947548e-13Q, 5.829648161155620359106976280093017981524e-13Q, 9.028496600869498357963548235512457258829e-13Q, 1.388826357069473033794159652839122295033e-12Q, 2.122196240029301709491138513135360364986e-12Q, 3.221611506135842421727691817477971674495e-12Q, 4.859091658706136214244133527025696573555e-12Q, 7.282405996980113883706062207316493538397e-12Q, 1.084614626633106462843146164014369523503e-11Q, 1.605458327457498641880369613222255948306e-11Q, 2.362039805046516326689547929276742382626e-11Q, 3.454465994486121845661011103063064511645e-11Q, 5.022506107218991611053939202358149250568e-11Q, 7.260149275135915690391382052565097178099e-11Q, 1.043506651266876142022178805768372845923e-10Q, 1.491447438205217428990418540357559180095e-10Q, 2.119930450717337762893944880079093620671e-10Q, 2.996908529590102178368349845632326420577e-10Q, 4.214055822301332409818763610781801512466e-10Q, 5.894380163761400407235801747311008727447e-10Q, 8.202054377127916232711329106917380504757e-10Q, 1.135504396304516014422645934598193894471e-09Q, 1.564123926801416152345998562700717501364e-09Q, 2.143895532536103685135640602614991156305e-09Q, 2.924284555594605553671769414519942616402e-09Q, 3.969649003737127932344749476989177485695e-09Q, 5.363316892671581077171752210602991068092e-09Q, 7.212662081948228982393580259053449241656e-09Q, 9.655391838969175725217005148400887863888e-09Q, 1.286729736245160124986798102409646699924e-08Q, 1.707176162884067575027148124091659866518e-08Q, 2.255136756706215921832547171587286426381e-08Q, 2.966200406055540209232028685038397255741e-08Q, 3.88499279165752963245413637224838028982e-08Q, 5.067230696631395898391507929991299499358e-08Q, 6.582184302397294059244050027864020017102e-08Q, 8.515615360415210982691891965235105797731e-08Q, 1.097326780309156415388972256670220023435e-07Q, 1.40849966698634516338474292825860882904e-07Q, 1.800963114520075404035053726417815773279e-07Q, 2.294067798711577907333029492475997054264e-07Q, 2.911298260373502821242208979104064808447e-07Q, 3.681047642935816556705697739214988768386e-07Q, 4.637515095891270700500412168316111896075e-07Q, 5.821741069987161473731830875047390436438e-07Q, 7.282796925275399454511805955028073483488e-07Q, 9.079146457486250991458577609594710846256e-07Q, 1.128019810375338411661718812277807260419e-06Q, 1.396806769576530095637743385965024634296e-06Q, 1.723957266560495308759186180749598884135e-06Q, 2.120847955410992129415865076137962702185e-06Q, 2.600802749963756201636001826403410052969e-06Q, 3.179375107191397469591646715949441120489e-06Q, 3.87466263359623762618892933003290214722e-06Q, 4.707656435964015050950934858654955898129e-06Q, 5.702627649010476273062734021720688061299e-06Q, 6.887553559542152392628913331393954866062e-06Q, 8.294585707464843920777395442479020873788e-06Q, 9.960562276198518660710860857487330693778e-06Q, 1.192756698691180898016628898883173906339e-05Q, 1.424353658086394053028809949739212752112e-05Q, 1.696291881074835378827238882926582147741e-05Q, 2.01473826643461040251220418003491119867e-05Q, 2.386658231149715001671441877242307172678e-05Q, 2.819897599830005539475352694423628206838e-05Q, 3.323270081093726790471346839279300126957e-05Q, 3.906650389646304004580423055599671571497e-05Q, 4.581073036065455323829979901479633510731e-05Q, 5.358836766549172709593068062566350767259e-05Q, 6.253614592338064003449893584965224320815e-05Q, 7.280569303474707324470305244376804359753e-05Q, 8.456474314345314007150181097613624934893e-05Q, 9.79983963944311971961128822060083281438e-05Q, 0.0001133104274741962557808980829717804420132Q, 0.0001307246399020691600023526497292212020485Q, 0.0001504862625229124093013402201618646645292Q, 0.0001728633841361022292487807700747299013219Q, 0.0001981484216856842586799572772305180575132Q, 0.0002266596169386652242612079138639764750973Q, 0.0002587425560977173732352397172201132721704Q, 0.0002947717063367408829161595331713295059784Q, 0.0003351519628181797614281622077674269794528Q, 0.0003803201993549968241927643417622446554493Q, 0.0004307468155228297461815381992767059891142Q, 0.0004869372727138194050273920414562891311034Q, 0.0005494336113573051545188073238892334141672Q, 0.0006188159413179756137819623192609947043238Q, 0.0006957038973226249969676643754938554868505Q, 0.0007807580511653439670770907738372309905166Q, 0.0008746812724001532761340934353267577792467Q, 0.0009782200292515512336811027407457153376092Q, 0.001092165621558351789459012058646682104199Q, 0.001217355337715058924188958933421742595571Q, 0.001354673527787729173843430392365052760195Q, 0.001505052585257047138767616555691474176257Q, 0.001669473830178774238569756010944073496615Q, 0.001848968286948808422945347651594893384821Q, 0.002044617350314201919025518009463240807713Q, 0.002257553333779458717720728149390573426284Q, 0.002488959895115589901221858059759895342055Q, 0.002740072334283588362025959812292414640791Q, 0.00301217775972961953607413014104144464497Q, 0.003306615119691370083379454518010740369845Q, 0.003624775095868402689060121197344456802957Q, 0.003968099857548535542156097701394553950805Q, 0.004338082675041517295499039588623167374938Q, 0.004736267392044797255794242147281512023857Q, 0.005164247757348130579312969849265866446317Q, 0.005623666617068244685007554336227354330017Q, 0.006116214969386021858860229251854316110788Q, 0.006643630884530937776730154149339974333344Q, 0.007207698293515321895878348292456453654359Q, 0.007810245649859081048265134316584789895785Q, 0.008453144469258828274121626639448497149435Q, 0.009138307752839171316702467004395243791217Q, 0.009867688300273872669999644933745875091601Q, 0.01064327691967670787558472076910092093735Q, 0.01146710054173253851741408239999923619768Q, 0.01234122024606522527074289502339224210353Q, 0.01326772920831782112966648361938182825161Q, 0.01424875057684974543947505353952098867137Q, 0.01528643528833354419122626389892565090942Q, 0.01638295983185904916112164488898195461532Q, 0.01754052397142437120423950233168880720244Q, 0.0187613484369107615886167354070274590455Q, 0.02004767259380194441465699051526802405725Q, 0.0214017521020184759779667849902676587795Q, 0.02282585657429483535407508444593379094269Q, 0.02432226724453248297751175594886236631783Q, 0.02589327465651758066521453776794690161073Q, 0.02754117638329931218995431551143369605661Q, 0.02926827478738593898790451312106545224234Q, 0.03107687483173329787258745383633763611989Q, 0.03296928195127705906828026282057099308205Q, 0.03494779999449857988040032623857920380255Q, 0.03701472924421765093424302565538084301254Q, 0.03917236452647701857524610316723537907177Q, 0.04142299341602656982308246993170945227151Q, 0.04376889454653285699001801294927841574839Q, 0.04621233603323564126441668379095446930966Q, 0.04875557401535079589039921987184194521511Q, 0.05140085132508167562704906922303703496827Q, 0.05415039628965234886880735200235133638008Q, 0.05700642167231927160453898977060771401466Q, 0.0599711237578563573226915069629858708525Q, 0.06304668158754517366223858841179395265763Q, 0.06623525634824027829561347043735130048892Q, 0.06953899091962247509330580436971686102996Q, 0.0729600095833028746833811927601826713891Q, 0.0765004178970007835650709418899798676114Q, 0.08016230273659117141990270524388318621874Q, 0.08394773250840516467839177192606243584909Q, 0.08785875753377190721656428075049332888429Q, 0.09189741060741426847468433104579159465809Q, 0.09606570773095614670505424425466367647119Q, 0.1003656490224672211409706019834699207746Q, 0.1047992198026634931898508322163299556015Q, 0.1093683918581001987330424053206431223269Q, 0.1140751248814388848942142458106393021799Q, 0.118921368088643682516754028336251837472Q, 0.1239090620127639775785842545955310252687Q, 0.1290401404737925560843903638541851287801Q, 0.1343165327239504988585911849315540274307Q, 0.1397401657676431414586481908138076263638Q, 0.1453129668552556812547539926611835917781Q, 0.1510368661499127946794457281180654907464Q, 0.1569137995663141144619238369429012314605Q, 0.1629457117807767176524264957760589252385Q, 0.1691345594116669265838074234685207817681Q, 0.1754823143694867020605796895050649984246Q, 0.1819909673759946372926833537044279604056Q, 0.1886625316518879311352366885204737593347Q, 0.1954990467727495928713431543594207025934Q, 0.2025025826931743565802835311741625023285Q, 0.2096752439392272067845965232957417681348Q, 0.2170191739696598929453619381656215678642Q, 0.2245365597066132128474132532044770980417Q, 0.2322296362368660795566899971447466971694Q, 0.2401006916850564012879982901404429833251Q, 0.2481520722606935992655817236397629937298Q, 0.2563861874812082306191368162104739675875Q, 0.2648055155737408114457597739460139210698Q, 0.2734126090588597747267265038277637879757Q, 0.2822101005199178701881044007666032408543Q, 0.2912007085623076464160082864035019623808Q, 0.3003872439674604947757906906819067257233Q, 0.3097726160470507530279833066428086671434Q, 0.3193598392035173757684907470415069603046Q, 0.3291520397037016404193916534806228825185Q, 0.3391524626731213938587717093791470119821Q, 0.3493644793191617507885033680278723282202Q, 0.3597915943922604099274241916243743202498Q, 0.370437453895004534297809334142470200637Q, 0.3813058530499373333547650352661480737284Q, 0.3924007445377981971755919946678712021003Q, 0.4037262470188928140903475071101821304505Q, 0.4152866539513117540688677957021817444604Q, 0.4270864427207903916573703120710338501449Q, 0.4391302840981329322252234037536723604273Q, 0.4514230520413121575982986672983445970989Q, 0.4639698338606081117511470803776773172719Q, 0.4767759407664674418491476565985386456096Q, 0.4898469188211550036177946416809944701631Q, 0.5031885603167355385407471102006047496143Q, 0.516806915603471063813928672429989712329Q, 0.5307083053943548685833492892416658817756Q, 0.544899333573231952763791571381569604648Q, 0.5593869005357851707458483857026244359117Q, 0.5741782170946036051801186516793426995427Q, 0.5892808189816027518756369857764771391118Q, 0.604702581983243549890321938796860532609Q, 0.6204517377463084432584827945463463628564Q, 0.6365368902944475668239615907758418765269Q, 0.6529670332983176740767048675459263366619Q, 0.6697515681449123115252066782831174608566Q, 0.6869003228546366803792541107869900910128Q, 0.7044235718978283242079024020772563155241Q, 0.7223320569657800605984787123162765141079Q, 0.7406370087549004552020459754059890701261Q, 0.7593501698264669376016144620943539451727Q, 0.7784838186085061098494460842596828305091Q, 0.7980507946106951600027541869735333876082Q, 0.8180645249278394856280467667607579883538Q, 0.838539052112468382179355150589367966048Q, 0.8594890635024286468165380673473754166204Q, 0.8809299220950730124913003197007267091987Q, 0.9028776990657666058321606844017813194226Q, 0.9253492080350027908463731668841887468309Q, 0.948362041195465249909046760063799591795Q, 0.9719346074179343990949614066840423597446Q, 0.9960861724630549479302366473419980629626Q, 1.020836901434702880136038002335887532136Q, 1.046207903620063540423272538165924635641Q, 1.07222127987161131376882927117522964634Q, 1.098900172697023686488065817678959243028Q, 1.126268819234731483687699755105102346279Q, 1.154352607305371556205746104983985376446Q, 1.183178134742943008313040704876221217254Q, 1.212773272224054755535396679944804822938Q, 1.243167229829379630892649667118722042897Q, 1.274390627588395280696510178366946433511Q, 1.306475570276800356042211803401477660985Q, 1.339455726755761299090854776902647953055Q, 1.373366414163496207916696260993796460505Q, 1.408244687292775319638246256496434465626Q, 1.444129433512862820237418019195005380596Q, 1.481061473621406240583458987854889421525Q, 1.519083669040977329410710130907067249025Q, 1.558241035806578679235039044308088638575Q, 1.59858086582466888372299852743006758704Q, 1.640152855921361574402265538231040950074Q, 1.683009245237678957954559946017992411702Q, 1.72720496157337210647316008484511209382Q, 1.772797777328169495475491773850651572118Q, 1.819848475740723857449237597299307993606Q, 1.868421028181370689596438549208663232364Q, 1.918582783315502273584026310535185025955Q, 1.970404669020352495193731841217502411354Q, 2.023961408009779237823690539642994612898Q, 2.079331748199772156275287309535810282094Q, 2.136598708932509466936874733788968855942Q, 2.195849844269505061444090956894789562589Q, 2.257177524665462326226386344962066768299Q, 2.320679238444695114506969192065453102806Q, 2.38645791462228535018090911257279622728Q, 2.454622268743510472485802015585977538477Q, 2.525287173558586284686837252134214325026Q, 2.598574056506641565930469422296652514342Q, 2.674611326154408827473590731512070423928Q, 2.75353482992286323949072031864016601102Q, 2.835488345640611439999643200601877219861Q, 2.92062410968804449738926309215771882388Q, 3.009103384743144622541911200865882785674Q, 3.101097070410615431476383817233400114544Q, 3.196786360313181016135882778770461391366Q, 3.296363449550237677932901170344316738063Q, 3.400032296787622239428000634643997693337Q, 3.508009445636508188824397561413278832782Q, 3.620524910413170580217782044901471996699Q, 3.737823131848823954579745937371900624793Q, 3.860164008844675289107469115579416301802Q, 3.987824012947036166619438121661763719179Q, 4.121097392856712044775558016541559733901Q, 4.260297476992532330650222886374288981273Q, 4.405758082908183742986369820036182319601Q, 4.557835043222720229607343330179101614167Q, 4.716907858677493920666662718003679310707Q, 4.883381489986147028731324484181342600844Q, 5.057688301311346413080048955955133931764Q, 5.24029016949517364937262385119050914101Q, 5.431680774604152215414745576056569940993Q, 5.632388088941263530838944426647235216134Q, 5.842977083444493240346088159010481650856Q, 6.064052672355303324054387062420722913264Q, 6.296262919224426838182742506396326825866Q, 6.540302529753004778869174624673669076774Q, 6.796916659674200034444948632350283775015Q, 7.066905068897762712353177820799890200225Q, 7.351126656505704724688125273958015673903Q, 7.650504414944385662659203665642040258745Q, 7.966030845955723910764349890266531446913Q, 8.298773885483222221468214739217431908518Q, 8.64988339003973506101525205018928180163Q, 9.020598242904561456999601751592885677702Q, 9.41225414510834360246219690427427333296Q, 9.826292163557269466732689978189811368073Q, 10.26426811694776371632533698438878780078Q, 10.72786288944826916813779631601409495717Q, 11.21889377261159001879701043038476676713Q, 11.73932694778443388521894681581610807556Q, 12.29129123457708270319215970282226419194Q, 12.87709324594766765515402048038669536198Q, 13.4992341073735758693176219364211695767Q, 14.16042791669191291271234624934713958783Q, 14.86362214279527089719453736582722220018Q, 15.61202018581665142041991318996024972122Q, 16.40910634912836056677912139837144777988Q, 17.25867350487402177091782658858013283139Q, 18.16485377037993024884452690977404455282Q, 19.13215255326167571891757955195233291448Q, 20.16548636905761204079359120396764800875Q, 21.27022488759428859211729062248302615527Q, 22.4522377239586858934126372942580332999Q, 23.71794655800352070106437529670545349828Q, 25.07438324400214828555529944234238427945Q, 26.52925466085620535573933853306193868668Q, 28.09101515483378720655301379661763173245Q, 29.76894754314429800021170138650587944439Q, 31.57325378002474417516854433656227175023Q, 33.51515654008411148311829427781923077265Q, 35.60701314953242130913508492608130123385Q, 37.86244349823339441594775773078079072641Q, 40.29647379850000394194999154115502761761Q, 42.9256983251566106568287701460452580677Q, 45.76846158142580776550763193789732785913Q, 48.84506369347253555255562043759063132523Q, 52.17799225094995370120933304290316705891Q, 55.79218429104484234314704060801385871774Q, 59.71532268038649506093311149177789765018Q, 63.97817179581388359256889501956078693274Q, 68.61495815679731739105182558138869817295Q, 73.66380253749173597579807670896348619996Q, 79.16721110650937730648828736138186887037Q, 85.17263433307891488469075132237625329786Q, 91.73310378961365450775367798895117611798Q, 98.90795860885862893373285703593128717067Q, 106.7636752615840049170921108192673039159Q, 115.3748165593138360964739919439025091047Q, 124.8251184167753335307884813481639551181Q, 135.2087360034668979739408892961618233969Q, 146.6316745601551591194184766080855899878Q, 159.2134344587212366502738176064757447706Q, 173.0889051680280399896165817677088786851Q, 188.4105488051885127906807545886516889139Q, 205.3509210823754434115791536392044147463Q, 224.1055859231269818834237202833297797781Q, 244.8964900834929361072626079301082497614Q, 267.9758760923573609795202757856526348931Q, 293.6308261096512585408835911644003226435Q, 322.1885463616083343430004234487963961674Q, 354.0225222209357737235698701666059446378Q, 389.5596984536108548077096261370629689439Q, 429.2888685030152394865736640219954342317Q, 473.7704919649917121515120988699951309401Q, 523.6482018956150921567202779251009371071Q, 579.6623148461239013729943303289916476255Q, 642.6657184518196254250998988603877103213Q, 713.6425863708155629919908359659403656033Q, 793.7304612802721925539978576829847118829Q, 884.2463570816121896178880212311454053258Q, 986.7176658841189012219850761458912237512Q, 1102.918819235722927744600414498283892661Q, 1234.91485329233271555981062082910716546Q, 1385.113272678479813634206124518231808971Q, 1556.325908312681685889992739657400589827Q, 1751.842833722475850243498798265810061319Q, 1975.520858975176784025953476571497190453Q, 2231.889682153460941507453429511802304092Q, 2526.279471529220797933682942282042851813Q, 2864.974510271917778566334688829570063707Q, 3255.398601385836981477327248620625297302Q, 3706.339256395488116333757365893728426179Q, 4228.219344042120788684028024525844687474Q, 4833.426940017626186335966263047791170787Q, 5536.716703957542012803288988529189752554Q, 6355.699353968381047550987173727520146629Q, 7311.439889033664714224839534528824153203Q, 8429.190352986375103659917942017957926758Q, 9739.289432574560082947218291110012238598Q, 11278.26941314174344865137745573539892162Q, 13090.22146527840192121556643882459793329Q, 15228.48353487758171912583592356379328602Q, 17757.7320759574131111084450686688920391Q, 20756.58056610832124979302179467528465881Q, 24320.81556946305416172004101150345528677Q, 28567.43688194010189078069185484468040728Q, 33639.71439652637892339557022075773032754Q, 39713.53390468433874079018761656799775516Q, 47005.38124868024276685194436174326123161Q, 55782.41454199081637721033867971136148933Q, 66375.20485467430976973616358391303682894Q, 79193.8964938789379080716557565128034655Q, 94748.76170569987926525384687205818258294Q, 113676.4185559940932985204557366937966947Q, 136773.3680937188787119816424376976346549Q, 165039.0188597090674337643015699657079395Q, 199731.0454972745979834726788415446981803Q, 242436.8306898628098527456078336958599012Q, 295165.9433837847718878457262129156537747Q, 360470.216849401713189605803840830130373Q, 441600.1519609350447724924713683024637015Q, 542709.2821490186584727843713857298955628Q, 669122.0692964885772249581763409255402396Q, 827686.2306514269967440238425057279466219Q, 1027237.646882789325395582817310098557766Q, 1279215.895361419046267273339768020024791Q, 1598482.001556073532061028566697317627191Q, 2004408.620417117903795710233263888056879Q, 2522338.537369602352689507222089859240384Q, 3185542.919287081047719844672603141954191Q, 4037860.118619087846479116022793787786343Q, 5137264.677480395599355604531997862929495Q, 6560712.534410318823827123644450645854025Q, 8410743.816776810796186473145045665937148Q, 10824515.55167440362485947269849464346556Q, 13986207.0209941330011779611362296564843Q, 18144124.90810505888082603159947148053492Q, 23634384.14477576245174950890211078768079Q, 30913826.95526480471448531540531281854327Q, 40605974.80378620661399473672299346895625Q, 53565444.57194199699651310605468978876294Q, 70968636.24955794350712584988752690989393Q, 94441963.80814532650216822140959524198571Q, 126243974.7954442094362911310588557317417Q, 169525168.7850776244769108117739517771857Q, 228700356.87037444467813945668623057383Q, 309984784.5945555486083699955906100203021Q, 422169676.419180296016038169604584024776Q, 577749487.0572079949357000884472359600731Q, 794568313.0307992201611056824664049192603Q, 1098236421.762334787107796693264193432183Q, 1525694882.086440344991905250910993556676Q, 2130500495.120059079142618634577471253541Q, 2990701697.368017711932087176125951177033Q, 4220637207.300671772783188221463829109696Q, 5988705306.551971098215414885650107897243Q, 8544269831.256129406510727541315985651644Q, 12258624497.59786938678183477943433708635Q, 17687708717.87495022845789287135040109813Q, 25668668250.58175914698250404635555840049Q, 37469379954.19249045788058580631395531215Q, 55021343701.47808222508026520305320946865Q, 81284573532.27450168954709280528031053888Q, 120822745771.3775527576541346782807310412Q, 180715302267.838335501258406348057915531Q, 272012900590.1587130429230121721901216984Q, 412074536897.799430443190475733419879223Q, 628344476944.1102285263714030386188019936Q, 964495715735.0823164995071629655123849865Q, 1490488802770.178852807340536150510230426Q, 2319151911693.03458420159878138301523182Q, 3633696221434.767157940890063426130568906Q, 5733695051202.934582494404097712673960175Q, 9112456759035.915558166110123534722925733Q, 14588156299469.85634878641183406469644201Q, 23527688830199.31431035896968138608336931Q, 38231623421869.65920594006767147759897662Q, 62601148428700.57299425483735853656627404Q, 103302358246928.8009047174017863251012655Q, 171814437520724.6796302867876243617578789Q, 288061024180302.6161380295256724616742758Q, 486899765795412.4945381221817576577795721Q, 829813516235357.2103923602912762213670883Q, 1426145535118378.951436282855348913815501Q, 2471991716108467.32565238550997265888506Q, 4322035403914148.133894111391643664621752Q, 7623370258751110.720304855446748890981251Q, 13566982446241751.95521593184313390214595Q, 24364538372998839.52259047925399940945603Q, 44160488249011501.98104668800830603643765Q, 80792929771140742.43357941688344049205352Q, 149224697949752140.7521990836163135293382Q, 278292163684832283.4160185479779845769773Q, 524107342845571057.9422283074584384844101Q, 996932213799835680.2597235801377919016134Q, 1915602123000823970.720466166997119896796Q, 3718848909517183870.143410573120269761073Q, 7295341760671302045.79313255542545772809Q, 14463988874285003035.94795686945931464091Q, 28987343448958931323.92810967706919677816Q, 58732754016747867529.00414398132271998153Q, 120331353070098168111.7390056337252147883Q, 249333004651588596284.035650776923709372Q, 522589314039917315810.223473765572860708Q, 1108152490641109934033.695782020580839626Q, 2377806308974776290281.711859341791971914Q, 5163834591017950405285.437821374070986535Q, 11351919331086858683918.1471528319768618Q, 25266839294442588226428.14778445717345898Q, 56951087826914109485973.59712623726588378Q, 130019587954518449740095.3405587711864565Q, 300717519321186724087928.9334487675138871Q, 704759216153309067051260.9313241944492729Q, 1673960445141169113758368.533624129723397Q, 4030544681474698805788178.936542366860127Q, 9839874954742709853120715.064425551442631Q, 24362247286979856257114998.8851952578909Q, 61184747201856950895364042.72498565866937Q, 155906667317075864701083324.9662928828906Q, 403163381047100871402409124.3779546257991Q, 1058261703628742425795196097.781097890238Q, 2820350066022680574530026898.432274605051Q, 7633343819011512595414528317.564843598457Q, 20986212852402084422748799314.66573670249Q, 58622994393166625667380328459.97406430494Q, 166427664782698297064027054016.028778848Q, 480305184367245946020952931414.3791654892Q, 1409469365276921639465057297415.183634189Q, 4206828103520948090625832005794.726896427Q, 12774108355248748130723515474898.16566641Q, 39473069418353402635694598912188.38756518Q, 124161027690416153525104720861908.998726Q, 397653952879188213452568013972672.1030911Q, 1297132481787798328222051462390494.77497Q, 4310699555554472364755479606514636.156607Q, 14598993032148232561844107749486020.15753Q, 50400995750152781199478648570188199.65257Q, 177430297054928348810918273327463082.018Q, 637121612274118077063576067207035125.0567Q, 2334308965896898251996924331341478060.108Q, 8729180311556704261437649253450972488.832Q, 33327870616504618405564608012803778253.06Q, 129957903565849452378953312970336477735.3Q, 517729777059756948461298024741483523105.8Q, 2107926524966039348251307533209594312777.0Q, 8774220406124443178237235835845685677777.0Q, 3.735197486182661954245100743924203262568e+40Q, 1.626762487644328121630687997548095289162e+41Q, 7.250973083083253199813538117009829490246e+41Q, 3.308936766532937115392827811529721364519e+42Q, 1.546541710130421473312439401601868673846e+43Q, 7.40592482120371542929543531360322220966e+43Q, 3.635026031346881800840788950800319505007e+44Q, 1.829426656802615545872238734711353926354e+45Q, 9.444371789843923777637569744583527921544e+45Q, 5.003291237038170466229131882466362255907e+46Q, 2.721071221382007933686249890911655353165e+47Q, 1.519865012090974117520450692809027707605e+48Q, 8.722349830799754316439247817774896336592e+48Q, 5.145299088117885927493542339522712625349e+49Q, 3.121221357870235693712216180124753139813e+50Q, 1.947899213175479452601623772691375555644e+51Q, 1.251210890644544336971252377162948639877e+52Q, 8.275874252588801763359933928249349963411e+52Q, 5.639192260136006716215984701965648621599e+53Q, 3.960436391373705651016231231787112634959e+54Q, 2.868130988088678181245153419409706139055e+55Q, 2.142864200359822342956549874731614126884e+56Q, 1.652506898141577776885280365380983877969e+57Q, 1.316016911424751010713227742852141936317e+58Q, 1.082852293820816389551974850072957597624e+59Q, 9.210644097586007954427562608847664200089e+59Q, 8.103092543855791898793790566984390085005e+60Q, 7.377040625432060608603217790009391493107e+61Q, 6.953737976979336176051071972961556866238e+62Q, 6.790427544984841974058656827100518158411e+63Q, 6.873219181285964966158787851203582418495e+64Q, 7.215276426549123743710202700699375386347e+65Q, 7.860040014854653238667256601459176244687e+66Q, 8.890552747510091206537761704842097735846e+67Q, 1.044773624845274406484242278763368099107e+69Q, 1.276339846429009678960092217254464675556e+70Q, 1.621909127730099101805179595189446592997e+71Q, 2.145222394949960636229309746712382373349e+72Q, 2.955136434459451093496393852873201995357e+73Q, 4.242484540386949293381593892190632931659e+74Q, 6.351598024216824109918004371203177858677e+75Q, 9.92322140177664793970985646435161664601e+76Q, 1.61890271292950503396982867447926469379e+78Q, 2.759835883031589426581500726726160092292e+79Q, 4.919725873480647138764805641435572041821e+80Q, 9.176966237443589394573048534481159624452e+81Q, 1.792537273106479512876232436227020228235e+83Q, 3.669131046186230038886281886697486654081e+84Q, 7.875974781863151481036630208790721389981e+85Q, 1.774257356669981483122646218784038073379e+87Q, 4.197883435791273747898935670006279670148e+88Q, 1.043953267600508611098731312756290706707e+90Q, 2.730922684509572139458179237102505154696e+91Q, 7.520756432311812479890602823961473367093e+92Q, 2.182171967918410224403041849327447242523e+94Q, 6.676499874620453543521727162652420305871e+95Q, 2.15577712365339698532597721844522720139e+97Q, 7.352286858278690688211435664926977400268e+98Q, 2.650811394091442291944564779047695087348e+100Q, 1.011237437351737388842116147030761121751e+102Q, 4.085370846206046405618971495958243394368e+103Q, 1.749468216493498166826699346132752537997e+105Q, 7.948317737498821871893743988852477827924e+106Q, 3.834807905023328863904941873118780424971e+108Q, 1.966628145855798245790683746091198936573e+110Q, 1.073071382517194531106278746912479484857e+112Q, 6.235722205835566650286247548113149395924e+113Q, 3.863024178163167333304337408956273310993e+115Q, 2.553807346093603757684677622217281376351e+117Q, 1.803488116000817634417017746648676518796e+119Q, 1.361928450409064286412411844878753266407e+121Q, 1.100955256966107712671861853615099298181e+123Q, 9.537293602323983258485510982542318832086e+124Q, 8.863266567274260063217354687374780337612e+126Q, 8.846188009560533969578546259096076506511e+128Q, 9.492930504934618253491690898644663173544e+130Q, 1.096533723415061531099016187787740114349e+133Q, 1.364975382571658955656460305314460765583e+135Q, 1.83324407540524757214204989774594748268e+137Q, 2.659671328312756196289158101058876969403e+139Q, 4.173261608816937493963987661707928522151e+141Q, 7.090865759140765750724147023181213198843e+143Q, 1.306301517030177176840321148170710506396e+146Q, 2.612529401702028055207351907664884448583e+148Q, 5.679555052608604602193055928305941291992e+150Q, 1.343920076232017946109889611934747955765e+153Q, 3.465917231693894339164893985895951010068e+155Q, 9.755225071272572958983312664175060577847e+157Q, 3.000742824526763344250019563325005284778e+160Q, 1.010183025811355809743868197177095335303e+163Q, 3.727075264673607112752380094424316792648e+165Q, 1.509245115418270293863342682538256987299e+168Q, 6.717559128302317419502861311585313379321e+170Q, 3.291318624734529160385171919931022097846e+173Q, 1.777836662264190438042312066790334422342e+176Q, 1.060338236589004151924947254106146518332e+179Q, 6.993672005277206691006295921013624374732e+181Q, 5.109315035547664200818831784655767554202e+184Q, 4.141101118954695995671586123417157559749e+187Q, 3.72970841944231900038690832200877504406e+190Q, 3.739049036766599115557194117114820248566e+193Q, 4.179336859308613161688286180307722723544e+196Q, 5.217443685257035669045459028493376857319e+199Q, 7.287327710700167211508944666212719983552e+202Q, 1.140792958868983691957356818511196462798e+206Q, 2.005179807700415852613810846388560032405e+209Q, 3.964605794076837186229454647465847803719e+212Q, 8.833882400656291129175201471618046038197e+215Q, 2.222416827262079161857013529468675017992e+219Q, 6.32487549000714259166529546382487457952e+222Q, 2.040207496855183891566222509116467026066e+226Q, 7.473933116405018227487255858678429348372e+229Q, 3.115635824480421807822417339161885727878e+233Q, 1.480984764640258342704597085687274914994e+237Q, 8.043751353020125109686268526532207882345e+240Q, 5.002449229484107509386335537403342295815e+244Q, 3.56984178603255912889435086930227079813e+248Q, 2.929532238219821490211564778591785188182e+252Q, 2.770679238026050606746236624138254643707e+256Q, 3.026798751595984436030709186683228573466e+260Q, 3.828036992387459381535969017271019185191e+264Q, 5.61778964283159075488466212754593198112e+268Q, 9.588901159209185095148527450244489057512e+272Q, 1.908180733385590686815575451459150865076e+277Q, 4.437792706543634540204526150192117697146e+281Q, 1.209142348425346993959353491937811099331e+286Q, 3.869310908075061490991368493783003476499e+290Q, 1.457926108247910333143812619546225873976e+295Q, 6.484855807244582773591724274648851980582e+299Q, 3.41399505989190389306038993462293155821e+304Q, 2.132926581369322983520027356423327793664e+309Q, 1.585660584493898360074791847406811357495e+314Q, 1.406549923600311781623297490488487143692e+319Q, 1.492858644861812662236576139363443931014e+324Q, 1.901200330136325650182339443918279093102e+329Q, 2.913594428067374876548048333381454532825e+334Q, 5.388753660372153318353497639257238947787e+339Q, 1.206400501839513571365268204575078366491e+345Q, 3.279025639761489754823013616224251826114e+350Q, 1.085362944039382532594119322284810147467e+356Q, 4.388637237003440512107759837586104007354e+361Q, 2.174591860496217544769291320830048605672e+367Q, 1.324675896729186199114724714897773943058e+373Q, 9.952624718323993743049191691571236891758e+378Q, 9.253292674624468877275054471751609753538e+384Q, 1.068175944610869281850017361625425792553e+391Q, 1.536233415754634782761541232392152383885e+397Q, 2.762122556175579381683600950713322858649e+403Q, 6.230559998086773008127784731120178792412e+409Q, 1.769541482165768371365926657095877950287e+416Q, 6.350669236692242487355167861453925877634e+422Q, 2.890704406534452721026792565610887691737e+429Q, 1.675092854792031970707972331086271904052e+436Q, 1.240441432963222229677830128231516291098e+443Q, 1.178400682719307171825255815152530484263e+450Q, 1.441758860787715996316806330169292187636e+457Q, 2.280896618995616398207821385872558406154e+464Q, 4.684783854898512240077048801484626654414e+471Q, 1.254382062452529400606345787473880256453e+479Q, 4.396832097929432333029382171843947213338e+486Q, 2.026103867409562112292321652086245531169e+494Q, 1.232725336259010710705619694645169566278e+502Q, 9.946131815388102167901949874677079252691e+509Q, 1.068946029136854556187731919763529005914e+518Q, 1.537205154906196455751501587209923504936e+526Q, 2.971488523144685380967551694691249695223e+534Q, 7.757209184017428909949567668621317830698e+542Q, 2.747774426890260234248395195407097655093e+551Q, 1.327052327970207303024364376423737858912e+560Q, 8.781052085532532513351576329773639941121e+568Q, 8.000370822300190275739495419036959668159e+577Q, 1.008709656376084238928867250812980114533e+587Q, 1.769035798555775145353374205587591814306e+596Q, 4.337887865267566149881332153701156202295e+605Q, 1.495146308822926755798228719893196247343e+615Q, 7.282512724193076983982833247777530464559e+624Q, 5.040065527191122347567048286402290970361e+634Q, 4.983688801691864935789903752926384680408e+644Q, 7.080529129251182167249954898842537768423e+654Q, 1.453648046373413551924040968198898941338e+665Q, 4.337598065643236527071167033605358927725e+675Q, 1.892313991275571732367620521996379213332e+686Q, 1.21419543901635843212963487739041197346e+697Q, 1.15285330851746771508587852221532721288e+708Q, 1.629782553411954975244284837756441953593e+719Q, 3.452055344385303141542795202545813325143e+730Q, 1.102512410379851438348571427232382982861e+742Q, 5.343866508694911882201645974783260583839e+753Q, 3.956826871594873007934411028424676095123e+765Q, 4.505631958696195386104188270723354358589e+777Q, 7.943741724189032271630373120507187623319e+789Q, 2.183459428673567948307965032840976723479e+802Q, 9.422208350325892638463546770197336134876e+814Q, 6.428840148770315798651380658113045680139e+827Q, 6.985833940158525432315159789439527191548e+840Q, 1.217845786540958113768113810573137032862e+854Q, 3.431528187148182849659646421877006421135e+867Q, 1.574663673077646155008069202772850496061e+881Q, 1.185846444352357252836601236236570671829e+895Q, 1.477057769851258028567499039349533232523e+909Q, 3.067158420904043177984085593633988645838e+923Q, 1.070385336228404234932902688736321198149e+938Q, 6.329361062260066695035899075868249670335e+952Q, 6.394430084983455208900711505672291428547e+967Q, 1.113087578022601582658889275733799715846e+983Q, 3.367156528651748518226447029503966911755e+998Q, 1.785596416013840188999074654317069177638e+1014Q, 1.674666787802858038890787260817621087922e+1030Q, 2.802838925410915198948806997205672228095e+1046Q, 8.447990981775688253045681606083551485684e+1062Q, 4.628258681649599746452829731806526694326e+1079Q, 4.652403352165737018608017815748357654583e+1096Q, 8.663306406163595964182894618845167463798e+1113Q, 3.017539509818074238591225328432214956732e+1131Q, 1.985491468553870196235393755910025018348e+1149Q, 2.492752117595816975254019948962503474621e+1167Q, 6.032605363101356373534719772171116367884e+1185Q, 2.843372909557441218412153608274974657095e+1204Q, 2.637696488690173901807892313463663992925e+1223Q, 4.867530936012666839215995814615900274247e+1242Q, 1.806297364908140811504547249661887475385e+1262Q, 1.362837915337647858769963651184997835872e+1282Q, 2.114105420285786331665845901133892184208e+1302Q, 6.819711630204384971623932887265931684823e+1322Q, 4.627744947987752918797524724541973729474e+1343Q, 6.683790011169256329679542877680372823771e+1364Q, 2.079180492288020730425138467537817647695e+1386Q, 1.410019079371984617158725525463202947604e+1408Q, 2.110334082726406632374960613564821609635e+1430Q, 7.058051491521915345419574349236726710823e+1452Q, 5.34226016580829579370410286869019558134e+1475Q, 9.269528949293586385450920959869061167858e+1498Q, 3.735566704990213502991174185370143251359e+1522Q, 3.543110166674891301675102145543023739261e+1546Q, 8.016707380888655159273391286811616288477e+1570Q, 4.386687461900889475748897922654392224916e+1595Q, 5.88635362961734378190669011184046381302e+1620Q, 1.964535219211330834129077713169656935329e+1646Q, 1.654278142010004007056058777791069121274e+1672Q, 3.566334264149844792966289257255345995689e+1698Q, 1.997696914392470061226774302379611252801e+1725Q, 2.951628334862652832836643008558957759962e+1752Q, 1.168023508080063514319067026006763505616e+1780Q, 1.257294797191357963612588713158077979814e+1808Q, 3.739918694766242006670350085465955624472e+1836Q, 3.123765125844391073468466650907077237401e+1865Q, 7.446408993561740205402068952680263307098e+1894Q, 5.150389021579176147263436232288928749684e+1924Q, 1.051097717221735323089186284217633448457e+1955Q, 6.438075549979749353380206207123056465567e+1985Q, 1.204191338766423126178080201430624216758e+2017Q, 6.999971798174361940960129565044032866623e+2048Q, 1.287400224651680358272160086786311987728e+2081Q, 7.628245018212267544254965199020501367005e+2113Q, 1.483306035186298578810854793693026754937e+2147Q, 9.644046259875525824373227005626744381049e+2180Q, 2.136807992154677198095425726464162609443e+2215Q, 1.644881859879540417424569583091022315341e+2250Q, 4.486258285656428254910735253711445952652e+2285Q, 4.422477869652754055735874573990613824885e+2321Q, 1.607928077696045804457995352614731652546e+2358Q, 2.200965498515380898569903830116828659581e+2395Q, 1.158169679831249142228245049215974628172e+2433Q, }, + }; + m_weights = { + { 1.311124362501499644235686793936615689367e-2539Q, 8.804534216807813314757104329326588296303e-933Q, 6.151866113634416819256167600386076492591e-342Q, 7.489561872273541742689179537030908098807e-125Q, 2.901271904710770582279868424530636078955e-45Q, 2.956328411110696011133881227129821807172e-16Q, 7.566001300199861545999807860317199813659e-06Q, 0.02939829736944376661348111575241831549228Q, 0.4375314491139458627156716229106118956143Q, 1.797291527801965779398851915787147159794Q, 20.19084569885298758559779466541998891553Q, 3190.204004406569421821255762141757969656Q, 464240600.3151569718431815049204268434463Q, 8064746494304895107671.373051861760453278Q, 1.345267603784213433366506701434024787812e+57Q, 1.312864386644320246962258704304378039761e+152Q, 3.774555882479308671780101506364300541449e+409Q, 4.727526321376723657695030280786783264447e+1108Q, }, + { 2.266244194795986437688029480753454536709e-1539Q, 5.948198448973651573057290957613527891511e-565Q, 9.309165866973257982306900988767978877e-207Q, 2.935089536156722196786549328771374738603e-75Q, 3.724520625101352679705795925568729252173e-27Q, 9.984303520500369046645618946072879096604e-10Q, 0.001431356453978288648029393232888019996234Q, 0.1627612496098382979023134567209341094245Q, 0.8715578869575546863808265846496354994425Q, 4.866023145010624995980060168572588092579Q, 155.7337423425961768825532940518427467513Q, 324159.1075527578458688529527151875836096Q, 52559121164917.31725683197728293103939879Q, 181320101439002742278180646071519946.3143Q, 1.108358234190440710092732108743944497577e+93Q, 2.358481112878241907590525258624871004068e+249Q, 3.697706182598331996489023917650042511899e+673Q, 8.005136174837239155367039692394787566174e+1825Q, }, + { 2.762173700981399765618908933145320277069e-1977Q, 2.39391240206587981734693603632697690162e-1198Q, 5.538595991089672359026435602811151013816e-726Q, 1.450273233250857905077679568886962533672e-439Q, 6.272581042589046274956826312460762996165e-266Q, 1.06595762540573348910987779005613885572e-160Q, 5.861309595694473480177550103363514588648e-97Q, 2.205278730651401402935850497892571252242e-58Q, 4.529434469306552018275201007754555774945e-35Q, 5.149496065541224290846694532009922569098e-21Q, 1.42514032948545940458919452929629803818e-12Q, 1.558687650051216471666230916065939291762e-07Q, 0.0001480770730060221114876366833392461280225Q, 0.00800978386203168352857804963031419632516Q, 0.0781267934470234464218464002858630624883Q, 0.2837432722671675969293700817591698892949Q, 0.6266921805102975877365600915734732725014Q, 1.224519291305484855806028685503263380562Q, 2.828371835589717993286260875443918026645Q, 9.308530387014651096841645763883748667386Q, 51.00340931322451024765452196424930212962Q, 604.5686663559257609710666271339665397866Q, 24963.7894862358300483813083168580513256Q, 8072295.599338304211683309182738003369921Q, 78274670038.30925761297829268300403781939Q, 208243829479833121.9614650100740045614524Q, 5835995851993422640885142487.353759023593Q, 7.038358981684021693676871973997393903892e+44Q, 7.365871905585280499359762130717295092668e+72Q, 8.356559316758425271433369887928065115855e+118Q, 5.152598671967255958872374447108140847196e+194Q, 3.367711726599649783722226912309479425978e+319Q, 1.485503800735698079387410309977283298303e+525Q, 1.206093277935111329439185628983764517497e+864Q, 5.101934496467121392771497579825667303128e+1422Q, 3.854461007601356020735662570367145309928e+2343Q, }, + { 6.801466297807648263832928079249921030841e-2241Q, 1.171357838472361572678710519863396121111e-1744Q, 3.263877177177999549213672495546362918233e-1358Q, 2.840730424450322878168790929290006130205e-1057Q, 6.331359514114723653384308531115955576826e-823Q, 1.940682122137038336501816556640832563117e-640Q, 2.424120579853831996718550176595436495523e-498Q, 1.060491186278820392276664616813055045647e-387Q, 1.47497560627560557171208231533307889666e-301Q, 1.711053655951593201729320308363487612571e-234Q, 2.748977044034961560163018702370375057024e-182Q, 1.183661289657511405743956059634031695806e-141Q, 4.956069833269360409024211595600427510944e-110Q, 1.987957235263791766538675534206288734102e-85Q, 2.726390196575204566967127968691492639624e-66Q, 2.069277780420174850386325233097351936186e-51Q, 7.599593796102130947873535802397682362576e-40Q, 7.30986765636526911109545189857700652429e-31Q, 6.860826488850009000152917649714036190099e-24Q, 1.750137476813662935088831237226143585691e-18Q, 2.694698939685357192909812465408615672038e-14Q, 4.662399523365191039306448758212945866003e-11Q, 1.471147096470191077279866117408849945112e-08Q, 1.234588382988672174156726122838549322181e-06Q, 3.698047527501062909973755871812833332555e-05Q, 0.0004974045204857426689718493339751312553248Q, 0.003594744266562108630858602906463214186729Q, 0.01606776382707240397141574634561698324885Q, 0.04963226590082011795403845149528264747534Q, 0.115744254393794946820912074463938084869Q, 0.2189395796674687235327095676147418958643Q, 0.3566541233572264162152813601314252592465Q, 0.526976767182178399604596779203609072881Q, 0.7398541068159815990923143586965891134531Q, 1.029425785377785516113796863012575526595Q, 1.472772244004991739780066538168681045534Q, 2.232105810859563539773192829947722929989Q, 3.664852093836574055260421484415211997792Q, 6.634229039042487667472625010842259069012Q, 13.47608350422833149354320757617644730575Q, 31.42073749047538137686874567762943831435Q, 86.79141791656354041821488779088943576306Q, 296.6528186585230549314029606641812360007Q, 1329.946577806955206827993564277915367892Q, 8441.344633114675813741927901407789834969Q, 83749.32841027025051399559911280792540265Q, 1475556.123428945995692670896358851704835Q, 54395134.46210963278883974741024860672763Q, 5179091016.902155867702113242034208944851Q, 1668941700142.962732014338449363262585953Q, 2575302232826040.930983214056263444447065Q, 29708121106264252782.32997718334559128081Q, 4538831967003783409536690.268981265379605Q, 19138023153446381738359211515557.27962435Q, 5716447050875173187782003939002192529233.0Q, 4.057627687752827735975516066653569584098e+50Q, 3.237780711010981929311620914986172494341e+64Q, 2.136177206956376829298160177481616436455e+82Q, 1.510581027396811547515066542591252259814e+105Q, 3.072511300612383685659247652666898751003e+134Q, 1.227994026803117836885996853139658018152e+172Q, 2.186769076188247553183183888358166072813e+220Q, 1.836091623107666564777188149335650549888e+282Q, 5.560380603618894755889563902333421267615e+361Q, 5.88998929678686832672515862440158058623e+463Q, 5.520096462216289192193975675075507876736e+594Q, 7.625041435865992600228986717464906255015e+762Q, 5.594942726633317888883469851113674080397e+978Q, 7.83065490388354698017246745548709611393e+1255Q, 5.31445051505238075828831366993821695924e+1611Q, 3.903967482555967268768154031672119092969e+2068Q, }, + { 1.386351840518308620839358763554215551931e-2385Q, 5.692714192122587749075617787151443181487e-2105Q, 2.451539999979072363325054695825688359483e-1857Q, 8.306259271201342345210834094714244365054e-1639Q, 5.821665674291993981062416504099267133283e-1446Q, 8.797358828459107177088680667625679647909e-1276Q, 1.320339777528218308293628576902954472032e-1125Q, 4.410206727121778476048579405149038344619e-993Q, 3.88958196740022428105997715246477744601e-876Q, 6.130840948743111294681197948959379863932e-773Q, 7.123986226444013036571903990814705244112e-682Q, 1.625956113900887259810636803089770478958e-601Q, 1.320572219097695369155247708778376474798e-530Q, 4.919706191404226525652134855992684547645e-468Q, 8.024860788515940296029723266854707311236e-413Q, 4.196871666597654619740159911562644470158e-364Q, 4.078224492411775554465972303455630373728e-321Q, 3.471191735147190701990574841139180851673e-283Q, 1.016777466021579755362597082466363719898e-249Q, 3.428953269503642726569674461101922799622e-220Q, 3.864648202676556945364513945878444511873e-194Q, 3.728313820662828523155813829174568160454e-171Q, 7.060208962235322129955144096761424864627e-151Q, 5.459090052012602911109845817641480236032e-133Q, 3.289567436086836109824643192921661921896e-117Q, 2.732791746839713887573903753808368756806e-103Q, 5.177831303085066219526632688623608474071e-91Q, 3.488982337185646306130499469791616370131e-80Q, 1.237442719251520028774158417551455658724e-70Q, 3.265026914390933861191439483297654102176e-62Q, 8.697379457734148653851179446161666064837e-55Q, 3.062345454155899894309388140629758140766e-48Q, 1.807833865712730097166039383871617541987e-42Q, 2.207201696331440225776336883273569215095e-37Q, 6.707139727572063961765308933879986454628e-33Q, 5.973483508300898776044037837138168377527e-29Q, 1.801180330026864986720562202650526101338e-25Q, 2.088388852078546115498528757421004935053e-22Q, 1.041793934618658976817408586406414722965e-19Q, 2.469049789233468018627633841281746668405e-17Q, 3.03431128584851438436540057561723628081e-15Q, 2.088889617504309972831708178248147497735e-13Q, 8.623861415427504342372142475897313432992e-12Q, 2.267520372707251092440673628855405207403e-10Q, 4.00434469899471800715993667519323799359e-09Q, 4.977449132259217603976612506935174810782e-08Q, 4.538968536823238628996215667606148804058e-07Q, 3.149630614091772394558558562673475357209e-06Q, 1.717661473089050710545820269467478657391e-05Q, 7.574967445230185640392007893916198017214e-05Q, 0.0002770384430817457004866373769076558592991Q, 0.0008592108153443758806376553027674462916736Q, 0.002304786360384424941771740344312552340356Q, 0.005441591917762328024217837565230797608769Q, 0.01148476167871522792645105471040075981536Q, 0.02196880253506076514443020083930138789152Q, 0.0385580396241706814351187454685124783203Q, 0.06277963108370615709268692244350221567785Q, 0.09576417409380607071669368828518626179562Q, 0.138082557357984497226918290243355129549Q, 0.1897351225141586893050983199373491867744Q, 0.250300181057554914230385878710297182992Q, 0.3192072549340042296492537721124960062069Q, 0.396080991004725824096103192363252504017Q, 0.4811067283954872948453453712777813856497Q, 0.5753914212017839181691468501697209245687Q, 0.6813248900530810118122761999613914470522Q, 0.8029798764915732889204873132214024785571Q, 0.9466241690181529814186874932394712810199Q, 1.121459300786612962966621888726574321557Q, 1.340759770715416009855754942434691146603Q, 1.623685219275531793982555905075386133233Q, 1.998211867629730384451407887613604637669Q, 2.505945399937510299544212230648723518997Q, 3.210163252219847883424432406111812852927Q, 4.209545478359448265983333053772635907905Q, 5.66221806820049392832515414216772490616Q, 7.82907923127299987879349586024812222669Q, 11.15440493963298675553174073341979600985Q, 16.4211729806540229459496343813231359463Q, 25.06213770772527921496874748041503923662Q, 39.80978364672011507488440928948335379928Q, 66.11905910269892631335237996583005145737Q, 115.4457061347595208831507793665792395105Q, 213.2410176092965330662887355382883213788Q, 419.7120557571478853925219015922721611943Q, 887.6243135338711385094394965082742389353Q, 2036.238442676944269983660634200868066177Q, 5122.12118711641868483849782862313248795Q, 14303.35249071777352807141644058493109469Q, 44963.76130260101727056610981483402829768Q, 161663.2341506202839569087583140422782503Q, 676850.9723274654978193458405608046555229Q, 3367904.732808158041991176278715985757882Q, 20381802.16891396956321794820770471285557Q, 153995295.8397188853456063357628382678262Q, 1496346599.741648156545891158553037248226Q, 19337797241.59405032267466119941485090523Q, 345272551967.2971484701102656571183717568Q, 8892537034918.26248560562610432170784198Q, 346910103925605.0063359353787631024771918Q, 21665929373961926.83928088004026581385863Q, 2306463422111622435.159433532385337024867Q, 449354136203242773092.5076776439573953522Q, 173650044978624626843389.7841238775680088Q, 145824377672837353076484945.9978156022493Q, 295089268707089209706730562239.5084852565Q, 1617782033479254791489149862949752.883819Q, 27439572735237674391627347457895077206.26Q, 1.673581697645403781224841542729295107102e+42Q, 4.352574542916664269993023807339615740421e+47Q, 5.85526745037344881314210199157273247914e+53Q, 5.070912889594583530997734588104227692577e+60Q, 3.622890387747150067406910684081678682268e+68Q, 2.828020276513886515649564791275027220768e+77Q, 3.316223981675888394574681086509262116403e+87Q, 8.379640459516602540499988839245270269136e+98Q, 6.867127982641854377436000349122572176257e+111Q, 2.900553033863247559187831400899198198647e+126Q, 1.067375865552333626918616370451069994481e+143Q, 6.203172809995726788998131622890100236377e+161Q, 1.117107695601654791970655214011701045665e+183Q, 1.338015284560800822144968909259062165181e+207Q, 2.532661918076356979939863944652000925382e+234Q, 2.020013699747769556918589976882904336926e+265Q, 2.062587137093633738153639964961537739828e+300Q, 9.497974733972601205199439097559404355421e+339Q, 8.216866861631646227849070101465292350345e+384Q, 6.727368363173988690006109427672655451647e+435Q, 3.256512214038182544092657678379570013082e+493Q, 7.431565554497628535696075925669517436095e+558Q, 8.404907826884863403395059072909982751661e+632Q, 6.774135867874352304403519336536368216792e+716Q, 7.978808683551832748089548367396910285319e+811Q, 4.210726051563171486361372753281330825868e+919Q, 4.815228807107039224016318021511536231054e+1041Q, 9.671936246443378281031357192551408517124e+1179Q, 4.965867685385961630088948794046462865437e+1336Q, 1.840788819983942185751345185174055491455e+1514Q, 2.949992127934753413488342242442835124216e+1715Q, 2.867592218659729126785338974659499305745e+1943Q, 6.225766615806442563214766060198378536369e+2201Q, }, + { 2.153709119065749047384536448355900579318e-2461Q, 4.147193855893089802932480896953837816201e-2312Q, 7.177658143381361090563844720372254951009e-2172Q, 3.944230945173987596102529995072916187169e-2040Q, 2.25203912532665129298170461102995236498e-1916Q, 4.069220991977459613504377433271627793079e-1800Q, 6.624466915659053303929653909407578699373e-1691Q, 2.596257880517152044266679980520189262305e-1588Q, 6.167272854034828267808038080246702477106e-1492Q, 2.113894573656814042644120551594507889596e-1401Q, 2.361521019353054468674145270219814329078e-1316Q, 1.848638669607253145389026119290761323843e-1236Q, 2.081403374877948007964079565701350764113e-1161Q, 6.623322864975529287136776279985505657405e-1091Q, 1.123590402158471434808995896499952788109e-1024Q, 1.844386514552891233533174646984024640794e-962Q, 5.128863718401367724889431337204044513391e-904Q, 4.088778734197102430329137280909077732089e-849Q, 1.531808371245169100620963725103848604027e-797Q, 4.290270905663487214153817815995887913095e-749Q, 1.389470421615532710115733425126799271732e-703Q, 7.838573060838659894518309211959299615802e-661Q, 1.131894291662080350703257522413580097058e-620Q, 6.006013929171556301601809240766812579204e-583Q, 1.644730968816111080320183371646275297305e-547Q, 3.198235005771726926394885789029782957714e-514Q, 5.959580309220240991340412270300143677861e-483Q, 1.410282910930590862816529755134883532288e-453Q, 5.521639312156930309110023768183565612495e-426Q, 4.585919516068868264280071563537738119217e-400Q, 1.020394119171727799567503936464494713616e-375Q, 7.574193909699610751429039846221563484459e-353Q, 2.30465092047628633493403784334464415825e-331Q, 3.48840220106323577890775923236785436425e-311Q, 3.150362661908098932123515245864546345115e-292Q, 2.013646164447659311144825526346127296191e-274Q, 1.069488936705677931335190498151163915494e-257Q, 5.487822844726864148884830007464470454824e-242Q, 3.134358187858381633591525778137729124473e-227Q, 2.276094570183129948569188857932257367076e-213Q, 2.381186996817690402995924843601642222159e-200Q, 4.035883965482480555809472106926843581355e-188Q, 1.237421125633634931787014328143031219326e-176Q, 7.612375248238611100167693433869538644334e-166Q, 1.03564517628310003846110294483553771263e-155Q, 3.414236525557816532714159962618179505079e-146Q, 2.972119191338884471738932645163613310679e-137Q, 7.405719578144237005638239996632269176066e-129Q, 5.697866971705411033338967165291329660286e-121Q, 1.453525650405010719093063409530168655253e-113Q, 1.314457042747800101250951995075815763416e-106Q, 4.487158944338714399472937522048625338578e-100Q, 6.133843010330477776911218592616869418346e-94Q, 3.549046569968448258108761477312785345444e-88Q, 9.15653736236172677846014482979591035913e-83Q, 1.106225007418683312537695601355577902976e-77Q, 6.552587618068599134320545512491211688749e-73Q, 1.986983959037010776999444552000407292986e-68Q, 3.212231088872538685545630958926283760161e-64Q, 2.876083037850198316572209488005734896643e-60Q, 1.478178451855495397755100020343123782752e-56Q, 4.510136913310968612160348544104344875802e-53Q, 8.43163306904015048294468768978670757577e-50Q, 9.949086338757522362613734399563150733015e-47Q, 7.619276387894797233552143024117256466731e-44Q, 3.887578603118804834388263706442887467952e-41Q, 1.354460425113896086794594963709153546321e-38Q, 3.297725535994022163897040708255026760814e-36Q, 5.733963913755196694875643096843980384457e-34Q, 7.266873043332808557472765774887708816006e-32Q, 6.842512280140593238694695887751428976356e-30Q, 4.873916238663169821502515125384510350419e-28Q, 2.67104044733090831863661929906177082711e-26Q, 1.144256425448742318630686443479692876226e-24Q, 3.889460608664331879375473469924970903769e-23Q, 1.063820968032088980245479855177643924172e-21Q, 2.372368187184684696934030650222501693836e-20Q, 4.367217234531848441087274222392461828198e-19Q, 6.714072048307672526701746503229203872406e-18Q, 8.715038929084108149220868369670810108493e-17Q, 9.649643353371338291949150921949043262283e-16Q, 9.202344844399561245249616317083794701473e-15Q, 7.627186782202012373857140553398508834043e-14Q, 5.541204897019768922378105161812644362096e-13Q, 3.557048030298498992879234830353226137603e-12Q, 2.032744001755231421592520905157658966757e-11Q, 1.041471970221369125727527396501651131028e-10Q, 4.815746961815888878707719559623238827298e-10Q, 2.022256033241840308293815584933936990392e-09Q, 7.757232961240456606859703523066518529705e-09Q, 2.733153775260544423882242088236116026231e-08Q, 8.891028969222217122426771244264445123634e-08Q, 2.683363699682823512352273715923881225589e-07Q, 7.547938347293146072138897896472002448211e-07Q, 1.987288087784999305724389158395024503401e-06Q, 4.917307260739981850972488313550395223813e-06Q, 1.147818087877776831871382182250485611551e-05Q, 2.536555822777680979640072567746984012303e-05Q, 5.324700805639575159848486238104008083539e-05Q, 0.0001065104593011935929690181523071874981403Q, 0.0002036201878041754169927401598406684761513Q, 0.0003730694572042112135642393073362991994966Q, 0.0006568041021168438789081239759748902651433Q, 0.001113856082390590315261750066635645853531Q, 0.001823795394232129061821994378958654853165Q, 0.002889513200651556198315930630030358001876Q, 0.00443881718224362291889374527793908773704Q, 0.006624370653018100869035486094303324374562Q, 0.009621643058168115506980743618776762488547Q, 0.01362474661061153688659710974159152873711Q, 0.01884028247930917278703173856744540683895Q, 0.02547957164901951276515984657668580178391Q, 0.03374986101820444134410850985898380264724Q, 0.04384524214597866779829228667526980197901Q, 0.05593807863817149350657574675807048756849Q, 0.07017170405513801042331008586630568895795Q, 0.08665503552527451253277350683009212070597Q, 0.1054595702235363867702301829785070516777Q, 0.1266190201109432391014527348400287053881Q, 0.1501316236075107886549638372376816417809Q, 0.1759649767559267732358948485233780510425Q, 0.2040630702512586485268749964249806985555Q, 0.2343551140988592187593366563877467767717Q, 0.2667656825843397368908190937623121671946Q, 0.3012257161225960732129884529500197323181Q, 0.3376839660798721233949233310785147371681Q, 0.3761185538003348421564742944823413913592Q, 0.4165484249847702522138862767113120553465Q, 0.4590446052165412998498906468918623478646Q, 0.5037412936922832954263365540046003893023Q, 0.5508469646129002757560299007304854908847Q, 0.6006557767190285077637253095947053526367Q, 0.6535597216576629891101800604144093765709Q, 0.7100620747737523822947126492473382788423Q, 0.7707928539773253442669973879355051153215Q, 0.8365271529352029829410941379841014207074Q, 0.9082074065630153160377196587855263177763Q, 0.9869708859999779495240452237028540164333Q, 1.074184028070142953846864518403663449244Q, 1.171485608204366918201829258479912815044Q, 1.280841302284684089954497564743618220051Q, 1.404612900635889239243367403680911038359Q, 1.545646402722480240247150802269938467715Q, 1.707384525263588509493128753610327227915Q, 1.894010926394097993786557902090588409739Q, 2.110635862415512116963868587235457795192Q, 2.363536303994741366574252227951115976696Q, 2.660468105686482827350797681159641534679Q, 3.011074164792230193113510360086440090828Q, 3.427421374693910835751367912941632897681Q, 3.924711673248156094377006203156860892723Q, 4.522230229488088770843806386045851485116Q, 5.244619212432280978773017572378093632495Q, 6.123602261918423455989664041297732186797Q, 7.200338212985471642696378036338100824922Q, 8.528661194163518647522330556738826698585Q, 10.1795808762825588115943699640538350698Q, 12.24759161182228183403936919987651507813Q, 14.85960439206079152354924082757358017039Q, 18.18772191639285225095582240934142331058Q, 22.46770693694438266788875673089834602979Q, 28.02598205678222312613627998636443255805Q, 35.31956839472836281617942063648805057637Q, 44.99589554931519875089171176915038299167Q, 57.98353389704885773969473673566367683191Q, 75.63171444720726311562293227564655477314Q, 99.92794457932308971895066190493770890577Q, 133.8425463310492883248985874380676641996Q, 181.8827841191322574272154105586756787384Q, 250.9989324790227325886260498692066131692Q, 352.0918043504840829713899165834496626436Q, 502.5673566776629477114581049222602222154Q, 730.7499663518253779065498110894726399171Q, 1083.663330851425621044011145629560752149Q, 1641.046090832866443292991561052478814981Q, 2541.175762543968047856727653734497274005Q, 4029.599963686451454823862824886660792972Q, 6553.444953601904053410984310275852939506Q, 10948.86156286092590781924054035970530589Q, 18824.24374198598947610407231104290274273Q, 33367.41042050707651941057262323589633578Q, 61100.32354761251643555142022778509780639Q, 115823.3197846099760624485067753700173466Q, 227800.5457979967285916898520734037878755Q, 465969.5974491004469600643539676692051643Q, 993823.6909873690422590985961324603809908Q, 2216084.13887947517519343506597373015701Q, 5181319.208019180282856303518778675455354Q, 12741027.34261421733969396616504794871165Q, 33059572.27383369273787469213830373668452Q, 90829891.07592666063192392492529195135112Q, 265220148.3252427142260298939914110596375Q, 826306755.697721615496224609055395381065Q, 2758381134.661518474947496017030009788597Q, 9910232200.243379934059362806886397274158Q, 38502881176.3933830609424901403318575962Q, 162584306967.2409325858164161316957369788Q, 750200992664.4359777908609835343088972969Q, 3804332487983.017078667225707645943133264Q, 21331904145388.14541475895031884650999707Q, 133122127507568.6787760048949572564123711Q, 930981675711560.5951829624728938156318722Q, 7350153770761857.738195134172081040509941Q, 66026171483511004.7598867374102237079003Q, 680486183952492003.9301399387520437691261Q, 8118174386406923586.599284563850167447239Q, 113170692154432424494.5216550607269731604Q, 1862134669947114232653.554228443860527992Q, 36554098616406740302516.43278601897053952Q, 865874280308076835063377.123348611020615Q, 25051406060214820093412273.85482035896521Q, 896751349474731244620492756.553903238626Q, 40266150489696916288472196890.64603620807Q, 2301369891996757289277873261787.184011061Q, 170047604983476347340915854457548.9867628Q, 16515349691975204027920973406952496.46185Q, 2145840986564667805146832484762675859.891Q, 380060769952839016072137090687963445752.9Q, 9.36123788558646358041896426324843981817e+40Q, 3.275494655666609981890875995623135434569e+43Q, 1.665398964860299545930184928911155962074e+46Q, 1.260451270788760156928310522092797529604e+49Q, 1.456947463601543501128002522603116571534e+52Q, 2.64322484187098185929268170588521133587e+55Q, 7.748613855444798667335906195147663845602e+58Q, 3.785779083813673709321393618005760329985e+62Q, 3.185930864211325729228980901011835019191e+66Q, 4.782979453124504957283130866796373448924e+70Q, 1.329705018427327910312331135948617996847e+75Q, 7.123048398653137809481237992377055295409e+79Q, 7.670126414228475157968011203109185943474e+84Q, 1.736689968283312998104946874213525703289e+90Q, 8.674483167127152572569881489730633083479e+95Q, 1.005836714694543802062236633293787516259e+102Q, 2.858670971133756835312878104822468805959e+108Q, 2.10991678144106388404020677820688045343e+115Q, 4.300927613568567564219321356837370605967e+122Q, 2.585292935715111244029099744261209770699e+130Q, 4.913585796022096573751225283239803494319e+138Q, 3.180331244781653863975221219946227781431e+147Q, 7.586729353605128898799633596174131151075e+156Q, 7.25574965577103086678452273743481928488e+166Q, 3.042628328617140159795776439859957241227e+177Q, 6.153982813886310112559054012984291284066e+188Q, 6.644716047129194946546223989317633525216e+200Q, 4.267010798047279459873744815427996740364e+213Q, 1.828261524200837793682416150708346778824e+227Q, 5.907192142855374833372550253101759665385e+241Q, 1.639613866135475410081422748292467992288e+257Q, 4.491164650248633394149160267786964834797e+273Q, 1.407205628682664127895373663193013840779e+291Q, 5.901973736086548723127533540481678230101e+309Q, 3.916881285333542675097708234397993801965e+329Q, 4.915136487337420126024738386450372286475e+350Q, 1.409678081844840550729970217105440686499e+373Q, 1.130683199310898290102829283325964896298e+397Q, 3.144117419652964064273526900880035236365e+422Q, 3.809876833653423585198167012150253087973e+449Q, 2.566258698784507090567153515899784014397e+478Q, 1.245112941213262053730574272447559130313e+509Q, 5.733709207713561096504201724939408030947e+541Q, 3.361300877024088016576478175807523211916e+576Q, 3.429058193604769142012855254783863281583e+613Q, 8.490713211274685176663921590498405237032e+652Q, 7.271789265612590062970363082306633017878e+694Q, 3.140603098783297467974052202677879991934e+739Q, 1.021802837240605643483742627625814386292e+787Q, 3.839307747037610497370639615169236613499e+837Q, 2.625348245611878921167180568009691832465e+891Q, 5.301810468703271471934335911636282471403e+948Q, 5.293953933728338458359735330414432271415e+1009Q, 4.523817161069727277868688722993321639055e+1074Q, 5.932188169476821247963196653927747373431e+1143Q, 2.222709326425237855173602817006726442049e+1217Q, 4.612038732897790803740603080628674002466e+1295Q, 1.071926720490530830314342236668609091118e+1379Q, 5.906749883873223055044444836570422088279e+1467Q, 1.714334001343939494661025595853170112809e+1562Q, 6.129355935256855944674667471697766641354e+1662Q, 6.669833729539525050372787353801005283761e+1769Q, 5.785462791059143624731094992917802825231e+1883Q, 1.11479279343352711500828293815386828494e+2005Q, 1.420693188301294963083799946944540546516e+2134Q, 3.825007293467971681545785259893286155041e+2271Q, 7.49023122288057767110049546000007822061e+2417Q, }, + { 3.396187965591260438897244230849252949133e-2500Q, 3.41747159490076194366166435197892344024e-2423Q, 1.468507678341085936510631686027018193702e-2348Q, 3.187196102551453055654175541511540035227e-2276Q, 4.111144618799882938247446443042495922138e-2206Q, 3.689982379249148439178153280533053022001e-2138Q, 2.685174204657092092067226298561204870573e-2072Q, 1.837147705508098860673717768368232067662e-2008Q, 1.364257907967552000423094508893268899947e-1946Q, 1.263771364208497251750238943339938928533e-1886Q, 1.671242563857819954841665799077012782254e-1828Q, 3.59572473348901442338115273389639464694e-1772Q, 1.428695046663295321301312704790120159931e-1717Q, 1.185320708968814213894285445648910693797e-1664Q, 2.312978025972053806095540476447810494724e-1613Q, 1.191384629114553103202392185340997162652e-1563Q, 1.811512325837822942229802348315430051691e-1515Q, 9.061690335018066855688935640999855840642e-1469Q, 1.656446393553325828143168688464980737559e-1423Q, 1.225078144907203399772561902982205963608e-1379Q, 4.046000991642731324022030505096438995941e-1337Q, 6.566030925389917368793803468023222144906e-1296Q, 5.744543867554393981259543937791978449595e-1256Q, 2.964190466284077618451217948796617398864e-1217Q, 9.841838762797010428171966754803344043532e-1180Q, 2.287831175258608392805748160775135819389e-1143Q, 4.040912495622704041470131809505159517349e-1108Q, 5.87056189991253569332657105113103824038e-1074Q, 7.575340244592727205322278379346787745011e-1041Q, 9.354001575325859412659652699978018590336e-1009Q, 1.188011952293188317901713987657283819367e-977Q, 1.664419563784475798800943375399832441798e-947Q, 2.752827383868394227330239571429534681919e-918Q, 5.740088624159127463245451711190174595819e-890Q, 1.608246374016315723402165607871082117057e-862Q, 6.440216987884563060048094831994625373593e-836Q, 3.913422837501277880548253194801428546448e-810Q, 3.823983955989560074096123125871957896214e-785Q, 6.356204437923014497781992143867806067066e-761Q, 1.897887002136970233209553057528902481451e-737Q, 1.073182396417440952923883248248820918596e-714Q, 1.209599587842878172907735383699977342323e-692Q, 2.855780038744229524130906951698839053919e-671Q, 1.481869691380590340606688460267010905665e-650Q, 1.770687381130960661518257581666080736263e-630Q, 5.097321233667122918955939586473322120615e-611Q, 3.693416425056334731671036194098592621278e-592Q, 7.028028538800977471757544285347858958102e-574Q, 3.659514003462772290514441124205917047976e-556Q, 5.426427278796883021042905920496694956698e-539Q, 2.381707918869144677895468509571771901592e-522Q, 3.212283372523687089209961685271370035808e-506Q, 1.380563704271665131614814775099207204703e-490Q, 1.958383048574468276677385071723507356519e-475Q, 9.48743029982518591875701010064880276966e-461Q, 1.622425672258543869160313396312274060462e-446Q, 1.011253624597190818422622302876493852764e-432Q, 2.369846278374825178509948199829322673406e-419Q, 2.151869280186648519304900103376776987149e-406Q, 7.794995966503254880771477408719032168903e-394Q, 1.158774967764284452774587235820678160811e-381Q, 7.265518880056698052413196249715572214718e-370Q, 1.973119772438811666557920176657054992131e-358Q, 2.381439826231545597543020603431153384525e-347Q, 1.309668015497819382164964970820775932287e-336Q, 3.362180147598881535117942142551368440204e-326Q, 4.124757840732051332008577708750119570912e-316Q, 2.473774062046798241443322474966268652708e-306Q, 7.414272202331839719973914818818580322732e-297Q, 1.134468775996673043912791038078875526892e-287Q, 9.047228020735108713214081674437370270152e-279Q, 3.836582522644715763942703819520627288712e-270Q, 8.821018545646132764191081245790014964075e-262Q, 1.120514881106390681395171052626683473171e-253Q, 8.008830218793913153208169453114674961091e-246Q, 3.278363148993695291288199990793809607438e-238Q, 7.818601615846121111349439345713965603164e-231Q, 1.104596257773265868270077717696885587749e-223Q, 9.394568230893641749287701746065205133818e-217Q, 4.885735162640535435890107738269252106649e-210Q, 1.577376231155234084689651390459997701678e-203Q, 3.208212741662475033190349289840478119199e-197Q, 4.169536264702376953290079421852225148214e-191Q, 3.510697043108920771297336971888026846695e-185Q, 1.940796992053920703808111564711495526893e-179Q, 7.136244685320035109754945708241458423185e-174Q, 1.76730280063163466059025249772515470605e-168Q, 2.983904480026560548776384248696357376925e-163Q, 3.475443323448652658867118439684844230342e-158Q, 2.824541702249354041220922001046298716151e-153Q, 1.619596258103472503516391027755171126672e-148Q, 6.622883213895051670195179932778951351576e-144Q, 1.951579126231643346975253911702685400056e-139Q, 4.18602835981743857108590756268931043387e-135Q, 6.599918926269709459823212257675014743931e-131Q, 7.721619700426055982173615669852719657832e-127Q, 6.765470266069447535409496863264786718304e-123Q, 4.478897242147858909930672029381816582225e-119Q, 2.259813587851430691340478359494188813328e-115Q, 8.762584216656783897599480439549782669278e-112Q, 2.632496848689131735621784382242972332592e-108Q, 6.175744762125928416051254264663305408061e-105Q, 1.139991187420054499517789858269823323244e-101Q, 1.668043996811119184547324447087614691957e-98Q, 1.948551942896453232736618306447207462772e-95Q, 1.829886111019235604640158140033504624484e-92Q, 1.390785816650512241305706201256468524959e-89Q, 8.610876597126909947907951239288763095391e-87Q, 4.370440681745287512655018464467927347986e-84Q, 1.829571499724700982569308406477858583305e-81Q, 6.35467982337703555609574874386279503639e-79Q, 1.841843585185443349017139118584710840766e-76Q, 4.47965436588705164639200919931593795846e-74Q, 9.192051994113798021355923589255861583052e-72Q, 1.599661377244400320973091930394038454107e-69Q, 2.372973035131768911030516185612566198015e-67Q, 3.01536930226127366549303637826992082662e-65Q, 3.297914067466215137502368249038560260817e-63Q, 3.118845146643306964903272759796966041873e-61Q, 2.561809323663349754640588340955031999901e-59Q, 1.835614139432453324042425981398349070542e-57Q, 1.1521864053538881965046566277201188672e-55Q, 6.361211949301700767511994322063706295027e-54Q, 3.101325408187412574813091914708051546337e-52Q, 1.340315366748084943795568462034401125423e-50Q, 5.153823682493916697673436399844338582989e-49Q, 1.769604350572757034480939371983385367057e-47Q, 5.444524938929029722644073109230252087076e-46Q, 1.506078410473230887467835250237074953313e-44Q, 3.758031524066051846680267047613132037807e-43Q, 8.485476543792520256759499913448061725315e-42Q, 1.73912337985688401526741472924132534839e-40Q, 3.245018402217835203803189828064206880925e-39Q, 5.52829245911326158677969008013854969983e-38Q, 8.623186993970885363149060426291059432547e-37Q, 1.234883577447636456455512573156980104766e-35Q, 1.627825555297558296682254587731016740804e-34Q, 1.980251853197110750740177033192542117995e-33Q, 2.228623687736138529232852162477642705595e-32Q, 2.325930995307119978621491337043388856308e-31Q, 2.256361660464174192555048087618606554597e-30Q, 2.03915117811515128440130306842025272854e-29Q, 1.720544614806180272783100692189304247844e-28Q, 1.358238700291425183093124587457930780547e-27Q, 1.005239457303406154474744151833947246431e-26Q, 6.988894303606753297669433851126311708373e-26Q, 4.573289270207565220088232217355246375583e-25Q, 2.821890506943991496371146647405255494984e-24Q, 1.644856636073523601510029605009201973651e-23Q, 9.073050442568561823275320558923185848283e-23Q, 4.744096929010692481229783323592456352853e-22Q, 2.355285875813243315269790791700485018621e-21Q, 1.112029876447833293355894317984646400697e-20Q, 5.0008478161487906265030783014276491832e-20Q, 2.14524119442811961043233114548051430279e-19Q, 8.79113320178734153345564529895449040709e-19Q, 3.446365815960497059834387107630422028738e-18Q, 1.29425069073833323669197152514107143377e-17Q, 4.662195383020049630863703520736565781021e-17Q, 1.613000201366897700480549038203950457934e-16Q, 5.366485961582633012834800491739735664821e-16Q, 1.719017688382153776104960609843894364829e-15Q, 5.307775363464215365491509744435747831714e-15Q, 1.58153224028765965650956502083229696234e-14Q, 4.552534798688262530368751552485493008278e-14Q, 1.267359873762161999061953574910727734371e-13Q, 3.415589293705976822709962615841017474303e-13Q, 8.920396441522617984563473743690015005656e-13Q, 2.259831056683534791299863302560269236812e-12Q, 5.558385496914281158626259742154054243881e-12Q, 1.328609277181416985306808048226260048845e-11Q, 3.088906383077323034217900364942328595424e-11Q, 6.991047069852996644705052389828829263697e-11Q, 1.541592161799424949759540552003006648952e-10Q, 3.314631696092892696852523428007047458956e-10Q, 6.954687377912267443923690708860638478132e-10Q, 1.425030481896628988210436275967793904415e-09Q, 2.853596165859016481994370182243409560513e-09Q, 5.588439560806246713133438407216443307775e-09Q, 1.071067205395228191517684123993601779709e-08Q, 2.010297293947428624088705656550599163117e-08Q, 3.697444612237240406525896448389116570807e-08Q, 6.668262990662516945946174242814702190448e-08Q, 1.179931847916722133357063059921902676628e-07Q, 2.049697303194034837958769536530460272066e-07Q, 3.497508382194711899593633326040760388855e-07Q, 5.865487025318323293753202306221287078656e-07Q, 9.672937611928622460886601535198624050582e-07Q, 1.569449303967431028048007992388750555246e-06Q, 2.506625809822351496367236588148835401765e-06Q, 3.942730303856445318459553494614961666457e-06Q, 6.110483188339684780731192452553392150661e-06Q, 9.335213605738775483770667944380871611306e-06Q, 1.406489270953562868811484480472520033374e-05Q, 2.090736966298033607047604777694817538599e-05Q, 3.067572523977360728549911196951929768457e-05Q, 4.444254125522237612570935119262098204356e-05Q, 6.360369186365502157943693424315842416464e-05Q, 8.995198988623426391713559325836996156118e-05Q, 0.0001257606674958313871253473701449253355037Q, 0.0001738762412077100706379667970818335522797Q, 0.0002378198178307528456808477520866366646793Q, 0.0003218953586603673896746051260032347406477Q, 0.000431302857278104350328175477422461855135Q, 0.0005722538300635913579360920152701977667389Q, 0.0007520859992681880710509445633320017863057Q, 0.0009793735988494621503195966592341074592935Q, 0.001264029384952618301528623595188256832377Q, 0.001617394214613631295305190408599562642199Q, 0.002052309991459652915632773174511094733367Q, 0.00258317188244673197819727310558453131011Q, 0.003225955993218896497486226124906372664769Q, 0.003998219150540716791460047207042995806204Q, 0.004919068068090767024211469275276612172327Q, 0.00600909594733817652192578530463654010429Q, 0.007290285460855384857058707803522235069712Q, 0.008785878047288446808894606650882064620093Q, 0.01052021047666635132307480661080880814452Q, 0.01251852068056883921977029876570047333533Q, 0.01480672584232190128610556778358216498454Q, 0.01741117666809860093225669085692180516086Q, 0.02035839257460948797638140898975661102703Q, 0.02367478320248247763739778834391071393716Q, 0.02738636217273390454768575395117704136113Q, 0.03151845933082324581907457369661258727617Q, 0.03609543786059629424946593596435380994262Q, 0.04114042259887953993494104853150125354906Q, 0.0466750456480661216715303674857866168132Q, 0.05271921498296900191850699684600263052343Q, 0.05929091119945738364187060701710146534661Q, 0.06640601688035302862345335055441729364649Q, 0.07407818228628303425809436316411971898579Q, 0.08231873024496119428365313871533264809944Q, 0.09113660224143843130137094535859755638343Q, 0.1005383468331949678476633629507285246196Q, 0.1105281506546976411534200317116736403124Q, 0.121107911460692283295465500059636925578Q, 0.1322773519071888937074497167516771096546Q, 0.1440341721011981269170563712300225480081Q, 0.1563742383781529019329462935434102354245Q, 0.16929180529890363384017378918294150837Q, 0.1827797675015790272999775984418466966127Q, 0.1968299377991512902933613706115501276824Q, 0.2114333477796263038189171478034961399731Q, 0.2265805671379344452230433758251512257964Q, 0.2422620380400139215659763053475126372656Q, 0.2584684209816167422154096623392631193615Q, 0.2751909488470871954314516615118286765006Q, 0.292421786186026106706648834563937352905Q, 0.3101543910972953239589783999692036454244Q, 0.3283838775292636198506142015003861049102Q, 0.3471073762620363765649565589914160563095Q, 0.3663243933219057311460108766773067464956Q, 0.3860371650816835811494186931036726843691Q, 0.406251009815427415089167957119716552498Q, 0.4269746759961805873630290348183986624008Q, 0.4482206881460109502730547965841668757419Q, 0.4700056915656277899431961667430783936476Q, 0.4923507977844861273498956739046383206408Q, 0.5152819330813603300309886035691222305983Q, 0.5388301929311863111421213198913401934378Q, 0.5630322057392941342388625306808580909827Q, 0.5879305097331706661595300552630455764344Q, 0.6135739474002000455026043925050716049865Q, 0.6400180823944171101131289807198543701499Q, 0.6673256443945673609364872806279077990422Q, 0.6955670079895264329659912952632680789938Q, 0.7248207123067282158967442704471550423678Q, 0.755174028797632235942287932936820869365Q, 0.7867235853661413244076962098206460684032Q, 0.8195760558879440923143584503029939308205Q, 0.8538489251399243780669486054066034940311Q, 0.8896713402605466323065095493330976770865Q, 0.9271850611189796768353779214968518621624Q, 0.9665455234106549820541670985068771774387Q, 1.007923029952093538678666103220858418246Q, 1.051504087555186687117183984945832760065Q, 1.097492909063483883997601555693094342315Q, 1.146113102680112719972734092736933142041Q, 1.197609573666617166428932839178577498609Q, 1.252250666911899143547941192591371436231Q, 1.310330582839888493701788295465003738157Q, 1.37217210373676733630920077182877790563Q, 1.438129672943398791959487191769629934714Q, 1.508592875605843567792546896641817408196Q, 1.583990376960161405728445978404738182695Q, 1.664794382629429266013098961741791558223Q, 1.751525695347873485191917162770484106857Q, 1.844759454157519975124726858748082186858Q, 1.945131655755179789450074815727091684967Q, 2.053346573670745058772720412100260503836Q, 2.170185209773702783125573644862289332091Q, 2.296514934764264073224142035073302023876Q, 2.433300500447164388577695004113074013905Q, 2.58161663747988776667509546620948920106Q, 2.742662488862789158372641819356759385405Q, 2.917778172822028903433359898800151747826Q, 3.108463820292819287982021469423989376857Q, 3.316401493599933781190010602613013995669Q, 3.54348046617653089369704252750263265078Q, 3.791826430729338944919813121549353097009Q, 4.063835308168158064754708867837643609124Q, 4.362212455574033518518003957573686930251Q, 4.690018223035719205027755685192834005172Q, 5.050720991947143731968899118688088940902Q, 5.448259048256953387079920394084937571864Q, 5.887112911771720144158430210651581802686Q, 6.372390067582751971642819361195420653775Q, 6.90992444125988827953012481002020831555Q, 7.506393442161772368175053194733459234238Q, 8.169455989725808324527513652199713813185Q, 8.907915661855472823639384908936684643353Q, 9.731913995136417711816003089572337623446Q, 10.65316006472897621652551260868663551892Q, 11.68520382944801969713109764242848374433Q, 12.84376241077977807680500867803300301828Q, 14.14711056741875730648931534734397225137Q, 15.61654923657610797854796792165924553916Q, 17.27696927711813081034870582050023535149Q, 19.1575316438972062177517199312460728233Q, 21.29249037469088386815163901407216178668Q, 23.72219127477837271220994964328656674383Q, 26.49428742050364820557155179532147420304Q, 29.66522306835508141969084020865324390507Q, 33.30205089827977157270000960709570859413Q, 37.48466458890380022160714648508118317334Q, 42.30855063623495252454033790164450670327Q, 47.8881915632378843451955961800195447245Q, 54.36128918373743651121334551785550120256Q, 61.89402398727235984409338948213129946593Q, 70.68762848584778035111708853851365105352Q, 80.98663318461299861455744390021635011055Q, 93.08925000731765179043536794223242453694Q, 107.360498051909977877638468111141356496Q, 124.2488620644913487541111414904888517612Q, 144.3075208306123537479577194819288207331Q, 168.2215125059906251544039241246965052271Q, 196.8426466712140109699287106212096785157Q, 231.2345700412004162865664673411149073857Q, 272.7312019667013277459148899897857891488Q, 323.0128578028804552965843198380088014832Q, 384.2058863035695149259386485193758599267Q, 459.0137217198435660140055247689248768806Q, 550.8901200041443942937196398242337901245Q, 664.2693368837686965599246065404881270217Q, 804.8735811989890924404636182648277160974Q, 980.1259156504395891459619379603039765341Q, 1199.707861561135993394057942286167343594Q, 1476.316731695328101407692303706838300626Q, 1826.700281041640180200375170800299114979Q, 2273.078763337010832434612762840156927958Q, 2845.111583125694562939705485499061319494Q, 3582.63445229515952348100007249931464674Q, 4539.493895490226925280328582195285263756Q, 5788.955233042394450770042652752120480379Q, 7431.382535413996455795580622729193897504Q, 9605.22268816346298456472600902460366535Q, 12502.83007762372328074237673282359093081Q, 16393.43674235796806736737398613354988262Q, 21656.75254389093564900375379131087677274Q, 28832.50596892479639714830479215091321586Q, 38694.08631185854918420830577505233860916Q, 52358.93467063693914614720804658599988759Q, 71455.456360801919182448351605271054385Q, 98377.64507715702272833892935236019203581Q, 136677.0756867775216880054458611011665626Q, 191672.0751837584047014496772899197949398Q, 271403.5992651355850921027142705425693394Q, 388150.1489980647547347704942553355997537Q, 560853.4130088772447154039295543588593931Q, 819043.3312820769048716008983572259664347Q, 1209258.817558563172770397433801307820624Q, 1805669.064478872952573635882889999089934Q, 2727847.041283590928457428564030560101144Q, 4170866.124317416698666405920199452972485Q, 6456890.228079086947156608652453964442837Q, 10124726.37272406821615834787676485411144Q, 16087301.34833727189340602159225001909214Q, 25912302.39431432285806898738587495423666Q, 42329233.71376092207616725342280744956334Q, 70158627.34273633230839208484182467105049Q, 118039913.5748636616256979688722947376115Q, 201693090.8294808535841471498441901946314Q, 350171893.7910157422614179826343745861743Q, 618045198.9354320713114267484128373842008Q, 1109520762.65117402853282816165715478028Q, 2027036851.386298662396084471850133567806Q, 3770865836.139748847448857684280330919226Q, 7146997570.085695415162843692670918823862Q, 13809155423.7635644350563312672690880342Q, 27216828505.22509686672818101177168461874Q, 54753167786.17979572173272483227070679431Q, 112503345834.2116875456216420474620516059Q, 236264339141.4388903275724307413980800073Q, 507468184268.3981316720163337618534278446Q, 1115599423406.056750358630646519147758314Q, 2511986677094.979276772007287643222172789Q, 5797849169011.042298094625503200359295722Q, 13727721548993.32343665617597576637303556Q, 33370617336501.58545603365672095860275791Q, 83354238202660.91699429975122294150089333Q, 214123217249312.3976721926402658332174117Q, 566186245097249.2404127137280597778292079Q, 1542458444402443.371440183667494867781715Q, 4333492171181691.733058240784286416444505Q, 12567757410549319.01294953377020420832395Q, 37662670435513236.74825914523236427898489Q, 116748202247647142.7587746965785438338682Q, 374749992316334764.5035248090549339897237Q, 1247000912952610699.068918595764499658321Q, 4306478248247432160.48599458994176300511Q, 15453273378202816390.33518176991213146053Q, 57688614909942567753.38454019969606422075Q, 224324420244279774891.5933154795594761405Q, 909792898611770682517.3964923463766620933Q, 3853617984492513550125.129076034019123708Q, 17070801413556696833779.13934163759159904Q, 79198380783368988856761.15648214291897699Q, 385383801466035476735828.0064437179791326Q, 1969895659051426429613504.41964918030692Q, 10593618501197001697030611.61632899678015Q, 60033966329846568637130543.04333463171392Q, 359106968518167632524691177.3080001529087Q, 2271277124005940993621700920.257498362904Q, 15216157171278585594752783876.84164894054Q, 108173748902143609868441659437.8836108294Q, 817597332272823012424833955943.3418687263Q, 6582674375871431329198879326278.80655534Q, 56569460748304763531726402484221.24071294Q, 519969127337393591722068633515796.7939186Q, 5122908034001797018186468009479969.983806Q, 54219575049584711207951705824720122.49792Q, 617850853251241831307357121612505215.2627Q, 7598326740673873945470445853982730673.683Q, 101090458794504259380071592279087005881.1Q, 1458628632586491581554836293603735700553.0Q, 2.288445431879986075288969228297589916294e+40Q, 3.914281502784266353374296872381741581596e+41Q, 7.319312087167267244726757556658409266855e+42Q, 1.500458683672485184540463104819915256685e+44Q, 3.382059446944515486362813459304381825179e+45Q, 8.40717228899724214872703723897524019292e+46Q, 2.311957183444258916605122634003678725418e+48Q, 7.056075282456062930798909861538304101971e+49Q, 2.397931935961417566906622041440033927301e+51Q, 9.105063361761505316713558735495605805833e+52Q, 3.876420331062826191501135623097992286507e+54Q, 1.857198647483778496415448329375750635825e+56Q, 1.005063215679245721735518932962246661573e+58Q, 6.167590234451758437399991565606037242384e+59Q, 4.308813152379759511416924169109982265891e+61Q, 3.441182726656605944775469940970363892009e+63Q, 3.155080085289705076440136183714307040901e+65Q, 3.335560569120603606052934730277045229653e+67Q, 4.084573232398309215368829036499274751723e+69Q, 5.820628809283804990396620764580300086666e+71Q, 9.699039800361010527223356682487354608079e+73Q, 1.89923980668320512816136152429593080513e+76Q, 4.392868007405665883421052875783971749913e+78Q, 1.206505986650708892173158064003257826858e+81Q, 3.956328505753650002939043382097189172455e+83Q, 1.557688055206654931604309948079068934868e+86Q, 7.406537535531269658298708915037136600795e+88Q, 4.278562761054468958052314006843284683637e+91Q, 3.021429361815161697337775526021250674025e+94Q, 2.624991835754469757869340327198684862761e+97Q, 2.824239055865323697007157867310795887143e+100Q, 3.788616439302435442144238888291948175614e+103Q, 6.381265012445197114926701012217755404272e+106Q, 1.359307419444233008395198137493298288245e+110Q, 3.689357736818599529286450344745920764709e+113Q, 1.285719405981015169347543552934268877769e+117Q, 5.79896089805386955461804251259128564304e+120Q, 3.412858686517390979492612468054488171338e+124Q, 2.643133109091891288299365259101435230764e+128Q, 2.717298021659115627801241121693599358524e+132Q, 3.741778449844632488889983162905015325601e+136Q, 6.965790897246310296313827180334657009428e+140Q, 1.769991845748830191769012548081426586684e+145Q, 6.199682080134586417994375593693813669468e+149Q, 3.024056421749683185151625522184732565621e+154Q, 2.075860353782646995243205830982511919541e+159Q, 2.027237041997503527729877101258258485667e+164Q, 2.84819019631263809337561430719405846138e+169Q, 5.823789472478759398822868913946380670277e+174Q, 1.753831670213037732308430178708200856584e+180Q, 7.875048994214403791228526371140330003633e+185Q, 5.33959995017489809314309431564145975465e+191Q, 5.539060004117798714171786555151150971203e+197Q, 8.910405429080536887142895484227329351929e+203Q, 2.25393372621235039418834085888287214571e+210Q, 9.095096825715822376272275522195235473437e+216Q, 5.94202303286497040346001141219106057472e+223Q, 6.382118127492160537643353652683681344379e+230Q, 1.144860031429102206755598498207317533823e+238Q, 3.486326812227187949835465276465097663203e+245Q, 1.832768040117385552841365088677720918755e+253Q, 1.692379509135740137727773957097833887452e+261Q, 2.794505326132115346915299861915404249723e+269Q, 8.405076170451043189493827526418502257828e+277Q, 4.693262451309588660736308776755416725156e+286Q, 4.961738495062629283767259212421455782816e+295Q, 1.013488586645822568937692055235633940552e+305Q, 4.084221398756118821350576889490962044446e+314Q, 3.31797255076755830584401562393461184623e+324Q, 5.556156061512309994500204693690071227389e+334Q, 1.962393306169292859108099309776943823055e+345Q, 1.496911135838772621973260501875737184473e+356Q, 2.527081774155980938068575705055676841454e+367Q, 9.682952487842774440282680190380581838128e+378Q, 8.642932154430007387844488354704403530376e+390Q, 1.846024495166690994263298662566528477956e+403Q, 9.699853937915510903638593851109203549831e+415Q, 1.29019233082477503168780727447218377249e+429Q, 4.474137533288725774889486358089933849193e+442Q, 4.170041218844572969270760095147757353548e+456Q, 1.077897308040601801221120607931770758264e+471Q, 7.981471823702425518749857998096499633387e+485Q, 1.750515936677737147078175240321968864283e+501Q, 1.177053303545360119348788135380274557129e+517Q, 2.514304327715581467017451008836642461283e+533Q, 1.769970977432511196406520490255351180778e+550Q, 4.2646343986308794030088301101938804053e+567Q, 3.657021198954671244361265926107390170785e+585Q, 1.161995022380376800254911849215938667325e+604Q, 1.426161883992266887019615450265103556361e+623Q, 7.057501509770417183799008967192326349846e+642Q, 1.471878408492178033263031885767465334416e+663Q, 1.354138353815247160487911075189635081583e+684Q, 5.760831288581247091444505472239736239879e+705Q, 1.189730645764784786336307075095066200968e+728Q, 1.254105261294047490114939349887062439042e+751Q, 7.105801021107686895390768106399523520351e+774Q, 2.28281648423858553167251131768916156991e+799Q, 4.393686187647260979367904999350735520579e+824Q, 5.362504350805858665245291197548444739952e+850Q, 4.400994460175449649406744849257249937177e+877Q, 2.580184691440319635082387832634782416379e+905Q, 1.150201187760129651179050406857281109502e+934Q, 4.158019827686647740035176845444359313922e+963Q, 1.302697158180542995105180498547801432023e+994Q, 3.78804315469310114235168697055913940647e+1025Q, 1.097277067032447599839448667453494574529e+1058Q, 3.405948056419239816971511993948200677928e+1091Q, 1.221452079059747140866097947720732213944e+1126Q, 5.469728834947448905323012416213783681996e+1161Q, 3.313684879917774900254086176181829781121e+1198Q, 2.950003898158737668709569796392213974285e+1236Q, 4.202906985201980113057532813808859421914e+1275Q, 1.046450503925266293149709371732059242222e+1316Q, 4.986188211546778571602783903171292775302e+1357Q, 4.993338241348295306012588782782184198345e+1400Q, 1.157626881881270934779792801922724477911e+1445Q, 6.864630422932014748167413728259165043085e+1490Q, 1.154057064570998816035086816885432531351e+1538Q, 6.116573955685408991594979059166788310164e+1586Q, 1.14033623849635356868515171774059586735e+1637Q, 8.373064137120280572431494406435413559046e+1688Q, 2.720845114960258853420084277841813860219e+1742Q, 4.413059336919928865301216672097302323433e+1797Q, 4.044822257870394599276743613321249907269e+1854Q, 2.381229351958722417177138670512610760689e+1913Q, 1.027611652914733400897244248728364151035e+1974Q, 3.725531848970894050805213745804832393498e+2036Q, 1.306062165371036629009984640124042230203e+2101Q, 5.118934916287102017127361633252835489039e+2167Q, 2.605313756841350663666908726854909254754e+2236Q, 2.009526310597759100040671805249352251293e+2307Q, 2.754855306228952463612144173863317999165e+2380Q, 7.912081217360857939375130225445886436671e+2455Q, }, + { 7.967275909080119173260394105433878829225e-2520Q, 1.018328235596330817906641738531405586075e-2480Q, 3.221582354315018745133234535022765889901e-2442Q, 2.577837396125923566854501272739510663846e-2404Q, 5.329692879048212454158155682964916728316e-2367Q, 2.907510479746435248283830679207105484516e-2330Q, 4.272515272958308108570054029079326796036e-2294Q, 1.725920944512128844318784735433112719801e-2258Q, 1.955365288532498067112004500362223834133e-2223Q, 6.33672146224698551106793067421941599521e-2189Q, 5.989055317923577956367893208101537342355e-2155Q, 1.682695935085939711542031154300739978911e-2121Q, 1.432104065344727957976083590066231975447e-2088Q, 3.761027283440035276506274748665174438543e-2056Q, 3.103973882224385163725384328628978101726e-2024Q, 8.196024681248225777873004659982426819745e-1993Q, 7.047501943265264073804265038957515028249e-1962Q, 2.008020122030836044260092764882735792941e-1931Q, 1.928585386478996757051377061536226588734e-1901Q, 6.349936504026115699331271816067930197654e-1872Q, 7.287319738451912662822173117194663954913e-1843Q, 2.962993354437338667093054088027903427137e-1814Q, 4.337549035352199493070093298251396522747e-1786Q, 2.322667953684500393631534979205588114281e-1758Q, 4.620940493203111397883251148877460552652e-1731Q, 3.46849175006702283349982309232738215393e-1704Q, 9.97197469066253825213923346003213563319e-1678Q, 1.114585267326982901794838942479030932334e-1651Q, 4.914714563824319863256125426084037061236e-1626Q, 8.673588082334046069888398076950448507162e-1601Q, 6.214129581324762232775539905301734104147e-1576Q, 1.832790291938882421191920578959728374086e-1551Q, 2.256171136581882657900944651081598896733e-1527Q, 1.175009240711975388097085650021684742673e-1503Q, 2.62368977120029668942611642547157610416e-1480Q, 2.545000194584350068428255601470918881705e-1457Q, 1.086378274323549748723752477385721065205e-1434Q, 2.066897696539443930872351598446447515579e-1412Q, 1.774772157298710208337196463122169403564e-1390Q, 6.963196512155587707171477008714118644169e-1369Q, 1.263545167784085371065018714077427939719e-1347Q, 1.073200483671541400965432755811734945193e-1326Q, 4.317082212314184926835882760831574340329e-1306Q, 8.32053604965395861253463941646191625903e-1286Q, 7.771734618559071081107688528229970310621e-1266Q, 3.557686044605213104209030012940037706499e-1246Q, 8.070528916876981426176871131000861955335e-1227Q, 9.171668926752907939883632747855449181794e-1208Q, 5.277894673647840384307719753102608158502e-1189Q, 1.55425000722110468554188982028632391378e-1170Q, 2.366680555098895290029405613091848674444e-1152Q, 1.882599225459190082401671846340953390019e-1134Q, 7.902192246540000601320781601302423345806e-1117Q, 1.767718149213402068974713376178812787862e-1099Q, 2.128098208048214966164629867555770669406e-1082Q, 1.392051591976656401133824170145523168896e-1065Q, 4.994719960920755555531504146997873320923e-1049Q, 9.922076126548449719468150236395605850173e-1033Q, 1.101311891894924117612397672953984177965e-1016Q, 6.892130837218420956087582351392004213975e-1001Q, 2.453524489921414170305853712838952078459e-985Q, 5.012096823429272595408207301327403858682e-970Q, 5.92625397256846848563576817503982351625e-955Q, 4.090293049633920583650165040912103911016e-940Q, 1.661753006709297398826495491631296133997e-925Q, 4.006680757962520202236462553833604795318e-911Q, 5.779925457403545302890808903391113431044e-897Q, 5.02848909102539886751126002796168835514e-883Q, 2.659105037910872144852205745069380936102e-869Q, 8.613275102396233614296997155697707276489e-856Q, 1.722011941149323047500322262512900155623e-842Q, 2.140858770279205828196814199482763570967e-829Q, 1.66733371240769894937624182878072907988e-816Q, 8.193863812957329774412230281809513275895e-804Q, 2.559097724964727559938640778629276385374e-791Q, 5.11527606584153978380615675677219021198e-779Q, 6.589313932434497001234913531610383100585e-767Q, 5.507550516048129444656311084411711270861e-755Q, 3.007020142650284579022887900120691321832e-743Q, 1.079545570904019147607701162275175357017e-731Q, 2.565046260212020805453775161290492247735e-720Q, 4.059551213679369050731379503131672168122e-709Q, 4.306509253842678754390905922017562669864e-698Q, 3.081277425837841400021155036519520671543e-687Q, 1.496049756497725324561151798326667339225e-676Q, 4.958858781223578709469932084235076593428e-666Q, 1.128776827757009886737844677649633126831e-655Q, 1.774824438031273259221674871341421861954e-645Q, 1.938718628529578614339845914362132261711e-635Q, 1.479580889476868168834482402842115319684e-625Q, 7.933076560959459481932759219061929332943e-616Q, 3.004696447884786585684784182577260233339e-606Q, 8.082686940259012888778153139360914820557e-597Q, 1.552426325390131757062306746548839627663e-587Q, 2.140102119938385745802494123096422882483e-578Q, 2.128429453740900159670547695806420238397e-569Q, 1.534912683226941140367083241016749973227e-560Q, 8.066256819954909759673837062709789215779e-552Q, 3.104238792273031330484452756380286340285e-543Q, 8.790844945644080595293305902463382662207e-535Q, 1.840618291261842948588744341179843557088e-526Q, 2.862777784664184513037699746755593033611e-518Q, 3.32279837181041061553234462323492937839e-510Q, 2.891235095586630121781435408715459157878e-502Q, 1.894375038101531296060137038995059871087e-494Q, 9.387752849968810937579512549662307625661e-487Q, 3.533872224235785186218523407943928105631e-479Q, 1.014810086945078087894935086994004318066e-471Q, 2.2324717569626557013949548912766445982e-464Q, 3.777884776738657261205533855337240737918e-457Q, 4.93786751664639347798897645870074547883e-450Q, 5.004920895479663677446497643024618520578e-443Q, 3.949427686727102477250133390725874321876e-436Q, 2.435767559087040930634684216214147613966e-429Q, 1.178587076580330886964544022890917953058e-422Q, 4.491023912606049854427428106653051102875e-416Q, 1.352680705533714285427651131064219006969e-409Q, 3.232175229700192859974514601701313013174e-403Q, 6.148979779244951167078060501065764873822e-397Q, 9.346618557699555690197507374939990133164e-391Q, 1.139095638725565354570660165510495028107e-384Q, 1.116882736988512594287339256913954444686e-378Q, 8.840180431626061992850152992185607078407e-373Q, 5.667122232091659511764331764542937857446e-367Q, 2.95210171074869287556924947738750388968e-361Q, 1.253616557485983210249402924206741962015e-355Q, 4.353499566130717956144486781651064963442e-350Q, 1.240243792752263780952771158279701378416e-344Q, 2.907393260879684488880153095982345233788e-339Q, 5.625244131026162975882364543895958678556e-334Q, 9.009739108786675273276970385188647555895e-329Q, 1.198087756353396256356294131034463223006e-323Q, 1.326548775108682048756687665666583870046e-318Q, 1.226448111135483120974035454571292238148e-313Q, 9.49468504349439811133142768178704940847e-309Q, 6.17181101323002240744175397407031718684e-304Q, 3.377707669589353604487497237523332765898e-299Q, 1.560512872109863571844393575758792286036e-294Q, 6.102236208573128122093888164692727956235e-290Q, 2.024929301988449522883491544065893159998e-285Q, 5.716567372402404783728122475078537540453e-281Q, 1.376428575092612476633988432370532525456e-276Q, 2.833585596240407856348272111949931080586e-272Q, 4.999632626016703452297995188196308401074e-268Q, 7.578746796653130874873290482021210756378e-264Q, 9.893195588497945068609978048738483752363e-260Q, 1.114710731734833240955445714249086995456e-255Q, 1.086588366772543409228146502433142567442e-251Q, 9.183764349360752966385023754968415218934e-248Q, 6.745119200393479925712383108023813390928e-244Q, 4.314368731526732239250885070923775496171e-240Q, 2.408432510386531771142800736481978254764e-236Q, 1.175865689260863816680634119022166918193e-232Q, 5.031403985679824041735142472001594305874e-229Q, 1.890676059338627176469623532390876131616e-225Q, 6.251957030364086922481747023515455758277e-222Q, 1.822832110299319014901260869272013670981e-218Q, 4.695228558883599546359502992313929137066e-215Q, 1.070485041990253205844787613056619988479e-211Q, 2.164411061170786494289133504038746022617e-208Q, 3.888149057834327052303287962939662414968e-205Q, 6.217077650284409358885672093877174576393e-202Q, 8.864490176680272259518995033084329107486e-199Q, 1.129060018025413968826902845797468943636e-195Q, 1.286873424792917053839022851662100381367e-192Q, 1.314795291417549889849051617164565642141e-189Q, 1.206202769586152888447188064879769552541e-186Q, 9.952847031230403569515431731634107940163e-184Q, 7.398656727363347668880677233416039563592e-181Q, 4.962946760441355726269312188537195172159e-178Q, 3.008841426137019577290269695130774172341e-175Q, 1.651250489636657038514219704463078872032e-172Q, 8.215822870116426810896344350411473632426e-170Q, 3.711707137271423160180212748621691502977e-167Q, 1.524862581521331587673406461025625884709e-164Q, 5.70508150602545345515626627261166302806e-162Q, 1.946690864521063015447882642259593648046e-159Q, 6.066751495971832907946605731816433411601e-157Q, 1.729218890749008111955745508052309562408e-154Q, 4.514184397107540977965003426103559880641e-152Q, 1.080776439193461578737828802075769030367e-149Q, 2.37630514513441024032933923861341092174e-147Q, 4.804539863300466911851715067980750771531e-145Q, 8.944359411396089882336022433298240800498e-143Q, 1.535148433653602528126818304598839769627e-140Q, 2.432217566861172517425147458255035408531e-138Q, 3.56159164851978783755994271005743068325e-136Q, 4.826206194592030239608964808604974782439e-134Q, 6.059123883793098626317651235341860311477e-132Q, 7.056186855737804734056421101084240937306e-130Q, 7.631197540594714170535291222444902661627e-128Q, 7.673190056935230923349040383785807876549e-126Q, 7.181420901238450533979697028062603205731e-124Q, 6.262949340804115487531782118695348240253e-122Q, 5.095149668836320992407738242504181244468e-120Q, 3.870905682539942846661487470875055347721e-118Q, 2.749201932883450268151961331830477076878e-116Q, 1.827228100144142861000456602099118570404e-114Q, 1.137673382674035107250733931604905546067e-112Q, 6.642336072005941146361966661287119272804e-111Q, 3.64028512339331626869107380312786986349e-109Q, 1.87450863444735780747041756540496602537e-107Q, 9.078133222842635422121285050940964351573e-106Q, 4.138812855052761279043494154268599225563e-104Q, 1.778000270650318764431469309976610087858e-102Q, 7.203855822800213289973969862777328396312e-101Q, 2.755303928538917650732532471686512499588e-99Q, 9.957111327196065437803034062710072445763e-98Q, 3.402816997218076148572057943527130789008e-96Q, 1.100680588716144971407937016574430544574e-94Q, 3.372653914433340593300308221192502433386e-93Q, 9.79793465921741389410002031066177808616e-92Q, 2.70089978913542155792813430020605674429e-90Q, 7.070447343835118744270507416522429771431e-89Q, 1.759128817422289300267493076673104253506e-87Q, 4.162968945574391702034525851121326185222e-86Q, 9.37779241810731989238679712769217329023e-85Q, 2.01243511678120567645753438316089357156e-83Q, 4.117122160765049554856907584525124497579e-82Q, 8.03596273765328793581294339359042233865e-81Q, 1.497514661862748564043414139894766607224e-79Q, 2.66627575240526913684138994676860937559e-78Q, 4.538860378486968408830116582994751799953e-77Q, 7.392623260932249293359287648677921377725e-76Q, 1.152810282079105430900943269743976641052e-74Q, 1.722334641963998877538919046212108072676e-73Q, 2.466982294003650362347496250523874402798e-72Q, 3.389902673647822893523319180268544603664e-71Q, 4.471576114525864494621630170567724674708e-70Q, 5.665802004349935660857687324817574414575e-69Q, 6.900180136205711399260007796162289923614e-68Q, 8.082103978670433565158160112244695539644e-67Q, 9.109949614051296700342120658333526754299e-66Q, 9.887660566787155914957022540708377404886e-65Q, 1.033978824499191800266695652953562102366e-63Q, 1.042367363142603472683903942222927019223e-62Q, 1.01360253850642711420235182625207856357e-61Q, 9.512510161747350299580075950049163390633e-61Q, 8.620693578866897400350402598749549001733e-60Q, 7.548215286708061079286950592874024396203e-59Q, 6.389002522263073684828225781548498851979e-58Q, 5.2304213467999807285495233989909068078e-57Q, 4.143618029730144849471458722659316057844e-56Q, 3.178215053889138479032361583006970626875e-55Q, 2.361375497747090350319603916992762005858e-54Q, 1.700353947901992650870275190000853698062e-53Q, 1.187181461482834292235814755757571995841e-52Q, 8.040926262915060358135936625876559056833e-52Q, 5.285800219918840044239185423363506533173e-51Q, 3.373901677142706872070242716798262993283e-50Q, 2.092036760993143554287714553393156854658e-49Q, 1.26071389736459024550376938832573535614e-48Q, 7.386967875256930161617715368501896621111e-48Q, 4.210245750567381301823721041940686239094e-47Q, 2.335212680852443576888813564758399301987e-46Q, 1.260975065550456669584777965304501230694e-45Q, 6.63174909295324620401889662345375243662e-45Q, 3.398355988046612747841700088585271753564e-44Q, 1.697476472841236183609850797662451898689e-43Q, 8.268085659326493130435461342952520749743e-43Q, 3.928638007500358866351367670626935931854e-42Q, 1.821720759355284457527987958132111168364e-41Q, 8.246860808847354549111270503081351496818e-41Q, 3.646064568177825762669789860457940857642e-40Q, 1.574882443754619623541008196995070064258e-39Q, 6.648395042005376085395386282489705285924e-39Q, 2.744004024875076628507083135601534661763e-38Q, 1.107653420681031633888214018454568434403e-37Q, 4.374454244420129201505123651246128890729e-37Q, 1.690799049659970724466269924181801546001e-36Q, 6.398132877939130220610010163346102651855e-36Q, 2.371103019047426350497793704573373960345e-35Q, 8.608431951088272831647481050248077098396e-35Q, 3.062756779443238602319536870269819051555e-34Q, 1.068198659583210038973746806524748536317e-33Q, 3.653227544700454531305797630670503225392e-33Q, 1.225515001519945073404871285296100665347e-32Q, 4.033738539559432392661992185921035446855e-32Q, 1.303082875824869971414005942159261214305e-31Q, 4.132734479820748852758173795520437853314e-31Q, 1.287147098350869770886623826581464367999e-30Q, 3.937913659653477883694284311172054333025e-30Q, 1.183782052799315485733017592458599891775e-29Q, 3.497544328892517187831545842100287032186e-29Q, 1.015914466727185220837422441064387754207e-28Q, 2.901804990894522420127448030270270503252e-28Q, 8.152849127534845411362622488936266274172e-28Q, 2.25367809417179806852681105934818375896e-27Q, 6.130912603089867849064196318283416796732e-27Q, 1.64178734291463510902060102240353937311e-26Q, 4.328857792089817047005743679842334899927e-26Q, 1.124084164810469092376383461223505192932e-25Q, 2.875386797856971912981506559923184846915e-25Q, 7.247144107627277984808094958723307043434e-25Q, 1.800156961022553615025218914199947112878e-24Q, 4.407829997906358459896106459287958053e-24Q, 1.064159909656974016807111538128709340566e-23Q, 2.533679394987778730189472745065558452445e-23Q, 5.950490597088776019748683578472561818409e-23Q, 1.378803645178565675477663430920122567538e-22Q, 3.152763311863490040779656649906049613957e-22Q, 7.11555798463800555819351867739855080496e-22Q, 1.585415769087416794558428166428232224083e-21Q, 3.488033184094363861639854904349888742437e-21Q, 7.578906150306100545423157126174164576149e-21Q, 1.626690309979793927151914765130208588376e-20Q, 3.449517091693030714666710333959651136005e-20Q, 7.228499497618258130899446599161547874565e-20Q, 1.497112865860816048764094432862181982629e-19Q, 3.065182400463867687382144796026279060458e-19Q, 6.204847831174082599165287964674983928818e-19Q, 1.242096716667761537684098553412968423806e-18Q, 2.4592597959525768067059363490903017727e-18Q, 4.81672896226015964045793790028985306539e-18Q, 9.334084950562834068284127795290557105276e-18Q, 1.789925014943490672474409292990156919458e-17Q, 3.397130025636848212544218713465822505885e-17Q, 6.382243159919550687632232044625421720437e-17Q, 1.187098865362206582279245836506254018227e-16Q, 2.186352889657557664550744789902758712378e-16Q, 3.987859744831167732326236478627157162656e-16Q, 7.204620697873539912480086209051030823416e-16Q, 1.289431790155955917841351554233503242944e-15Q, 2.286467374882308613486205332118436402814e-15Q, 4.017662252161183047836187284910855861237e-15Q, 6.99656785784342408232633767751107637346e-15Q, 1.207703613093171430146873960414485693713e-14Q, 2.066611834161126240026963698131523479667e-14Q, 3.506221191208017396780249818547308545177e-14Q, 5.89874025912113410833559535930664457693e-14Q, 9.841824583826900982294185470382304100122e-14Q, 1.628711979356644195640673557575737399349e-13Q, 2.673747297244544464041144412989940524217e-13Q, 4.354698030762685456146522867684472784597e-13Q, 7.037375613470243013811036742819534450189e-13Q, 1.128576426207602409839136130428624894649e-12Q, 1.796265444979361204491866760276216506487e-12Q, 2.837790274411961929167645624257533119362e-12Q, 4.450517051624898219124643410702559319937e-12Q, 6.92963583879943637167224732796899185484e-12Q, 1.071343498653279805152831768444006526848e-11Q, 1.644800798713549170982066141603139794962e-11Q, 2.507905928632347374338630836942320447304e-11Q, 3.798122183988670139277644917971882044735e-11Q, 5.713892308950583341199546461179201773938e-11Q, 8.539758065003606420501230564062147832472e-11Q, 1.268100729620471661902817410073941033457e-10Q, 1.871113767059724245386976661776370778825e-10Q, 2.743644295142664772759283079615343882946e-10Q, 3.99833185555888171640293913723530982506e-10Q, 5.791550996315273321902088121824651906299e-10Q, 8.33905623640836900250032445405370043217e-10Q, 1.193672562105227931589388299289134785728e-09Q, 1.698789266026923550073522461535190652611e-09Q, 2.403913727893853297080383302536080724682e-09Q, 3.382686884515520208065080745279262391703e-09Q, 4.733759174712641803740945710631487071936e-09Q, 6.588541092193685952258947629496486846735e-09Q, 9.121112685152380583998835576941094529702e-09Q, 1.256082033795070258308096624958598291786e-08Q, 1.720819844523096099720474511434503885155e-08Q, 2.345498050299132447846326603361136043516e-08Q, 3.180911042916052139309955352436778506108e-08Q, 4.292583225702628201046231718407734046636e-08Q, 5.764612626060727958623931970026984259394e-08Q, 7.704397341666848653267095123338097208871e-08Q, 1.02484168952891991947754465547361714047e-07Q, 1.356926702837583879755051597078815730847e-07Q, 1.788417551503950471950015064517069882061e-07Q, 2.346525819658947020385582160747980704228e-07Q, 3.065180852876392019694236336586654765768e-07Q, 3.986495033191807496354173430939013698484e-07Q, 5.162502188850122540844684197019554711165e-07Q, 6.65720997012649014040997771515440610649e-07Q, 8.549011167117627077144919459539055163198e-07Q, 1.093350316344842739482570460075507090481e-06Q, 1.392676894662565462032126480798341973487e-06Q, 1.766917725585667241992898344161547873865e-06Q, 2.232976345560288036947373699573375726808e-06Q, 2.811125648202381706895272765136403841401e-06Q, 3.525582061468103068665653163476736687771e-06Q, 4.405158376428709913646029278948069283329e-06Q, 5.484002631927202129384801097079834656695e-06Q, 6.802430623520435693108355760476215953221e-06Q, 8.407859685487256287710959317409001943954e-06Q, 1.03558513786321915073962476007182566071e-05Q, 1.27112705917308531277560249413305391114e-05Q, 1.554956831891198412168337708959965747403e-05Q, 1.895819499809689983959597375272763044769e-05Q, 2.303815077706507768668930312189393944145e-05Q, 2.790567840555153504276820390388733949771e-05Q, 3.369410362760997145481708684122315699185e-05Q, 4.055582696403286559517626972868029344242e-05Q, 4.866446962805309592997024360400453753624e-05Q, 5.821717500966089824845365574649413158772e-05Q, 6.943706569830923930053447899093868098698e-05Q, 8.257585439721267879079897718480289417549e-05Q, 9.7916605324640385949085647909368095273e-05Q, 0.0001157766408114819489026696755064685711663Q, 0.0001365105858059673951916433332558940095964Q, 0.0001605135409048256559138258125495353142543Q, 0.0001882243723673180815859848425981422149923Q, 0.000220129105359083888832193195380277964631Q, 0.0002567644044435395558985376934615952746774Q, 0.0002987211231186489549516252551089359495587Q, 0.0003466479020167920218943287065081041086883Q, 0.0004012547932769214992784035333438157199896Q, 0.0004633168865935784338501681041310863439442Q, 0.0005336779105791366983905761533437676567429Q, 0.0006132537813759504708063524124765235945565Q, 0.0007030360689550059158765139669182449713927Q, 0.0008040953502668325012890028878715651258039Q, 0.0009175844173963607454679355479874424263829Q, 0.001044741308141107407038707367942396160755Q, 0.001186892126003470975743583081981798214652Q, 0.001345453616481502859286364987039915779821Q, 0.001521935466772907586110083455839761654915Q, 0.001717942296584680418941635241375263314963Q, 0.001935175308671765557581701564207351830222Q, 0.002175433569013882948578843986006403688485Q, 0.00244061488817701827933962177717454590009Q, 0.002732716277387093760523031790972800227035Q, 0.003053833955155494667190955668647144637077Q, 0.003406162882922376111090737904328858634942Q, 0.003791995811102684339694547552585507990223Q, 0.004213721820106255238520670138395000924438Q, 0.004673824344328191012589440091579259760752Q, 0.005174878670736688316509780570084920182513Q, 0.005719548907487502446481303679623316137136Q, 0.00631058442192985698627201889000303700039Q, 0.006950815751398609527548621000197550798988Q, 0.007643149994271354192801093440865419580856Q, 0.008390565692865655199126566293274333642062Q, 0.009196107223819374276889186313994843390353Q, 0.01006287871559507536535044833068973909294Q, 0.0109940375166376773728040945023712313313Q, 0.01199278724145422091671644293048154728942Q, 0.01306237042543906222476060243442814308369Q, 0.01420606082260259352562017237936801265042Q, 0.01542715538344503858931888643358628745717Q, 0.0167289659530203930831754338734874664053Q, 0.01811481073173395916859919022391664972282Q, 0.01958800554358856744019143892683179847952Q, 0.02115185495842169316583797633449771810677Q, 0.0228096433161443911301425779096357227542Q, 0.02456462570209342382627799804527821306298Q, 0.02642001892333428109789892692937509533337Q, 0.02837899253610309628758625557724591354616Q, 0.03044465997455174638840433200930338711507Q, 0.0326200698305684182561478766940614844802Q, 0.03490819733369493186523156261607315466053Q, 0.03731193607906478545336713244881109055547Q, 0.03983409004985797457339959837144377122436Q, 0.04247736597902870508264605012848775314015Q, 0.04524436609303125412480485866465061775906Q, 0.04813758127797071695188343575966783160027Q, 0.05115938470606436195469305247887685131832Q, 0.05431202595754248111789162569375577872956Q, 0.0575976256701728356651407164727388580805Q, 0.0610181707454887735519286127955001295239Q, 0.06457551013756707073912038813096685540493Q, 0.06827135124686695200131838960274498733873Q, 0.07210725693823589850320643270045776879156Q, 0.0760846431987396666107037402041258283206Q, 0.08020477744751167235556685358836323731335Q, 0.08446877750636786639701687175860442218662Q, 0.08887761123652361947156590658579628794683Q, 0.09343209684340379971159263353331405267565Q, 0.09813290384827947634314597377864550592762Q, 0.1029805547223161917217849662754146410394Q, 0.107975427175599384648800929258392588213Q, 0.1131177570908303240224652780558492398361Q, 0.1184076420886768784022524072852628267607Q, 0.1238450457092316689652810284506150029169Q, 0.1294298021916876848049165341926394261599Q, 0.1351616218321983257068963021357149291953Q, 0.1410400968979531369261616983876599890975Q, 0.1470647080737783262838611415820062681671Q, 0.153234831416066732619412144570512369546Q, 0.1595497457875576600290825257800962557912Q, 0.1660086407454235928297088004549011805831Q, 0.1726106248542773238830740951304465857529Q, 0.1793547343950870081915214248666534071515Q, 0.1862399424405742377120762392711272315017Q, 0.1932651682674662866336549954877868791502Q, 0.2004292870759719115746122524278836114001Q, 0.2077311399870431986348998739442376385985Q, 0.2151695442883657277414314663960325511106Q, 0.2227433039005768119334724476408616510273Q, 0.2304512200359371707379802858704110927547Q, 0.238292102022565012438636869295500477757Q, 0.2462647782683726466471199486866921649987Q, 0.254368107340013678004869448238984448963Q, 0.2626009891334426438055153641042268648289Q, 0.2709623761140977072718583929657258698507Q, 0.2794512846062298136893226330853142403707Q, 0.2880668061125078167787824382718038889734Q, 0.296808118646717980840005593177875755319Q, 0.3056744980641377677579036909396937192142Q, 0.3146653293759881203313235805942140830196Q, 0.3237801180362461983090820270519599818301Q, 0.3330185011910228622657311928027273913756Q, 0.3423802588826678418804113983776109433992Q, 0.3518653252027527789924367138981015674402Q, 0.3614737993900911492268336792036467644866Q, 0.3712059568719780542735256003769499002505Q, 0.3810622602488663480435171795984767091639Q, 0.3910433702247335339010502511824521314023Q, 0.4011501564874320933236375501478126225841Q, 0.4113837085453508612370763030338926460708Q, 0.4217453465287439745740029610957751723861Q, 0.4322366319661047574509906269685113863411Q, 0.4428593785479733817386890110895733244681Q, 0.4536156628925687094231449505202515619854Q, 0.464507835329626572328505104590646627441Q, 0.4755385307208097937482079206198446406668Q, 0.4867106793370311448540891233670977920386Q, 0.4980275178150015090250825860923349908605Q, 0.5094926002172848568191354394503605415964Q, 0.5211098092221129673730069757438879031618Q, 0.5328833674711906123911808005586354523419Q, 0.5448178491057112741679836363725011074712Q, 0.5569181915228102063547315863613788776984Q, 0.5691897073867122497869745706167773132242Q, 0.5816380969308934474793883532843665800915Q, 0.594269460589676005299802716361632023448Q, 0.6070903119998240471222356070870425052955Q, 0.6201075914149121414331976341764137620912Q, 0.6333286795775096670077450936959654630057Q, 0.6467614120965724037497804104943555382337Q, 0.6604140943798696982054270851497081511967Q, 0.6742955171738133585239271173870307816064Q, 0.6884149727657060911128222112013278833933Q, 0.7027822719062066643044698811599154029693Q, 0.7174077615127308354587586170401139201738Q, 0.7323023432175871214633425313512827364943Q, 0.7474774928279014552006592596985716213354Q, 0.7629452807678324593654003954321067804243Q, 0.7787183935772384484317206900527945313626Q, 0.794810156544848547172767589390981649492Q, 0.8112345575581350364947114757891812390685Q, 0.8280062722565051964220310805112035656865Q, 0.8451406905791530670663872308556803104808Q, 0.862653944803960940002105223911111611703Q, 0.8805629391792451103891710796280884448635Q, 0.8988853812559305452871967488187545907845Q, 0.9176398150339469056412351899494533187875Q, 0.9368456560432984078524666287687994133458Q, 0.9565232284874095042002045886475279507954Q, 0.9766938045840272767944337301321751065917Q, 0.9973796462472128045133642631801931333523Q, 1.01860404926282392956317946592394034531Q, 1.040391390119430800501306096390484332391Q, 1.062767175666867240516297891529939479756Q, 1.085758095785663642281105802222348812045Q, 1.10939207926249369916261716500126785443Q, 1.133698353079565973147506826247703249701Q, 1.158707505339675825255735779161136390472Q, 1.184451552063483495095045621317392891301Q, 1.210964008111586732614521606850934884333Q, 1.238279962501205323185680973891105950334Q, 1.266436158405892106534863447479802864076Q, 1.295471078146741458304256385907446823312Q, 1.325425033505202083685015684659959438256Q, 1.356340261710947294764081629105735343643Q, 1.388261027483455161025774293888757855687Q, 1.421233731533158113469992887140017312801Q, 1.455307025957405656451286211771500914052Q, 1.490531936998228868219023421638164269274Q, 1.526961995663202046567211183531908173458Q, 1.564653376747784111876581362830437011253Q, 1.603665046837629160778144804262475653057Q, 1.644058921912742785217971171041985143034Q, 1.685900035222313480214992667532713310022Q, 1.729256716149878219924242767000386187611Q, 1.774200780843528793008066259722862522388Q, 1.820807735445503515984476325588028533978Q, 1.869156992820145515977178445445390578286Q, 1.919332103749290742415019782061183726939Q, 1.971421003640165834597778573110233965466Q, 2.025516275873364649088115856648097485223Q, 2.081715433008021275938209590135990804757Q, 2.140121217158552655052438896015999577182Q, 2.200841920963014547929530531274604977917Q, 2.263991730677979497484300076901683513364Q, 2.32969109305976045411657347024763207472Q, 2.398067107827710058779643401999432795631Q, 2.469253947653258420191531652724380454066Q, 2.543393307779451047507153399185346597841Q, 2.620634887551268158229579783397916906989Q, 2.701136906328329337203785565785074072196Q, 2.785066656460237449889254046340672661742Q, 2.872601096232473677614318257460754228219Q, 2.963927485939276452660257201800769243529Q, 3.059244070511369011437875195340374346818Q, 3.158760812423005873912952719525474220384Q, 3.262700178927088806749953484425989249023Q, 3.371297988021823798897713011575447983367Q, 3.484804317940613202084006553747118493489Q, 3.603484485381990625764882737049172673747Q, 3.727620098162165171514708146288863084124Q, 3.857510188483308323724907886381561506691Q, 3.993472433570707806928526443290607188682Q, 4.135844471046451472454246597080688613615Q, 4.284985317082080327173205151052609770788Q, 4.441276896113985089457451399096067523765Q, 4.605125691720244026764370781104263535342Q, 4.776964529153930976873581660867167367634Q, 4.95725450101436623824090639311762907648Q, 5.146487048624035738339801115424373145069Q, 5.345186212875773055646526104283213166619Q, 5.553911069634338220218711432966624812946Q, 5.77325836623218909927059759764589584879Q, 6.003865377206048605761449274343927216903Q, 6.246412999195612054604668256261603981218Q, 6.501629106887186763618395996193518237451Q, 6.770292194054217171968109306745209606844Q, 7.053235326147045417971320097171996692265Q, 7.35135043354224614666015033130666518755Q, 7.665592977507008524711768710447822251596Q, 7.99698702419947858650763841033117635338Q, 8.346630765648955546734771430943712584567Q, 8.715702530682195108316710736134856148585Q, 9.105467333230856750332784441560793915267Q, 9.517284010423279804954247067378435207565Q, 9.952613008390899735914523387635646169422Q, 10.41302487987290341264917855291653594177Q, 10.90020956455793654418731784931574442836Q, 11.41598653074432960761644356555484658751Q, 11.96231586542698517926431253288706983627Q, 12.54131040943894482491352029147685616503Q, 13.15524904491223096736253493917986547645Q, 13.80659125421566013309472641076367137531Q, 14.49799308283537068733806522611592929918Q, 15.23232465356644138323597883223098213734Q, 16.01268939608506359051333506048449232573Q, 16.8424451747018194731026127671712692775Q, 17.72522751812091969571786639162509975806Q, 18.66497517864721511431497872041775884551Q, 19.66595827483338098446967472260739788953Q, 20.73280930143244666471574442281522903193Q, 21.87055732415900772060659367071969224017Q, 23.08466571467196402575438824917868654178Q, 24.38107382395057915687200907586246892126Q, 25.7662430405051812966499914509625384785Q, 27.24720773440068300935745005728667380869Q, 28.83163164974229758945104220936171273136Q, 30.52787037807261230893713949085699006405Q, 32.3450406241987409077896619933344018561Q, 34.29309706561872681849669817137072613286Q, 36.38291770845545162245476827741032427239Q, 38.62639875836956225627789882526940946526Q, 41.03656015631005798746236445920699096398Q, 43.62766307847848111679875785712898620598Q, 46.41534087019270662202361582551787873513Q, 49.41674507751608025548331094469808937291Q, 52.65070846212654381646552716106077643221Q, 56.13792713806019302031335914182740881889Q, 59.90116425845236114237707095933490569938Q, 63.96547801176112688533109691101640809997Q, 68.35847706663356290654056305516520187869Q, 73.1106070400535228943010840853771922367Q, 78.2554720634100436673165461770242295508Q, 83.83019609580841382274286001915828318548Q, 89.87582929516635773217532104021295646478Q, 96.43780551924200423365120382987901990037Q, 103.5664579069193585087895746723625879788Q, 111.3176005037851754525798266671368531998Q, 119.7531850674833499641095701349550588967Q, 128.9420435435961078207576974725019132169Q, 138.9607282724984871708695514001995649591Q, 149.8944638077825781408536567743182992156Q, 161.8382263398671525938367526689287312097Q, 174.8979691743083696073045128037176486302Q, 189.1920155721483495460012542161168057521Q, 204.8526435891665175913537920041964014778Q, 222.027891434725956190837338565467777867Q, 240.88361640690763753526746528298183629Q, 261.6058457649334272046319924765364648261Q, 284.403464110476071641090421744246851318Q, 309.51128913049882030120008084966685685Q, 337.1935961013210043006610512490274375597Q, 367.7481615999600937711438359582960700752Q, 401.5109086931381617979355424315925378221Q, 438.8612498100309866908178648997732329971Q, 480.2282399512316532893085494373602185103Q, 526.0976723225701163012986065722476344299Q, 577.0202714839153277613560365269689534811Q, 633.6211663623286914660652375227156227858Q, 696.6108578302568399031998061512477922416Q, 766.7979339996213953902457962279823199983Q, 845.1038321483961377544033152655484401883Q, 932.5800007502418686784878634625973295461Q, 1030.427880205268371607863481564260421702Q, 1140.022198738619409531305753764053160504Q, 1262.938173179340126267770568255475671177Q, 1400.983316165672812706630096023677023453Q, 1556.234685661799166419834076272895832667Q, 1731.082574302171248664168847453614878774Q, 1928.281830862719311465180216556548647829Q, 2151.012241278362996194541735020086674113Q, 2402.949680908323672668281479483735120957Q, 2688.35009405274898539046388166782344203Q, 3012.148774428996002817780038366771869698Q, 3380.077927947738665430980404057153553452Q, 3798.8061171273287816025804901302085407Q, 4276.103940178038843575493542846970132437Q, 4821.041218620766468858314278886473414916Q, 5444.222094388470795213327524033646097556Q, 6158.065819431147727245029087643341223611Q, 6977.142718757731621969847227843666046181Q, 7918.57689772303460428259761072791249996Q, 9002.529841616973008609731087967074460965Q, 10252.78224006547697358532192963572223849Q, 11697.43531120386115196874312407799521273Q, 13369.75779118806422297716318991439523796Q, 15309.21083364664327603498100930983535561Q, 17562.690635400711230682290340971331153Q, 20186.03805526835731073576014831323115031Q, 23245.87631298432720823386094470123690508Q, 26821.8526708964660159886933177732467881Q, 31009.37861130203017968748996249105326523Q, 35922.98645004505473991896385042800280479Q, 41700.44988478085183088793644390235506667Q, 48507.85335185738720597387629792697758441Q, 56545.84243439263590453434852169343975209Q, 66057.34773622772120970119305119425356007Q, 77337.15125150264720189777207255380428642Q, 90743.76204222132276487959174812557638943Q, 106714.1931345439161543996792387468025379Q, 125782.3919792783606644548980631212452294Q, 148602.28308268868913284386494314759249Q, 175976.6472537126831529901228629810350888Q, 208893.4054123648023151893924130651509251Q, 248571.3198896581872265252528072315261787Q, 296517.7041099588785074932688713451965026Q, 354601.4842046107884858345245389612826445Q, 425145.9388942126878002415502363163400429Q, 511046.7307492540007761231679727362111046Q, 615922.5313638820825468503152050330940154Q, 744307.7672522774013301855992769478990101Q, 901899.9500280627208570829224628231273515Q, 1095877.943017809647466283294609129783732Q, 1335312.680400192900473900972313608959584Q, 1631698.732799417297778849111829227960256Q, 1999644.301287932721508706558730228833034Q, 2457769.533243204063209231606836355450074Q, 3029879.601126654923164320051829081011141Q, 3746501.296107716197697994644755801894388Q, 4646902.065144207843314545735079873944726Q, 5781751.367051714701608613666500464883081Q, 7216639.965420261461783043861588641172554Q, 9036748.91103818439407145784950842727797Q, 11353064.30295396674362518583710002098171Q, 14310677.38848294383826734043939982225179Q, 18099907.52814647757667209831825354212464Q, 22971259.6668891917836879617589957239566Q, 29255608.85808781354322251315088609515549Q, 37391535.59237359316460832559373862826806Q, 47962479.20390166985661378587634109109441Q, 61747421.18114908020763006555364067577321Q, 79790283.20014303517364767024983720002342Q, 103495309.7818322791392225142306514842407Q, 134758668.4335062392784062691770869168908Q, 176150727.1167647396710291203195515696546Q, 231169523.1730998536214569360302706436015Q, 304594644.4399651635506297387509567217169Q, 402983315.5328752866261842165179493486228Q, 535368712.0454349728436136721216726833139Q, 714247070.3053378406139506672831438081902Q, 956978978.7740373778892004432884152696425Q, 1287787251.056266365052170195833743740423Q, 1740617888.192125045084695206325485163025Q, 2363255270.596386879033770262261785331955Q, 3223268243.013810967426011910089526282321Q, 4416641191.505012065410596295491828581351Q, 6080361037.679268493630106361893438552833Q, 8410860300.522297192863904820721664748136Q, 11691170810.23185446900657258020662184426Q, 16331097466.34382519842012415317299709164Q, 22926949953.32506221058163368461899055449Q, 32350801251.34441900313971832417983264306Q, 45884550887.87373756921169916820389200205Q, 65422328991.26591065899030653729434101914Q, 93777690083.05024525805287034041120136343Q, 135152344877.9312446339111822592163115366Q, 195855262619.5102394227400235042902030497Q, 285411966950.5744584463492472652528305332Q, 418285339123.4088687905886483684441030554Q, 616560216997.1507015559128477210327029614Q, 914155798247.046721897379660004085140681Q, 1363474103153.313475332332520737128454563Q, 2045955806530.38080332307163606468874395Q, 3088941238912.347778181637746413811180547Q, 4692768203830.229326011299203618570047404Q, 7174593389222.668179510729483054183954121Q, 11039707421424.7535285760553205782673006Q, 17098339814642.30883189402376214028857248Q, 26658220492645.27096615518476281285140601Q, 41844137833284.34059723603044347303078534Q, 66131822092212.56260433143407179128676762Q, 105246004103885.8447522437221674794658493Q, 168681559938365.0716704855055188081332796Q, 272298230587943.4228747819094080068890302Q, 442778332914208.8581203935475801325800709Q, 725340820090340.5850347950296827399214103Q, 1197189129009285.106993300968997149725738Q, 1991130686955199.032617972879924186900084Q, 3337378010666735.506952950406469988115707Q, 5638099922749490.406581662527138521678621Q, 9601427499741881.211823807926750198760527Q, 16484254092349348.98845372947631486314024Q, 28535723974924115.84032543376000631602713Q, 49813965452361994.64837345276433255672811Q, 87702782408500507.02084267463945306822658Q, 155752125029829556.4155463030004333389455Q, 279043670263039211.1950144058463979753731Q, 504415149791330774.373714179037049083309Q, 920116740121384961.3827433654664139990454Q, 1693942563317466607.969360487779734224803Q, 3147881813588503606.949687187530927219109Q, 5905629394327348620.964750033118718606609Q, 11186830170429972683.90503304219913230732Q, 21399669223814878252.89102214192683014818Q, 41345985808186444702.65217417004483350894Q, 80696386697395085475.26410049325816995634Q, 159125037274329006606.8786857330403125667Q, 317071329836898082746.6238825600530512982Q, 638529399076067500974.9466574352370019617Q, 1299818924097534326158.990461297267263975Q, 2675078654074978206518.637506117225931Q, 5566944189022631213362.099038457498976086Q, 11716552341597990248990.5171435566483995Q, 24943805360858062472816.00063661308666544Q, 53725930189976218263874.47358413133583937Q, 117096316957750403564988.56304888156271Q, 258298292038703721390495.8236396936501247Q, 576767877261231270067849.8484954071029679Q, 1303963227039250295013435.358818079135299Q, 2985377159576379451118689.073633893728235Q, 6922912113704827260367186.083906017707785Q, 16263788067632228522850044.30274061276946Q, 38715669422591640446273220.48107692525781Q, 93405902326795746218849693.41808866100623Q, 228442062263956655676707457.4277829780059Q, 566480802429004551807161785.525553048924Q, 1424611114198876208195667756.664348169039Q, 3634172949857829218775326055.022683993536Q, 9406122364586675152583301141.322786625963Q, 24706464444758897130981477914.48038397415Q, 65872820457540932835165401933.67205736797Q, 178319944111489749419279438635.2410294258Q, 490225068350940521098480834251.6808904126Q, 1368984772740533848004072374113.409441503Q, 3884333014472347772834359801746.655971535Q, 11201029764013440779432129805270.58958674Q, 32834751787829632611461325466661.61440042Q, 97871488077698794764611261629326.14611831Q, 296714970484721897998030463296972.3588181Q, 915165168173240309272518702527005.381633Q, 2872460267173498910803623624768017.743058Q, 9177464747767130953083654377275067.095958Q, 29855687257363621764846076009157648.30726Q, 98921454300453615088000828632641016.23094Q, 333916858936387164243193277343677648.8645Q, 1148677119756490680705739927834502644.262Q, 4028085735873633572809913571370067079.051Q, 14403629095536081310122394964760721828.66Q, 52535284391711770924959341342130057524.83Q, 195511238702341217234148056362961569426.5Q, 742628359135587348679681010616409214772.4Q, 2879985786290129359256278011916116854096.0Q, 1.140696796840996797711738648003995766426e+40Q, 4.615889998203199535641248805067886524741e+40Q, 1.908941368569039653622830158192604926747e+41Q, 8.071058712835471546948188653318290734289e+41Q, 3.489959706112432919449108947044335064462e+42Q, 1.543888386814652700671726911000678239128e+43Q, 6.989932474233277622942141615547447627292e+43Q, 3.240038117762964872837102805973332306521e+44Q, 1.538183968209712484725068871595387907532e+45Q, 7.481883824192840270769874827358924746817e+45Q, 3.73013225339343201187931343434453690825e+46Q, 1.906851076505672829935280449453775492013e+47Q, 9.999077656071522270351775782972854776915e+47Q, 5.380563552050893470837576599671463394205e+48Q, 2.972330032282961488357047932157273938273e+49Q, 1.686348374699422063673300554972483611095e+50Q, 9.830168535442368803758339268296974599245e+50Q, 5.890108429190751064006128529315046824849e+51Q, 3.629296561939369243399179077578354993584e+52Q, 2.300645004501572067249374084078975050572e+53Q, 1.50106294849063099901010627951209585913e+54Q, 1.008480606717589095366587976999767304221e+55Q, 6.980007119035887928080977649978198675152e+55Q, 4.979288841677991603006522250488653330001e+56Q, 3.66276106448839180486992300970231614026e+57Q, 2.779646718727500962719473248533230654228e+58Q, 2.177326686395961419408952027332377399652e+59Q, 1.761274961525829532053705828024510976734e+60Q, 1.472042344123250900757337524678434441804e+61Q, 1.271822455421028839508598095571294694327e+62Q, 1.136508544602098866393539277964124525428e+63Q, 1.050968050635916077523427282417608640335e+64Q, 1.00626207712914662753370159827651041146e+65Q, 9.981030000833852218070495344493841448017e+65Q, 1.026180847075813778541059391701842979761e+67Q, 1.09421374737140946315988080967962942332e+68Q, 1.210763841397564590646317030645949174098e+69Q, 1.391069896832891097224590572614426931551e+70Q, 1.66045803643638884585898488848404012021e+71Q, 2.060428539953847004622281786713096894814e+72Q, 2.659520130664924331541795505319434146906e+73Q, 3.573013284264659144117143659354260264313e+74Q, 4.999486492804923952719809970672723582345e+75Q, 7.290439237429593217623599777130532573045e+76Q, 1.108669253112891672863961714590332883419e+78Q, 1.759370316250180690332753515259259156688e+79Q, 2.915485723182837008934603124966328270354e+80Q, 5.048461194348245760902730455814691168198e+81Q, 9.14118029796915194428405620075256632899e+82Q, 1.731992937477462342845227375134295284526e+84Q, 3.436376953072005833211777807213125461832e+85Q, 7.144658133694111972876923978928526300053e+86Q, 1.55778737763103944888409221887807238926e+88Q, 3.564561555743844052143091887908206876342e+89Q, 8.566541566276859225670891601341438867685e+90Q, 2.163923297209145308730010116371450613445e+92Q, 5.74984144627868535047457089036754294733e+93Q, 1.60839847723572274756032280074086871365e+95Q, 4.740310317452400773817968906768308847938e+96Q, 1.473168155068744631692643356229607264882e+98Q, 4.831622757046275226639687085840067067887e+99Q, 1.673775819766076748422178976772154137065e+101Q, 6.129702080773580414198288240232221663836e+102Q, 2.375195572649536955856341846366320025447e+104Q, 9.746830708765397472546215846003382904173e+105Q, 4.239588455190572482069216933841673146039e+107Q, 1.956494245370687105054870244894992250777e+109Q, 9.588102853447409054394849979650825404339e+110Q, 4.994557760892807128927411547962380678913e+112Q, 2.768146852290885169241442660307412799022e+114Q, 1.633928319786263704798907980813701003631e+116Q, 1.028156908727469064515118226996254551401e+118Q, 6.904080374041585885024483266963686212709e+119Q, 4.952411576392766271393256067965393360727e+121Q, 3.798774197493427340709475899043548697485e+123Q, 3.119209910408000389677151746883852508364e+125Q, 2.74464281329371919028887605085237578063e+127Q, 2.590837914912684682640131392851692377728e+129Q, 2.626566210336074467392696546232535266827e+131Q, 2.862979557234280901204803416309101850378e+133Q, 3.359121393671599351439597581159266025716e+135Q, 4.247313211033286464137443445775235101828e+137Q, 5.7942272714265457019323508964771867228e+139Q, 8.538645358004657015182819424098214783173e+141Q, 1.360888004282941018668670601150276254469e+144Q, 2.348723067724485698744588128779913095071e+146Q, 4.395029120308788033535362463288942558768e+148Q, 8.928228383284871526851861594213174257963e+150Q, 1.971533670422240464246243093548157857339e+153Q, 4.738589737247294610658233560831235896082e+155Q, 1.241308244941580876284153148872321788032e+158Q, 3.548824589134106728881153020185390663367e+160Q, 1.108821925774839482718156058757565092921e+163Q, 3.791568324747532283399755029435267152261e+165Q, 1.420930300659947104773952851462106093989e+168Q, 5.84453799109152853361078444336558106409e+170Q, 2.642333927756119541622130789938393830472e+173Q, 1.315018700128967486521348415446442009019e+176Q, 7.215055214056115599570975509522351983024e+178Q, 4.370972004835405599501947122396095759213e+181Q, 2.9283613461041822425605630116860831466e+184Q, 2.173040852495516111888092260762700043093e+187Q, 1.788985622982511228211473383825580284642e+190Q, 1.636634504773987713192039651921165926626e+193Q, 1.666570888998858107369856444049108728955e+196Q, 1.892151113181535234424384795106566625139e+199Q, 2.399341256020760750689416036737132433809e+202Q, 3.403990692562377717224530571668026437231e+205Q, 5.412684450566753125713167924326746292328e+208Q, 9.663735052574312957366051717393887459725e+211Q, 1.940785411690247394647362413292066051113e+215Q, 4.392532041151062373685805234839718468544e+218Q, 1.122469784801228315610393382333655697996e+222Q, 3.244792593820658963686565461190260558268e+225Q, 1.063151412606654581889047233605046614442e+229Q, 3.955995687476636211061457789343143304844e+232Q, 1.675093730347128892220647880504964819835e+236Q, 8.087770848773335454281892374161575798369e+239Q, 4.461929541005863065785797298033896045328e+243Q, 2.818594400456011731351928477247466992727e+247Q, 2.043076786152914736967629947070114858535e+251Q, 1.703020313436824993942113027133546248076e+255Q, 1.636038893251936899296016502545612941115e+259Q, 1.815418460356235422023246399959725267478e+263Q, 2.332142886850178672234463486793710072382e+267Q, 3.476404726198879520090342868431980509165e+271Q, 6.02725450669274575708398710171785543849e+275Q, 1.218304996377836253272518577114790751006e+280Q, 2.877990538823511127754633031010804415019e+284Q, 7.964996943223120262348859076890157988359e+288Q, 2.588973716628916728047311617227986411804e+293Q, 9.908669888497828069120771232809956622636e+297Q, 4.476782590934448698631648708447218305023e+302Q, 2.393946289872904750991457301609667478573e+307Q, 1.519194065472150234303611944283693040837e+312Q, 1.147184880467145335990085347869884772013e+317Q, 1.033627774385061887195237160951315788932e+322Q, 1.114329281092576402692439832629726866969e+327Q, 1.441479839401683621084678999839363913781e+332Q, 2.243859327319511203437262571615345659758e+337Q, 4.215418497025923051098094558302194889077e+342Q, 9.585829785115038185661111425389321480842e+347Q, 2.646481452232988267470696963344934626712e+353Q, 8.89784570848809579740737460434820021581e+358Q, 3.654478434391815119731593878923994274866e+364Q, 1.839328571998191153309682048643039357777e+370Q, 1.138091115297408561689593979279964151166e+376Q, 8.685420860596502744558689502785399264335e+381Q, 8.202294873735399393185427253762485343561e+387Q, 9.617622211012637558143840626406701008311e+393Q, 1.404972969423732814470812460457324672731e+400Q, 2.565898938978703228107858106775855677516e+406Q, 5.879082125410122180654821992667679428038e+412Q, 1.696012443986232559131127974976016333649e+419Q, 6.182635207061036709662140763355431230729e+425Q, 2.858535933001077693342990841750579771279e+432Q, 1.682537298081273384688483838923408088448e+439Q, 1.265575099379113494236586140787099830899e+446Q, 1.221210377447344985626110580846200012905e+453Q, 1.517665191579856561612622774652863045029e+460Q, 2.438792156389105075630091184035735481592e+467Q, 5.087970569512535749002437068314762668605e+474Q, 1.383791668577664156393179945731681404331e+482Q, 4.926818942421142280481071642006166530446e+489Q, 2.306079479408307605132901861123305364681e+497Q, 1.425163636904652491964810204050170654619e+505Q, 1.167988230033416008655199893436256564186e+513Q, 1.275046076993048598825372293330373578487e+521Q, 1.86246353592536022566810742828968418859e+529Q, 3.656923281780862954333590022998862124388e+537Q, 9.696905002869973525940370399688193605905e+545Q, 3.488948519517137250033917388900863677716e+554Q, 1.711541280860496566193503287636236147624e+563Q, 1.150354590150357338329469526604301396277e+572Q, 1.064586955227472600644681500814476378383e+581Q, 1.363399241303394867639622834102250083249e+590Q, 2.428730562379263868477135617904841079855e+599Q, 6.049324540156405309997840862794643030452e+608Q, 2.117864171596828953446343836759090767393e+618Q, 1.047807516700166731633507555828693597684e+628Q, 7.365840114672675880252522494113514523595e+637Q, 7.398145492560429927900357801839811327058e+647Q, 1.067636747584131414468100025618283209301e+658Q, 2.22639858034098687306401094797599805894e+668Q, 6.748057923046794570772294496845240165064e+678Q, 2.990257191488723121175096872976103128614e+689Q, 1.948901043872427503145006863820911627038e+700Q, 1.879581186786894369816802738913105922879e+711Q, 2.698997931735600125081085882104105417964e+722Q, 5.806794882741622880474886909554775109619e+733Q, 1.883770843607193027100793847871062947288e+745Q, 9.274404492358642603751756778289018245069e+756Q, 6.975307042717716858281521605314873677261e+768Q, 8.067850522456048441251197638882843500221e+780Q, 1.444817834210597780118974729779559393721e+793Q, 4.033842652061704730692481744304620504234e+805Q, 1.768122616586398867633690641669676999188e+818Q, 1.225400779279196264005900309164283624649e+831Q, 1.352538486275098128663407391866246559851e+844Q, 2.395022076176373866310260662550018260889e+857Q, 6.85473457159274328678409145257099377572e+870Q, 3.195043165613256224203167145283241373075e+884Q, 2.444011394541681034079796623093288489705e+898Q, 3.092132542900569483086826127272209424616e+912Q, 6.52202827899369001274608906112336954129e+926Q, 2.311918230803327273869816369617489055755e+941Q, 1.388602808524064591680879431092854078226e+956Q, 1.424970459220504800074970047827419053133e+971Q, 2.519528084028136647765117343629838887978e+986Q, 7.741747865648544410946053665346929221769e+1001Q, 4.170084664493231900748918523968910566173e+1017Q, 3.972609017709578843063743585633222829841e+1033Q, 6.753538916409713709617458845853916542168e+1049Q, 2.067628729105681113174425295794554011159e+1066Q, 1.150595286862592019698043377859855347102e+1083Q, 1.174811465056168119582538764054374610771e+1100Q, 2.222083328904688772385369058449897242601e+1117Q, 7.861682153952467469302910158034016013007e+1134Q, 5.254318461012202675141984565028119771927e+1152Q, 6.700594094583685233271878665147881576963e+1170Q, 1.647119020685994883163368465161853068246e+1189Q, 7.885690686668208640526803176415414652937e+1207Q, 7.4304751845758892706961097079985818407e+1226Q, 1.392792237173373732943845763489796692971e+1246Q, 5.249920365660960360703118769306589305549e+1265Q, 4.023402905801975410548914995317394511897e+1285Q, 6.339599284962247390595019787493325156388e+1305Q, 2.077241686093845039324765598314087816491e+1326Q, 1.431779975481430956320443955567912020619e+1347Q, 2.100465323416655119498460724075198611756e+1368Q, 6.636983859221341948458642440032983398444e+1389Q, 4.571823013121701821960348272081362696364e+1411Q, 6.950266919826043719478213435615389027377e+1433Q, 2.361135677422321798996803825169777731761e+1456Q, 1.81529414070336188314937395066678659112e+1479Q, 3.199377508347820763307843188560103423205e+1502Q, 1.309634685394754467330604052024343046006e+1526Q, 1.261723464022528810857575246242118215115e+1550Q, 2.899755666233745652203077582611886981277e+1574Q, 1.611713776270703974807271588562419300726e+1599Q, 2.19676411063602902712587963185490636918e+1624Q, 7.447023857089897627918973727754688355819e+1649Q, 6.369675504111348389431884118799197436233e+1675Q, 1.394815207171927514566140884379200385497e+1702Q, 7.936153825171883059251330198006999518483e+1728Q, 1.1910445325646918131560389884140321995e+1756Q, 4.787444622805551600670119808904041332089e+1783Q, 5.234499335419787802823707399035765773041e+1811Q, 1.581561346401448146226935104237919854933e+1840Q, 1.341800978646655211480455388688595380576e+1869Q, 3.248945821168265660658282098925159913182e+1898Q, 2.282556137907219990369095437167406320923e+1928Q, 4.731625652419454163270049779439076104421e+1958Q, 2.943806123841568264632623519839271578756e+1989Q, 5.592866921504286485703902089288874207169e+2020Q, 3.302335002048689098318554609779249829828e+2052Q, 6.169134926587465224122713900861282080699e+2084Q, 3.712967718086223830358857404823946563008e+2117Q, 7.333531367839546065849712040185078455141e+2150Q, 4.843145606030966902891830748397061937228e+2184Q, 1.089982666110516514588223374299888929834e+2219Q, 8.522650010812465527516484755846137052377e+2253Q, 2.3610765478146005801436450249132797273e+2289Q, 2.364162440159704628905098100196710729676e+2325Q, 8.731002547249769088070048025315387840088e+2361Q, 1.213938210671504830248830740465072981967e+2399Q, 6.488456377484030822273896401425291289227e+2436Q, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_min = -8.916559006047578828258918121202852111589Q; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + /* + std::cout << std::setprecision(35) << m_t_min << std::endl; + for (unsigned i = 0; i < m_abscissas[0].size(); ++i) + std::cout << m_abscissas[0][i] << ", "; + std::cout << std::endl; + for (unsigned i = 0; i < m_abscissas[0].size(); ++i) + std::cout << m_weights[0][i] << ", "; + std::cout << std::endl; + */ +} +#endif + +} +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp b/libcxx/src/third-party/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/detail/ooura_fourier_integrals_detail.hpp @@ -0,0 +1,676 @@ +// Copyright Nick Thompson, 2019 +// 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_QUADRATURE_DETAIL_OOURA_FOURIER_INTEGRALS_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_OOURA_FOURIER_INTEGRALS_DETAIL_HPP +#include // for std::pair. +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#include +#endif + +namespace boost { namespace math { namespace quadrature { namespace detail { + +// Ooura and Mori, A robust double exponential formula for Fourier-type integrals, +// eta is the argument to the exponential in equation 3.3: +template +std::pair ooura_eta(Real x, Real alpha) { + using std::expm1; + using std::exp; + using std::abs; + Real expx = exp(x); + Real eta_prime = 2 + alpha/expx + expx/4; + Real eta; + // This is the fast branch: + if (abs(x) > 0.125) { + eta = 2*x - alpha*(1/expx - 1) + (expx - 1)/4; + } + else {// this is the slow branch using expm1 for small x: + eta = 2*x - alpha*expm1(-x) + expm1(x)/4; + } + return {eta, eta_prime}; +} + +// Ooura and Mori, A robust double exponential formula for Fourier-type integrals, +// equation 3.6: +template +Real calculate_ooura_alpha(Real h) +{ + using boost::math::constants::pi; + using std::log1p; + using std::sqrt; + Real x = sqrt(16 + 4*log1p(pi()/h)/h); + return 1/x; +} + +template +std::pair ooura_sin_node_and_weight(long n, Real h, Real alpha) +{ + using std::expm1; + using std::exp; + using std::abs; + using boost::math::constants::pi; + using std::isnan; + + if (n == 0) { + // Equation 44 of https://arxiv.org/pdf/0911.4796.pdf + // Fourier Transform of the Stretched Exponential Function: Analytic Error Bounds, + // Double Exponential Transform, and Open-Source Implementation, + // Joachim Wuttke, + // The C library libkww provides functions to compute the Kohlrausch-Williams-Watts function, + // the Laplace-Fourier transform of the stretched (or compressed) exponential function exp(-t^beta) + // for exponent beta between 0.1 and 1.9 with sixteen decimal digits accuracy. + + Real eta_prime_0 = Real(2) + alpha + Real(1)/Real(4); + Real node = pi()/(eta_prime_0*h); + Real weight = pi()*boost::math::sin_pi(1/(eta_prime_0*h)); + Real eta_dbl_prime = -alpha + Real(1)/Real(4); + Real phi_prime_0 = (1 - eta_dbl_prime/(eta_prime_0*eta_prime_0))/2; + weight *= phi_prime_0; + return {node, weight}; + } + Real x = n*h; + auto p = ooura_eta(x, alpha); + auto eta = p.first; + auto eta_prime = p.second; + + Real expm1_meta = expm1(-eta); + Real exp_meta = exp(-eta); + Real node = -n*pi()/expm1_meta; + + + // I have verified that this is not a significant source of inaccuracy in the weight computation: + Real phi_prime = -(expm1_meta + x*exp_meta*eta_prime)/(expm1_meta*expm1_meta); + + // The main source of inaccuracy is in computation of sin_pi. + // But I've agonized over this, and I think it's as good as it can get: + Real s = pi(); + Real arg; + if(eta > 1) { + arg = n/( 1/exp_meta - 1 ); + s *= boost::math::sin_pi(arg); + if (n&1) { + s *= -1; + } + } + else if (eta < -1) { + arg = n/(1-exp_meta); + s *= boost::math::sin_pi(arg); + } + else { + arg = -n*exp_meta/expm1_meta; + s *= boost::math::sin_pi(arg); + if (n&1) { + s *= -1; + } + } + + Real weight = s*phi_prime; + return {node, weight}; +} + +#ifdef BOOST_MATH_INSTRUMENT_OOURA +template +void print_ooura_estimate(size_t i, Real I0, Real I1, Real omega) { + using std::abs; + std::cout << std::defaultfloat + << std::setprecision(std::numeric_limits::digits10) + << std::fixed; + std::cout << "h = " << Real(1)/Real(1<::epsilon() * 2) { + throw std::domain_error("The relative error goal cannot be smaller than the unit roundoff."); + } + using std::abs; + requested_levels_ = levels; + starting_level_ = 0; + rel_err_goal_ = relative_error_goal; + big_nodes_.reserve(levels); + bweights_.reserve(levels); + little_nodes_.reserve(levels); + lweights_.reserve(levels); + + for (size_t i = 0; i < levels; ++i) { + if (std::is_same::value) { + add_level(i); + } + else if (std::is_same::value) { + add_level(i); + } + else { + add_level(i); + } + } + } + + std::vector> const & big_nodes() const { + return big_nodes_; + } + + std::vector> const & weights_for_big_nodes() const { + return bweights_; + } + + std::vector> const & little_nodes() const { + return little_nodes_; + } + + std::vector> const & weights_for_little_nodes() const { + return lweights_; + } + + template + std::pair integrate(F const & f, Real omega) { + using std::abs; + using std::max; + using boost::math::constants::pi; + + if (omega == 0) { + return {Real(0), Real(0)}; + } + if (omega < 0) { + auto p = this->integrate(f, -omega); + return {-p.first, p.second}; + } + + Real I1 = std::numeric_limits::quiet_NaN(); + Real relative_error_estimate = std::numeric_limits::quiet_NaN(); + // As we compute integrals, we learn about their structure. + // Assuming we compute f(t)sin(wt) for many different omega, this gives some + // a posteriori ability to choose a refinement level that is roughly appropriate. + size_t i = starting_level_; + do { + Real I0 = estimate_integral(f, omega, i); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(i, I0, I1, omega); +#endif + Real absolute_error_estimate = abs(I0-I1); + Real scale = (max)(abs(I0), abs(I1)); + if (!isnan(I1) && absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(i) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + } while(++i < big_nodes_.size()); + + // We've used up all our precomputed levels. + // Now we need to add more. + // It might seems reasonable to just keep adding levels indefinitely, if that's what the user wants. + // But in fact the nodes and weights just merge into each other and the error gets worse after a certain number. + // This value for max_additional_levels was chosen by observation of a slowly converging oscillatory integral: + // f(x) := cos(7cos(x))sin(x)/x + size_t max_additional_levels = 4; + while (big_nodes_.size() < requested_levels_ + max_additional_levels) { + size_t ii = big_nodes_.size(); + if (std::is_same::value) { + add_level(ii); + } + else if (std::is_same::value) { + add_level(ii); + } + else { + add_level(ii); + } + Real I0 = estimate_integral(f, omega, ii); + Real absolute_error_estimate = abs(I0-I1); + Real scale = (max)(abs(I0), abs(I1)); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(ii, I0, I1, omega); +#endif + if (absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(ii) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + ++ii; + } + + starting_level_ = static_cast(big_nodes_.size() - 2); + return {I1/omega, relative_error_estimate}; + } + +private: + + template + void add_level(size_t i) { + using std::abs; + size_t current_num_levels = big_nodes_.size(); + Real unit_roundoff = std::numeric_limits::epsilon()/2; + // h0 = 1. Then all further levels have h_i = 1/2^i. + // Since the nodes don't nest, we could conceivably divide h by (say) 1.5, or 3. + // It's not clear how much benefit (or loss) would be obtained from this. + PreciseReal h = PreciseReal(1)/PreciseReal(1< bnode_row; + std::vector bweight_row; + + // This is a pretty good estimate for how many elements will be placed in the vector: + bnode_row.reserve((static_cast(1)<(1)< lnode_row; + std::vector lweight_row; + + lnode_row.reserve((static_cast(1)<(1)<(precise_nw.first); + Real weight = static_cast(precise_nw.second); + w = weight; + if (bnode_row.size() == bnode_row.capacity()) { + bnode_row.reserve(2*bnode_row.size()); + bweight_row.reserve(2*bnode_row.size()); + } + + bnode_row.push_back(node); + bweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + ++n; + // f(t)->0 as t->infty, which is why the weights are computed up to the unit roundoff. + } while(abs(w) > unit_roundoff*max_weight); + + // This class tends to consume a lot of memory; shrink the vectors back down to size: + bnode_row.shrink_to_fit(); + bweight_row.shrink_to_fit(); + // Why we are splitting the nodes into regimes where t_n >> 1 and t_n << 1? + // It will create the opportunity to sensibly truncate the quadrature sum to significant terms. + n = -1; + do { + auto precise_nw = ooura_sin_node_and_weight(n, h, alpha); + Real node = static_cast(precise_nw.first); + if (node <= 0) { + break; + } + Real weight = static_cast(precise_nw.second); + w = weight; + using std::isnan; + if (isnan(node)) { + // This occurs at n = -11 in quad precision: + break; + } + if (lnode_row.size() > 0) { + if (lnode_row[lnode_row.size()-1] == node) { + // The nodes have fused into each other: + break; + } + } + if (lnode_row.size() == lnode_row.capacity()) { + lnode_row.reserve(2*lnode_row.size()); + lweight_row.reserve(2*lnode_row.size()); + } + lnode_row.push_back(node); + lweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + --n; + // f(t)->infty is possible as t->0, hence compute up to the min. + } while(abs(w) > (std::numeric_limits::min)()*max_weight); + + lnode_row.shrink_to_fit(); + lweight_row.shrink_to_fit(); + + #ifdef BOOST_HAS_THREADS + // std::scoped_lock once C++17 is more common? + std::lock_guard lock(node_weight_mutex_); + #endif + // Another thread might have already finished this calculation and appended it to the nodes/weights: + if (current_num_levels == big_nodes_.size()) { + big_nodes_.push_back(bnode_row); + bweights_.push_back(bweight_row); + + little_nodes_.push_back(lnode_row); + lweights_.push_back(lweight_row); + } + } + + template + Real estimate_integral(F const & f, Real omega, size_t i) { + // Because so few function evaluations are required to get high accuracy on the integrals in the tests, + // Kahan summation doesn't really help. + //auto cond = boost::math::tools::summation_condition_number(0); + Real I0 = 0; + auto const & b_nodes = big_nodes_[i]; + auto const & b_weights = bweights_[i]; + // Will benchmark if this is helpful: + Real inv_omega = 1/omega; + for(size_t j = 0 ; j < b_nodes.size(); ++j) { + I0 += f(b_nodes[j]*inv_omega)*b_weights[j]; + } + + auto const & l_nodes = little_nodes_[i]; + auto const & l_weights = lweights_[i]; + // If f decays rapidly as |t|->infty, not all of these calls are necessary. + for (size_t j = 0; j < l_nodes.size(); ++j) { + I0 += f(l_nodes[j]*inv_omega)*l_weights[j]; + } + return I0; + } + + #ifdef BOOST_HAS_THREADS + std::mutex node_weight_mutex_; + #endif + // Nodes for n >= 0, giving t_n = pi*phi(nh)/h. Generally t_n >> 1. + std::vector> big_nodes_; + // The term bweights_ will indicate that these are weights corresponding + // to the big nodes: + std::vector> bweights_; + + // Nodes for n < 0: Generally t_n << 1, and an invariant is that t_n > 0. + std::vector> little_nodes_; + std::vector> lweights_; + Real rel_err_goal_; + + #ifdef BOOST_HAS_THREADS + std::atomic starting_level_{}; + #else + long starting_level_; + #endif + size_t requested_levels_; +}; + +template +class ooura_fourier_cos_detail { +public: + ooura_fourier_cos_detail(const Real relative_error_goal, size_t levels) { +#ifdef BOOST_MATH_INSTRUMENT_OOURA + std::cout << "ooura_fourier_cos with relative error goal " << relative_error_goal + << " & " << levels << " levels." << std::endl; + std::cout << "epsilon for type = " << std::numeric_limits::epsilon() << std::endl; +#endif // BOOST_MATH_INSTRUMENT_OOURA + if (relative_error_goal < std::numeric_limits::epsilon() * 2) { + throw std::domain_error("The relative error goal cannot be smaller than the unit roundoff!"); + } + + using std::abs; + requested_levels_ = levels; + starting_level_ = 0; + rel_err_goal_ = relative_error_goal; + big_nodes_.reserve(levels); + bweights_.reserve(levels); + little_nodes_.reserve(levels); + lweights_.reserve(levels); + + for (size_t i = 0; i < levels; ++i) { + if (std::is_same::value) { + add_level(i); + } + else if (std::is_same::value) { + add_level(i); + } + else { + add_level(i); + } + } + + } + + template + std::pair integrate(F const & f, Real omega) { + using std::abs; + using std::max; + using boost::math::constants::pi; + + if (omega == 0) { + throw std::domain_error("At omega = 0, the integral is not oscillatory. The user must choose an appropriate method for this case.\n"); + } + + if (omega < 0) { + return this->integrate(f, -omega); + } + + Real I1 = std::numeric_limits::quiet_NaN(); + Real absolute_error_estimate = std::numeric_limits::quiet_NaN(); + Real scale = std::numeric_limits::quiet_NaN(); + size_t i = starting_level_; + do { + Real I0 = estimate_integral(f, omega, i); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(i, I0, I1, omega); +#endif + absolute_error_estimate = abs(I0-I1); + scale = (max)(abs(I0), abs(I1)); + if (!isnan(I1) && absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(i) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + } while(++i < big_nodes_.size()); + + size_t max_additional_levels = 4; + while (big_nodes_.size() < requested_levels_ + max_additional_levels) { + size_t ii = big_nodes_.size(); + if (std::is_same::value) { + add_level(ii); + } + else if (std::is_same::value) { + add_level(ii); + } + else { + add_level(ii); + } + Real I0 = estimate_integral(f, omega, ii); +#ifdef BOOST_MATH_INSTRUMENT_OOURA + print_ooura_estimate(ii, I0, I1, omega); +#endif + absolute_error_estimate = abs(I0-I1); + scale = (max)(abs(I0), abs(I1)); + if (absolute_error_estimate <= rel_err_goal_*scale) { + starting_level_ = (max)(long(ii) - 1, long(0)); + return {I0/omega, absolute_error_estimate/scale}; + } + I1 = I0; + ++ii; + } + + starting_level_ = static_cast(big_nodes_.size() - 2); + return {I1/omega, absolute_error_estimate/scale}; + } + +private: + + template + void add_level(size_t i) { + using std::abs; + size_t current_num_levels = big_nodes_.size(); + Real unit_roundoff = std::numeric_limits::epsilon()/2; + PreciseReal h = PreciseReal(1)/PreciseReal(1< bnode_row; + std::vector bweight_row; + bnode_row.reserve((static_cast(1)<(1)< lnode_row; + std::vector lweight_row; + + lnode_row.reserve((static_cast(1)<(1)<(precise_nw.first); + Real weight = static_cast(precise_nw.second); + w = weight; + if (bnode_row.size() == bnode_row.capacity()) { + bnode_row.reserve(2*bnode_row.size()); + bweight_row.reserve(2*bnode_row.size()); + } + + bnode_row.push_back(node); + bweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + ++n; + // f(t)->0 as t->infty, which is why the weights are computed up to the unit roundoff. + } while(abs(w) > unit_roundoff*max_weight); + + bnode_row.shrink_to_fit(); + bweight_row.shrink_to_fit(); + n = -1; + do { + auto precise_nw = ooura_cos_node_and_weight(n, h, alpha); + Real node = static_cast(precise_nw.first); + // The function cannot be singular at zero, + // so zero is not a unreasonable node, + // unlike in the case of the Fourier Sine. + // Hence only break if the node is negative. + if (node < 0) { + break; + } + Real weight = static_cast(precise_nw.second); + w = weight; + if (lnode_row.size() > 0) { + if (lnode_row.back() == node) { + // The nodes have fused into each other: + break; + } + } + if (lnode_row.size() == lnode_row.capacity()) { + lnode_row.reserve(2*lnode_row.size()); + lweight_row.reserve(2*lnode_row.size()); + } + + lnode_row.push_back(node); + lweight_row.push_back(weight); + if (abs(weight) > max_weight) { + max_weight = abs(weight); + } + --n; + } while(abs(w) > (std::numeric_limits::min)()*max_weight); + + lnode_row.shrink_to_fit(); + lweight_row.shrink_to_fit(); + + #ifdef BOOST_HAS_THREADS + std::lock_guard lock(node_weight_mutex_); + #endif + + // Another thread might have already finished this calculation and appended it to the nodes/weights: + if (current_num_levels == big_nodes_.size()) { + big_nodes_.push_back(bnode_row); + bweights_.push_back(bweight_row); + + little_nodes_.push_back(lnode_row); + lweights_.push_back(lweight_row); + } + } + + template + Real estimate_integral(F const & f, Real omega, size_t i) { + Real I0 = 0; + auto const & b_nodes = big_nodes_[i]; + auto const & b_weights = bweights_[i]; + Real inv_omega = 1/omega; + for(size_t j = 0 ; j < b_nodes.size(); ++j) { + I0 += f(b_nodes[j]*inv_omega)*b_weights[j]; + } + + auto const & l_nodes = little_nodes_[i]; + auto const & l_weights = lweights_[i]; + for (size_t j = 0; j < l_nodes.size(); ++j) { + I0 += f(l_nodes[j]*inv_omega)*l_weights[j]; + } + return I0; + } + + #ifdef BOOST_HAS_THREADS + std::mutex node_weight_mutex_; + #endif + + std::vector> big_nodes_; + std::vector> bweights_; + + std::vector> little_nodes_; + std::vector> lweights_; + Real rel_err_goal_; + + #ifdef BOOST_HAS_THREADS + std::atomic starting_level_{}; + #else + long starting_level_; + #endif + + size_t requested_levels_; +}; + + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/detail/sinh_sinh_detail.hpp b/libcxx/src/third-party/boost/math/quadrature/detail/sinh_sinh_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/detail/sinh_sinh_detail.hpp @@ -0,0 +1,488 @@ +// Copyright Nick Thompson, 2017 +// 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_QUADRATURE_DETAIL_SINH_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_SINH_SINH_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + + +// Returns the sinh-sinh quadrature of a function f over the entire real line + +template +class sinh_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + sinh_sinh_detail(size_t max_refinements); + + template + auto integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels)->decltype(std::declval()(std::declval())) const; + +private: +private: + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); + void init(const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const std::integral_constant&); +#endif + + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + using std::sinh; + using std::cosh; + using std::exp; + using constants::half_pi; + + std::size_t row = ++m_committed_refinements; + + Real h = ldexp(Real(1), -static_cast(row)); + size_t k = static_cast(boost::math::lltrunc(ceil(m_t_max / (2 * h)))); + m_abscissas[row].reserve(k); + m_weights[row].reserve(k); + Real arg = h; + while (arg < m_t_max) + { + Real tmp = half_pi()*sinh(arg); + Real x = sinh(tmp); + m_abscissas[row].emplace_back(x); + Real w = cosh(arg)*half_pi()*cosh(tmp); + m_weights[row].emplace_back(w); + arg += 2 * h; + } + } + + Real m_t_max; + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + std::size_t m_max_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif +}; + +template +sinh_sinh_detail::sinh_sinh_detail(size_t max_refinements) + : m_abscissas(max_refinements), m_weights(max_refinements), m_max_refinements(max_refinements) +{ + init(std::integral_constant()); +} + +template +template +auto sinh_sinh_detail::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels)->decltype(std::declval()(std::declval())) const +{ + using std::abs; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + static const char* function = "boost::math::quadrature::sinh_sinh<%1%>::integrate"; + + typedef decltype(f(static_cast(0))) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + K y_max = f(boost::math::tools::max_value()); + if(abs(y_max) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at infinity, and instead evaluates to %1%", y_max, Policy())); + } + + K y_min = f(-boost::math::tools::max_value()); + if(abs(y_min) > boost::math::tools::epsilon()) + { + return static_cast(policies::raise_domain_error(function, + "The function you are trying to integrate does not go to zero at -infinity, and instead evaluates to %1%", y_max, Policy())); + } + + // Get the party started with two estimates of the integral: + K I0 = f(0)*half_pi(); + Real L1_I0 = abs(I0); + for(size_t i = 0; i < m_abscissas[0].size(); ++i) + { + Real x = m_abscissas[0][i]; + K yp = f(x); + K ym = f(-x); + I0 += (yp + ym)*m_weights[0][i]; + L1_I0 += (abs(yp)+abs(ym))*m_weights[0][i]; + } + + // Uncomment the estimates to work the convergence on the command line. + // std::cout << std::setprecision(std::numeric_limits::digits10); + // std::cout << "First estimate : " << I0 << std::endl; + K I1 = I0; + Real L1_I1 = L1_I0; + for (size_t i = 0; i < m_abscissas[1].size(); ++i) + { + Real x= m_abscissas[1][i]; + K yp = f(x); + K ym = f(-x); + I1 += (yp + ym)*m_weights[1][i]; + L1_I1 += (abs(yp) + abs(ym))*m_weights[1][i]; + } + + I1 *= half(); + L1_I1 *= half(); + Real err = abs(I0 - I1); + // std::cout << "Second estimate: " << I1 << " Error estimate at level " << 1 << " = " << err << std::endl; + + size_t i = 2; + for(; i <= m_max_refinements; ++i) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + Real h = static_cast(1) / static_cast(1 << i); + K sum = 0; + Real absum = 0; + + Real abterm1 = 1; + Real eps = boost::math::tools::epsilon()*L1_I1; + + auto abscissa_row = get_abscissa_row(i); + auto weight_row = get_weight_row(i); + + for(size_t j = 0; j < abscissa_row.size(); ++j) + { + Real x = abscissa_row[j]; + K yp = f(x); + K ym = f(-x); + sum += (yp + ym)*weight_row[j]; + Real abterm0 = (abs(yp) + abs(ym))*weight_row[j]; + absum += abterm0; + + // We require two consecutive terms to be < eps in case we hit a zero of f. + if (x > static_cast(100) && abterm0 < eps && abterm1 < eps) + { + break; + } + abterm1 = abterm0; + } + + I1 += sum*h; + L1_I1 += absum*h; + err = abs(I0 - I1); + // std::cout << "Estimate: " << I1 << " Error estimate at level " << i << " = " << err << std::endl; + if (!(boost::math::isfinite)(L1_I1)) + { + const char* err_msg = "The sinh_sinh quadrature evaluated your function at a singular point, leading to the value %1%.\n" + "sinh_sinh quadrature cannot handle singularities in the domain.\n" + "If you are sure your function has no singularities, please submit a bug against boost.math\n"; + return static_cast(policies::raise_evaluation_error(function, err_msg, I1, Policy())); + } + if (err <= tolerance*L1_I1) + { + break; + } + } + + if (error) + { + *error = err; + } + + if (L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = i; + } + + return I1; +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + using std::log; + using std::sqrt; + using std::cosh; + using std::sinh; + using std::ceil; + using boost::math::constants::two_div_pi; + using boost::math::constants::half_pi; + + m_committed_refinements = 4; + + // t_max is chosen to make g'(t_max) ~ sqrt(max) (g' grows faster than g). + // This will allow some flexibility on the users part; they can at least square a number function without overflow. + // But there is no unique choice; the further out we can evaluate the function, the better we can do on slowly decaying integrands. + m_t_max = log(2 * two_div_pi()*log(2 * two_div_pi()*sqrt(tools::max_value()))); + + for (size_t i = 0; i <= 4; ++i) + { + Real h = static_cast(1) / static_cast(1 << i); + size_t k = static_cast(boost::math::lltrunc(ceil(m_t_max / (2 * h)))); + m_abscissas[i].reserve(k); + m_weights[i].reserve(k); + // We don't add 0 to the abscissas; that's treated as a special case. + Real arg = h; + while (arg < m_t_max) + { + Real tmp = half_pi()*sinh(arg); + Real x = sinh(tmp); + m_abscissas[i].emplace_back(x); + Real w = cosh(arg)*half_pi()*cosh(tmp); + m_weights[i].emplace_back(w); + + if (i != 0) + { + arg += 2 * h; + } + else + { + arg += h; + } + } + } +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828742e+00f, 1.48993185e+02f, 3.41228925e+06f, 2.06932577e+18f, }, + { 9.13048763e-01f, 1.41578929e+01f, 6.70421552e+03f, 9.64172533e+10f, }, + { 4.07297690e-01f, 1.68206671e+00f, 6.15089799e+00f, 4.00396235e+01f, 7.92920025e+02f, 1.02984971e+05f, 3.03862311e+08f, 1.56544547e+14f, }, + { 1.98135272e-01f, 6.40155674e-01f, 1.24892870e+00f, 2.26608084e+00f, 4.29646270e+00f, 9.13029039e+00f, 2.31110765e+01f, 7.42770603e+01f, 3.26720921e+02f, 2.15948569e+03f, 2.41501526e+04f, 5.31819400e+05f, 2.80058686e+07f, 4.52406508e+09f, 3.08561257e+12f, 1.33882673e+16f, }, + { 9.83967894e-02f, 3.00605618e-01f, 5.19857979e-01f, 7.70362083e-01f, 1.07131137e+00f, 1.45056976e+00f, 1.95077855e+00f, 2.64003177e+00f, 3.63137237e+00f, 5.11991533e+00f, 7.45666098e+00f, 1.13022613e+01f, 1.79641069e+01f, 3.01781070e+01f, 5.40387580e+01f, 1.04107731e+02f, 2.18029520e+02f, 5.02155699e+02f, 1.28862131e+03f, 3.73921687e+03f, 1.24750730e+04f, 4.87639975e+04f, 2.28145658e+05f, 1.30877796e+06f, 9.46084663e+06f, 8.88883120e+07f, 1.12416883e+09f, 1.99127673e+10f, 5.16743469e+11f, 2.06721881e+13f, 1.35061503e+15f, 1.53854066e+17f, }, + { 4.91151004e-02f, 1.48013150e-01f, 2.48938814e-01f, 3.53325424e-01f, 4.62733557e-01f, 5.78912068e-01f, 7.03870253e-01f, 8.39965859e-01f, 9.90015066e-01f, 1.15743257e+00f, 1.34641276e+00f, 1.56216711e+00f, 1.81123885e+00f, 2.10192442e+00f, 2.44484389e+00f, 2.85372075e+00f, 3.34645891e+00f, 3.94664582e+00f, 4.68567310e+00f, 5.60576223e+00f, 6.76433234e+00f, 8.24038318e+00f, 1.01439436e+01f, 1.26302471e+01f, 1.59213040e+01f, 2.03392186e+01f, 2.63584645e+01f, 3.46892633e+01f, 4.64129147e+01f, 6.32055079e+01f, 8.77149726e+01f, 1.24209693e+02f, 1.79718635e+02f, 2.66081728e+02f, 4.03727303e+02f, 6.28811307e+02f, 1.00707984e+03f, 1.66156823e+03f, 2.82965144e+03f, 4.98438627e+03f, 9.10154693e+03f, 1.72689266e+04f, 3.41309958e+04f, 7.04566898e+04f, 1.52340422e+05f, 3.46047978e+05f, 8.28472421e+05f, 2.09759615e+06f, 5.63695080e+06f, 1.61407141e+07f, 4.94473068e+07f, 1.62781052e+08f, 5.78533297e+08f, 2.23083854e+09f, 9.38239131e+09f, 4.32814954e+10f, 2.20307274e+11f, 1.24524507e+12f, 7.86900053e+12f, 5.59953143e+13f, 4.52148695e+14f, 4.17688952e+15f, 4.45286776e+16f, 5.52914285e+17f, 8.07573252e+18f, }, + { 2.45471558e-02f, 7.37246687e-02f, 1.23152531e-01f, 1.73000138e-01f, 2.23440665e-01f, 2.74652655e-01f, 3.26821679e-01f, 3.80142101e-01f, 4.34818964e-01f, 4.91070037e-01f, 5.49128046e-01f, 6.09243132e-01f, 6.71685571e-01f, 7.36748805e-01f, 8.04752842e-01f, 8.76048080e-01f, 9.51019635e-01f, 1.03009224e+00f, 1.11373586e+00f, 1.20247203e+00f, 1.29688123e+00f, 1.39761124e+00f, 1.50538689e+00f, 1.62102121e+00f, 1.74542840e+00f, 1.87963895e+00f, 2.02481711e+00f, 2.18228138e+00f, 2.35352849e+00f, 2.54026147e+00f, 2.74442267e+00f, 2.96823279e+00f, 3.21423687e+00f, 3.48535896e+00f, 3.78496698e+00f, 4.11695014e+00f, 4.48581137e+00f, 4.89677825e+00f, 5.35593629e+00f, 5.87038976e+00f, 6.44845619e+00f, 7.09990245e+00f, 7.83623225e+00f, 8.67103729e+00f, 9.62042778e+00f, 1.07035620e+01f, 1.19433001e+01f, 1.33670142e+01f, 1.50075962e+01f, 1.69047155e+01f, 1.91063967e+01f, 2.16710044e+01f, 2.46697527e+01f, 2.81898903e+01f, 3.23387613e+01f, 3.72490076e+01f, 4.30852608e+01f, 5.00527965e+01f, 5.84087761e+01f, 6.84769282e+01f, 8.06668178e+01f, 9.54992727e+01f, 1.13640120e+02f, 1.35945194e+02f, 1.63520745e+02f, 1.97804969e+02f, 2.40678754e+02f, 2.94617029e+02f, 3.62896953e+02f, 4.49886178e+02f, 5.61444735e+02f, 7.05489247e+02f, 8.92790773e+02f, 1.13811142e+03f, 1.46183599e+03f, 1.89233262e+03f, 2.46939604e+03f, 3.24931157e+03f, 4.31236711e+03f, 5.77409475e+03f, 7.80224724e+03f, 1.06426753e+04f, 1.46591538e+04f, 2.03952854e+04f, 2.86717062e+04f, 4.07403376e+04f, 5.85318231e+04f, 8.50568927e+04f, 1.25064927e+05f, 1.86137394e+05f, 2.80525578e+05f, 4.28278249e+05f, 6.62634051e+05f, 1.03944324e+06f, 1.65385743e+06f, 2.67031565e+06f, 4.37721203e+06f, 7.28807171e+06f, 1.23317299e+07f, 2.12155729e+07f, 3.71308625e+07f, 6.61457938e+07f, 1.20005529e+08f, 2.21862941e+08f, 4.18228294e+08f, 8.04370413e+08f, 1.57939299e+09f, 3.16812242e+09f, 6.49660681e+09f, 1.36285199e+10f, 2.92686390e+10f, 6.43979867e+10f, 1.45275523e+11f, 3.36285446e+11f, 7.99420279e+11f, 1.95326423e+12f, 4.90958187e+12f, 1.27062273e+13f, 3.38907099e+13f, 9.32508403e+13f, 2.64948942e+14f, 7.78129518e+14f, 2.36471505e+15f, 7.44413803e+15f, 2.43021724e+16f, 8.23706864e+16f, 2.90211705e+17f, 1.06415768e+18f, 4.06627711e+18f, }, + { 1.22722792e-02f, 3.68272289e-02f, 6.14133763e-02f, 8.60515971e-02f, 1.10762884e-01f, 1.35568393e-01f, 1.60489494e-01f, 1.85547813e-01f, 2.10765290e-01f, 2.36164222e-01f, 2.61767321e-01f, 2.87597761e-01f, 3.13679240e-01f, 3.40036029e-01f, 3.66693040e-01f, 3.93675878e-01f, 4.21010910e-01f, 4.48725333e-01f, 4.76847237e-01f, 5.05405685e-01f, 5.34430786e-01f, 5.63953775e-01f, 5.94007101e-01f, 6.24624511e-01f, 6.55841151e-01f, 6.87693662e-01f, 7.20220285e-01f, 7.53460977e-01f, 7.87457528e-01f, 8.22253686e-01f, 8.57895297e-01f, 8.94430441e-01f, 9.31909591e-01f, 9.70385775e-01f, 1.00991475e+00f, 1.05055518e+00f, 1.09236885e+00f, 1.13542087e+00f, 1.17977990e+00f, 1.22551840e+00f, 1.27271289e+00f, 1.32144424e+00f, 1.37179794e+00f, 1.42386447e+00f, 1.47773961e+00f, 1.53352485e+00f, 1.59132774e+00f, 1.65126241e+00f, 1.71344993e+00f, 1.77801893e+00f, 1.84510605e+00f, 1.91485658e+00f, 1.98742510e+00f, 2.06297613e+00f, 2.14168493e+00f, 2.22373826e+00f, 2.30933526e+00f, 2.39868843e+00f, 2.49202464e+00f, 2.58958621e+00f, 2.69163219e+00f, 2.79843963e+00f, 2.91030501e+00f, 3.02754584e+00f, 3.15050230e+00f, 3.27953915e+00f, 3.41504770e+00f, 3.55744805e+00f, 3.70719145e+00f, 3.86476298e+00f, 4.03068439e+00f, 4.20551725e+00f, 4.38986641e+00f, 4.58438376e+00f, 4.78977239e+00f, 5.00679110e+00f, 5.23625945e+00f, 5.47906320e+00f, 5.73616037e+00f, 6.00858792e+00f, 6.29746901e+00f, 6.60402117e+00f, 6.92956515e+00f, 7.27553483e+00f, 7.64348809e+00f, 8.03511888e+00f, 8.45227058e+00f, 8.89695079e+00f, 9.37134780e+00f, 9.87784877e+00f, 1.04190601e+01f, 1.09978298e+01f, 1.16172728e+01f, 1.22807990e+01f, 1.29921443e+01f, 1.37554055e+01f, 1.45750793e+01f, 1.54561061e+01f, 1.64039187e+01f, 1.74244972e+01f, 1.85244301e+01f, 1.97109839e+01f, 2.09921804e+01f, 2.23768845e+01f, 2.38749023e+01f, 2.54970927e+01f, 2.72554930e+01f, 2.91634608e+01f, 3.12358351e+01f, 3.34891185e+01f, 3.59416839e+01f, 3.86140099e+01f, 4.15289481e+01f, 4.47120276e+01f, 4.81918020e+01f, 5.20002465e+01f, 5.61732106e+01f, 6.07509371e+01f, 6.57786566e+01f, 7.13072704e+01f, 7.73941341e+01f, 8.41039609e+01f, 9.15098607e+01f, 9.96945411e+01f, 1.08751694e+02f, 1.18787600e+02f, 1.29922990e+02f, 1.42295202e+02f, 1.56060691e+02f, 1.71397955e+02f, 1.88510933e+02f, 2.07632988e+02f, 2.29031559e+02f, 2.53013612e+02f, 2.79932028e+02f, 3.10193130e+02f, 3.44265522e+02f, 3.82690530e+02f, 4.26094527e+02f, 4.75203518e+02f, 5.30860437e+02f, 5.94045681e+02f, 6.65901543e+02f, 7.47761337e+02f, 8.41184173e+02f, 9.47996570e+02f, 1.07034233e+03f, 1.21074246e+03f, 1.37216724e+03f, 1.55812321e+03f, 1.77275819e+03f, 2.02098849e+03f, 2.30865326e+03f, 2.64270219e+03f, 3.03142418e+03f, 3.48472668e+03f, 4.01447750e+03f, 4.63492426e+03f, 5.36320995e+03f, 6.22000841e+03f, 7.23030933e+03f, 8.42439022e+03f, 9.83902287e+03f, 1.15189746e+04f, 1.35188810e+04f, 1.59055875e+04f, 1.87610857e+04f, 2.21862046e+04f, 2.63052621e+04f, 3.12719440e+04f, 3.72767546e+04f, 4.45564828e+04f, 5.34062659e+04f, 6.41950058e+04f, 7.73851264e+04f, 9.35579699e+04f, 1.13446538e+05f, 1.37977827e+05f, 1.68327749e+05f, 2.05992575e+05f, 2.52882202e+05f, 3.11442272e+05f, 3.84814591e+05f, 4.77048586e+05f, 5.93380932e+05f, 7.40606619e+05f, 9.27573047e+05f, 1.16584026e+06f, 1.47056632e+06f, 1.86169890e+06f, 2.36558487e+06f, 3.01715270e+06f, 3.86288257e+06f, 4.96486431e+06f, 6.40636283e+06f, 8.29948185e+06f, 1.07957589e+07f, 1.41008733e+07f, 1.84951472e+07f, 2.43622442e+07f, 3.22295113e+07f, 4.28249388e+07f, 5.71579339e+07f, 7.66343793e+07f, 1.03221273e+08f, 1.39683399e+08f, 1.89925150e+08f, 2.59486540e+08f, 3.56266474e+08f, 4.91582541e+08f, 6.81731647e+08f, 9.50299811e+08f, 1.33159830e+09f, 1.87580198e+09f, 2.65667391e+09f, 3.78324022e+09f, 5.41753185e+09f, 7.80169537e+09f, 1.12996537e+10f, 1.64614916e+10f, 2.41235400e+10f, 3.55648690e+10f, 5.27534501e+10f, 7.87357211e+10f, 1.18256902e+11f, 1.78754944e+11f, 2.71963306e+11f, 4.16512215e+11f, 6.42178186e+11f, 9.96872550e+11f, 1.55821233e+12f, 2.45280998e+12f, 3.88865623e+12f, 6.20986899e+12f, 9.98992422e+12f, 1.61915800e+13f, 2.64432452e+13f, 4.35201885e+13f, 7.21888469e+13f, 1.20699764e+14f, 2.03448372e+14f, 3.45755310e+14f, 5.92524851e+14f, 1.02405779e+15f, 1.78517405e+15f, 3.13930699e+15f, 5.56985627e+15f, 9.97176335e+15f, 1.80168749e+16f, 3.28570986e+16f, 6.04901854e+16f, 1.12437528e+17f, 2.11044513e+17f, 4.00073701e+17f, 7.66084936e+17f, 1.48201877e+18f, 2.89694543e+18f, 5.72279017e+18f, 1.14268996e+19f, }, + }; + m_weights = { + { 7.86824160e+00f, 8.80516388e+02f, 5.39627832e+07f, 8.87651190e+19f, }, + { 2.39852428e+00f, 5.24459642e+01f, 6.45788782e+04f, 2.50998524e+12f, }, + { 1.74936958e+00f, 3.97965898e+00f, 1.84851460e+01f, 1.86488072e+02f, 5.97420570e+03f, 1.27041264e+06f, 6.16419301e+09f, 5.23085003e+15f, }, + { 1.61385906e+00f, 1.99776729e+00f, 3.02023198e+00f, 5.47764184e+00f, 1.17966092e+01f, 3.03550485e+01f, 9.58442179e+01f, 3.89387024e+02f, 2.17919325e+03f, 1.83920812e+04f, 2.63212061e+05f, 7.42729651e+06f, 5.01587565e+08f, 1.03961087e+11f, 9.10032891e+13f, 5.06865116e+17f, }, + { 1.58146596e+00f, 1.66914991e+00f, 1.85752319e+00f, 2.17566262e+00f, 2.67590138e+00f, 3.44773868e+00f, 4.64394654e+00f, 6.53020450e+00f, 9.58228502e+00f, 1.46836141e+01f, 2.35444955e+01f, 3.96352727e+01f, 7.03763521e+01f, 1.32588012e+02f, 2.66962565e+02f, 5.79374920e+02f, 1.36869193e+03f, 3.55943572e+03f, 1.03218668e+04f, 3.38662130e+04f, 1.27816626e+05f, 5.65408251e+05f, 2.99446204e+06f, 1.94497502e+07f, 1.59219301e+08f, 1.69428882e+09f, 2.42715618e+10f, 4.87031785e+11f, 1.43181966e+13f, 6.48947152e+14f, 4.80375775e+16f, 6.20009636e+18f, }, + { 1.57345777e+00f, 1.59489276e+00f, 1.63853652e+00f, 1.70598041e+00f, 1.79972439e+00f, 1.92332285e+00f, 2.08159737e+00f, 2.28093488e+00f, 2.52969785e+00f, 2.83878478e+00f, 3.22239575e+00f, 3.69908136e+00f, 4.29318827e+00f, 5.03686536e+00f, 5.97287114e+00f, 7.15853842e+00f, 8.67142780e+00f, 1.06174736e+01f, 1.31428500e+01f, 1.64514563e+01f, 2.08309945e+01f, 2.66923599e+01f, 3.46299351e+01f, 4.55151836e+01f, 6.06440809e+01f, 8.19729692e+01f, 1.12502047e+02f, 1.56909655e+02f, 2.22620435e+02f, 3.21638549e+02f, 4.73757451e+02f, 7.12299455e+02f, 1.09460965e+03f, 1.72169779e+03f, 2.77592491e+03f, 4.59523007e+03f, 7.82342759e+03f, 1.37235744e+04f, 2.48518896e+04f, 4.65553875e+04f, 9.04176678e+04f, 1.82484396e+05f, 3.83680026e+05f, 8.42627197e+05f, 1.93843257e+06f, 4.68511285e+06f, 1.19352867e+07f, 3.21564375e+07f, 9.19600893e+07f, 2.80222318e+08f, 9.13611083e+08f, 3.20091090e+09f, 1.21076526e+10f, 4.96902475e+10f, 2.22431575e+11f, 1.09212534e+12f, 5.91688298e+12f, 3.55974344e+13f, 2.39435365e+14f, 1.81355107e+15f, 1.55873671e+16f, 1.53271488e+17f, 1.73927478e+18f, 2.29884122e+19f, 3.57403070e+20f, }, + { 1.57146132e+00f, 1.57679017e+00f, 1.58749564e+00f, 1.60367396e+00f, 1.62547113e+00f, 1.65308501e+00f, 1.68676814e+00f, 1.72683132e+00f, 1.77364814e+00f, 1.82766042e+00f, 1.88938482e+00f, 1.95942057e+00f, 2.03845873e+00f, 2.12729290e+00f, 2.22683194e+00f, 2.33811466e+00f, 2.46232715e+00f, 2.60082286e+00f, 2.75514621e+00f, 2.92706011e+00f, 3.11857817e+00f, 3.33200254e+00f, 3.56996830e+00f, 3.83549565e+00f, 4.13205150e+00f, 4.46362211e+00f, 4.83479919e+00f, 5.25088196e+00f, 5.71799849e+00f, 6.24325042e+00f, 6.83488580e+00f, 7.50250620e+00f, 8.25731548e+00f, 9.11241941e+00f, 1.00831875e+01f, 1.11876913e+01f, 1.24472371e+01f, 1.38870139e+01f, 1.55368872e+01f, 1.74323700e+01f, 1.96158189e+01f, 2.21379089e+01f, 2.50594593e+01f, 2.84537038e+01f, 3.24091185e+01f, 3.70329629e+01f, 4.24557264e+01f, 4.88367348e+01f, 5.63712464e+01f, 6.52994709e+01f, 7.59180776e+01f, 8.85949425e+01f, 1.03788130e+02f, 1.22070426e+02f, 1.44161210e+02f, 1.70968019e+02f, 2.03641059e+02f, 2.43645006e+02f, 2.92854081e+02f, 3.53678602e+02f, 4.29234308e+02f, 5.23570184e+02f, 6.41976690e+02f, 7.91405208e+02f, 9.81042209e+02f, 1.22309999e+03f, 1.53391256e+03f, 1.93546401e+03f, 2.45753455e+03f, 3.14073373e+03f, 4.04081819e+03f, 5.23488160e+03f, 6.83029446e+03f, 8.97771323e+03f, 1.18901592e+04f, 1.58712239e+04f, 2.13571111e+04f, 2.89798371e+04f, 3.96630673e+04f, 5.47687519e+04f, 7.63235654e+04f, 1.07371915e+05f, 1.52531667e+05f, 2.18877843e+05f, 3.17362450e+05f, 4.65120153e+05f, 6.89253766e+05f, 1.03311989e+06f, 1.56688798e+06f, 2.40549203e+06f, 3.73952896e+06f, 5.88912115e+06f, 9.39904635e+06f, 1.52090328e+07f, 2.49628719e+07f, 4.15775926e+07f, 7.03070537e+07f, 1.20759856e+08f, 2.10788251e+08f, 3.74104720e+08f, 6.75449459e+08f, 1.24131674e+09f, 2.32331003e+09f, 4.43117602e+09f, 8.61744649e+09f, 1.70983691e+10f, 3.46357452e+10f, 7.16760712e+10f, 1.51634762e+11f, 3.28172932e+11f, 7.27110260e+11f, 1.65049955e+12f, 3.84133815e+12f, 9.17374427e+12f, 2.24990195e+13f, 5.67153509e+13f, 1.47074225e+14f, 3.92701252e+14f, 1.08063998e+15f, 3.06767147e+15f, 8.99238679e+15f, 2.72472254e+16f, 8.54294612e+16f, 2.77461372e+17f, 9.34529948e+17f, 3.26799612e+18f, 1.18791443e+19f, 4.49405341e+19f, 1.77170665e+20f, }, + { 1.57096255e+00f, 1.57229290e+00f, 1.57495658e+00f, 1.57895955e+00f, 1.58431079e+00f, 1.59102230e+00f, 1.59910918e+00f, 1.60858966e+00f, 1.61948515e+00f, 1.63182037e+00f, 1.64562338e+00f, 1.66092569e+00f, 1.67776241e+00f, 1.69617233e+00f, 1.71619809e+00f, 1.73788633e+00f, 1.76128784e+00f, 1.78645779e+00f, 1.81345587e+00f, 1.84234658e+00f, 1.87319943e+00f, 1.90608922e+00f, 1.94109632e+00f, 1.97830698e+00f, 2.01781368e+00f, 2.05971547e+00f, 2.10411838e+00f, 2.15113585e+00f, 2.20088916e+00f, 2.25350798e+00f, 2.30913084e+00f, 2.36790578e+00f, 2.42999091e+00f, 2.49555516e+00f, 2.56477893e+00f, 2.63785496e+00f, 2.71498915e+00f, 2.79640147e+00f, 2.88232702e+00f, 2.97301705e+00f, 3.06874019e+00f, 3.16978367e+00f, 3.27645477e+00f, 3.38908227e+00f, 3.50801806e+00f, 3.63363896e+00f, 3.76634859e+00f, 3.90657947e+00f, 4.05479525e+00f, 4.21149322e+00f, 4.37720695e+00f, 4.55250922e+00f, 4.73801517e+00f, 4.93438579e+00f, 5.14233166e+00f, 5.36261713e+00f, 5.59606472e+00f, 5.84356014e+00f, 6.10605759e+00f, 6.38458564e+00f, 6.68025373e+00f, 6.99425915e+00f, 7.32789480e+00f, 7.68255767e+00f, 8.05975815e+00f, 8.46113023e+00f, 8.88844279e+00f, 9.34361190e+00f, 9.82871448e+00f, 1.03460033e+01f, 1.08979234e+01f, 1.14871305e+01f, 1.21165112e+01f, 1.27892047e+01f, 1.35086281e+01f, 1.42785033e+01f, 1.51028871e+01f, 1.59862046e+01f, 1.69332867e+01f, 1.79494108e+01f, 1.90403465e+01f, 2.02124072e+01f, 2.14725057e+01f, 2.28282181e+01f, 2.42878539e+01f, 2.58605342e+01f, 2.75562800e+01f, 2.93861096e+01f, 3.13621485e+01f, 3.34977526e+01f, 3.58076454e+01f, 3.83080730e+01f, 4.10169773e+01f, 4.39541917e+01f, 4.71416602e+01f, 5.06036855e+01f, 5.43672075e+01f, 5.84621188e+01f, 6.29216205e+01f, 6.77826252e+01f, 7.30862125e+01f, 7.88781469e+01f, 8.52094636e+01f, 9.21371360e+01f, 9.97248336e+01f, 1.08043785e+02f, 1.17173764e+02f, 1.27204209e+02f, 1.38235512e+02f, 1.50380485e+02f, 1.63766039e+02f, 1.78535118e+02f, 1.94848913e+02f, 2.12889407e+02f, 2.32862309e+02f, 2.55000432e+02f, 2.79567594e+02f, 3.06863126e+02f, 3.37227087e+02f, 3.71046310e+02f, 4.08761417e+02f, 4.50874968e+02f, 4.97960949e+02f, 5.50675821e+02f, 6.09771424e+02f, 6.76110054e+02f, 7.50682104e+02f, 8.34626760e+02f, 9.29256285e+02f, 1.03608458e+03f, 1.15686082e+03f, 1.29360914e+03f, 1.44867552e+03f, 1.62478326e+03f, 1.82509876e+03f, 2.05330964e+03f, 2.31371761e+03f, 2.61134924e+03f, 2.95208799e+03f, 3.34283233e+03f, 3.79168493e+03f, 4.30817984e+03f, 4.90355562e+03f, 5.59108434e+03f, 6.38646863e+03f, 7.30832183e+03f, 8.37874981e+03f, 9.62405722e+03f, 1.10756067e+04f, 1.27708661e+04f, 1.47546879e+04f, 1.70808754e+04f, 1.98141031e+04f, 2.30322789e+04f, 2.68294532e+04f, 3.13194118e+04f, 3.66401221e+04f, 4.29592484e+04f, 5.04810088e+04f, 5.94547213e+04f, 7.01854788e+04f, 8.30475173e+04f, 9.85009981e+04f, 1.17113127e+05f, 1.39584798e+05f, 1.66784302e+05f, 1.99790063e+05f, 2.39944995e+05f, 2.88925794e+05f, 3.48831531e+05f, 4.22297220e+05f, 5.12639825e+05f, 6.24046488e+05f, 7.61817907e+05f, 9.32683930e+05f, 1.14521401e+06f, 1.41035265e+06f, 1.74212004e+06f, 2.15853172e+06f, 2.68280941e+06f, 3.34498056e+06f, 4.18399797e+06f, 5.25055801e+06f, 6.61086017e+06f, 8.35163942e+06f, 1.05869253e+07f, 1.34671524e+07f, 1.71914827e+07f, 2.20245345e+07f, 2.83191730e+07f, 3.65476782e+07f, 4.73445266e+07f, 6.15653406e+07f, 8.03684303e+07f, 1.05328028e+08f, 1.38592169e+08f, 1.83103699e+08f, 2.42910946e+08f, 3.23606239e+08f, 4.32947522e+08f, 5.81743297e+08f, 7.85117979e+08f, 1.06432920e+09f, 1.44938958e+09f, 1.98286647e+09f, 2.72541431e+09f, 3.76386796e+09f, 5.22313881e+09f, 7.28378581e+09f, 1.02080964e+10f, 1.43789932e+10f, 2.03583681e+10f, 2.89749983e+10f, 4.14577375e+10f, 5.96383768e+10f, 8.62622848e+10f, 1.25466705e+11f, 1.83521298e+11f, 2.69981221e+11f, 3.99492845e+11f, 5.94638056e+11f, 8.90440997e+11f, 1.34155194e+12f, 2.03376855e+12f, 3.10262796e+12f, 4.76359832e+12f, 7.36142036e+12f, 1.14512696e+13f, 1.79331419e+13f, 2.82758550e+13f, 4.48929705e+13f, 7.17780287e+13f, 1.15585510e+14f, 1.87483389e+14f, 3.06351036e+14f, 5.04340065e+14f, 8.36616340e+14f, 1.39855635e+15f, 2.35633575e+15f, 4.00176517e+15f, 6.85137513e+15f, 1.18269011e+16f, 2.05867353e+16f, 3.61396878e+16f, 6.39911218e+16f, 1.14301619e+17f, 2.05988138e+17f, 3.74584679e+17f, 6.87444303e+17f, 1.27340764e+18f, 2.38124192e+18f, 4.49583562e+18f, 8.57144202e+18f, 1.65044358e+19f, 3.21010035e+19f, 6.30778012e+19f, 1.25240403e+20f, 2.51300530e+20f, 5.09677626e+20f, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 4.03936524f; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.088287417976322866e+00, 1.489931846492091580e+02, 3.412289247883437102e+06, 2.069325766042617791e+18, 2.087002407609475560e+50, 2.019766160717908151e+137, }, + { 9.130487626376696748e-01, 1.415789294662811592e+01, 6.704215516223276482e+03, 9.641725327150499415e+10, 2.508950760085778485e+30, 1.447263535710337145e+83, }, + { 4.072976900657586902e-01, 1.682066707021148743e+00, 6.150897986386729515e+00, 4.003962351929400222e+01, 7.929200247931026321e+02, 1.029849713330979583e+05, 3.038623109252438574e+08, 1.565445474362494869e+14, 4.042465098430219104e+23, 1.321706827429658179e+39, 4.991231782099557998e+64, 7.352943850359875966e+106, }, + { 1.981352722514781726e-01, 6.401556735005260177e-01, 1.248928698253977663e+00, 2.266080840944321232e+00, 4.296462696702327381e+00, 9.130290387099955696e+00, 2.311107653864279933e+01, 7.427706034324012430e+01, 3.267209207115258917e+02, 2.159485694311818716e+03, 2.415015262896413060e+04, 5.318194002756929158e+05, 2.800586857217043323e+07, 4.524065079794338780e+09, 3.085612573980677122e+12, 1.338826733015807478e+16, 6.254617176562341381e+20, 6.182098535814164754e+26, 3.077293649788458067e+34, 2.348957289370104303e+44, 1.148543197899469758e+57, 2.255300070010069868e+73, 1.877919500569195394e+94, 1.367473887938624280e+121, }, + { 9.839678940067320339e-02, 3.006056176599550351e-01, 5.198579789949384900e-01, 7.703620832988877009e-01, 1.071311369641311830e+00, 1.450569758088998445e+00, 1.950778549520360334e+00, 2.640031773695551468e+00, 3.631372373667412273e+00, 5.119915330903350570e+00, 7.456660981404883289e+00, 1.130226126889972624e+01, 1.796410692472772550e+01, 3.017810704601898222e+01, 5.403875800312370567e+01, 1.041077314477469548e+02, 2.180295201202628077e+02, 5.021556986259101646e+02, 1.288621310998222420e+03, 3.739216870800548324e+03, 1.247507297020191232e+04, 4.876399753226692124e+04, 2.281456582219130122e+05, 1.308777960064843017e+06, 9.460846634209664077e+06, 8.888831203637279622e+07, 1.124168828974344134e+09, 1.991276729532144470e+10, 5.167434691060984650e+11, 2.067218814203990888e+13, 1.350615033184100406e+15, 1.538540662836508188e+17, 3.290747290540350661e+19, 1.437291381884498816e+22, 1.409832445530347286e+25, 3.459135480277971441e+28, 2.398720582340954092e+32, 5.398806604617292960e+36, 4.613340002580628610e+41, 1.787685909667902457e+47, 3.841984370124338536e+53, 5.752797955708583700e+60, 7.771812038427286551e+68, 1.269673044204081626e+78, 3.495676773765731568e+88, 2.362519474971692445e+100, 6.002143893273651123e+113, 9.290716303464155539e+128, 1.514442238033847090e+146, }, + { 4.911510035029024930e-02, 1.480131496743607333e-01, 2.489388137406836857e-01, 3.533254236926684378e-01, 4.627335566122353259e-01, 5.789120681640963067e-01, 7.038702533860627799e-01, 8.399658591446505688e-01, 9.900150664244376147e-01, 1.157432570143699131e+00, 1.346412759185361763e+00, 1.562167113901335551e+00, 1.811238852782323380e+00, 2.101924419006550301e+00, 2.444843885584197934e+00, 2.853720746632915024e+00, 3.346458910955350787e+00, 3.946645821057838387e+00, 4.685673101596678529e+00, 5.605762230908151175e+00, 6.764332336830574204e+00, 8.240383175379985221e+00, 1.014394356129857730e+01, 1.263024714338892472e+01, 1.592130395780345258e+01, 2.033921861921857185e+01, 2.635846445760633752e+01, 3.468926333224152409e+01, 4.641291467019728963e+01, 6.320550793890424203e+01, 8.771497261808906374e+01, 1.242096926240411498e+02, 1.797186347845127557e+02, 2.660817283327900190e+02, 4.037273029575712841e+02, 6.288113066545908703e+02, 1.007079837507490594e+03, 1.661568229185114288e+03, 2.829651440786582598e+03, 4.984386266585669139e+03, 9.101546927647810893e+03, 1.726892655475049727e+04, 3.413099578778601190e+04, 7.045668977053092802e+04, 1.523404217761279128e+05, 3.460479782897947414e+05, 8.284724209233183002e+05, 2.097596146601193946e+06, 5.636950798861273236e+06, 1.614071410855607245e+07, 4.944730678915060360e+07, 1.627810516820991356e+08, 5.785332971632280838e+08, 2.230838540681955690e+09, 9.382391306064739643e+09, 4.328149544776551692e+10, 2.203072744049242904e+11, 1.245245067109136413e+12, 7.869000534957822375e+12, 5.599531432979422461e+13, 4.521486949902090877e+14, 4.176889516548293265e+15, 4.452867759650496656e+16, 5.529142853140498068e+17, 8.075732516562854275e+18, 1.402046916260468698e+20, 2.925791412832239850e+21, 7.426433029335410886e+22, 2.321996331245735364e+24, 9.064194250638442432e+25, 4.481279048819445609e+27, 2.849046304726990645e+29, 2.367381159183355975e+31, 2.615825578455121227e+33, 3.914764948263290808e+35, 8.092042448555929219e+37, 2.358921320940630332e+40, 9.915218648535332591e+42, 6.152851059342658764e+45, 5.780276340144515388e+48, 8.443751734186488626e+51, 1.973343350899766708e+55, 7.605247378556219980e+58, 4.992057104939510418e+62, 5.775863423903912316e+66, 1.221808201945355603e+71, 4.912917230387133816e+75, 3.913971813732202372e+80, 6.456388069905286787e+85, 2.311225068528010358e+91, 1.887458157719431339e+97, 3.708483165438453094e+103, 1.855198812283538635e+110, 2.509787873171705318e+117, 9.790423755591216617e+124, 1.179088807944050747e+133, 4.714631846722476620e+141, 6.762657785959713240e+150, }, + { 2.454715583629863651e-02, 7.372466873903346224e-02, 1.231525309416766543e-01, 1.730001377719248556e-01, 2.234406649596860001e-01, 2.746526549718518258e-01, 3.268216792980646669e-01, 3.801421009804789245e-01, 4.348189637215614948e-01, 4.910700365099428407e-01, 5.491280459480215441e-01, 6.092431324382654397e-01, 6.716855712021148069e-01, 7.367488049067938643e-01, 8.047528416336950644e-01, 8.760480802482050705e-01, 9.510196351823332253e-01, 1.030092244532470067e+00, 1.113735859588680765e+00, 1.202472030918058876e+00, 1.296881226496863751e+00, 1.397611241828373026e+00, 1.505386891360545205e+00, 1.621021205894798030e+00, 1.745428403369044572e+00, 1.879638952031029331e+00, 2.024817107609328524e+00, 2.182281382147884181e+00, 2.353528494823881355e+00, 2.540261468229626457e+00, 2.744422672171478111e+00, 2.968232787190606619e+00, 3.214236869520657666e+00, 3.485358957907730467e+00, 3.784966983117372821e+00, 4.116950138940295100e+00, 4.485811369388231710e+00, 4.896778246562001812e+00, 5.355936290826725948e+00, 5.870389762600956907e+00, 6.448456189131117605e+00, 7.099902452679558236e+00, 7.836232253282841261e+00, 8.671037293575230635e+00, 9.620427777985990363e+00, 1.070356198876799531e+01, 1.194330008139441022e+01, 1.336701421038499647e+01, 1.500759615914396343e+01, 1.690471548203528376e+01, 1.910639668731689597e+01, 2.167100443216577994e+01, 2.466975274695099197e+01, 2.818989025157845355e+01, 3.233876132429401745e+01, 3.724900758097245740e+01, 4.308526084907741997e+01, 5.005279647654703975e+01, 5.840877607253876528e+01, 6.847692821534239862e+01, 8.066681777060714848e+01, 9.549927270200249260e+01, 1.136401195769487885e+02, 1.359451944976603209e+02, 1.635207451879744447e+02, 1.978049687912586950e+02, 2.406787535889776661e+02, 2.946170292930555023e+02, 3.628969532147125333e+02, 4.498861782715596902e+02, 5.614447353133496106e+02, 7.054892470899271429e+02, 8.927907732799964116e+02, 1.138111424979478376e+03, 1.461835991563605367e+03, 1.892332623444716186e+03, 2.469396036186133479e+03, 3.249311569298824731e+03, 4.312367113170283012e+03, 5.774094754500139661e+03, 7.802247237500851845e+03, 1.064267530975806972e+04, 1.465915383535674990e+04, 2.039528541239754835e+04, 2.867170622421556265e+04, 4.074033762183453297e+04, 5.853182310596923393e+04, 8.505689265265206640e+04, 1.250649269847856615e+05, 1.861373943166749766e+05, 2.805255777452010927e+05, 4.282782486084761748e+05, 6.626340506127657304e+05, 1.039443239650339565e+06, 1.653857426112961316e+06, 2.670315650125279161e+06, 4.377212026624358795e+06, 7.288071713698413821e+06, 1.233172993400331694e+07, 2.121557285769933699e+07, 3.713086254861535383e+07, 6.614579377352135534e+07, 1.200055291694917110e+08, 2.218629410296880690e+08, 4.182282939928687703e+08, 8.043704132493714804e+08, 1.579392989425668114e+09, 3.168122415524104635e+09, 6.496606811549861323e+09, 1.362851988356444486e+10, 2.926863897008707708e+10, 6.439798665209493735e+10, 1.452755233772903022e+11, 3.362854459389246576e+11, 7.994202785433479271e+11, 1.953264233362291960e+12, 4.909581868242554569e+12, 1.270622730765015610e+13, 3.389070986742985764e+13, 9.325084030208844833e+13, 2.649489423834534140e+14, 7.781295184094957195e+14, 2.364715052527355639e+15, 7.444138031465958255e+15, 2.430217240684749635e+16, 8.237068641534357762e+16, 2.902117050664548840e+17, 1.064157679404037013e+18, 4.066277106061960017e+18, 1.621274233630359097e+19, 6.754156830915450013e+19, 2.944056841733781919e+20, 1.344640139549107817e+21, 6.444586158944723300e+21, 3.246218667554608934e+22, 1.721234579556653533e+23, 9.622533890240474391e+23, 5.681407260417956671e+24, 3.548890779995928184e+25, 2.349506425672269562e+26, 1.651618130605205643e+27, 1.235147426493113059e+28, 9.845947239792057550e+28, 8.383130781984610418e+29, 7.639649461399172445e+30, 7.467862732233885201e+31, 7.847691482004993660e+32, 8.886032557626454704e+33, 1.086734890678302436e+35, 1.438967777036538458e+36, 2.068168865475603521e+37, 3.234885320223912385e+38, 5.521233641542628514e+39, 1.031148231194663855e+41, 2.113272035816365982e+42, 4.766724345485077520e+43, 1.186961550990218287e+45, 3.273172169205847573e+46, 1.002821226769167753e+48, 3.424933903935156479e+49, 1.308436017026428736e+51, 5.611378330048420503e+52, 2.711424806327139291e+54, 1.481771793644066442e+56, 9.194282071042778804e+57, 6.503661455875355562e+59, 5.266329986868627303e+61, 4.902662807969347359e+63, 5.270511057289557050e+65, 6.572856511670583316e+67, 9.553956030013225387e+69, 1.626491911159411616e+72, 3.259410915500951223e+74, 7.728460318113614280e+76, 2.179881996905918059e+79, 7.354484388371505915e+81, 2.984831270803957746e+84, 1.465828267813438962e+87, 8.763355972629864261e+89, 6.417909665847831130e+92, 5.794958649229893510e+95, 6.494224472311908365e+98, 9.095000156016433698e+101, 1.603058498455299102e+105, 3.582099119119320529e+108, 1.022441227139854687e+112, 3.756872185015086057e+115, 1.791363463832849159e+119, 1.117641882039472124e+123, 9.202159565546528285e+126, 1.008716474827888568e+131, 1.485546487089301805e+135, 2.966961534830566097e+139, 8.114207284664369360e+143, 3.069178087507669739e+148, 1.622223681147791473e+153, }, + { 1.227227917054637830e-02, 3.682722894492590471e-02, 6.141337626871079991e-02, 8.605159708778207907e-02, 1.107628840017845446e-01, 1.355683934957785482e-01, 1.604894937454335489e-01, 1.855478131645089496e-01, 2.107652898670700524e-01, 2.361642222214626268e-01, 2.617673206785495261e-01, 2.875977610631342900e-01, 3.136792395249035647e-01, 3.400360293536632770e-01, 3.666930398731810193e-01, 3.936758776386451797e-01, 4.210109101746846268e-01, 4.487253325041450341e-01, 4.768472367324829462e-01, 5.054056849688209375e-01, 5.344307858825229079e-01, 5.639537752137267134e-01, 5.940071005777549000e-01, 6.246245109268716053e-01, 6.558411510586397969e-01, 6.876936615883514922e-01, 7.202202848338683401e-01, 7.534609770949572224e-01, 7.874575278460963461e-01, 8.222536864020499377e-01, 8.578952966595825808e-01, 8.944304405668593009e-01, 9.319095910247435485e-01, 9.703857749817920659e-01, 1.009914747547728584e+00, 1.050555178019083150e+00, 1.092368848786092579e+00, 1.135420868172514300e+00, 1.179779898350424466e+00, 1.225518399571142610e+00, 1.272712892062026473e+00, 1.321444237057985065e+00, 1.371797938567245953e+00, 1.423864467614384096e+00, 1.477739610861208115e+00, 1.533524845679288858e+00, 1.591327743938355098e+00, 1.651262406984310076e+00, 1.713449934511288211e+00, 1.778018930286256858e+00, 1.845106047964720870e+00, 1.914856580544951899e+00, 1.987425097349017093e+00, 2.062976132795275283e+00, 2.141684931642916785e+00, 2.223738255848994521e+00, 2.309335258687213796e+00, 2.398688432341103821e+00, 2.492024635808356095e+00, 2.589586210645122756e+00, 2.691632192846832444e+00, 2.798439630014497291e+00, 2.910305013902562652e+00, 3.027545839497364963e+00, 3.150502302946919722e+00, 3.279539151967394330e+00, 3.415047703805410611e+00, 3.557448047456550733e+00, 3.707191448649779817e+00, 3.864762978128342125e+00, 4.030684386016531344e+00, 4.205517247588613835e+00, 4.389866408585172458e+00, 4.584383761391930748e+00, 4.789772386950687695e+00, 5.006791101261363264e+00, 5.236259449815274050e+00, 5.479063198337523150e+00, 5.736160373884817415e+00, 6.008587916728619858e+00, 6.297469010648863048e+00, 6.604021167380929133e+00, 6.929565150124677837e+00, 7.275534831383860972e+00, 7.643488092123492064e+00, 8.035118882502459288e+00, 8.452270579478188130e+00, 8.896950793641785313e+00, 9.371347797016395173e+00, 9.877848765573446033e+00, 1.041906005527762037e+01, 1.099782975900831706e+01, 1.161727282423952258e+01, 1.228079904848924611e+01, 1.299214431196691048e+01, 1.375540545535625881e+01, 1.457507926620621316e+01, 1.545610610104852468e+01, 1.640391874338302925e+01, 1.742449718154208970e+01, 1.852443008688437526e+01, 1.971098388378266494e+01, 2.099218043080961648e+01, 2.237688448013982946e+01, 2.387490225270073820e+01, 2.549709266380430464e+01, 2.725549296232531555e+01, 2.916346081119624987e+01, 3.123583514423284962e+01, 3.348911849136805118e+01, 3.594168387985465099e+01, 3.861400990307230737e+01, 4.152894811329303023e+01, 4.471202755441533396e+01, 4.819180202224910174e+01, 5.200024654361558757e+01, 5.617321062537384494e+01, 6.075093706918782079e+01, 6.577865661168003966e+01, 7.130727037357721343e+01, 7.739413413465805794e+01, 8.410396085269633392e+01, 9.150986068496734448e+01, 9.969454113547704016e+01, 1.087516939426018897e+02, 1.187876000643037532e+02, 1.299229897614516371e+02, 1.422952015056372537e+02, 1.560606914665002671e+02, 1.713979549326432406e+02, 1.885109325154830073e+02, 2.076329877740125935e+02, 2.290315594654587370e+02, 2.530136115655676467e+02, 2.799320282398896912e+02, 3.101931299766730890e+02, 3.442655222107529892e+02, 3.826905303289378387e+02, 4.260945266207607701e+02, 4.752035175892902045e+02, 5.308604366239058864e+02, 5.940456805372995009e+02, 6.659015428338778262e+02, 7.477613367309153870e+02, 8.411841730471343023e+02, 9.479965698013741524e+02, 1.070342331375881840e+03, 1.210742457518582660e+03, 1.372167241552205820e+03, 1.558123212187692722e+03, 1.772758188662716282e+03, 2.020988485411862984e+03, 2.308653259329163157e+03, 2.642702189813684273e+03, 3.031424182869210212e+03, 3.484726676985756018e+03, 4.014477504733973505e+03, 4.634924264049394751e+03, 5.363209949773439749e+03, 6.220008412114342803e+03, 7.230309332853029956e+03, 8.424390216735217783e+03, 9.839022871538541787e+03, 1.151897463083113988e+04, 1.351888098874374202e+04, 1.590558745460066947e+04, 1.876108572764816176e+04, 2.218620462393366275e+04, 2.630526205054915357e+04, 3.127194401941711057e+04, 3.727675461256652923e+04, 4.455648280312273249e+04, 5.340626592018903930e+04, 6.419500580388918123e+04, 7.738512642386820060e+04, 9.355796993981725963e+04, 1.134465375820669470e+05, 1.379778272209741713e+05, 1.683277485807887053e+05, 2.059925746120735305e+05, 2.528822024503158254e+05, 3.114422718347725915e+05, 3.848145913435570736e+05, 4.770485864966822643e+05, 5.933809324724740854e+05, 7.406066190351666115e+05, 9.275730471470643372e+05, 1.165840260940180415e+06, 1.470566322118246135e+06, 1.861698899014921971e+06, 2.365584870298354495e+06, 3.017152695505764877e+06, 3.862882573599929249e+06, 4.964864305589750358e+06, 6.406362829959736606e+06, 8.299481847261302115e+06, 1.079575892642401854e+07, 1.410087327474604091e+07, 1.849514724418250100e+07, 2.436224419670805500e+07, 3.222951131863941234e+07, 4.282493882385925337e+07, 5.715793394339267637e+07, 7.663437932745451635e+07, 1.032212725498489699e+08, 1.396833991976194842e+08, 1.899251497664892740e+08, 2.594865396467505851e+08, 3.562664742464501497e+08, 4.915825413172413471e+08, 6.817316470116958142e+08, 9.502998105202541438e+08, 1.331598295343277538e+09, 1.875801976010459831e+09, 2.656673907709731487e+09, 3.783240215616365909e+09, 5.417531848500136979e+09, 7.801695369892847510e+09, 1.129965368955098833e+10, 1.646149161390821924e+10, 2.412353995736687694e+10, 3.556486895431927094e+10, 5.275345014093760519e+10, 7.873572108325378177e+10, 1.182569020317863604e+11, 1.787549442508363461e+11, 2.719633064979986142e+11, 4.165122153119897946e+11, 6.421781858205134197e+11, 9.968725497576275918e+11, 1.558212327122960399e+12, 2.452809984907093786e+12, 3.888656232828140210e+12, 6.209868990509424909e+12, 9.989924216297983665e+12, 1.619158001378611351e+13, 2.644324518669926559e+13, 4.352018847904374786e+13, 7.218884688202741709e+13, 1.206997640727349538e+14, 2.034483722445207402e+14, 3.457553102874402920e+14, 5.925248511957505706e+14, 1.024057793713038672e+15, 1.785174045941642162e+15, 3.139306988668494696e+15, 5.569856270174890128e+15, 9.971763353834460328e+15, 1.801687491114883092e+16, 3.285709858322565542e+16, 6.049018540910759710e+16, 1.124375283211369572e+17, 2.110445125952435305e+17, 4.000737007891229992e+17, 7.660849361564329309e+17, 1.482018770996176700e+18, 2.896945433910857945e+18, 5.722790165693470493e+18, 1.142689960439921462e+19, 2.306616559984106723e+19, 4.707857184616093863e+19, 9.717346347495342813e+19, 2.028735605622585444e+20, 4.284840254171000581e+20, 9.157027329021623836e+20, 1.980457834766411777e+21, 4.335604886702252004e+21, 9.609258559714223995e+21, 2.156604630608586997e+22, 4.902045909695270289e+22, 1.128749227121328467e+23, 2.633414623049930879e+23, 6.226335684490998543e+23, 1.492205279014148921e+24, 3.625768249717590109e+24, 8.933899764961444882e+24, 2.232786981682262383e+25, 5.661295336293986732e+25, 1.456616710298133142e+26, 3.803959852868488245e+26, 1.008531585603036490e+27, 2.715247425129423358e+27, 7.425071766766651967e+27, 2.062860712173225003e+28, 5.824055458799413312e+28, 1.671388836696436644e+29, 4.876830632023956392e+29, 1.447170071146107156e+30, 4.368562208925583783e+30, 1.341873806249251338e+31, 4.195251632754338682e+31, 1.335360134828214136e+32, 4.328681350715136340e+32, 1.429401866150319186e+33, 4.809736146227180696e+33, 1.649624114567602575e+34, 5.768677492419801469e+34, 2.057442854162761350e+35, 7.486423509917811063e+35, 2.780052791791155051e+36, 1.053908347660081874e+37, 4.080046334235754223e+37, 1.613553311592805373e+38, 6.520836332997615098e+38, 2.693848186257510992e+39, 1.138002408430710800e+40, 4.917748008813924613e+40, 2.174691073191358676e+41, 9.844523745430526502e+41, 4.563707467590116732e+42, 2.167352073708379137e+43, 1.054860193887170754e+44, 5.263588225566847365e+44, 2.693772458797916623e+45, 1.414506760560163074e+46, 7.624126763512016620e+46, 4.219828148762794411e+47, 2.399387665831793264e+48, 1.402139947254117434e+49, 8.424706325525422943e+49, 5.206918479942619318e+50, 3.311787866477716151e+51, 2.168683295509859155e+52, 1.462786368779206713e+53, 1.016761784575838363e+54, 7.286460995145043184e+54, 5.386194237448865407e+55, 4.108917480528740640e+56, 3.236445625945552728e+57, 2.633440652417619669e+58, 2.214702339357939268e+59, 1.926058995948268392e+60, 1.733067740414174932e+61, 1.614307160124426969e+62, 1.557464328486352138e+63, 1.557226155197192031e+64, 1.614473962707995344e+65, 1.736617406327386105e+66, 1.939201243451190521e+67, 2.249277732936622876e+68, 2.711593798719765599e+69, 3.399628732048687119e+70, 4.435389696730206291e+71, 6.025566076164003981e+72, 8.529161425383779849e+73, 1.258746322992988688e+75, 1.938112175186560210e+76, 3.115432363572610661e+77, 5.231797674434390018e+78, 9.184930207860680757e+79, 1.686929404780378772e+81, 3.243565624474232635e+82, 6.533812498930220075e+83, 1.379898823144620314e+85, 3.057650444842839916e+86, 7.114050545839171245e+87, 1.739275024442258674e+89, 4.471782915853177804e+90, 1.210036789494028144e+92, 3.448828044590862359e+93, 1.036226783750561565e+95, 3.284801914751206038e+96, 1.099514933602224638e+98, 3.889581731378242597e+99, 1.455434287901069991e+101, 5.765729934387419019e+102, 2.420349568745475582e+104, 1.077606625929777536e+106, 5.093346988695851845e+107, 2.558090824110323997e+109, 1.366512508719047964e+111, 7.771735800763526406e+112, 4.710398638793014918e+114, 3.045563885587013954e+116, 2.102762552861442993e+118, 1.551937536212596136e+120, 1.225676354426075970e+122, 1.036950946169703711e+124, 9.407885268970827717e+125, 9.163369107785093171e+127, 9.592531095671168926e+129, 1.080486293361823875e+132, 1.311034829557782450e+134, 1.715642975932639188e+136, 2.424231742707881878e+138, 3.703231223333127919e+140, 6.123225027409988902e+142, 1.097271040771196765e+145, 2.133693643241295977e+147, 4.508099184895777328e+149, 1.036252806686291189e+152, }, + }; + m_weights = { + { 7.868241604839621507e+00, 8.805163880733011116e+02, 5.396278323520705668e+07, 8.876511896968161317e+19, 2.432791879269225553e+52, 6.399713512080202911e+139, }, + { 2.398524276302635218e+00, 5.244596423726681022e+01, 6.457887819598201760e+04, 2.509985242511374506e+12, 1.774029269327138701e+32, 2.781406115983097314e+85, }, + { 1.749369583108386852e+00, 3.979658981934607813e+00, 1.848514598574449570e+01, 1.864880718932067988e+02, 5.974205695263265855e+03, 1.270412635144623341e+06, 6.164193014295984071e+09, 5.230850031811222530e+15, 2.226260929943369774e+25, 1.199931102042181592e+41, 7.470602144275146214e+66, 1.814465860528410676e+109, }, + { 1.613859062188366173e+00, 1.997767291869673262e+00, 3.020231979908834220e+00, 5.477641843859057761e+00, 1.179660916492671672e+01, 3.035504848518598294e+01, 9.584421793794920860e+01, 3.893870238229992076e+02, 2.179193250357911344e+03, 1.839208123964132852e+04, 2.632120612599856167e+05, 7.427296507169468210e+06, 5.015875648341232356e+08, 1.039610867241544113e+11, 9.100328911818091977e+13, 5.068651163890231571e+17, 3.039966520714902616e+22, 3.857740194672007962e+28, 2.465542763666581087e+36, 2.416439449167799461e+46, 1.517091553926604149e+59, 3.825043412021411380e+75, 4.089582396821598640e+96, 3.823775894295564050e+123, }, + { 1.581465959536694744e+00, 1.669149910438534746e+00, 1.857523188595005770e+00, 2.175662623626994120e+00, 2.675901375211020564e+00, 3.447738682498791744e+00, 4.643946540355464126e+00, 6.530204496574248616e+00, 9.582285015566804961e+00, 1.468361407515440960e+01, 2.354449548740987533e+01, 3.963527273305166705e+01, 7.037635206267538547e+01, 1.325880124784838868e+02, 2.669625649541569172e+02, 5.793749198508472676e+02, 1.368691928321303605e+03, 3.559435721533130554e+03, 1.032186677270763318e+04, 3.386621302858741487e+04, 1.278166259840246830e+05, 5.654082513926693098e+05, 2.994462044781721833e+06, 1.944975023421914947e+07, 1.592193007690560588e+08, 1.694288818617459913e+09, 2.427156182311303271e+10, 4.870317848199455490e+11, 1.431819656229181793e+13, 6.489471523099301256e+14, 4.803757752508989106e+16, 6.200096361305331541e+18, 1.502568562439914899e+21, 7.436061367189688251e+23, 8.264761218677928603e+26, 2.297735027897804345e+30, 1.805449779569534997e+34, 4.604472360199061931e+38, 4.458371212030626854e+43, 1.957638261114809309e+49, 4.767368137162500764e+55, 8.088820139476721285e+62, 1.238260897349286357e+71, 2.292272505278842062e+80, 7.151392373749193549e+90, 5.476714850156044431e+102, 1.576655618370700681e+116, 2.765448595957851958e+131, 5.108051255283132673e+148, }, + { 1.573457773573108386e+00, 1.594892755038663787e+00, 1.638536515530234742e+00, 1.705980408212213620e+00, 1.799724394608737275e+00, 1.923322854425656307e+00, 2.081597373313268178e+00, 2.280934883790070511e+00, 2.529697852387704655e+00, 2.838784782552951185e+00, 3.222395745020980612e+00, 3.699081358854235112e+00, 4.293188274330526800e+00, 5.036865356322330076e+00, 5.972871140910932199e+00, 7.158538424311077564e+00, 8.671427800892076385e+00, 1.061747360297922326e+01, 1.314285002260235600e+01, 1.645145625668428040e+01, 2.083099449998189069e+01, 2.669235989791640190e+01, 3.462993514791378189e+01, 4.551518362653662579e+01, 6.064408087764392116e+01, 8.197296917485846798e+01, 1.125020468081652564e+02, 1.569096552844714123e+02, 2.226204347868638276e+02, 3.216385489504077755e+02, 4.737574505945461739e+02, 7.122994548146997637e+02, 1.094609652686376553e+03, 1.721697789176049576e+03, 2.775924909253835146e+03, 4.595230066268149347e+03, 7.823427586641573672e+03, 1.372357435269105405e+04, 2.485188961645119553e+04, 4.655538745425972783e+04, 9.041766782135686884e+04, 1.824843964862728392e+05, 3.836800264094614027e+05, 8.426271970245168026e+05, 1.938432574158782634e+06, 4.685112849356485528e+06, 1.193528667218607927e+07, 3.215643752247989316e+07, 9.196008928386600386e+07, 2.802223178457559964e+08, 9.136110825267458886e+08, 3.200910900783148591e+09, 1.210765264234723689e+10, 4.969024745093101808e+10, 2.224315751863855216e+11, 1.092125344449313660e+12, 5.916882980019919359e+12, 3.559743438494577249e+13, 2.394353652945465191e+14, 1.813551073517501917e+15, 1.558736706166165738e+16, 1.532714875555114333e+17, 1.739274776190789212e+18, 2.298841216802216313e+19, 3.574030698837762664e+20, 6.604899705451419080e+21, 1.467155879591820659e+23, 3.964094964398509381e+24, 1.319342840595348793e+26, 5.482251971340400742e+27, 2.885137894723827518e+29, 1.952539840765392110e+31, 1.727051489032222797e+33, 2.031343507095439396e+35, 3.236074146972599980e+37, 7.120487412983497200e+39, 2.209552707411017265e+42, 9.886282647791384648e+44, 6.530514048788273529e+47, 6.530706672481546528e+50, 1.015518807431281951e+54, 2.526366773162394510e+57, 1.036450519906790297e+61, 7.241966032627135861e+64, 8.919402520769714938e+68, 2.008463619152992905e+73, 8.596914764830260020e+77, 7.290599546829495220e+82, 1.280199563216419112e+88, 4.878349285603201150e+93, 4.240828248064127940e+99, 8.869771764721598720e+105, 4.723342575741417669e+112, 6.802035963326188581e+119, 2.824531180990009549e+127, 3.621049216745982252e+135, 1.541270150334942520e+144, 2.353376995174362785e+153, }, + { 1.571461316550783294e+00, 1.576790166316938345e+00, 1.587495640370383316e+00, 1.603673956341370210e+00, 1.625471125457493943e+00, 1.653085011915939302e+00, 1.686768142525911236e+00, 1.726831323537516202e+00, 1.773648138667236602e+00, 1.827660421478661448e+00, 1.889384817044018196e+00, 1.959420572855037091e+00, 2.038458728047908923e+00, 2.127292904083847225e+00, 2.226831940199076941e+00, 2.338114664555130296e+00, 2.462327148722991304e+00, 2.600822860927085164e+00, 2.755146214814554359e+00, 2.927060108424483555e+00, 3.118578166240921951e+00, 3.332002540339506630e+00, 3.569968300410740276e+00, 3.835495653996447262e+00, 4.132051496512934885e+00, 4.463622106699067881e+00, 4.834799191008006557e+00, 5.250881957765679608e+00, 5.717998490875333124e+00, 6.243250421598568105e+00, 6.834885801226541839e+00, 7.502506202789340802e+00, 8.257315484493544201e+00, 9.112419405864642634e+00, 1.008318749543997758e+01, 1.118769134993865202e+01, 1.244723705914106881e+01, 1.388701390605507587e+01, 1.553688715915900190e+01, 1.743237000680942831e+01, 1.961581894823993424e+01, 2.213790886354273806e+01, 2.505945934677137610e+01, 2.845370377742137561e+01, 3.240911845969524834e+01, 3.703296289480230161e+01, 4.245572644746267911e+01, 4.883673480337985582e+01, 5.637124640586975420e+01, 6.529947092752610340e+01, 7.591807755694122837e+01, 8.859494252391663822e+01, 1.037881295005788124e+02, 1.220704263969226746e+02, 1.441612098131200535e+02, 1.709680191245773511e+02, 2.036410593843575570e+02, 2.436450058708723643e+02, 2.928540812182076105e+02, 3.536786019152253392e+02, 4.292343083967296939e+02, 5.235701840488733027e+02, 6.419766898003024575e+02, 7.914052083668759283e+02, 9.810422089081931637e+02, 1.223099994999740393e+03, 1.533912555427112127e+03, 1.935464013605830339e+03, 2.457534549912886852e+03, 3.140733731623635519e+03, 4.040818188564651898e+03, 5.234881599712225681e+03, 6.830294457607329226e+03, 8.977713228649887143e+03, 1.189015920967326839e+04, 1.587122387044346962e+04, 2.135711106445789331e+04, 2.897983705189681437e+04, 3.966306726795547950e+04, 5.476875193750000787e+04, 7.632356539388055680e+04, 1.073719149754976951e+05, 1.525316674555574152e+05, 2.188778434744216586e+05, 3.173624496019295608e+05, 4.651201525869328462e+05, 6.892537656280580572e+05, 1.033119885120019982e+06, 1.566887981043252499e+06, 2.405492027026531795e+06, 3.739528964815910340e+06, 5.889121154895580032e+06, 9.399046351922342030e+06, 1.520903276129653518e+07, 2.496287187293576168e+07, 4.157759259963074840e+07, 7.030705366950267312e+07, 1.207598558452493366e+08, 2.107882509464846833e+08, 3.741047199023457864e+08, 6.754494594987415572e+08, 1.241316740415880537e+09, 2.323310032649552862e+09, 4.431176019026625759e+09, 8.617446487400900130e+09, 1.709836906604031513e+10, 3.463574521880171339e+10, 7.167607123799270726e+10, 1.516347620910054079e+11, 3.281729323238950526e+11, 7.271102600298280790e+11, 1.650499552378780378e+12, 3.841338149508803917e+12, 9.173744267785176575e+12, 2.249901946357519979e+13, 5.671535089900611731e+13, 1.470742250307697019e+14, 3.927012518464311775e+14, 1.080639977391212820e+15, 3.067671466720475189e+15, 8.992386789198328428e+15, 2.724722536524592111e+16, 8.542946122263389258e+16, 2.774613718725574755e+17, 9.345299479382029121e+17, 3.267996122987731882e+18, 1.187914433455468315e+19, 4.494053408418564214e+19, 1.771706652195486743e+20, 7.288102552885931527e+20, 3.132512430816625349e+21, 1.408743767951073110e+22, 6.638294268236060414e+22, 3.282543608403565013e+23, 1.705920098038394064e+24, 9.332259385148524285e+24, 5.382727175874888312e+25, 3.278954235122093249e+26, 2.113191697957458099e+27, 1.443411041499643040e+28, 1.046864394654982423e+29, 8.077319226958905700e+29, 6.643146963432616277e+30, 5.835670121359986260e+31, 5.486890296790230798e+32, 5.533726968508261614e+33, 5.999734996418352834e+34, 7.009176119466122569e+35, 8.844061966424597499e+36, 1.208226860869605961e+38, 1.791648514311063338e+39, 2.891313916713205762e+40, 5.091457860211527298e+41, 9.810630588402496553e+42, 2.074441239147378860e+44, 4.827650116937700540e+45, 1.240287939111549029e+47, 3.528782858644784616e+48, 1.115449490471696659e+50, 3.930510643328196314e+51, 1.549243712957852337e+53, 6.854998238041301002e+54, 3.417479961583207704e+56, 1.926905498641079990e+58, 1.233580963004919450e+60, 9.002819902898076915e+61, 7.521415141253441645e+63, 7.224277554900578993e+65, 8.012832830535078610e+67, 1.030999620286380369e+70, 1.546174957076748679e+72, 2.715803772613248694e+74, 5.615089920571746438e+76, 1.373667859345343337e+79, 3.997541020769625126e+81, 1.391500589339800087e+84, 5.826693844912022892e+86, 2.952274820929549096e+89, 1.821023061478466282e+92, 1.375973022137941526e+95, 1.281852367543412945e+98, 1.482130127201990503e+101, 2.141574273792435314e+104, 3.894495540947112380e+107, 8.978646362580102961e+110, 2.644131589807244050e+114, 1.002403539841913834e+118, 4.931412804903905259e+121, 3.174401112435865044e+125, 2.696624001761892390e+129, 3.049799322320447166e+133, 4.634041526818687785e+137, 9.548983134803106512e+141, 2.694404866192089829e+146, 1.051502720036395325e+151, 5.734170640626244955e+155, }, + { 1.570962550997832611e+00, 1.572292902367211961e+00, 1.574956581912666755e+00, 1.578959553636163985e+00, 1.584310789563614305e+00, 1.591022301117035107e+00, 1.599109181186160337e+00, 1.608589657109067468e+00, 1.619485154826419743e+00, 1.631820374530739318e+00, 1.645623378191125679e+00, 1.660925689395424109e+00, 1.677762406016463717e+00, 1.696172326277082973e+00, 1.716198088860732467e+00, 1.737886327791014562e+00, 1.761287842885152410e+00, 1.786457786673686420e+00, 1.813455868772335587e+00, 1.842346578792652542e+00, 1.873199428986627521e+00, 1.906089217937612619e+00, 1.941096316736779451e+00, 1.978306979221816566e+00, 2.017813678003844337e+00, 2.059715468170813895e+00, 2.104118380732327493e+00, 2.151135848063375554e+00, 2.200889163814591418e+00, 2.253507979986114202e+00, 2.309130844113053375e+00, 2.367905779785113334e+00, 2.429990914023652954e+00, 2.495555155369085590e+00, 2.564778926893134514e+00, 2.637854958747451684e+00, 2.714989145296268067e+00, 2.796401472360280536e+00, 2.882327020626578700e+00, 2.973017051860293803e+00, 3.068740185193628238e+00, 3.169783671473487386e+00, 3.276454774427328601e+00, 3.389082268266156098e+00, 3.508018062292869136e+00, 3.633638964133530274e+00, 3.766348594369884204e+00, 3.906579466636309289e+00, 4.054795248667541120e+00, 4.211493221360917802e+00, 4.377206954666462219e+00, 4.552509221059946388e+00, 4.738015169510782826e+00, 4.934385785253587887e+00, 5.142331663338191074e+00, 5.362617126899976224e+00, 5.596064724397100194e+00, 5.843560143744373307e+00, 6.106057585381734693e+00, 6.384585640900671436e+00, 6.680253728973824449e+00, 6.994259146058412709e+00, 7.327894795748901060e+00, 7.682557667824588764e+00, 8.059758146071137270e+00, 8.461130232962342889e+00, 8.888442789395671080e+00, 9.343611899025485155e+00, 9.828714479494622022e+00, 1.034600327721380625e+01, 1.089792339849122916e+01, 1.148713054801325790e+01, 1.211651116619788555e+01, 1.278920468010096321e+01, 1.350862810871281096e+01, 1.427850329305334421e+01, 1.510288705493181327e+01, 1.598620462612703196e+01, 1.693328673269081128e+01, 1.794941076780000506e+01, 1.904034654190823159e+01, 2.021240716182964334e+01, 2.147250566192247370e+01, 2.282821809199713505e+01, 2.428785385941680425e+01, 2.586053422878117785e+01, 2.755628000354674426e+01, 2.938610955221109564e+01, 3.136214849990951329e+01, 3.349775258749912582e+01, 3.580764540799625468e+01, 3.830807296872530167e+01, 4.101697730155473447e+01, 4.395419165876113623e+01, 4.714166019494196927e+01, 5.060368545366659226e+01, 5.436720746019445252e+01, 5.846211877912138439e+01, 6.292162054058128784e+01, 6.778262518512416663e+01, 7.308621254265223015e+01, 7.887814686488147292e+01, 8.520946359734658334e+01, 9.213713603387774717e+01, 9.972483357670754649e+01, 1.080437851679046426e+02, 1.171737636088621692e+02, 1.272042089988687372e+02, 1.382355124664102373e+02, 1.503804848151483311e+02, 1.637660387526102742e+02, 1.785351181233383403e+02, 1.948489131607280604e+02, 2.128894073598352670e+02, 2.328623093447990790e+02, 2.550004322843281994e+02, 2.795675942672445782e+02, 3.068631259124280934e+02, 3.372270867451200874e+02, 3.710463099965576255e+02, 4.087614170466174911e+02, 4.508749684194593670e+02, 4.979609488959773491e+02, 5.506758209385785877e+02, 6.097714244663179092e+02, 6.761100535726473685e+02, 7.506821038741422446e+02, 8.346267600518081192e+02, 9.292562845315541998e+02, 1.036084578498234728e+03, 1.156860819661897657e+03, 1.293609142453808600e+03, 1.448675521854205144e+03, 1.624783259532197615e+03, 1.825098759915318560e+03, 2.053309635972617554e+03, 2.313717614494777200e+03, 2.611349236640186999e+03, 2.952087994093624299e+03, 3.342832332560548180e+03, 3.791684927756595099e+03, 4.308179838716318955e+03, 4.903555624570201673e+03, 5.591084343634811452e+03, 6.386468625571246341e+03, 7.308321829412979440e+03, 8.378749812799703561e+03, 9.624057218749638059e+03, 1.107560666191146008e+04, 1.277086605445904388e+04, 1.475468792019489452e+04, 1.708087537417066343e+04, 1.981410309695485051e+04, 2.303227888204754908e+04, 2.682945317928632535e+04, 3.131941178398428200e+04, 3.664012209706997997e+04, 4.295924836668690170e+04, 5.048100882639843572e+04, 5.945472133180055290e+04, 7.018547875172689579e+04, 8.304751726175694003e+04, 9.850099805053575446e+04, 1.171131266261766060e+05, 1.395847982160589845e+05, 1.667843016393077556e+05, 1.997900626520524686e+05, 2.399449946032992187e+05, 2.889257939838013232e+05, 3.488315309194304548e+05, 4.222972201496778447e+05, 5.126398246369253619e+05, 6.240464876221989792e+05, 7.618179073233615941e+05, 9.326839300224119257e+05, 1.145214007774297539e+06, 1.410352646274233119e+06, 1.742120041875863385e+06, 2.158531716934287014e+06, 2.682809410126426731e+06, 3.344980563595418861e+06, 4.183997972337706048e+06, 5.250558008165501752e+06, 6.610860174141680988e+06, 8.351639423967558693e+06, 1.058692532393929900e+07, 1.346715235106239409e+07, 1.719148271024263021e+07, 2.202453449027701694e+07, 2.831917301724337797e+07, 3.654767820268344932e+07, 4.734452657230626106e+07, 6.156534063509513873e+07, 8.036843026897869248e+07, 1.053280284359690289e+08, 1.385921689084126286e+08, 1.831036985925683524e+08, 2.429109457458640820e+08, 3.236062393759667463e+08, 4.329475218599986663e+08, 5.817432967962929479e+08, 7.851179789388191786e+08, 1.064329197627075307e+09, 1.449389582912945485e+09, 1.982866469377991849e+09, 2.725414314698094324e+09, 3.763867964111621444e+09, 5.223138814950990937e+09, 7.283785810644397704e+09, 1.020809642381158743e+10, 1.437899318470510521e+10, 2.035836812543633578e+10, 2.897499827080027444e+10, 4.145773751645494878e+10, 5.963837683872426287e+10, 8.626228483915530800e+10, 1.254667045389825180e+11, 1.835212982264913186e+11, 2.699812207400151604e+11, 3.994928452151922954e+11, 5.946380558701434550e+11, 8.904409967424091107e+11, 1.341551941677775838e+12, 2.033768550332151892e+12, 3.102627959875753214e+12, 4.763598321705862063e+12, 7.361420360560813584e+12, 1.145126961456557423e+13, 1.793314186996273926e+13, 2.827585501285792232e+13, 4.489297053678444669e+13, 7.177802872658499571e+13, 1.155855098545820625e+14, 1.874833886367883093e+14, 3.063510356402174454e+14, 5.043400653005970242e+14, 8.366163396892429890e+14, 1.398556351640947289e+15, 2.356335749516164682e+15, 4.001765167382637456e+15, 6.851375128404941445e+15, 1.182690111761543990e+16, 2.058673527013806443e+16, 3.613968784314904633e+16, 6.399112184394213551e+16, 1.143016185628376923e+17, 2.059881383915666443e+17, 3.745846788353680914e+17, 6.874443034683149068e+17, 1.273407643613485314e+18, 2.381241916829895366e+18, 4.495835617307108399e+18, 8.571442024901952701e+18, 1.650443584181656965e+19, 3.210100352421317851e+19, 6.307780124442703091e+19, 1.252404031157661279e+20, 2.513005295649985394e+20, 5.096776255690838436e+20, 1.045019200016673046e+21, 2.166476479260878466e+21, 4.542138145678395463e+21, 9.632082324449137128e+21, 2.066386536688254528e+22, 4.485529785554428251e+22, 9.853879573610977508e+22, 2.191158874464374408e+23, 4.932835964390971668e+23, 1.124501529971774363e+24, 2.596269136156756008e+24, 6.072292938313625501e+24, 1.438989066308003836e+25, 3.455841956406570469e+25, 8.412655191713576490e+25, 2.076289061650816510e+26, 5.196515024640220322e+26, 1.319173194089644043e+27, 3.397455895980380794e+27, 8.879057454438503591e+27, 2.355272361492064126e+28, 6.342762007722624824e+28, 1.734531093990859705e+29, 4.817893170606830871e+29, 1.359597346490148232e+30, 3.898969689906500392e+30, 1.136542986529989936e+31, 3.368450043991780017e+31, 1.015304084709817260e+32, 3.113144376221918237e+32, 9.713072739730140403e+32, 3.084517643581725946e+33, 9.972682139820497284e+33, 3.283625052288491586e+34, 1.101378785390827536e+35, 3.764333367592714297e+35, 1.311403465938242926e+36, 4.658135710682813672e+36, 1.687517347470511392e+37, 6.237053685018323490e+37, 2.352571314427744869e+38, 9.058938240219699936e+38, 3.562249097611136071e+39, 1.430959291578558210e+40, 5.873974584984375049e+40, 2.464828549811283787e+41, 1.057649203090855628e+42, 4.642475639281078035e+42, 2.085287118272421779e+43, 9.588439985186632177e+43, 4.514982011246092280e+44, 2.177974048341973204e+45, 1.076720976822900458e+46, 5.457267432929085589e+46, 2.836869270455781134e+47, 1.513103201392011626e+48, 8.283974667225617075e+48, 4.657239491995971344e+49, 2.689796370712836937e+50, 1.596597846911970388e+51, 9.744154538256586629e+51, 6.117238394843313065e+52, 3.952049650585241827e+53, 2.628701592074258213e+54, 1.800990196502679393e+55, 1.271554462563068383e+56, 9.255880104477760711e+56, 6.949737920133919393e+57, 5.385167200769965621e+58, 4.308493668102978774e+59, 3.560951557542178371e+60, 3.041888528384649992e+61, 2.687094441930837189e+62, 2.455920538900000855e+63, 2.323648254168641537e+64, 2.277129741584892331e+65, 2.312633552913224734e+66, 2.435407592981291129e+67, 2.660910388822465246e+68, 3.018105943423533920e+69, 3.555823489510192503e+70, 4.354188877793849013e+71, 5.544975795511813315e+72, 7.348276481909886336e+73, 1.013998025722423261e+75, 1.457911462244607943e+76, 2.185488876819505295e+77, 3.418022153286623008e+78, 5.580843920601835728e+79, 9.519586502799733908e+80, 1.697573578247197786e+82, 3.166906670990180014e+83, 6.185099106418675430e+84, 1.265541134386934377e+86, 2.714828965877756899e+87, 6.110386802964494082e+88, 1.444054086171083239e+90, 3.586083726638388165e+91, 9.365231868063239600e+92, 2.574080116205122449e+94, 7.452134689862302719e+95, 2.274309903836169819e+97, 7.323011134121164749e+98, 2.489816421737932462e+100, 8.946533386359281588e+101, 3.400401372391165979e+103, 1.368288186208928217e+105, 5.834277489829591931e+106, 2.638486937672383424e+108, 1.266728882767139521e+110, 6.462225178314182803e+111, 3.506432320607573604e+113, 2.025608933943268165e+115, 1.247041677084784707e+117, 8.189865188405279038e+118, 5.743610894406099965e+120, 4.305808934084489763e+122, 3.454156966079496755e+124, 2.968316601530352737e+126, 2.735456242372183592e+128, 2.706317176690077847e+130, 2.877679916342060385e+132, 3.292412878268106390e+134, 4.057840961953725969e+136, 5.393783049105737324e+138, 7.741523901672235406e+140, 1.201209962310668456e+143, 2.017456079556807301e+145, 3.672176623483062526e+147, 7.253163798058577630e+149, 1.556591535302570570e+152, 3.634399832790394885e+154, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 6.114056619798597593; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} + +#if LDBL_MAX_EXP == 16384 +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828741797632286606397498241221385e+00L, 1.48993184649209158013612709175719825e+02L, 3.41228924788343710247727162226946917e+06L, 2.06932576604261779073902718911207249e+18L, 2.08700240760947556038306635808129743e+50L, 2.01976616071790815078008252209994199e+137L, 5.67213444764437168603513205349222232e+373L, 3.06198394306784061113736467298565948e+1016L, }, + { 9.13048762637669674838078869945948356e-01L, 1.41578929466281159169215570833490092e+01L, 6.70421551622327648231120321610008518e+03L, 9.64172532715049941526010563818587232e+10L, 2.50895076008577848514087028569888161e+30L, 1.44726353571033714499079379626715686e+83L, 3.75263401205045334128277886549019357e+226L, 2.57846123932685341261715758547064293e+616L, 1.25169402230987931584130068460134989e+1676L, }, + { 4.07297690065758690150573950473604675e-01L, 1.68206670702114874332932330092838356e+00L, 6.15089798638672951539668935798437533e+00L, 4.00396235192940022205839866641270319e+01L, 7.92920024793102632052902471550336177e+02L, 1.02984971333097958319686053784919407e+05L, 3.03862310925243857437932941891415841e+08L, 1.56544547436249486913719231527597560e+14L, 4.04246509843021910355659662715183671e+23L, 1.32170682742965817915034577861235933e+39L, 4.99123178209955799774620736137366103e+64L, 7.35294385035987596594501676609562008e+106L, 2.45145417229813114714431821340237112e+176L, 1.03030479197459267961759023741376327e+291L, 9.88478945193556730604342445576518136e+479L, 3.74498116076433060427765453233124618e+791L, 1.90292390713026708045766158039087796e+1305L, 1.72712488231809244721915842027236657e+2152L, }, + { 1.98135272251478172615235718398538323e-01L, 6.40155673500526017670785720911319502e-01L, 1.24892869825397766254802900819319987e+00L, 2.26608084094432123181038001270985037e+00L, 4.29646269670232738148137717958679987e+00L, 9.13029038709995569641811827045549232e+00L, 2.31110765386427993316995139635470937e+01L, 7.42770603432401243012214481410240677e+01L, 3.26720920711525891697790966796945063e+02L, 2.15948569431181871552028449867301828e+03L, 2.41501526289641306037808670196966696e+04L, 5.31819400275692915826269282626844010e+05L, 2.80058685721704332307817790755562305e+07L, 4.52406507979433877971977526863358905e+09L, 3.08561257398067712180174566763237112e+12L, 1.33882673301580747789133427708622972e+16L, 6.25461717656234138147247754416652254e+20L, 6.18209853581416475394863999233554548e+26L, 3.07729364978845806686511011060697837e+34L, 2.34895728937010430290698332595743680e+44L, 1.14854319789946975790127332653552673e+57L, 2.25530007001006986846545694404767295e+73L, 1.87791950056919539419801461538703336e+94L, 1.36747388793862427976781689638282239e+121L, 4.24212177246407592514720294750151286e+155L, 8.23473099012134325391170623028607158e+199L, 6.06134211888406631001019923425936351e+256L, 6.32519197436029413652766295658658263e+329L, 3.61942292928205643948383705201563065e+423L, 8.82464433126646489632943769283758364e+543L, 3.35512488018651738642854323317447493e+698L, 1.02411434678684822400261582079656500e+897L, 7.40716670979374017620610271197945784e+1151L, 1.30455147283895162835186634827124464e+1479L, 2.02948723345659016173510134582487641e+1899L, 6.99019443250345564805134094483457477e+2438L, }, + { 9.83967894006732033862249554537934739e-02L, 3.00605617659955035122465185012715805e-01L, 5.19857978994938490000644785900799951e-01L, 7.70362083298887700858583505753306721e-01L, 1.07131136964131183026831222500748063e+00L, 1.45056975808899844502126797109703210e+00L, 1.95077854952036033400296546339240312e+00L, 2.64003177369555146770080103921424631e+00L, 3.63137237366741227331951933364601985e+00L, 5.11991533090335057003526222543242753e+00L, 7.45666098140488328926087222725984231e+00L, 1.13022612688997262443461342203136009e+01L, 1.79641069247277254966592982669611020e+01L, 3.01781070460189822236726995418068214e+01L, 5.40387580031237056709826662540066860e+01L, 1.04107731447746954767459980678311109e+02L, 2.18029520120262807725988909352359830e+02L, 5.02155698625910164594509258651311707e+02L, 1.28862131099822242045586488612672886e+03L, 3.73921687080054832376623401153054636e+03L, 1.24750729702019123239464970064060864e+04L, 4.87639975322669212414357357061002683e+04L, 2.28145658221913012154676335814417144e+05L, 1.30877796006484301664040981436471740e+06L, 9.46084663420966407698078336053299177e+06L, 8.88883120363727962245667776649286152e+07L, 1.12416882897434413447175648471746990e+09L, 1.99127672953214446985509145592687205e+10L, 5.16743469106098464964433058111638245e+11L, 2.06721881420399088776240044545119948e+13L, 1.35061503318410040604770421574064883e+15L, 1.53854066283650818848773859278941683e+17L, 3.29074729054035066052820102585085173e+19L, 1.43729138188449881561963100200796631e+22L, 1.40983244553034728562740932242727657e+25L, 3.45913548027797144127990544649862792e+28L, 2.39872058234095409213724024023509754e+32L, 5.39880660461729295997086364918754801e+36L, 4.61334000258062860955942270137550165e+41L, 1.78768590966790245678294238939560892e+47L, 3.84198437012433853552557148945213178e+53L, 5.75279795570858370009870455748773410e+60L, 7.77181203842728655149182334288749850e+68L, 1.26967304420408162635234502672130357e+78L, 3.49567677376573156773252547632961336e+88L, 2.36251947497169244454694635287097330e+100L, 6.00214389327365112307366927985587840e+113L, 9.29071630346415553922675334522602561e+128L, 1.51444223803384709004933819608345315e+146L, 4.83290204410990250226310317342789471e+165L, 6.09623012864338569215560315517200736e+187L, 6.73889214277659359787962707085479315e+212L, 1.60917893672694484647176104023542732e+241L, 2.30724123468764987944582372785293125e+273L, 6.32636439816284705814531208407868829e+309L, 1.23274815890184688792156489065830724e+351L, 7.55519778823055185901318833981345378e+397L, 7.85730655106759111844772008129590573e+450L, 9.36328400229780321059086898529742817e+510L, 1.11332545426270395766246494603539938e+579L, 1.53432069979625061288117473415446630e+656L, 3.94622553764411915381186808199466267e+743L, 4.41554290953392996069257034424439949e+842L, 7.62037777854651720247173134262034607e+954L, 1.15650294539918196985498353779647134e+1082L, 1.50761161209705395018419027031866347e+1226L, 3.03485088181756935935831645680716816e+1389L, 3.38561189018537177501905611143498298e+1574L, 1.64407968993192526511230001818530622e+1784L, 6.63148743223242467667800355907041029e+2021L, 1.15911606715877477373516464924821476e+2291L, }, + { 4.91151003502902493004859475143401791e-02L, 1.48013149674360733270682895306542340e-01L, 2.48938813740683685679302156785267041e-01L, 3.53325423692668437764413545980527251e-01L, 4.62733556612235325924240102411897269e-01L, 5.78912068164096306746325958452873475e-01L, 7.03870253386062779930091622585657886e-01L, 8.39965859144650568772715366992985538e-01L, 9.90015066424437614655918533324528544e-01L, 1.15743257014369913143250540144278056e+00L, 1.34641275918536176274682426896283388e+00L, 1.56216711390133555099139972670978661e+00L, 1.81123885278232337973709010374295886e+00L, 2.10192441900655030086142289233010995e+00L, 2.44484388558419793403331221069953203e+00L, 2.85372074663291502355627105440782037e+00L, 3.34645891095535078662878051589922609e+00L, 3.94664582105783838715586741669722603e+00L, 4.68567310159667852940801410152900804e+00L, 5.60576223090815117543658276010994803e+00L, 6.76433233683057420359243855855175747e+00L, 8.24038317537998522052755780107530197e+00L, 1.01439435612985772971719760903679427e+01L, 1.26302471433889247197016543768391586e+01L, 1.59213039578034525767683420917805218e+01L, 2.03392186192185718515730871595417962e+01L, 2.63584644576063375239063530328964372e+01L, 3.46892633322415240903243772580777748e+01L, 4.64129146701972896279022543245987086e+01L, 6.32055079389042420324823016892494512e+01L, 8.77149726180890637368701810147417239e+01L, 1.24209692624041149789460094889690346e+02L, 1.79718634784512755704082576283626343e+02L, 2.66081728332790018970422286819998479e+02L, 4.03727302957571284052623415274320934e+02L, 6.28811306654590870314912279241546792e+02L, 1.00707983750749059403228978538051896e+03L, 1.66156822918511428805794334715835287e+03L, 2.82965144078658259775800007408843245e+03L, 4.98438626658566913853681230634186899e+03L, 9.10154692764781089316711776560031531e+03L, 1.72689265547504972749956316341831556e+04L, 3.41309957877860119013952370617496464e+04L, 7.04566897705309280220071327032864763e+04L, 1.52340421776127912819322591860346971e+05L, 3.46047978289794741370038030428999755e+05L, 8.28472420923318300234685980449600520e+05L, 2.09759614660119394556971994518988102e+06L, 5.63695079886127323617800640982012165e+06L, 1.61407141085560724511058572293479599e+07L, 4.94473067891506035994359725043521250e+07L, 1.62781051682099135552732962095205423e+08L, 5.78533297163228083837980097936281368e+08L, 2.23083854068195568971189557384768608e+09L, 9.38239130606473964277252886929412279e+09L, 4.32814954477655169232818147143370442e+10L, 2.20307274404924290439096300978395664e+11L, 1.24524506710913641251205336694034299e+12L, 7.86900053495782237478847410099854059e+12L, 5.59953143297942246131549106648666176e+13L, 4.52148694990209087674492643778610401e+14L, 4.17688951654829326508268412199901397e+15L, 4.45286775965049665585698503105745526e+16L, 5.52914285314049806809138826588984682e+17L, 8.07573251656285427526228838811700627e+18L, 1.40204691626046869792238856080062664e+20L, 2.92579141283223985009947325351094360e+21L, 7.42643302933541088612408356755400686e+22L, 2.32199633124573536432554419147246735e+24L, 9.06419425063844243203436385576505269e+25L, 4.48127904881944560890552322697008678e+27L, 2.84904630472699064463968599282594753e+29L, 2.36738115918335597454764956918757980e+31L, 2.61582557845512122680388807973635504e+33L, 3.91476494826329080795479762913295296e+35L, 8.09204244855592921872201325412806040e+37L, 2.35892132094063033238721339006551614e+40L, 9.91521864853533259120934844876236731e+42L, 6.15285105934265876352030730244956160e+45L, 5.78027634014451538840307809528507880e+48L, 8.44375173418648862568787172019022001e+51L, 1.97334335089976670761175825761931164e+55L, 7.60524737855621997973474323106432459e+58L, 4.99205710493951041807363394610235299e+62L, 5.77586342390391231642398949899839793e+66L, 1.22180820194535560304052518248291191e+71L, 4.91291723038713381630505551954597084e+75L, 3.91397181373220237220120723831917341e+80L, 6.45638806990528678730571952330861768e+85L, 2.31122506852801035759561549878351498e+91L, 1.88745815771943133919251977215527414e+97L, 3.70848316543845309405007424631179900e+103L, 1.85519881228353863491690263658048910e+110L, 2.50978787317170531780713813087390423e+117L, 9.79042375559121661656574862110333881e+124L, 1.17908880794405074709159757136517906e+133L, 4.71463184672247661988055185868884361e+141L, 6.76265778595971324046101731037889126e+150L, 3.77863792934416463055998231270977695e+160L, 8.97819133628477274891556066769979914e+170L, 9.95914407403494739885505580434362313e+181L, 5.69630798679205432723450802096176313e+193L, 1.86743452325707784871951519925288377e+206L, 3.92719945859412568046939678789391943e+219L, 5.97262802266570558434581771213406728e+233L, 7.46293577265068378653739984957785219e+248L, 8.77620026161886682323882402399676732e+264L, 1.12240955327637524990782988952974327e+282L, 1.82091452946462555573948654780251641e+300L, 4.41446070956615785669448222555093749e+319L, 1.90397541953366074155779318767572880e+340L, 1.75902281129585020130874703618203168e+362L, 4.24169226543235148528312412985493520e+385L, 3.29481560149200680874049429678412127e+410L, 1.03135148368973063748422508803572335e+437L, 1.65119340908368036904973428016231291e+465L, 1.74266589416784110509614783944413581e+495L, 1.58844581452329281145953920728196433e+527L, 1.66707913260906132496128590135534752e+561L, 2.73591938942385354685476950777714705e+597L, 9.72579530056263762611950442873242859e+635L, 1.05939976357545005153997575210948938e+677L, 5.11518133258374954640812727174811520e+720L, 1.62189977683387633564608415164137138e+767L, 5.13160378352024380054652132361473058e+816L, 2.52913238575275285564889845966314333e+869L, 3.11944472707029467274111976509771118e+925L, 1.59495166899855372832309254674677663e+985L, 5.78489108811836645985010918537259212e+1048L, 2.63682062563962607583302320466728244e+1116L, 2.77639914729635446526568065100606294e+1188L, 1.29100591117079370649785145859270604e+1265L, 5.28444381883484729377275155781628201e+1346L, 3.96822241951490935324304074734991606e+1433L, 1.19450143809568524145027520220707370e+1526L, 3.31232848440880307300003548888720354e+1624L, 2.05165402811808892980123939590704909e+1729L, 7.28745294435475474950235921073537827e+1840L, 4.04980582052614743975213722266303496e+1959L, 1.02489069982330185861864247663932840e+2086L, 3.68323339665104313610706754895420191e+2220L, 6.30765607309438726154024457882187086e+2363L, }, + { 2.45471558362986365068916495863375252e-02L, 7.37246687390334622422734853496288652e-02L, 1.23152530941676654318795303724845312e-01L, 1.73000137771924855589325108501317324e-01L, 2.23440664959686000105440799041805360e-01L, 2.74652654971851825832501290298110601e-01L, 3.26821679298064666878532098621581949e-01L, 3.80142100980478924532143540106066542e-01L, 4.34818963721561494844111167726460593e-01L, 4.91070036509942840677161193401564426e-01L, 5.49128045948021544092182270959032951e-01L, 6.09243132438265439671151238479162657e-01L, 6.71685571202114806905814141850507988e-01L, 7.36748804906793864301473114817726587e-01L, 8.04752841633695064447122683633828025e-01L, 8.76048080248205070538153903222362252e-01L, 9.51019635182333225305914695670696308e-01L, 1.03009224453247006650365629888427541e+00L, 1.11373585958868076495962122155474153e+00L, 1.20247203091805887562283157205483916e+00L, 1.29688122649686375081031224280895230e+00L, 1.39761124182837302592381732283067440e+00L, 1.50538689136054520464181654424860094e+00L, 1.62102120589479802996006107398491112e+00L, 1.74542840336904457155639617870301735e+00L, 1.87963895203102933109827214352261973e+00L, 2.02481710760932852386806039721112499e+00L, 2.18228138214788418140109912591097815e+00L, 2.35352849482388135462737441996874099e+00L, 2.54026146822962645747200253699005204e+00L, 2.74442267217147811137997080576917741e+00L, 2.96823278719060661900608946565759698e+00L, 3.21423686952065766588900110700898117e+00L, 3.48535895790773046725176601804623352e+00L, 3.78496698311737282096444166343378976e+00L, 4.11695013894029509955211911245969952e+00L, 4.48581136938823171042685637747918431e+00L, 4.89677824656200181220988391922608405e+00L, 5.35593629082672594809503436864536474e+00L, 5.87038976260095690701450882557564694e+00L, 6.44845618913111760490837120481487939e+00L, 7.09990245267955823638498704195342171e+00L, 7.83623225328284126133289428371735767e+00L, 8.67103729357523063452024155765264339e+00L, 9.62042777798599036292354986394365067e+00L, 1.07035619887679953097266587864897721e+01L, 1.19433000813944102150187593166292839e+01L, 1.33670142103849964717469335941905385e+01L, 1.50075961591439634296262105146352627e+01L, 1.69047154820352837629069726738079470e+01L, 1.91063966873168959742774555727687289e+01L, 2.16710044321657799400571191555580338e+01L, 2.46697527469509919694460528848277171e+01L, 2.81898902515784535507915179415086299e+01L, 3.23387613242940174515264777910328241e+01L, 3.72490075809724574016769417176033924e+01L, 4.30852608490774199699508301986096898e+01L, 5.00527964765470397507453905247128474e+01L, 5.84087760725387652778097774354827947e+01L, 6.84769282153423986221602875181609661e+01L, 8.06668177706071484780398912645020900e+01L, 9.54992727020024926023862465179431320e+01L, 1.13640119576948788485338465195796676e+02L, 1.35945194497660320895127779474436433e+02L, 1.63520745187974444650772294136165162e+02L, 1.97804968791258694996900535479466855e+02L, 2.40678753588977666070114453459006852e+02L, 2.94617029293055502283701272741864024e+02L, 3.62896953214712533295812475420140158e+02L, 4.49886178271559690246754005443952599e+02L, 5.61444735313349610605402755114132063e+02L, 7.05489247089927142932822047183046835e+02L, 8.92790773279996411641203534672635638e+02L, 1.13811142497947837649816383892464930e+03L, 1.46183599156360536709532001371341489e+03L, 1.89233262344471618571971876282268943e+03L, 2.46939603618613347923158360306283371e+03L, 3.24931156929882473061795067124714454e+03L, 4.31236711317028301201344127304044700e+03L, 5.77409475450013966113987691727433327e+03L, 7.80224723750085184509285318864950930e+03L, 1.06426753097580697178856711472253120e+04L, 1.46591538353567498972551254799117195e+04L, 2.03952854123975483493635354197048606e+04L, 2.86717062242155626463726121489695136e+04L, 4.07403376218345329677215262695648133e+04L, 5.85318231059692339303875522971681880e+04L, 8.50568926526520663990658694675860445e+04L, 1.25064926984785661460287048343378461e+05L, 1.86137394316674976633487938076388915e+05L, 2.80525577745201092730917964861422661e+05L, 4.28278248608476174804382253986989659e+05L, 6.62634050612765730354133581004327179e+05L, 1.03944323965033956450234998906270616e+06L, 1.65385742611296131560210844780522467e+06L, 2.67031565012527916099202454680251592e+06L, 4.37721202662435879490158484533403820e+06L, 7.28807171369841382127860775464397414e+06L, 1.23317299340033169377433189565436518e+07L, 2.12155728576993369873860452866846505e+07L, 3.71308625486153538260132253550700609e+07L, 6.61457937735213553402161639469475625e+07L, 1.20005529169491711045823979192639236e+08L, 2.21862941029688069011551388945586459e+08L, 4.18228293992868770261761230703186170e+08L, 8.04370413249371480388874614907492609e+08L, 1.57939298942566811374336496311019268e+09L, 3.16812241552410463468859624242708347e+09L, 6.49660681154986132317647460889788282e+09L, 1.36285198835644448552647856869429224e+10L, 2.92686389700870770766115985553270450e+10L, 6.43979866520949373493178830943697748e+10L, 1.45275523377290302218030864454825923e+11L, 3.36285445938924657613055409970261746e+11L, 7.99420278543347927144872935893265787e+11L, 1.95326423336229196043471517599153542e+12L, 4.90958186824255456862636657247754379e+12L, 1.27062273076501561032764305894113023e+13L, 3.38907098674298576400746683674724217e+13L, 9.32508403020884483292253012776198040e+13L, 2.64948942383453414004877623922649545e+14L, 7.78129518409495719454885394657867226e+14L, 2.36471505252735563941195059995826485e+15L, 7.44413803146595825477962585154187758e+15L, 2.43021724068474963516185214140527324e+16L, 8.23706864153435776160816132466078110e+16L, 2.90211705066454883998576313308511774e+17L, 1.06415767940403701307268606275625099e+18L, 4.06627710606196001743762877107146413e+18L, 1.62127423363035909653152786372227505e+19L, 6.75415683091545001302004267324917730e+19L, 2.94405684173378191865875139697985419e+20L, 1.34464013954910781728162580030274237e+21L, 6.44458615894472329986968048792306357e+21L, 3.24621866755460893428420802873638947e+22L, 1.72123457955665353317614924039447693e+23L, 9.62253389024047439092145016046085843e+23L, 5.68140726041795667144549981860838281e+24L, 3.54889077999592818369666361009585253e+25L, 2.34950642567226956175428754094351900e+26L, 1.65161813060520564300895544060422208e+27L, 1.23514742649311305869239755896991097e+28L, 9.84594723979205755046350596451684287e+28L, 8.38313078198461041780434493882428621e+29L, 7.63964946139917244491542497186650823e+30L, 7.46786273223388520123213229503835823e+31L, 7.84769148200499366026301301860529069e+32L, 8.88603255762645470434690507794367917e+33L, 1.08673489067830243582954987160820285e+35L, 1.43896777703653845844251806933839180e+36L, 2.06816886547560352123602144529722761e+37L, 3.23488532022391238528760911223890778e+38L, 5.52123364154262851432456431974095092e+39L, 1.03114823119466385539623421556538031e+41L, 2.11327203581636598172202380321061095e+42L, 4.76672434548507751952154119062281282e+43L, 1.18696155099021828703717401094811909e+45L, 3.27317216920584757332668902845797411e+46L, 1.00282122676916775281745610945056481e+48L, 3.42493390393515647893744567642140320e+49L, 1.30843601702642873582064430681159468e+51L, 5.61137833004842050312648039721074217e+52L, 2.71142480632713929135631433480050921e+54L, 1.48177179364406644198189668782951739e+56L, 9.19428207104277880378138495715383545e+57L, 6.50366145587535556181715778862405651e+59L, 5.26632998686862730262822409628217101e+61L, 4.90266280796934735938520451826335739e+63L, 5.27051105728955705039001489033126495e+65L, 6.57285651167058331634360929791632134e+67L, 9.55395603001322538662375429270666445e+69L, 1.62649191115941161585027771743899152e+72L, 3.25941091550095122341298778408441950e+74L, 7.72846031811361427986096662411063427e+76L, 2.17988199690591805869859473392710071e+79L, 7.35448438837150591476717971591286847e+81L, 2.98483127080395774595532033544389202e+84L, 1.46582826781343896171132281512590065e+87L, 8.76335597262986426104836504228132778e+89L, 6.41790966584783113047113716478179340e+92L, 5.79495864922989350993450871503126827e+95L, 6.49422447231190836548908540847688948e+98L, 9.09500015601643369774077853623649258e+101L, 1.60305849845529910220272077472033035e+105L, 3.58209911911932052869313856359636456e+108L, 1.02244122713985468653173668554645414e+112L, 3.75687218501508605716480350749498176e+115L, 1.79136346383284915921138840751400855e+119L, 1.11764188203947212384081419514165395e+123L, 9.20215956554652828530686799399533824e+126L, 1.00871647482788856814534779759128531e+131L, 1.48554648708930180487801088228218062e+135L, 2.96696153483056609742176098165601109e+139L, 8.11420728466436936033056414100674073e+143L, 3.06917808750766973862958599324080278e+148L, 1.62222368114779147260405024572949430e+153L, 1.21094608845400598319807865894230970e+158L, 1.29069460371207764384235331328282226e+163L, 1.98663030134211110165437011771903132e+168L, 4.46757261704134429970068624260491498e+173L, 1.48564187771108280640829188970287255e+179L, 7.39669065831627851911038512117013389e+184L, 5.58477447271859974925476129175614574e+190L, 6.47976647473179732779115257999520915e+196L, 1.17117420317317171387535528766936277e+203L, 3.34428267755162742939489398076764840e+209L, 1.53076558056194845489001829008909627e+216L, 1.14010185551912954998170816176845430e+223L, 1.40319939603195121408389523582430293e+230L, 2.89974936197123389451668716314083017e+237L, 1.02284833216532051937856086912560392e+245L, 6.26387216223145817942640023700922965e+252L, 6.77735971213475345230129326178116125e+260L, 1.31920032114466459135766725110063188e+269L, 4.70640341492973980389482209817290571e+277L, 3.13724441498341266441161693520329378e+286L, 3.98571382107801782113811082484615717e+295L, 9.85039693194582447444400924997258508e+304L, 4.83687381317675554709367324551273400e+314L, 4.82285202614019890234802453942628315e+324L, 9.98703239968301934722476402798215616e+334L, 4.39579560388542750852159646726102667e+345L, 4.21213245293498773753031381258995955e+356L, 9.00647826017501992250418906434620537e+367L, 4.40820570973056960340923739077146754e+379L, 5.07036496321109968512657627671150030e+391L, 1.40820593625978850981984707085120209e+404L, 9.71170922560303314648712317222502389e+416L, 1.71185299004740150846260848238269630e+430L, 7.94539187117702846067322763172557224e+443L, 1.00135866851780201306228838620557915e+458L, 3.53720801942577272956188201390769482e+472L, 3.61856514873836509067172206947444182e+487L, 1.10885899005952624619970603738429749e+503L, 1.05391354932473165812334641476989979e+519L, 3.22052822779158301893419142803165095e+535L, 3.28354332174247719776999412908271692e+552L, 1.16054782509911106933820737153108500e+570L, 1.47919833966504706156198174688381009e+588L, 7.08133783868969672071172398101964598e+606L, 1.32792489232842472677863721400834701e+626L, 1.01864740027867286775312222487805144e+646L, 3.34261841519397423195159276540555265e+666L, 4.91359232957804830460198547632977969e+687L, 3.39338961080932963058551495328009206e+709L, 1.15643101006244038688616288204262882e+732L, 2.04580060100421448267115092746141073e+755L, 1.97956226677236405650286559215774642e+779L, 1.10576482674657666978217926798043956e+804L, 3.76975534316002585938373910751464161e+829L, 8.30723712530280347580443574905340732e+855L, 1.25551214072288994426628885709173410e+883L, 1.38340901524945057559377504414014724e+911L, 1.18367583857036159478030255830898223e+940L, 8.39312984240762796712708279978405886e+969L, 5.27445408794117779852142535860614541e+1000L, 3.14827291975085189890248083313318702e+1032L, 1.91708860929520191993037622102307238e+1065L, 1.28205230070904948620917170049585485e+1099L, 1.01601053886738575799673411634857928e+1134L, 1.03205637073787228175634527391820202e+1170L, 1.45709248520841293241982349536788740e+1207L, 3.10836026767661586110721101783586616e+1245L, 1.09211875259058272695772315187071594e+1285L, 6.90756042513315914107755467851436390e+1325L, 8.62072629674515227183116754798059355e+1367L, 2.33367455582609053817676883927592981e+1411L, 1.51088703661957707064674032871094166e+1456L, 2.58751847359969149251723060639056652e+1502L, 1.30061395127966085145757755976532379e+1550L, 2.13606222552299322654005297188550444e+1599L, 1.28040046650693999927593879574416998e+1650L, 3.14004479696111085451082602060045251e+1702L, 3.54445798947819813290733040762684700e+1756L, 2.07959058928044687396800353571401401e+1812L, 7.18928436789152221379187719747515467e+1869L, 1.66674057039586083195182422956301841e+1929L, 2.96144319154423967308042996118314268e+1990L, 4.62818622228372755683383431403798070e+2053L, 7.33344579812102490343077358675798902e+2118L, 1.36418147108226874642787854899398972e+2186L, 3.46578234556914165783357030404723460e+2255L, 1.40565670831906218450256157719581702e+2327L, 1.06915717420033634558717882909227336e+2401L, }, + { 1.22722791705463782987186673092730169e-02L, 3.68272289449259047084662870963424169e-02L, 6.14133762687107999107794380606156658e-02L, 8.60515970877820790729887694832007789e-02L, 1.10762884001784544594356091768970671e-01L, 1.35568393495778548180370153140547366e-01L, 1.60489493745433548938038568465534727e-01L, 1.85547813164508949628358434474487020e-01L, 2.10765289867070052445854835116288718e-01L, 2.36164222221462626796458521613760417e-01L, 2.61767320678549526133854585166690062e-01L, 2.87597761063134290040469640683594256e-01L, 3.13679239524903564719983726260388052e-01L, 3.40036029353663277020320913399073202e-01L, 3.66693039873181019259593465683200480e-01L, 3.93675877638645179710808224562806486e-01L, 4.21010910174684626844126582677407364e-01L, 4.48725332504145034061613569614932171e-01L, 4.76847236732482946224267058692370227e-01L, 5.05405684968820937507178521019349537e-01L, 5.34430785882522907921272727308422687e-01L, 5.63953775213726713429575640521392073e-01L, 5.94007100577754899987320597582638522e-01L, 6.24624510926871605306723866692531653e-01L, 6.55841151058639796949436231740377164e-01L, 6.87693661588351492208131027097817883e-01L, 7.20220284833868340062109216385730821e-01L, 7.53460977094957222390047011401038344e-01L, 7.87457527846096346070444259791519611e-01L, 8.22253686402049937748559808122413409e-01L, 8.57895296659582580760899947902549978e-01L, 8.94430440566859300921740259698532581e-01L, 9.31909591024743548462187459499302759e-01L, 9.70385774981792065875818381502464879e-01L, 1.00991474754772858364115613090157760e+00L, 1.05055517801908314962647763431650363e+00L, 1.09236884878609257919070489976671100e+00L, 1.13542086817251430035405051069824787e+00L, 1.17977989835042446581611499466432280e+00L, 1.22551839957114260989771330348614290e+00L, 1.27271289206202647251525071825625510e+00L, 1.32144423705798506493224886295961288e+00L, 1.37179793856724595345645859982391269e+00L, 1.42386446761438409645831411537400020e+00L, 1.47773961086120811494347321807905579e+00L, 1.53352484567928885758582112389540236e+00L, 1.59132774393835509765516748425726982e+00L, 1.65126240698431007605515051243084836e+00L, 1.71344993451128821134705183982006487e+00L, 1.77801893028625685775809622156398356e+00L, 1.84510604796472086962932266394457464e+00L, 1.91485658054495189874749078346703174e+00L, 1.98742509734901709257017841100790150e+00L, 2.06297613279527528332657028179424398e+00L, 2.14168493164291678457053660944377397e+00L, 2.22373825584899452105160804133355977e+00L, 2.30933525868721379620595550412858017e+00L, 2.39868843234110382076332419963510302e+00L, 2.49202463580835609502681428341212971e+00L, 2.58958621064512275641789028727789739e+00L, 2.69163219284683244353140722232296853e+00L, 2.79843963001449729057960489638268331e+00L, 2.91030501390256265160483634586060233e+00L, 3.02754583949736496303590546881335550e+00L, 3.15050230294691972178684607549631061e+00L, 3.27953915196739433034632435779672485e+00L, 3.41504770380541061125886820639123018e+00L, 3.55744804745655073349177433143963235e+00L, 3.70719144864977981720917442750632409e+00L, 3.86476297812834212534134362353667523e+00L, 4.03068438601653134401780732606469366e+00L, 4.20551724758861383531605318041260028e+00L, 4.38986640858517245778656669889477004e+00L, 4.58438376139193074830218319449001571e+00L, 4.78977238695068769484017601922716285e+00L, 5.00679110126136326392507134554822932e+00L, 5.23625944981527405022093792997629943e+00L, 5.47906319833752315041593490985864953e+00L, 5.73616037388481741547685088499196591e+00L, 6.00858791672861985829483499535828449e+00L, 6.29746901064886304750229195240462364e+00L, 6.60402116738092913326417425575120773e+00L, 6.92956515012467783689325375523493772e+00L, 7.27553483138386097168028487959046984e+00L, 7.64348809212349206445236344518102598e+00L, 8.03511888250245928810782085772095077e+00L, 8.45227057947818812962999536922397314e+00L, 8.89695079364178531317631891553840631e+00L, 9.37134779701639517335117345438905815e+00L, 9.87784876557344603277558247754926945e+00L, 1.04190600552776203680920477623835667e+01L, 1.09978297590083170587228134865897514e+01L, 1.16172728242395225830192073579898657e+01L, 1.22807990484892461058359016635119689e+01L, 1.29921443119669104778276499842319618e+01L, 1.37554054553562588138800381241813305e+01L, 1.45750792662062131604851118656361439e+01L, 1.54561061010485246793800779406223808e+01L, 1.64039187433830292507497745621200597e+01L, 1.74244971815420897003963134996594183e+01L, 1.85244300868843752575149709549249943e+01L, 1.97109838837826649364051644134983470e+01L, 2.09921804308096164753912694285306280e+01L, 2.23768844801398294581745473457799699e+01L, 2.38749022527007382030837433327528532e+01L, 2.54970926638043046429091560004131137e+01L, 2.72554929623253155508089897070407353e+01L, 2.91634608111962498675086489719161981e+01L, 3.12358351442328496157597338087371982e+01L, 3.34891184913680511842485226603345913e+01L, 3.59416838798546509869193271004218290e+01L, 3.86140099030723073708193155942738501e+01L, 4.15289481132930302349687386068430483e+01L, 4.47120275544153339602356644078995085e+01L, 4.81918020222491017368298630788454953e+01L, 5.20002465436155875740198471916042599e+01L, 5.61732106253738449367657038097317749e+01L, 6.07509370691878207865695555214723350e+01L, 6.57786566116800396636894823760941404e+01L, 7.13072703735772134302608508415302565e+01L, 7.73941341346580579448409414339011685e+01L, 8.41039608526963339165414121007032304e+01L, 9.15098606849673444816151204282990934e+01L, 9.96945411354770401552161275609161166e+01L, 1.08751693942601889700382157585301539e+02L, 1.18787600064303753208251167345242212e+02L, 1.29922989761451637135259469378151165e+02L, 1.42295201505637253678660735501099867e+02L, 1.56060691466500267146385748883961050e+02L, 1.71397954932643240617797882975933747e+02L, 1.88510932515483007342988031066863162e+02L, 2.07632987774012593538662727768467525e+02L, 2.29031559465458736990493497603665470e+02L, 2.53013611565567646662052901877967628e+02L, 2.79932028239889691165098106403660221e+02L, 3.10193129976673089035599193653267696e+02L, 3.44265522210752989223327890530839313e+02L, 3.82690530328937838722167127466549147e+02L, 4.26094526620760770127774483839356753e+02L, 4.75203517589290204505256185266901137e+02L, 5.30860436623905886389110002239619071e+02L, 5.94045680537299500918768911865886523e+02L, 6.65901542833877826224842736585170818e+02L, 7.47761336730915387004112664458834008e+02L, 8.41184173047134302254019501114516601e+02L, 9.47996569801374152415232558717779048e+02L, 1.07034233137588184029692740932268166e+03L, 1.21074245751858265959674123771999362e+03L, 1.37216724155220581953081355884482812e+03L, 1.55812321218769272183468357733000347e+03L, 1.77275818866271628150109400030205931e+03L, 2.02098848541186298361330491694554409e+03L, 2.30865325932916315664195536323762336e+03L, 2.64270218981368427312930076396387941e+03L, 3.03142418286921021219727597009903791e+03L, 3.48472667698575601755930501247710368e+03L, 4.01447750473397350451805793460750946e+03L, 4.63492426404939475098008035447052569e+03L, 5.36320994977343974892087068772061383e+03L, 6.22000841211434280322218569985211936e+03L, 7.23030933285302995642999721294241650e+03L, 8.42439021673521778311062568091410678e+03L, 9.83902287153854178745596238243054980e+03L, 1.15189746308311398832174294139085014e+04L, 1.35188809887437420186309997879371889e+04L, 1.59055874546006694678895534154510667e+04L, 1.87610857276481617624948313285750831e+04L, 2.21862046239336627450920062330548753e+04L, 2.63052620505491535696779646542992118e+04L, 3.12719440194171105738301413156011152e+04L, 3.72767546125665292256151356126569138e+04L, 4.45564828031227324859783992706804335e+04L, 5.34062659201890392985687357687040023e+04L, 6.41950058038891812326608231510870856e+04L, 7.73851264238682005972799669756325711e+04L, 9.35579699398172596314688114151429601e+04L, 1.13446537582066946954261668152086820e+05L, 1.37977827220974171292929858459577092e+05L, 1.68327748580788705255881136304020641e+05L, 2.05992574612073530499207561599578962e+05L, 2.52882202450315825396186949822484192e+05L, 3.11442271834772591489327431348343937e+05L, 3.84814591343557073602914002196809171e+05L, 4.77048586496682264260701809258611041e+05L, 5.93380932472474085420815642783399996e+05L, 7.40606619035166611456854888146209865e+05L, 9.27573047147064337154043416441694054e+05L, 1.16584026094018041532121013906762681e+06L, 1.47056632211824613527279037871707355e+06L, 1.86169889901492197099442712763381073e+06L, 2.36558487029835449538535481946926618e+06L, 3.01715269550576487659856266530294113e+06L, 3.86288257359992924875408921517049995e+06L, 4.96486430558975035817682789982702410e+06L, 6.40636282995973660643182932326803288e+06L, 8.29948184726130211549565432685136745e+06L, 1.07957589264240185368036619492890404e+07L, 1.41008732747460409136778616182972970e+07L, 1.84951472441825010015226156029368615e+07L, 2.43622441967080550013889014979179789e+07L, 3.22295113186394123446611158573926085e+07L, 4.28249388238592533660285754208101809e+07L, 5.71579339433926763705565010979377786e+07L, 7.66343793274545163464956180626615373e+07L, 1.03221272549848969879325123115356857e+08L, 1.39683399197619484239843178827556776e+08L, 1.89925149766489273996177039954695089e+08L, 2.59486539646750585135581953531723138e+08L, 3.56266474246450149668190479113931322e+08L, 4.91582541317241347106730357233806750e+08L, 6.81731647011695814167689014048918740e+08L, 9.50299810520254143758401252895411400e+08L, 1.33159829534327753848250753466160796e+09L, 1.87580197601045983131635998256926235e+09L, 2.65667390770973148718390348704244405e+09L, 3.78324021561636590874538087942452353e+09L, 5.41753184850013697899991815866441223e+09L, 7.80169536989284750988699417135654043e+09L, 1.12996536895509883334977946121306167e+10L, 1.64614916139082192438237472977949088e+10L, 2.41235399573668769368537292636420902e+10L, 3.55648689543192709406699873104224405e+10L, 5.27534501409376051919461374149743655e+10L, 7.87357210832537817724326568648616226e+10L, 1.18256902031786360426341053633539951e+11L, 1.78754944250836346103770384839274996e+11L, 2.71963306497998614239753953623599024e+11L, 4.16512215311989794586279802552971310e+11L, 6.42178185820513419673438138950789714e+11L, 9.96872549757627591785162935837099498e+11L, 1.55821232712296039863279650270498705e+12L, 2.45280998490709378571967041325143017e+12L, 3.88865623282814020969225986222930869e+12L, 6.20986899050942490907341584961146266e+12L, 9.98992421629798366453910164990598035e+12L, 1.61915800137861135092472802019186093e+13L, 2.64432451866992655897802160266314720e+13L, 4.35201884790437478598011793154963363e+13L, 7.21888468820274170949384690425513293e+13L, 1.20699764072734953803867091697058471e+14L, 2.03448372244520740184714594138600722e+14L, 3.45755310287440291972421764598644671e+14L, 5.92524851195750570615520553006806424e+14L, 1.02405779371303867152496937066868237e+15L, 1.78517404594164216208571127025070841e+15L, 3.13930698866849469593365078009075683e+15L, 5.56985627017489012771720073467849986e+15L, 9.97176335383446032822138577325280050e+15L, 1.80168749111488309180201148764368470e+16L, 3.28570985832256554206799328627718020e+16L, 6.04901854091075971038418094513619254e+16L, 1.12437528321136957183940077137648079e+17L, 2.11044512595243530534854315009251863e+17L, 4.00073700789122999206498186212756047e+17L, 7.66084936156432930897007145016954725e+17L, 1.48201877099617670026480296368024580e+18L, 2.89694543391085794507262308584519511e+18L, 5.72279016569347049314117808244814073e+18L, 1.14268996043992146219736887475145416e+19L, 2.30661655998410672274449611000740199e+19L, 4.70785718461609386331913071438798214e+19L, 9.71734634749534281292184698073106843e+19L, 2.02873560562258544354738566036230939e+20L, 4.28484025417100058060231110755876699e+20L, 9.15702732902162383627232801008773485e+20L, 1.98045783476641177674243338550380776e+21L, 4.33560488670225200389961701585516223e+21L, 9.60925855971422399500251930072135526e+21L, 2.15660463060858699692371033788512835e+22L, 4.90204590969527028901267517972005859e+22L, 1.12874922712132846722486415215181510e+23L, 2.63341462304993087921430516281962614e+23L, 6.22633568449099854312810660038498408e+23L, 1.49220527901414892100221726222044247e+24L, 3.62576824971759010933939677750446994e+24L, 8.93389976496144488245242728630867648e+24L, 2.23278698168226238263925345166626442e+25L, 5.66129533629398673236467837398265907e+25L, 1.45661671029813314161310452512420504e+26L, 3.80395985286848824540247897299973294e+26L, 1.00853158560303648965770564091212618e+27L, 2.71524742512942335771421173573350598e+27L, 7.42507176676665196668682930989072343e+27L, 2.06286071217322500340710263294206778e+28L, 5.82405545879941331172090843001915861e+28L, 1.67138883669643664401793246595736207e+29L, 4.87683063202395639212825400688637822e+29L, 1.44717007114610715647680482586441902e+30L, 4.36856220892558378299543245366740004e+30L, 1.34187380624925133807232471810065508e+31L, 4.19525163275433868171703825329949387e+31L, 1.33536013482821413616157861182819558e+32L, 4.32868135071513633988478443702722304e+32L, 1.42940186615031918577626278068758606e+33L, 4.80973614622718069618478648576546160e+33L, 1.64962411456760257539667516081290921e+34L, 5.76867749241980146921395997917892869e+34L, 2.05744285416276135030539237103441019e+35L, 7.48642350991781106283346301415985262e+35L, 2.78005279179115505131111680664033100e+36L, 1.05390834766008187386632631340309755e+37L, 4.08004633423575422346694643614725290e+37L, 1.61355331159280537271141620030872711e+38L, 6.52083633299761509812680604349515166e+38L, 2.69384818625751099248700493623895698e+39L, 1.13800240843071080011666704740931517e+40L, 4.91774800881392461265365745148130197e+40L, 2.17469107319135867637675221560360895e+41L, 9.84452374543052650164816403972682005e+41L, 4.56370746759011673249611086081412694e+42L, 2.16735207370837913732627450052443800e+43L, 1.05486019388717075432105322007580054e+44L, 5.26358822556684736475437714203858810e+44L, 2.69377245879791662278222405278060831e+45L, 1.41450676056016307353065763949943988e+46L, 7.62412676351201661991424110428992680e+46L, 4.21982814876279441119734812029287822e+47L, 2.39938766583179326419454951543637572e+48L, 1.40213994725411743432292186837126106e+49L, 8.42470632552542294312824936421510125e+49L, 5.20691847994261931825305937850643235e+50L, 3.31178786647771615130587348221001406e+51L, 2.16868329550985915487173624396649870e+52L, 1.46278636877920671278346292184781720e+53L, 1.01676178457583836251098427369753410e+54L, 7.28646099514504318390031595979099009e+54L, 5.38619423744886540736133132036039525e+55L, 4.10891748052874064027571987877723004e+56L, 3.23644562594555272761751761693655719e+57L, 2.63344065241761966896134121065725150e+58L, 2.21470233935793926784783273212022849e+59L, 1.92605899594826839190384056135440397e+60L, 1.73306774041417493183516299971659594e+61L, 1.61430716012442696900215232150692807e+62L, 1.55746432848635213822960416335985349e+63L, 1.55722615519719203130606727886637242e+64L, 1.61447396270799534426677571780472075e+65L, 1.73661740632738610492724345532304845e+66L, 1.93920124345119052093186699988150897e+67L, 2.24927773293662287552890832545827854e+68L, 2.71159379871976559871119761600619238e+69L, 3.39962873204868711911086284140566930e+70L, 4.43538969673020629145547409643969707e+71L, 6.02556607616400398134689309091612155e+72L, 8.52916142538377984909758513093573554e+73L, 1.25874632299298868846704179091958707e+75L, 1.93811217518656021005493439215804850e+76L, 3.11543236357261066088271223403230465e+77L, 5.23179767443439001771782033104475730e+78L, 9.18493020786068075728039142759876527e+79L, 1.68692940478037877214426031162304858e+81L, 3.24356562447423263461643222429327622e+82L, 6.53381249893022007452896440352725950e+83L, 1.37989882314462031449133502146398295e+85L, 3.05765044484283991620932285441735220e+86L, 7.11405054583917124472478320152556329e+87L, 1.73927502444225867447030753694640018e+89L, 4.47178291585317780365328749453520010e+90L, 1.21003678949402814425759810458701117e+92L, 3.44882804459086235858169840236819767e+93L, 1.03622678375056156465794049465547871e+95L, 3.28480191475120603834848118907352203e+96L, 1.09951493360222463836336540053884847e+98L, 3.88958173137824259730333790282903582e+99L, 1.45543428790106999149108053530575702e+101L, 5.76572993438741901863543434592570728e+102L, 2.42034956874547558153049344213268717e+104L, 1.07760662592977753585432532225577347e+106L, 5.09334698869585184485524316150431382e+107L, 2.55809082411032399725764692067377039e+109L, 1.36651250871904796376617702296414102e+111L, 7.77173580076352640634836399351925362e+112L, 4.71039863879301491830684051990330316e+114L, 3.04556388558701395434830609997782218e+116L, 2.10276255286144299282309486039761104e+118L, 1.55193753621259613591555622965540441e+120L, 1.22567635442607596952721498552003566e+122L, 1.03695094616970371146721395255392215e+124L, 9.40788526897082771733750170914488215e+125L, 9.16336910778509317089313688240113814e+127L, 9.59253109567116892554520172575780003e+129L, 1.08048629336182387529116109869898182e+132L, 1.31103482955778245018110865569797769e+134L, 1.71564297593263918799907327094023177e+136L, 2.42423174270788187824126863980761699e+138L, 3.70323122333312791897064549131589865e+140L, 6.12322502740998890169801438496313135e+142L, 1.09727104077119676484946099784861221e+145L, 2.13369364324129597715060714813970067e+147L, 4.50809918489577732767734472523944713e+149L, 1.03625280668629118864461701581877696e+152L, 2.59492839368798847123238762058931299e+154L, 7.08856065084285960511459463166728250e+156L, 2.11523492515131956204689196091626210e+159L, 6.90448414659433816403326070235535578e+161L, 2.46882138492543386747726128195908117e+164L, 9.68405620339094731040251680095733169e+166L, 4.17318211031646842247767173261932179e+169L, 1.97862256312448325694613011941349554e+172L, 1.03370703084875834422987498885049116e+175L, 5.95983823379168614646426490979367954e+177L, 3.79793920709700480341002000892325755e+180L, 2.67930862060725892983600714882836079e+183L, 2.09582063696050703960100191266610779e+186L, 1.82074244214148973928235757920582367e+189L, 1.75963855825241574501304502726864570e+192L, 1.89499379332809905379546394212298551e+195L, 2.27793735309853697376707463982899100e+198L, 3.06180392186430523426845441481052145e+201L, 4.60976071298011598021963844074936266e+204L, 7.78790454205446308413194702704532804e+207L, 1.47908157180353184742483342055946619e+211L, 3.16368583872054810499056635486446885e+214L, 7.63549763158546449019055671859541326e+217L, 2.08329116709848069811436257881072129e+221L, 6.43828341650089537912773112646579654e+224L, 2.25813433461443519689405569138116459e+228L, 9.00646808360283887236786414348123292e+231L, 4.09320439419929471708152017376102969e+235L, 2.12407325647515198386324613590453899e+239L, 1.26118767744139661919617876453932054e+243L, 8.58648519817790365555570528355195441e+246L, 6.71757354945431655557160007037610215e+250L, 6.05231172230061504649457274179966269e+254L, 6.29372154343611302741074349158106138e+258L, 7.57097597581835804454005529249965405e+262L, 1.05596735728342565613175490019879868e+267L, 1.71165116794080014782255848570375371e+271L, 3.23201945416757368365209341689336569e+275L, 7.12640648337469193163827718081711822e+279L, 1.83935498907936650155252747841577857e+284L, 5.57103618187823353431701691950875589e+288L, 1.98507054903582594730288556561442957e+293L, 8.34251060679185969108286852637314516e+297L, 4.14598050279815660053056892060055710e+302L, 2.44294673707515955659314553816687272e+307L, 1.71128222954502480992240259231707340e+312L, 1.42900308749681080618580596429329500e+317L, 1.42642910690539638749189376290614404e+322L, 1.70684173154227881505687976959428819e+327L, 2.45528610324097413976825941240621397e+332L, 4.25829782132342793910509184917611473e+337L, 8.93046646026781112771479518830708119e+342L, 2.27151544737307916343177075009962798e+348L, 7.02878727199449743249339960113532074e+353L, 2.65404789370370153123009487802961972e+359L, 1.22676780524208968705932842819459632e+365L, 6.96344727462083702750636558199408867e+370L, 4.86966795424296645258294731476827244e+376L, 4.20934473165669380666938166564826622e+382L, 4.51252011030278817555903939588122000e+388L, 6.01984854233799583525556662766352847e+394L, 1.00278809583154248088779511185941092e+401L, 2.09319142855536626778348201007914114e+407L, 5.49449523120000769396463190666315855e+413L, 1.82025791721843330667826837307018788e+420L, 7.63864295498675379110157901286555290e+426L, 4.07562853905456437955133694031162566e+433L, 2.77530355159307878582751292111532382e+440L, 2.42120842363222072539668100784464301e+447L, 2.71677827391519917988250533365057684e+454L, 3.93638693069501511102210790122717956e+461L, 7.39454183839498133330514511562965145e+468L, 1.80830021083203927258676228302841634e+476L, 5.78068632124848075130373030745294118e+483L, 2.42588452835387252450192322587436972e+491L, 1.34215845252903171028854514732509154e+499L, 9.83265508980143417319549250479290229e+506L, 9.58056982887069577741485477351756765e+514L, 1.24714172045678509784766926344381810e+523L, 2.17883996343750012869434076146952309e+531L, 5.13253875779605180900218275684122450e+539L, 1.63787417999262086647656267832207076e+548L, 7.11453353628067905769574986613707006e+556L, 4.22706394134172663816196292889312018e+565L, 3.45223064191878555675199989739485645e+574L, 3.89497996822823191874712723630878414e+583L, 6.10190158010921783812771061850774756e+592L, 1.33421132288849391233542855134113771e+602L, 4.09320749021551498574887738660496448e+611L, 1.77132716471266560117452274418925035e+621L, 1.08713213788405301831391213988591367e+631L, 9.51489736810900467024086259204897883e+640L, 1.19423949258625915586962226198410651e+651L, 2.16177179741543970148744161752725437e+661L, 5.67627906160460395827390123125168239e+671L, 2.17468780419782497779087319492719363e+682L, 1.22290652527655281598138666471594618e+693L, 1.01549393259398829829790551999023256e+704L, 1.25289600863132317250645757199143453e+715L, 2.31107594661956354485796436668094840e+726L, 6.41394790132987132728494077504399223e+737L, 2.69551958118799603835043225368071745e+749L, 1.72664572305999101481397361296053504e+761L, 1.69703260411568714431268560545429241e+773L, 2.57650655058878846949421879421719884e+785L, 6.08415755628422694511089641903676709e+797L, 2.25018717111577650332251351426363709e+810L, 1.31266605271635406458566527913919394e+823L, 1.21653337436496205608516398221959572e+836L, 1.80423787152105848481394522091997928e+849L, 4.31399102346512532331941966328171850e+862L, 1.67550866484958200095075315692314084e+876L, 1.06515761703845778105889680563699868e+890L, 1.11699400379133199608851392356049526e+904L, 1.94751426714424559351617923238456424e+918L, 5.69089114062808012687080164398087070e+932L, 2.80983921519267570591812248264495618e+947L, 2.36358690419951504134253704409272547e+962L, 3.41581578617948637677662230945252306e+977L, 8.55364646944583859412326553382242541e+992L, 3.74370530455423912034790817625191291e+1008L, 2.88911104228589616462565573594290893e+1024L, 3.96659525977064102663870040642245025e+1040L, 9.77693110684684436928410437465483271e+1056L, 4.36636679166615668883990202463770904e+1073L, 3.56644781478399708285654633626787310e+1090L, 5.37871519143314493436384142989505797e+1107L, 1.51231507376826438439352643482625072e+1125L, 8.00547597409214659416862336552752652e+1142L, 8.05824292014776003962551051182620642e+1160L, 1.55810667707874651581920999067306413e+1179L, 5.84685322894210562805362663900103590e+1197L, 4.30279053871861463775007328286068764e+1216L, 6.27606568696844727186804750244767860e+1235L, 1.83405691639178257209003812558712559e+1255L, 1.08562206577049472147312923532596973e+1275L, 1.31617110088183556471407953592008454e+1295L, 3.30534811890625751178778666339188597e+1315L, 1.73929710751143724152073404455311704e+1336L, 1.94017558758640506527365311633351598e+1357L, 4.64256117877888468390840687039281473e+1378L, 2.41181028167559547953976181592626603e+1400L, 2.75359028326650146526233980288420348e+1422L, 6.99538184026698121966983693939988891e+1444L, 4.00451124186760586509360315430592520e+1467L, 5.23202484555080004711423052985251790e+1490L, 1.58057811961053246035386581678791248e+1514L, 1.11871792077110492782575037665515064e+1538L, 1.88021076704060084216083677757823795e+1562L, 7.60656064089491206752552083826812435e+1586L, 7.51058336307020750806534892000369186e+1611L, 1.83554419567039732901090730190332067e+1637L, 1.12631598317224168716420027493130577e+1663L, 1.76058045324267978077071148859252887e+1689L, 7.11454090252573253550862708170430267e+1715L, 7.54447665013986581882495689819567483e+1742L, 2.13157561258614754140817896581925999e+1770L, 1.62953544267683384450064825605699335e+1798L, 3.42393824570039208761545128642814549e+1826L, 2.00910152737038919233657554807306054e+1855L, 3.34591874171713502502193846562110253e+1884L, 1.60768420173566681503057284560969387e+1914L, 2.26623321264716591681578650589551852e+1944L, 9.53208108881430895613749023747672822e+1974L, 1.21710154769951529957336846304572308e+2006L, 4.80082954212402831503263841738379326e+2037L, 5.95484092414598408997112765002169497e+2069L, 2.36496081234284780469612914593602194e+2102L, 3.06292618387296708176633714456063693e+2135L, 1.31792936450130144017383754294435167e+2169L, 1.92000470996606623202622993195686002e+2203L, 9.65401246356529853165036795448719991e+2237L, 1.70836636787270782624240314280943940e+2273L, 1.08524396756651055665425968680627268e+2309L, 2.52515527758383642102305453689375992e+2345L, 2.19655419566926380800477364631433717e+2382L, 7.29302139222844158929601074949211737e+2419L, 9.43942215540978305304206842223557338e+2457L, }, + }; + m_weights = { + { 7.86824160483962150718731247753528972e+00L, 8.80516388073301111614873617217928009e+02L, 5.39627832352070566780640331455747505e+07L, 8.87651189696816131653619534136597185e+19L, 2.43279187926922555339407396412240848e+52L, 6.39971351208020291074628474066382445e+139L, 4.88537754925138382971529406336289926e+376L, 7.16883681174178397147232888689884595e+1019L, }, + { 2.39852427630263521821751964327863340e+00L, 5.24459642372668102196104972893810164e+01L, 6.45788781959820175983419155536535220e+04L, 2.50998524251137450575088710958358197e+12L, 1.77402926932713870128394504873348147e+32L, 2.78140611598309731397930137939524577e+85L, 1.96038425539892219077400134901764646e+229L, 3.66150166331050442649946863740591804e+619L, 4.83160223742266359875093017291942249e+1679L, }, + { 1.74936958310838685164948357553735581e+00L, 3.97965898193460781260142246747934196e+00L, 1.84851459857444957000370375296526856e+01L, 1.86488071893206798762140574520079510e+02L, 5.97420569526326585534733485801413054e+03L, 1.27041263514462334076609190768051333e+06L, 6.16419301429598407050713079962266577e+09L, 5.23085003181122252980303620742723664e+15L, 2.22626092994336977442577822584431966e+25L, 1.19993110204218159156995352671876189e+41L, 7.47060214427514621386633671542416223e+66L, 1.81446586052841067579857900138568293e+109L, 9.97368828205170536427067380214302839e+178L, 6.91104863699861841609881512683369620e+293L, 1.09318211394169115127064538702854062e+483L, 6.82844528756738528157668552351754659e+794L, 5.72058982179767644458682394627277737e+1308L, 8.56032690374774097638382410967859196e+2155L, }, + { 1.61385906218836617287347897159238284e+00L, 1.99776729186967326240633804225996920e+00L, 3.02023197990883422014272607858586524e+00L, 5.47764184385905776136260784219973923e+00L, 1.17966091649267167180700675171097629e+01L, 3.03550484851859829445106624470076282e+01L, 9.58442179379492086007230677188042206e+01L, 3.89387023822999207648300659707623000e+02L, 2.17919325035791134362027855479039721e+03L, 1.83920812396413285238691815996130729e+04L, 2.63212061259985616674528417452471371e+05L, 7.42729650716946820985576548297567563e+06L, 5.01587564834123235599460194208596041e+08L, 1.03961086724154411336246801784030341e+11L, 9.10032891181809197707572646881781254e+13L, 5.06865116389023157141527800972456655e+17L, 3.03996652071490261550678134010186516e+22L, 3.85774019467200796234141077624516370e+28L, 2.46554276366658108662483315347592086e+36L, 2.41643944916779946083480638296809418e+46L, 1.51709155392660414912154078562432491e+59L, 3.82504341202141137966304147261186085e+75L, 4.08958239682159863968142401533332977e+96L, 3.82377589429556404969214069508991010e+123L, 1.52310131188389950567280579870007714e+158L, 3.79636429591225792206340580596443044e+202L, 3.58806569407775804668752012761380285e+259L, 4.80771394235873283225580334249205764e+332L, 3.53246347094395956018650264083397114e+426L, 1.10588270611697913736223556513462127e+547L, 5.39876096236024571737551333865366627e+701L, 2.11595993056851385189640470523173475e+900L, 1.96510021934867185245970661270267904e+1155L, 4.44393205109502635384704176698510343e+1482L, 8.87699807096655545789464168899561262e+1902L, 3.92593109193326452307669545677335709e+2442L, }, + { 1.58146595953669474418006927755018553e+00L, 1.66914991043853474595928766810899114e+00L, 1.85752318859500577038805456054280667e+00L, 2.17566262362699411973750280579195666e+00L, 2.67590137521102056412774254907718688e+00L, 3.44773868249879174414308452011308777e+00L, 4.64394654035546412593428923628065357e+00L, 6.53020449657424861626175040050215115e+00L, 9.58228501556680496101434956408351228e+00L, 1.46836140751544096048943311347045852e+01L, 2.35444954874098753301967806270994218e+01L, 3.96352727330516670475446596081886449e+01L, 7.03763520626753854729866526912608057e+01L, 1.32588012478483886772029444321222706e+02L, 2.66962564954156917240259777486475719e+02L, 5.79374919850847267642551329761882844e+02L, 1.36869192832130360517783396696756604e+03L, 3.55943572153313055370459329132660088e+03L, 1.03218667727076331844496375241465304e+04L, 3.38662130285874148722242481662728477e+04L, 1.27816625984024682983932609690817446e+05L, 5.65408251392669309819682774275375355e+05L, 2.99446204478172183285915112991350446e+06L, 1.94497502342191494704216422938073734e+07L, 1.59219300769056058775193216743984073e+08L, 1.69428881861745991307405037132734657e+09L, 2.42715618231130327064401251217732118e+10L, 4.87031784819945548978505622564878836e+11L, 1.43181965622918179279761684530563788e+13L, 6.48947152309930125567236832263111486e+14L, 4.80375775250898910621624420686976943e+16L, 6.20009636130533154063228597685772759e+18L, 1.50256856243991489872472363253210358e+21L, 7.43606136718968825065770257988550430e+23L, 8.26476121867792860277670169213789988e+26L, 2.29773502789780434527854280137181506e+30L, 1.80544977956953499695878114747293447e+34L, 4.60447236019906193095622500171344417e+38L, 4.45837121203062685356208723886733392e+43L, 1.95763826111480930920135175891530462e+49L, 4.76736813716250076391436967954985413e+55L, 8.08882013947672128478290968549029064e+62L, 1.23826089734928635728800137667726115e+71L, 2.29227250527884206154485624438166937e+80L, 7.15139237374919354944182099110281069e+90L, 5.47671485015604443103262357109062276e+102L, 1.57665561837070068115746726288773175e+116L, 2.76544859595785195782707224216472471e+131L, 5.10805125528313267335507302418826239e+148L, 1.84712724771593770593326127127227089e+168L, 2.64019849791365137425805671512502957e+190L, 3.30712207665004277982044248938187504e+215L, 8.94854908018147130170828014681013313e+243L, 1.45387781135416845215757148230318159e+276L, 4.51726707740089625471551690811905600e+312L, 9.97430447590682462482304866834403173e+353L, 6.92693028486990716815899177110112886e+400L, 8.16310561774970561761094556639568748e+453L, 1.10229203674018117764688357752075301e+514L, 1.48517414340573263317638725427854581e+582L, 2.31930659130340479680373862468017961e+659L, 6.75943980795305614491339585238335763e+746L, 8.57037256903489416057847741388693004e+845L, 1.67601881139415883633596646631875881e+958L, 2.88227840597067494281761984210848274e+1085L, 4.25760590360997372209644858208981618e+1229L, 9.71180927884114514977776411099980676e+1392L, 1.22768447544318231419683656745290694e+1578L, 6.75552744777466879522724469574589977e+1787L, 3.08769330528996647489562213811332711e+2025L, 6.11556995885701147380172201043083647e+2294L, }, + { 1.57345777357310838646187303563867071e+00L, 1.59489275503866378652125176234375753e+00L, 1.63853651553023474161201404240726646e+00L, 1.70598040821221362042267472116012952e+00L, 1.79972439460873727464624167982278042e+00L, 1.92332285442565630724716834865923523e+00L, 2.08159737331326817824115844787944556e+00L, 2.28093488379007051069614759371332643e+00L, 2.52969785238770465522974588384012833e+00L, 2.83878478255295118549225363326336900e+00L, 3.22239574502098061154099310373833179e+00L, 3.69908135885423511174795221061725889e+00L, 4.29318827433052679979662014839909054e+00L, 5.03686535632233007617225633242190622e+00L, 5.97287114091093219903794699750262296e+00L, 7.15853842431107756435392592099817447e+00L, 8.67142780089207638456187671594514668e+00L, 1.06174736029792232565670017416978690e+01L, 1.31428500226023559963724543395522033e+01L, 1.64514562566842803959315507240301356e+01L, 2.08309944999818906870911848992408145e+01L, 2.66923598979164019005652953856219015e+01L, 3.46299351479137818875120770497256101e+01L, 4.55151836265366257897259922581190951e+01L, 6.06440808776439211617961123881399848e+01L, 8.19729691748584679772374579308014156e+01L, 1.12502046808165256396405270593673624e+02L, 1.56909655284471412314380735570422525e+02L, 2.22620434786863827630193937721495593e+02L, 3.21638548950407775497940425181412035e+02L, 4.73757450594546173931972158718216152e+02L, 7.12299454814699763671577043536625350e+02L, 1.09460965268637655307120839628626644e+03L, 1.72169778917604957594996919520027157e+03L, 2.77592490925383514631415480161515100e+03L, 4.59523006626814934713366494475518926e+03L, 7.82342758664157367197225266771664916e+03L, 1.37235743526910540538254088034330370e+04L, 2.48518896164511955326091118611007805e+04L, 4.65553874542597278270867281925971401e+04L, 9.04176678213568688399001015321300800e+04L, 1.82484396486272839208899824313480775e+05L, 3.83680026409461402659414641247062580e+05L, 8.42627197024516802563287310497296237e+05L, 1.93843257415878263434890786889254173e+06L, 4.68511284935648552770705724295731096e+06L, 1.19352866721860792702129481323969824e+07L, 3.21564375224798931587480096707273872e+07L, 9.19600892838660038574630990314077029e+07L, 2.80222317845755996380600711673673348e+08L, 9.13611082526745888639724836491288094e+08L, 3.20091090078314859097182280497599932e+09L, 1.21076526423472368892320719657876832e+10L, 4.96902474509310180847282308967509245e+10L, 2.22431575186385521573661995325533148e+11L, 1.09212534444931366008730317965795763e+12L, 5.91688298001991935913437013926087352e+12L, 3.55974343849457724875846980164154730e+13L, 2.39435365294546519110955303872941851e+14L, 1.81355107351750191688958030705258863e+15L, 1.55873670616616573768075986251057862e+16L, 1.53271487555511433265791312985848665e+17L, 1.73927477619078921206684554401295421e+18L, 2.29884121680221631264260395223605839e+19L, 3.57403069883776266374408947394989771e+20L, 6.60489970545141907950722926660909000e+21L, 1.46715587959182065910258109064501314e+23L, 3.96409496439850938104106380506197921e+24L, 1.31934284059534879276193138323357204e+26L, 5.48225197134040074244755342952808857e+27L, 2.88513789472382751842871762855110475e+29L, 1.95253984076539210960955400019857653e+31L, 1.72705148903222279729658337426192599e+33L, 2.03134350709543939580166226396358099e+35L, 3.23607414697259998035422932108168633e+37L, 7.12048741298349720027592249584649287e+39L, 2.20955270741101726546978031488466999e+42L, 9.88628264779138464833350749737352873e+44L, 6.53051404878827352855218417636385136e+47L, 6.53070667248154652797117704066842547e+50L, 1.01551880743128195070423638840822631e+54L, 2.52636677316239450980056816553072407e+57L, 1.03645051990679029664966085872637264e+61L, 7.24196603262713586073897504016245799e+64L, 8.91940252076971493816577515322150818e+68L, 2.00846361915299290502283821529295631e+73L, 8.59691476483026002005094018998424562e+77L, 7.29059954682949521964023913634428261e+82L, 1.28019956321641911210408802307006043e+88L, 4.87834928560320114983891893560226105e+93L, 4.24082824806412793978885646592598549e+99L, 8.86977176472159872046976711615695992e+105L, 4.72334257574141766931261505651248075e+112L, 6.80203596332618858057580041658814811e+119L, 2.82453118099000954895979587744113614e+127L, 3.62104921674598225195529453488856248e+135L, 1.54127015033494251978994281882356439e+144L, 2.35337699517436278507886852532825112e+153L, 1.39975657916895026384257958622345253e+163L, 3.54037503829826541837221286091526442e+173L, 4.18047500721395810079642214620070836e+184L, 2.54530778191403081572971577964641848e+196L, 8.88250526322285889574436025179770286e+208L, 1.98845751036127430533908054978079217e+222L, 3.21915661509946819003841034873947498e+236L, 4.28183215516658291456439674095688919e+251L, 5.36006145974509206228714676601426569e+267L, 7.29722806821457796264952588871034685e+284L, 1.26019994797636341237075623262002305e+303L, 3.25215241711283834871808603425369243e+322L, 1.49313102632599158215031971670664716e+343L, 1.46842377691796129245813472736592684e+365L, 3.76931518236156669675469780787997744e+388L, 3.11671991143285521404945273561352902e+413L, 1.03852445906488241953781523768340610e+440L, 1.76991068936691550622045923706396857e+468L, 1.98843278522413458075823481121326426e+498L, 1.92935688449069146367365017414279935e+530L, 2.15545898606278242992831028009446695e+564L, 3.76556572065746315676705102085514331e+600L, 1.42493629186903074753303377268119903e+639L, 1.65224172380259971159552714105694350e+680L, 8.49215944410421946026158352935784666e+723L, 2.86631893981320588349507785370693896e+770L, 9.65377141044877270160840903468092119e+819L, 5.06475979937176267805686278644876593e+872L, 6.64979079902917739733555562625190968e+928L, 3.61927525412094487856735509111512169e+988L, 1.39737404381894022658529893979427383e+1052L, 6.78018387620311055320186127570560827e+1119L, 7.59952044103401209205510909410129754e+1191L, 3.76162862667265940011010617225061429e+1268L, 1.63904309514033654209643026524489542e+1350L, 1.31017858257252889370615733020834140e+1437L, 4.19821396072116298475329351264459339e+1529L, 1.23923791809549425227491870065845752e+1628L, 8.17087984671936465200033730232853592e+1732L, 3.08946915513007963115203650683840400e+1844L, 1.82761916569338643673217752139790470e+1963L, 4.92348318803338950087945240543349430e+2089L, 1.88350835331965060456271693216651123e+2224L, 3.43360015586068277793841059306542129e+2367L, }, + { 1.57146131655078329437644376888801138e+00L, 1.57679016631693834484126246342345329e+00L, 1.58749564037038331646069625234555521e+00L, 1.60367395634137020950291269057600307e+00L, 1.62547112545749394267938666988196139e+00L, 1.65308501191593930171844822364141731e+00L, 1.68676814252591123625053019619255158e+00L, 1.72683132353751620184313195813656600e+00L, 1.77364813866723660171326886678529701e+00L, 1.82766042147866144821632902536146347e+00L, 1.88938481704401819562549601165115021e+00L, 1.95942057285503709111658357403615203e+00L, 2.03845872804790892275259742585569433e+00L, 2.12729290408384722476899855222432786e+00L, 2.22683194019907694104850876757126753e+00L, 2.33811466455513029581902771513343722e+00L, 2.46232714872299130380967769641847017e+00L, 2.60082286092708516436098022317536381e+00L, 2.75514621481455435937229822050004007e+00L, 2.92706010842448355516791030533685920e+00L, 3.11857816624092195149666191379786472e+00L, 3.33200254033950662971711811118318338e+00L, 3.56996830041074027550628111498923678e+00L, 3.83549565399644726181552365400966870e+00L, 4.13205149651293488468153425460318353e+00L, 4.46362210669906788115667211361364802e+00L, 4.83479919100800655701530131187647507e+00L, 5.25088195776567960767293727240320892e+00L, 5.71799849087533312421158643544587353e+00L, 6.24325042159856810533215887376856930e+00L, 6.83488580122654183866366620676303900e+00L, 7.50250620278934080195915244309172491e+00L, 8.25731548449354420110207897041998984e+00L, 9.11241940586464263380079984086513597e+00L, 1.00831874954399775830998395457182684e+01L, 1.11876913499386520162594085796167645e+01L, 1.24472370591410688131760615976965093e+01L, 1.38870139060550758665255786705519681e+01L, 1.55368871591590018952847646637454593e+01L, 1.74323700068094283108112572669239084e+01L, 1.96158189482399342378436216339159090e+01L, 2.21379088635427380602824337731297019e+01L, 2.50594593467713760968808829296439171e+01L, 2.84537037774213756120135736520435304e+01L, 3.24091184596952483433430577491101072e+01L, 3.70329628948023016142035941015485370e+01L, 4.24557264474626791146220920324192917e+01L, 4.88367348033798558171280311705362727e+01L, 5.63712464058697542020818458752120814e+01L, 6.52994709275261034008086934786702551e+01L, 7.59180775569412283714380617539343408e+01L, 8.85949425239166382162609558265821220e+01L, 1.03788129500578812415162165531670704e+02L, 1.22070426396922674625756853326498468e+02L, 1.44161209813120053456742433728771078e+02L, 1.70968019124577351122499690038707734e+02L, 2.03641059384357556999222931732850856e+02L, 2.43645005870872364316059216110059642e+02L, 2.92854081218207610543177302881458406e+02L, 3.53678601915225339202500542949917795e+02L, 4.29234308396729693907268968564609660e+02L, 5.23570184048873302665650155276206906e+02L, 6.41976689800302457508415746115180260e+02L, 7.91405208366875928332161102969868782e+02L, 9.81042208908193163688535235538889459e+02L, 1.22309999499974039331272100414750813e+03L, 1.53391255542711212726525490457861725e+03L, 1.93546401360583033885511419988831009e+03L, 2.45753454991288685207196097797062484e+03L, 3.14073373162363551894782974867325472e+03L, 4.04081818856465189750723035050638141e+03L, 5.23488159971222568136194576211612571e+03L, 6.83029445760732922582000345557383347e+03L, 8.97771322864988714349790288910627671e+03L, 1.18901592096732683947870697270695144e+04L, 1.58712238704434696215746702894136306e+04L, 2.13571110644578933143540830593360855e+04L, 2.89798370518968143718297906801146350e+04L, 3.96630672679554794954087134590560762e+04L, 5.47687519375000078688553248953764732e+04L, 7.63235653938805568016142182690471993e+04L, 1.07371914975497695062170132456450593e+05L, 1.52531667455557415180420019888676134e+05L, 2.18877843474421658617449971461581691e+05L, 3.17362449601929560775572985879585343e+05L, 4.65120152586932846156175983364596723e+05L, 6.89253765628058057206329188782990860e+05L, 1.03311988512001998186230013733752720e+06L, 1.56688798104325249948154338241641806e+06L, 2.40549202702653179507492073842261453e+06L, 3.73952896481591033994026114668796352e+06L, 5.88912115489558003244667233279563785e+06L, 9.39904635192234203007457377008255614e+06L, 1.52090327612965351790614542733698474e+07L, 2.49628718729357616773929842263043964e+07L, 4.15775925996307484022703929049831425e+07L, 7.03070536695026731176158877103497776e+07L, 1.20759855845249336607363637052870598e+08L, 2.10788250946484683324104572583041111e+08L, 3.74104719902345786397351281755078701e+08L, 6.75449459498741557237788387723071522e+08L, 1.24131674041588053743260021864117384e+09L, 2.32331003264955286246594304305695965e+09L, 4.43117601902662575879840759020751450e+09L, 8.61744648740090012951326726568665021e+09L, 1.70983690660403151330619158427281665e+10L, 3.46357452188017133850611855017361923e+10L, 7.16760712379927072634183907084755700e+10L, 1.51634762091005407908273857408800162e+11L, 3.28172932323895052570169126695951209e+11L, 7.27110260029828078950026409435831711e+11L, 1.65049955237878037840731169761272102e+12L, 3.84133814950880391685509371196326109e+12L, 9.17374426778517657484962791255187134e+12L, 2.24990194635751997880832549111511175e+13L, 5.67153508990061173097292032404781538e+13L, 1.47074225030769701852963232235912597e+14L, 3.92701251846431177545392497147427712e+14L, 1.08063997739121282020832802862957248e+15L, 3.06767146672047518894275739534732971e+15L, 8.99238678919832842771174638355746631e+15L, 2.72472253652459211109041460799535823e+16L, 8.54294612226338925817358060817490416e+16L, 2.77461371872557475533476908014408616e+17L, 9.34529947938202912146296976663431863e+17L, 3.26799612298773188163350554315742192e+18L, 1.18791443345546831451732293519928714e+19L, 4.49405340841856421397062311314705655e+19L, 1.77170665219548674305185389795833488e+20L, 7.28810255288593152697603764235601397e+20L, 3.13251243081662534865188632436805529e+21L, 1.40874376795107311038838007000777184e+22L, 6.63829426823606041441317767891166205e+22L, 3.28254360840356501289107248021554584e+23L, 1.70592009803839406409667145645666005e+24L, 9.33225938514852428454935743602712728e+24L, 5.38272717587488831207327363463407970e+25L, 3.27895423512209324910006662705296242e+26L, 2.11319169795745809927716305122705952e+27L, 1.44341104149964304009687846325713305e+28L, 1.04686439465498242316197235200069352e+29L, 8.07731922695890570023291958025986094e+29L, 6.64314696343261627707440459400107155e+30L, 5.83567012135998626006817430636714368e+31L, 5.48689029679023079776199817150941362e+32L, 5.53372696850826161418229677716330718e+33L, 5.99973499641835283449509393028972981e+34L, 7.00917611946612256941556198729562373e+35L, 8.84406196642459749869759626748371565e+36L, 1.20822686086960596115573575744502341e+38L, 1.79164851431106333799499432947126299e+39L, 2.89131391671320576216903362266762013e+40L, 5.09145786021152729801159516043566174e+41L, 9.81063058840249655325327952160218101e+42L, 2.07444123914737886022245738089968362e+44L, 4.82765011693770054022189143000576390e+45L, 1.24028793911154902904261886940649724e+47L, 3.52878285864478461616951002487254771e+48L, 1.11544949047169665881036414807872651e+50L, 3.93051064332819631369914292573124112e+51L, 1.54924371295785233686867649142553059e+53L, 6.85499823804130100151231679166543611e+54L, 3.41747996158320770357877327002949632e+56L, 1.92690549864107998957222500013304086e+58L, 1.23358096300491944958557136475962190e+60L, 9.00281990289807691528078151573158069e+61L, 7.52141514125344164522463463202808470e+63L, 7.22427755490057899279344696654950663e+65L, 8.01283283053507860974456727997488253e+67L, 1.03099962028638036919997632019550562e+70L, 1.54617495707674867923983623892142209e+72L, 2.71580377261324869371341160824868908e+74L, 5.61508992057174643750226165228505259e+76L, 1.37366785934534333692942668275259398e+79L, 3.99754102076962512613158938364235073e+81L, 1.39150058933980008745266389466237314e+84L, 5.82669384491202289249159160687839973e+86L, 2.95227482092954909582266634062763990e+89L, 1.82102306147846628152669685943631657e+92L, 1.37597302213794152564743989887492097e+95L, 1.28185236754341294523601004808033157e+98L, 1.48213012720199050337233086306566580e+101L, 2.14157427379243531419232668034147566e+104L, 3.89449554094711237984570195229015661e+107L, 8.97864636258010296104790318951217808e+110L, 2.64413158980724405044777067425347595e+114L, 1.00240353984191383430257305957041439e+118L, 4.93141280490390525871801097705197944e+121L, 3.17440111243586504420672164931106998e+125L, 2.69662400176189239027511019786185589e+129L, 3.04979932232044716644635827452454425e+133L, 4.63404152681868778475392087605038845e+137L, 9.54898313480310651224157422560754643e+141L, 2.69440486619208982853089677098686964e+146L, 1.05150272003639532507210605903884076e+151L, 5.73417064062624495509840837865743050e+155L, 4.41627650777870044428827641421915327e+160L, 4.85653500442164862297918118887566388e+165L, 7.71243776020172406235461422008761914e+170L, 1.78944284768135145352387398006192815e+176L, 6.13948504948193852500464630902178966e+181L, 3.15374719244414866832063986813364807e+187L, 2.45678229633130089072342575625791640e+193L, 2.94097956743157560377748279040964662e+199L, 5.48435772238022826264635788020315114e+205L, 1.61576755939787162649511106856450099e+212L, 7.63055674811964328822328719215905762e+218L, 5.86357963426750903008317058039636736e+225L, 7.44578009523250679265610908767109796e+232L, 1.58753358925950887380498944645468602e+240L, 5.77757179750005470017336807397418313e+247L, 3.65046885264085030960970127282511879e+255L, 4.07509702021276189043935129812053895e+263L, 8.18389073292535025618266801702554839e+271L, 3.01238089652162618211263051563523370e+280L, 2.07176624104483264053704912869659325e+289L, 2.71562735784398218302697011744202385e+298L, 6.92451661016398143622710849660362520e+307L, 3.50810155650162047040906671177815417e+317L, 3.60896781300246599975888048597671985e+327L, 7.71058277826701049982730585006218034e+337L, 3.50154660288711246272389096490054302e+348L, 3.46175331564137723439223486579386975e+359L, 7.63696466254316472130052183903629062e+370L, 3.85655304044390258996784681505914035e+382L, 4.57665692577932081843759029527968784e+394L, 1.31143566628034307965133274338127595e+407L, 9.33142940209453779649608781259673613e+419L, 1.69703443400488874615229289912465401e+433L, 8.12664327627950884948530966790210152e+446L, 1.05671342182667061564323377987059929e+461L, 3.85123350151333031094457679550412807e+475L, 4.06487630836024540948583469098247829e+490L, 1.28516517984503545753808504263016648e+506L, 1.26025754690341684764700072541766676e+522L, 3.97331612896914344554453503890576277e+538L, 4.17965516524315248567041014799432863e+555L, 1.52416658652941127494202186163265994e+573L, 2.00432202283496263048589917253126663e+591L, 9.89983817930114056039301724151237036e+609L, 1.91539340453423886973992445388091844e+629L, 1.51593315523153267229971976448703684e+649L, 5.13233111267478387648166311677061530e+669L, 7.78392571224632702458474933380523830e+690L, 5.54632077048043201021342066119640603e+712L, 1.95012604607548018918112113273623192e+735L, 3.55940947870861006830654543397286882e+758L, 3.55349341454925685547195460273265331e+782L, 2.04795692045857243226580641802720017e+807L, 7.20348918974342452885439546130773017e+832L, 1.63778937282231874342883712446170710e+859L, 2.55384218509638087014670377175798088e+886L, 2.90332357089198897009653578594580665e+914L, 2.56300421336271050326091753908665515e+943L, 1.87504708602076913446948153935468528e+973L, 1.21573089114719501597325465689193734e+1004L, 7.48693407429699486755736805187051392e+1035L, 4.70376397570597947605315058283235338e+1068L, 3.24549375035327607806235059706162609e+1102L, 2.65365798053210741189633750297123713e+1137L, 2.78113361306514574568406809189880354e+1173L, 4.05114001708803517429009145027606492e+1210L, 8.91647476482514121118371429882160487e+1248L, 3.23223851331898724884680382253593571e+1288L, 2.10925909168894371224120829576314259e+1329L, 2.71594389750881594498007515800169231e+1371L, 7.58558239286242519535157411695442827e+1414L, 5.06701669031717221741926320252846248e+1459L, 8.95314256637167381172114473249653533e+1505L, 4.64314397380853725563695225910483395e+1553L, 7.86772811149376784892131781209226509e+1602L, 4.86578559687970087801384706555207321e+1653L, 1.23116054769360594876926981962811083e+1706L, 1.43383897399728293235616506956599019e+1760L, 8.67960762728500385489074199138374599e+1815L, 3.09584788327503858182429306492345781e+1873L, 7.40514657822678853879551103162851562e+1932L, 1.35750288266752565171774149402837640e+1994L, 2.18886955807028168114167639122307268e+2057L, 3.57839966436010585653478204799948336e+2122L, 6.86791017358151132323155526430183469e+2189L, 1.80021943882415618419042799861559854e+2259L, 7.53312429569410546159363413753399067e+2330L, 5.91165553375547478649257686857639971e+2404L, }, + { 1.57096255099783261137673508918980377e+00L, 1.57229290236721196082451564636254803e+00L, 1.57495658191266675503402671533627186e+00L, 1.57895955363616398471678434379990522e+00L, 1.58431078956361430514416599492388597e+00L, 1.59102230111703510742216272394562613e+00L, 1.59910918118616033722590556649394763e+00L, 1.60858965710906746764504456185444654e+00L, 1.61948515482641974319339137784305225e+00L, 1.63182037453073931785527493516038124e+00L, 1.64562337819112567903033806653906069e+00L, 1.66092568939542410935608828998468834e+00L, 1.67776240601646371733138779357535047e+00L, 1.69617232627708297296989766202480515e+00L, 1.71619808886073246730768842066355199e+00L, 1.73788632779101456236627555096372654e+00L, 1.76128784288515241044102589887617560e+00L, 1.78645778667368642025315725404601102e+00L, 1.81345586877233558659749539967614045e+00L, 1.84234657879265254187280543490489739e+00L, 1.87319942898662752121993510591579920e+00L, 1.90608921793761261888076943857856180e+00L, 1.94109631673677945144587926354356120e+00L, 1.97830697922181656566949720098719647e+00L, 2.01781367800384433737712026561151498e+00L, 2.05971546817081389507270282494773392e+00L, 2.10411838073232749275747224342524909e+00L, 2.15113584806337555354918618566085438e+00L, 2.20088916381459141771044083611555369e+00L, 2.25350797998611420231160903572594743e+00L, 2.30913084411305337537709048855358397e+00L, 2.36790577978511333384857209921738492e+00L, 2.42999091402365295350102767412517845e+00L, 2.49555515536908558968587982458158759e+00L, 2.56477892689313451429557802920827974e+00L, 2.63785495874745168415081659796280588e+00L, 2.71498914529626806741705564771250802e+00L, 2.79640147236028053619149909690973720e+00L, 2.88232702062657870038560203490158574e+00L, 2.97301705186029380311201985278736098e+00L, 3.06874018519362823755119514588303156e+00L, 3.16978367147348738564623946178566521e+00L, 3.27645477442732860056345607892739085e+00L, 3.38908226826615609816107421136979984e+00L, 3.50801806229286913554992299494422526e+00L, 3.63363896413353027399263692498221540e+00L, 3.76634859436988420367634452674074607e+00L, 3.90657946663630928939225987850575005e+00L, 4.05479524866754112035397645627643742e+00L, 4.21149322136091780158052739625729631e+00L, 4.37720695466646221916071477112304019e+00L, 4.55250922105994638849140210916632132e+00L, 4.73801516951078282566987752649050466e+00L, 4.93438578525358788671420711795537458e+00L, 5.14233166333819107447595069798421539e+00L, 5.36261712689997622445803908396748884e+00L, 5.59606472439710019418213140693069575e+00L, 5.84356014374437330661446789126222075e+00L, 6.10605758538173469317727364122669467e+00L, 6.38458564090067143612732202429488542e+00L, 6.68025372897382444864907987044889317e+00L, 6.99425914605841270881961646990609410e+00L, 7.32789479574890106033548644768353338e+00L, 7.68255766782458876413667730681699443e+00L, 8.05975814607113727007240055318338450e+00L, 8.46113023296234288939356989479671723e+00L, 8.88844278939567108027044653070693778e+00L, 9.34361189902548515485066576358196470e+00L, 9.82871447949462202212030994384949241e+00L, 1.03460032772138062549383568058709409e+01L, 1.08979233984912291622835480030167114e+01L, 1.14871305480132578973614919602781370e+01L, 1.21165111661978855517781913327317255e+01L, 1.27892046801009632078942555615288463e+01L, 1.35086281087128109623831457304510920e+01L, 1.42785032930533442126932924888187804e+01L, 1.51028870549318132669071327511660921e+01L, 1.59862046261270319640752848374642080e+01L, 1.69332867326908112807352382039426796e+01L, 1.79494107678000050622926329104204826e+01L, 1.90403465419082315888820165929975494e+01L, 2.02124071618296433363312214170232623e+01L, 2.14725056619224736964251610816575600e+01L, 2.28282180919971350546248653847563966e+01L, 2.42878538594168042463845071817020910e+01L, 2.58605342287811778487151334440784950e+01L, 2.75562800035467442565131080245429614e+01L, 2.93861095522110956389210768876799587e+01L, 3.13621484999095132865600012683857137e+01L, 3.34977525874991258153646142408367963e+01L, 3.58076454079962546803810835720597110e+01L, 3.83080729687253016658377309622401176e+01L, 4.10169773015547344709659456503154667e+01L, 4.39541916587611362308342994483809472e+01L, 4.71416601949419692729062784327679986e+01L, 5.06036854536665922553724504470269960e+01L, 5.43672074601944525232284101611170030e+01L, 5.84621187791213843904071404608607478e+01L, 6.29216205405812878410372213510070276e+01L, 6.77826251851241666263837617897404532e+01L, 7.30862125426522301461255132629846162e+01L, 7.88781468648814729209715096907821639e+01L, 8.52094635973465833426799692679733796e+01L, 9.21371360338777471668559829773781201e+01L, 9.97248335767075464896305315099053068e+01L, 1.08043785167904642576949987865910954e+02L, 1.17173763608862169247776700625586421e+02L, 1.27204208998868737227575356110541727e+02L, 1.38235512466410237338282474486031692e+02L, 1.50380484815148331050381123359927804e+02L, 1.63766038752610274212021042234298836e+02L, 1.78535118123338340289613569013808793e+02L, 1.94848913160728060357302969254459805e+02L, 2.12889407359835266977366307026062112e+02L, 2.32862309344799079018746113493039633e+02L, 2.55000432284328199435640048881527463e+02L, 2.79567594267244578195192766207761694e+02L, 3.06863125912428093434496643114651412e+02L, 3.37227086745120087399301385427960651e+02L, 3.71046309996557625549265358225650347e+02L, 4.08761417046617491055856040237506316e+02L, 4.50874968419459367009632339064163929e+02L, 4.97960948895977349122916983180817637e+02L, 5.50675820938578587679472462796822793e+02L, 6.09771424466317909206822143572649707e+02L, 6.76110053572647368547479902312230309e+02L, 7.50682103874142244645724064576848341e+02L, 8.34626760051808119187547981730818179e+02L, 9.29256284531554199823656475151338963e+02L, 1.03608457849823472804207172846963877e+03L, 1.15686081966189765730466332807313547e+03L, 1.29360914245380859999201252074469995e+03L, 1.44867552185420514387789438088656434e+03L, 1.62478325953219761549580736728832563e+03L, 1.82509875991531856022535679631713756e+03L, 2.05330963597261755441688599655848892e+03L, 2.31371761449477720025881552764731872e+03L, 2.61134923664018699944734187657483567e+03L, 2.95208799409362429898911389656789101e+03L, 3.34283233256054817982471990245472659e+03L, 3.79168492775659509883214798303432158e+03L, 4.30817983871631895490690508451026040e+03L, 4.90355562457020167332670064217006554e+03L, 5.59108434363481145162671079876733528e+03L, 6.38646862557124634146730890858054275e+03L, 7.30832182941297944038809179971510199e+03L, 8.37874981279970356111509048453001571e+03L, 9.62405721874963805881171453111047092e+03L, 1.10756066619114600841076275282388063e+04L, 1.27708660544590438787794590107117849e+04L, 1.47546879201948945213025955616435132e+04L, 1.70808753741706634268551294101897318e+04L, 1.98141030969548505096681178137364270e+04L, 2.30322788820475490754732581365999861e+04L, 2.68294531792863253502182123460963590e+04L, 3.13194117839842820030641964449539820e+04L, 3.66401220970699799668192565829190288e+04L, 4.29592483666869017028607105165763804e+04L, 5.04810088263984357248209974578040223e+04L, 5.94547213318005529011388227962133751e+04L, 7.01854787517268957919092596317475529e+04L, 8.30475172617569400265716546608431303e+04L, 9.85009980505357544638949542794405193e+04L, 1.17113126626176606026864191754698095e+05L, 1.39584798216058984483938678946454092e+05L, 1.66784301639307755633312351999980104e+05L, 1.99790062652052468605951710457597772e+05L, 2.39944994603299218686253514351518948e+05L, 2.88925793983801323167992289814829493e+05L, 3.48831530919430454806103930858415528e+05L, 4.22297220149677844682618484564386312e+05L, 5.12639824636925361908056913471196846e+05L, 6.24046487622198979196137566922551170e+05L, 7.61817907323361594136262168936978923e+05L, 9.32683930022411925704630601110030182e+05L, 1.14521400777429753902355978052778602e+06L, 1.41035264627423311876298925540665884e+06L, 1.74212004187586338510201667214170577e+06L, 2.15853171693428701405141183541166264e+06L, 2.68280941012642673073659887232388938e+06L, 3.34498056359541886091597912499527306e+06L, 4.18399797233770604788689812330719069e+06L, 5.25055800816550175243256559083639418e+06L, 6.61086017414168098803951872291131863e+06L, 8.35163942396755869310534556270941378e+06L, 1.05869253239392990034806970327887878e+07L, 1.34671523510623940861241599892229316e+07L, 1.71914827102426302145958883698307763e+07L, 2.20245344902770169422620623417295079e+07L, 2.83191730172433779681268016861978467e+07L, 3.65476782026834493187990343694010282e+07L, 4.73445265723062610640363034466641760e+07L, 6.15653406350951387288804933390908042e+07L, 8.03684302689786924828741611740519293e+07L, 1.05328028435969028854761469747289545e+08L, 1.38592168908412628618546923035162247e+08L, 1.83103698592568352374304770508191971e+08L, 2.42910945745864082034287213456845086e+08L, 3.23606239375966746282831194186614169e+08L, 4.32947521859998666323053129499091577e+08L, 5.81743296796292947920442886775592966e+08L, 7.85117978938819178602650773642870262e+08L, 1.06432919762707530726575966438229782e+09L, 1.44938958291294548467516226794019366e+09L, 1.98286646937799184909776706883985509e+09L, 2.72541431469809432350206616813747393e+09L, 3.76386796411162144400474070771015333e+09L, 5.22313881495099093715899688078276720e+09L, 7.28378581064439770444275729738468286e+09L, 1.02080964238115874250636198090464363e+10L, 1.43789931847051052135186583023967432e+10L, 2.03583681254363357780032810961889254e+10L, 2.89749982708002744366825785538936402e+10L, 4.14577375164549487752492409798515416e+10L, 5.96383768387242628650336526594122215e+10L, 8.62622848391553079951805623395652598e+10L, 1.25466704538982518000690409655705216e+11L, 1.83521298226491318558080545133554232e+11L, 2.69981220740015160361114268684563366e+11L, 3.99492845215192295441294253418780644e+11L, 5.94638055870143455023933020703444642e+11L, 8.90440996742409110650533033931653292e+11L, 1.34155194167777583831947241717631506e+12L, 2.03376855033215189170105222958089604e+12L, 3.10262795987575321360135087196684567e+12L, 4.76359832170586206290082815387968037e+12L, 7.36142036056081358397678626842794083e+12L, 1.14512696145655742338758840735549183e+13L, 1.79331418699627392634462052642542749e+13L, 2.82758550128579223200239017529280909e+13L, 4.48929705367844466861372765075631687e+13L, 7.17780287265849957064212371548037347e+13L, 1.15585509854582062520354852997620279e+14L, 1.87483388636788309288478433629583664e+14L, 3.06351035640217445409310567498133847e+14L, 5.04340065300597024230361727189343426e+14L, 8.36616339689242989007881200440488764e+14L, 1.39855635164094728875364679627485304e+15L, 2.35633574951616468243164849507855064e+15L, 4.00176516738263745645278590345795707e+15L, 6.85137512840494144543571512545601884e+15L, 1.18269011176154399046326619510431010e+16L, 2.05867352701380644281110910622942185e+16L, 3.61396878431490463311666873476678412e+16L, 6.39911218439421355095519025524482256e+16L, 1.14301618562837692261569180960886276e+17L, 2.05988138391566644299797673070467922e+17L, 3.74584678835368091393630059068193045e+17L, 6.87444303468314906803024757565005462e+17L, 1.27340764361348531366853034790770231e+18L, 2.38124191682989536626992792404294190e+18L, 4.49583561730710839927340662784958898e+18L, 8.57144202490195270096830399067728169e+18L, 1.65044358418165696532477771893166700e+19L, 3.21010035242131785085169993033188229e+19L, 6.30778012444270309076492866733769742e+19L, 1.25240403115766127899628450500249765e+20L, 2.51300529564998539443832117224536420e+20L, 5.09677625569083843571268035202853929e+20L, 1.04501920001667304566512216455267827e+21L, 2.16647647926087846601520265828431353e+21L, 4.54213814567839546278770815494416868e+21L, 9.63208232444913712819259248595549405e+21L, 2.06638653668825452816630915727527426e+22L, 4.48552978555442825059406438230470388e+22L, 9.85387957361097750825498509227133701e+22L, 2.19115887446437440814640517501285189e+23L, 4.93283596439097166796547625560314132e+23L, 1.12450152997177436346173556893175508e+24L, 2.59626913615675600812300017445220112e+24L, 6.07229293831362550112108555687653017e+24L, 1.43898906630800383562329122001513450e+25L, 3.45584195640657046905140678735606870e+25L, 8.41265519171357648977229820858109463e+25L, 2.07628906165081651016090959669418757e+26L, 5.19651502464022032237151119613068945e+26L, 1.31917319408964404296057699402007921e+27L, 3.39745589598038079361346075350889747e+27L, 8.87905745443850359109225209251728000e+27L, 2.35527236149206412607849676379867126e+28L, 6.34276200772262482389475687836384423e+28L, 1.73453109399085970484897533524593455e+29L, 4.81789317060683087119323058524624972e+29L, 1.35959734649014823198654051259347560e+30L, 3.89896968990650039174705544740914822e+30L, 1.13654298652998993600898528562905634e+31L, 3.36845004399178001650511659074612092e+31L, 1.01530408470981725989945294876828360e+32L, 3.11314437622191823730222798219255685e+32L, 9.71307273973014040273869048577801862e+32L, 3.08451764358172594571945077912559223e+33L, 9.97268213982049728423469082288644341e+33L, 3.28362505228849158612675319471610094e+34L, 1.10137878539082753552686700652535380e+35L, 3.76433336759271429732220889611944227e+35L, 1.31140346593824292621577115225698644e+36L, 4.65813571068281367213354863266427946e+36L, 1.68751734747051139203189162215633629e+37L, 6.23705368501832349017363870039959902e+37L, 2.35257131442774486893301429598817553e+38L, 9.05893824021969993626817980294413695e+38L, 3.56224909761113607077591549609142868e+39L, 1.43095929157855820977839447284784020e+40L, 5.87397458498437504922632656680942932e+40L, 2.46482854981128378684502286098690220e+41L, 1.05764920309085562822396787743332401e+42L, 4.64247563928107803530506772359734012e+42L, 2.08528711827242177927156523287132065e+43L, 9.58843998518663217709277358040461543e+43L, 4.51498201124609227956079072858258677e+44L, 2.17797404834197320411588567916752909e+45L, 1.07672097682290045825361349736107198e+46L, 5.45726743292908558875367244655615249e+46L, 2.83686927045578113375020568154351117e+47L, 1.51310320139201162564313806536303971e+48L, 8.28397466722561707458255405781541923e+48L, 4.65723949199597134403065145457979764e+49L, 2.68979637071283693718739500357715726e+50L, 1.59659784691197038762901224386099403e+51L, 9.74415453825658662874112107295166701e+51L, 6.11723839484331306452493250946377612e+52L, 3.95204965058524182677586041680204451e+53L, 2.62870159207425821306145211826683375e+54L, 1.80099019650267939321809025642439880e+55L, 1.27155446256306838318997486480890087e+56L, 9.25588010447776071059464920928086632e+56L, 6.94973792013391939342588109222317053e+57L, 5.38516720076996562080859176422021036e+58L, 4.30849366810297877444039522534393308e+59L, 3.56095155754217837059656555899190815e+60L, 3.04188852838464999204043663335571874e+61L, 2.68709444193083718922293037351168007e+62L, 2.45592053890000085507656649738841713e+63L, 2.32364825416864153745578539849845717e+64L, 2.27712974158489233058096874867974690e+65L, 2.31263355291322473374027008502422191e+66L, 2.43540759298129112939388619780518297e+67L, 2.66091038882246524570905302589811279e+68L, 3.01810594342353392025458974267831671e+69L, 3.55582348951019250289525994888733340e+70L, 4.35418887779384901315251041444022899e+71L, 5.54497579551181331524599144834616000e+72L, 7.34827648190988633565298908145357523e+73L, 1.01399802572242326074394064208241565e+75L, 1.45791146224460794340779409761344050e+76L, 2.18548887681950529537081926891986328e+77L, 3.41802215328662300798456454917771592e+78L, 5.58084392060183572830239216435019125e+79L, 9.51958650279973390758331753317257950e+80L, 1.69757357824719778562747265505252946e+82L, 3.16690667099018001388115076193097403e+83L, 6.18509910641867543038652223056425804e+84L, 1.26554113438693437654962757714903554e+86L, 2.71482896587775689871692274985919286e+87L, 6.11038680296449408162222719197467046e+88L, 1.44405408617108323852658132530082074e+90L, 3.58608372663838816495703910754396082e+91L, 9.36523186806323959966772742491929522e+92L, 2.57408011620512244881601880029319908e+94L, 7.45213468986230271920125476429174422e+95L, 2.27430990383616981910627355587444817e+97L, 7.32301113412116474943463116371095103e+98L, 2.48981642173793246167799170730006141e+100L, 8.94653338635928158843209476986997508e+101L, 3.40040137239116597862336436061445989e+103L, 1.36828818620892821730981225660157834e+105L, 5.83427748982959193060571787534606697e+106L, 2.63848693767238342424340754241860221e+108L, 1.26672888276713952132156406152434700e+110L, 6.46222517831418280306046165038174027e+111L, 3.50643232060757360375065377104810475e+113L, 2.02560893394326816509670349356333828e+115L, 1.24704167708478470702273287091045609e+117L, 8.18986518840527903795498196049278255e+118L, 5.74361089440609996487936977642920132e+120L, 4.30580893408448976261136511421423734e+122L, 3.45415696607949675499703108821962730e+124L, 2.96831660153035273688363706593385374e+126L, 2.73545624237218359223636851390580041e+128L, 2.70631717669007784745026117275242499e+130L, 2.87767991634206038473084413615742294e+132L, 3.29241287826810639047033778585737812e+134L, 4.05784096195372596931902665934287382e+136L, 5.39378304910573732382585500687737807e+138L, 7.74152390167223540621293648465491842e+140L, 1.20120996231066845642412985516875175e+143L, 2.01745607955680730064740044686640147e+145L, 3.67217662348306252636962893865111425e+147L, 7.25316379805857762968710347450256630e+149L, 1.55659153530257056999948366173645285e+152L, 3.63439983279039488510674235872123571e+154L, 9.24438760046827764031744167566698413e+156L, 2.56505460126015154661078513762260065e+159L, 7.77468767447849521051212939671796074e+161L, 2.57775340952739965069105894604883404e+164L, 9.36236559200171990439286451934391539e+166L, 3.73025928974609135812613567068392186e+169L, 1.63280699411172483017448754437467171e+172L, 7.86350685466830069681739337700194312e+174L, 4.17288659053103260909421860789088638e+177L, 2.44376468354452976432259429734905692e+180L, 1.58182604983516221850901239956537929e+183L, 1.13349408906485996833819126879692168e+186L, 9.00609317867158059779746161516574861e+188L, 7.94724581006520631483760616875503191e+191L, 7.80148734070770210787180909072341250e+194L, 8.53389980133319877537947288273508168e+197L, 1.04199907704816359699116619452657846e+201L, 1.42261945983107616739713958471131412e+204L, 2.17558254343347922345039318825837040e+207L, 3.73339221107050141050095672544726852e+210L, 7.20212971416878494124587287789857735e+213L, 1.56476087980246841023430707631510252e+217L, 3.83599289170088247519036274601375492e+220L, 1.06310518934360483187879118646180568e+224L, 3.33719954606082150504485397744546787e+227L, 1.18890644129926367056386614030943443e+231L, 4.81657405194041613555936914144916344e+234L, 2.22347874123114616622582251703709887e+238L, 1.17199258523361213934517364652872480e+242L, 7.06839671131322838482398929154588609e+245L, 4.88812662946732326430886472870070228e+249L, 3.88441192207630934518298772235960268e+253L, 3.55483921979499015020713995580889030e+257L, 3.75484510816250928148708038190395303e+261L, 4.58798720933643387311573482445886110e+265L, 6.49989966050568126079524541048529496e+269L, 1.07018103272413666142402906179157598e+274L, 2.05258799808849457042833394124187317e+278L, 4.59710306190259625117029822247574448e+282L, 1.20521640888055636836192268959955157e+287L, 3.70784262206985650361726040790594581e+291L, 1.34198324051735290325452259089861845e+296L, 5.72866922601176092550850127280325304e+300L, 2.89181208605318627652310091586335359e+305L, 1.73078309894901278503683645288680165e+310L, 1.23150483936231719457381379774516673e+315L, 1.04456022524616506171048138618772005e+320L, 1.05909848234544418123752752792015094e+325L, 1.28725694153849592436889057738754649e+330L, 1.88087499295689639308903342601320607e+335L, 3.31344446614783992260480183208324732e+340L, 7.05835740270200829603933852702222207e+345L, 1.82360609116987101874149506325271866e+351L, 5.73167527316999715111499624522524490e+356L, 2.19834460849656433024448179756162490e+362L, 1.03213196012299389398122351217909554e+368L, 5.95090459142945173642877532664315820e+373L, 4.22711326689560391486862730288730260e+379L, 3.71146073815998244096864189178283440e+385L, 4.04143285030597516778349567433491877e+391L, 5.47630493200706306950643242188138639e+397L, 9.26610183846830899934754118194991047e+403L, 1.96463867218278875638951764233831097e+410L, 5.23826401399289488725708314794013273e+416L, 1.76269979359229195206462702562496087e+423L, 7.51358974574222029659643352716721030e+429L, 4.07203690042780566335825621191079282e+436L, 2.81652392485993763998682010256080428e+443L, 2.49586432083962995754217338958145192e+450L, 2.84464997550187838898841424132533307e+457L, 4.18656911271834268911740204159815337e+464L, 7.98835944729121866190974499356597568e+471L, 1.98427885725374523364086923738598523e+479L, 6.44313780728812316513345459942694301e+486L, 2.74646447436726496994650106679472135e+494L, 1.54345331097536381511922890966406624e+502L, 1.14854061177091306735355343708426610e+510L, 1.13671799925771100929831048483235430e+518L, 1.50301408173820906903238314130252343e+526L, 2.66721742401349021977265127553699936e+534L, 6.38191727827371990119668697526910696e+542L, 2.06864189323929509313332139375745418e+551L, 9.12718925758572793769909253655546363e+559L, 5.50827087084343716443556503345322384e+568L, 4.56943096951975523591483538202467049e+577L, 5.23664812769936727945516120554813767e+586L, 8.33295831969513770916127078276468196e+595L, 1.85073603040006635508770638738735213e+605L, 5.76725912854578779706265298662279369e+614L, 2.53507221317613667093309510235117825e+624L, 1.58037348241924263546145926074674624e+634L, 1.40497098317887844492262106048698980e+644L, 1.79118532756424559114150403858023467e+654L, 3.29340233091271285034548969456076701e+664L, 8.78384225704905897945003526718634352e+674L, 3.41824790512159692619674889187554870e+685L, 1.95247619547378795632466874007982924e+696L, 1.64685615123975037569921507294781182e+707L, 2.06385512057306929298128483493412318e+718L, 3.86691162964076111860523245198584961e+729L, 1.09008736553561747232882422664193409e+741L, 4.65333391196364819411904308657257877e+752L, 3.02768585771015415481330091322447912e+764L, 3.02262040534180824988954474846992913e+776L, 4.66133722640174567906974646266839244e+788L, 1.11806119156969171229108916233644999e+801L, 4.20019655376202192049844032418033555e+813L, 2.48880615873773868126893696694455625e+826L, 2.34286193142054643224145247339492426e+839L, 3.52941162196327496812531706159176164e+852L, 8.57183106082165907783781027353105401e+865L, 3.38163627323872188047900717079347979e+879L, 2.18363447282104345585022834572887531e+893L, 2.32596275137292895223293068081362090e+907L, 4.11925247272574761366980289309686003e+921L, 1.22265489460258041690738897372130823e+936L, 6.13184165651799059701146847592463464e+950L, 5.23922303275545560334122760478493484e+965L, 7.69087233862553980667730597006685190e+980L, 1.95622275953749870274795206909257068e+996L, 8.69670052895401378378113763338699958e+1011L, 6.81715148318539616903616353647181598e+1027L, 9.50697711954141544724599553989093262e+1043L, 2.38019733682587370869498352841844428e+1060L, 1.07973324919847346937291516197684901e+1077L, 8.95814284819025403820872820042945790e+1093L, 1.37229192661307043018958002675397831e+1111L, 3.91918794622242371528673544888524419e+1128L, 2.10730218913863433412315532873510194e+1146L, 2.15459607934366008026324206138837528e+1164L, 4.23163839295623007237154131840451677e+1182L, 1.61294441956204958952970453918741185e+1201L, 1.20568335528354973250479511763057854e+1220L, 1.78630819666459637235669417819650103e+1239L, 5.30233997012953850434143324467683139e+1258L, 3.18800705045665419646272046839479382e+1278L, 3.92589619613994835597705628928304867e+1298L, 1.00145056975313260959947278741812233e+1319L, 5.35268808912615454171856125906228237e+1339L, 6.06491960606218539467705074145131193e+1360L, 1.47410187506507259371724909079906759e+1382L, 7.77855372825975976779550291054389078e+1403L, 9.02071339187528665617085297107535931e+1425L, 2.32776342394968427168699373890370933e+1448L, 1.35351409374730203846799381939288903e+1471L, 1.79625881886715571166142200348072039e+1494L, 5.51189494978629938318487744451579809e+1517L, 3.96270198063441303687686251379779681e+1541L, 6.76492837567767494547614386605795924e+1565L, 2.77991073110506719318274536923711255e+1590L, 2.78805951202715437087943440518839779e+1615L, 6.92116280606414755524296394791409952e+1640L, 4.31380309053366092943951122004431463e+1666L, 6.84923073262139995438889690748178280e+1692L, 2.81137418164430829179092468240459910e+1719L, 3.02821524237655652451836921974619657e+1746L, 8.69048903533522694231765189726868666e+1773L, 6.74828063313306417588175763238310325e+1801L, 1.44026065844141159256872926595644247e+1830L, 8.58426091495439408178371839859019039e+1858L, 1.45211919400936944187225846047638548e+1888L, 7.08718013380970011842483247147601395e+1917L, 1.01475962220405902523641440040104610e+1948L, 4.33542978691578087509838132034723750e+1978L, 5.62285772227295495777726116212032065e+2009L, 2.25285072921565445630031609130087435e+2041L, 2.83839050906274298341210206309759282e+2073L, 1.14501659579022194588844609345877849e+2106L, 1.50629562239998305958408533546634030e+2139L, 6.58342161306998815751663631350733541e+2172L, 9.74198999952210922892973281379349494e+2206L, 4.97552704772088889228035264268694867e+2241L, 8.94330619882842342247706838649878784e+2276L, 5.77072420156026800834371478648673792e+2312L, 1.36388225285320494361282201451878478e+2349L, 1.20508189950290985406298094670730466e+2386L, 4.06413362486490272506766749982212198e+2423L, 5.34308092015215251528601382597439463e+2461L, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 8.88600744303961370002819023592353264e+00L; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif +#ifdef BOOST_HAS_FLOAT128 +template +void sinh_sinh_detail::init(const std::integral_constant&) +{ + m_abscissas = { + { 3.08828741797632286606397498241221385e+00Q, 1.48993184649209158013612709175719825e+02Q, 3.41228924788343710247727162226946917e+06Q, 2.06932576604261779073902718911207249e+18Q, 2.08700240760947556038306635808129743e+50Q, 2.01976616071790815078008252209994199e+137Q, 5.67213444764437168603513205349222232e+373Q, 3.06198394306784061113736467298565948e+1016Q, }, + { 9.13048762637669674838078869945948356e-01Q, 1.41578929466281159169215570833490092e+01Q, 6.70421551622327648231120321610008518e+03Q, 9.64172532715049941526010563818587232e+10Q, 2.50895076008577848514087028569888161e+30Q, 1.44726353571033714499079379626715686e+83Q, 3.75263401205045334128277886549019357e+226Q, 2.57846123932685341261715758547064293e+616Q, 1.25169402230987931584130068460134989e+1676Q, }, + { 4.07297690065758690150573950473604675e-01Q, 1.68206670702114874332932330092838356e+00Q, 6.15089798638672951539668935798437533e+00Q, 4.00396235192940022205839866641270319e+01Q, 7.92920024793102632052902471550336177e+02Q, 1.02984971333097958319686053784919407e+05Q, 3.03862310925243857437932941891415841e+08Q, 1.56544547436249486913719231527597560e+14Q, 4.04246509843021910355659662715183671e+23Q, 1.32170682742965817915034577861235933e+39Q, 4.99123178209955799774620736137366103e+64Q, 7.35294385035987596594501676609562008e+106Q, 2.45145417229813114714431821340237112e+176Q, 1.03030479197459267961759023741376327e+291Q, 9.88478945193556730604342445576518136e+479Q, 3.74498116076433060427765453233124618e+791Q, 1.90292390713026708045766158039087796e+1305Q, 1.72712488231809244721915842027236657e+2152Q, }, + { 1.98135272251478172615235718398538323e-01Q, 6.40155673500526017670785720911319502e-01Q, 1.24892869825397766254802900819319987e+00Q, 2.26608084094432123181038001270985037e+00Q, 4.29646269670232738148137717958679987e+00Q, 9.13029038709995569641811827045549232e+00Q, 2.31110765386427993316995139635470937e+01Q, 7.42770603432401243012214481410240677e+01Q, 3.26720920711525891697790966796945063e+02Q, 2.15948569431181871552028449867301828e+03Q, 2.41501526289641306037808670196966696e+04Q, 5.31819400275692915826269282626844010e+05Q, 2.80058685721704332307817790755562305e+07Q, 4.52406507979433877971977526863358905e+09Q, 3.08561257398067712180174566763237112e+12Q, 1.33882673301580747789133427708622972e+16Q, 6.25461717656234138147247754416652254e+20Q, 6.18209853581416475394863999233554548e+26Q, 3.07729364978845806686511011060697837e+34Q, 2.34895728937010430290698332595743680e+44Q, 1.14854319789946975790127332653552673e+57Q, 2.25530007001006986846545694404767295e+73Q, 1.87791950056919539419801461538703336e+94Q, 1.36747388793862427976781689638282239e+121Q, 4.24212177246407592514720294750151286e+155Q, 8.23473099012134325391170623028607158e+199Q, 6.06134211888406631001019923425936351e+256Q, 6.32519197436029413652766295658658263e+329Q, 3.61942292928205643948383705201563065e+423Q, 8.82464433126646489632943769283758364e+543Q, 3.35512488018651738642854323317447493e+698Q, 1.02411434678684822400261582079656500e+897Q, 7.40716670979374017620610271197945784e+1151Q, 1.30455147283895162835186634827124464e+1479Q, 2.02948723345659016173510134582487641e+1899Q, 6.99019443250345564805134094483457477e+2438Q, }, + { 9.83967894006732033862249554537934739e-02Q, 3.00605617659955035122465185012715805e-01Q, 5.19857978994938490000644785900799951e-01Q, 7.70362083298887700858583505753306721e-01Q, 1.07131136964131183026831222500748063e+00Q, 1.45056975808899844502126797109703210e+00Q, 1.95077854952036033400296546339240312e+00Q, 2.64003177369555146770080103921424631e+00Q, 3.63137237366741227331951933364601985e+00Q, 5.11991533090335057003526222543242753e+00Q, 7.45666098140488328926087222725984231e+00Q, 1.13022612688997262443461342203136009e+01Q, 1.79641069247277254966592982669611020e+01Q, 3.01781070460189822236726995418068214e+01Q, 5.40387580031237056709826662540066860e+01Q, 1.04107731447746954767459980678311109e+02Q, 2.18029520120262807725988909352359830e+02Q, 5.02155698625910164594509258651311707e+02Q, 1.28862131099822242045586488612672886e+03Q, 3.73921687080054832376623401153054636e+03Q, 1.24750729702019123239464970064060864e+04Q, 4.87639975322669212414357357061002683e+04Q, 2.28145658221913012154676335814417144e+05Q, 1.30877796006484301664040981436471740e+06Q, 9.46084663420966407698078336053299177e+06Q, 8.88883120363727962245667776649286152e+07Q, 1.12416882897434413447175648471746990e+09Q, 1.99127672953214446985509145592687205e+10Q, 5.16743469106098464964433058111638245e+11Q, 2.06721881420399088776240044545119948e+13Q, 1.35061503318410040604770421574064883e+15Q, 1.53854066283650818848773859278941683e+17Q, 3.29074729054035066052820102585085173e+19Q, 1.43729138188449881561963100200796631e+22Q, 1.40983244553034728562740932242727657e+25Q, 3.45913548027797144127990544649862792e+28Q, 2.39872058234095409213724024023509754e+32Q, 5.39880660461729295997086364918754801e+36Q, 4.61334000258062860955942270137550165e+41Q, 1.78768590966790245678294238939560892e+47Q, 3.84198437012433853552557148945213178e+53Q, 5.75279795570858370009870455748773410e+60Q, 7.77181203842728655149182334288749850e+68Q, 1.26967304420408162635234502672130357e+78Q, 3.49567677376573156773252547632961336e+88Q, 2.36251947497169244454694635287097330e+100Q, 6.00214389327365112307366927985587840e+113Q, 9.29071630346415553922675334522602561e+128Q, 1.51444223803384709004933819608345315e+146Q, 4.83290204410990250226310317342789471e+165Q, 6.09623012864338569215560315517200736e+187Q, 6.73889214277659359787962707085479315e+212Q, 1.60917893672694484647176104023542732e+241Q, 2.30724123468764987944582372785293125e+273Q, 6.32636439816284705814531208407868829e+309Q, 1.23274815890184688792156489065830724e+351Q, 7.55519778823055185901318833981345378e+397Q, 7.85730655106759111844772008129590573e+450Q, 9.36328400229780321059086898529742817e+510Q, 1.11332545426270395766246494603539938e+579Q, 1.53432069979625061288117473415446630e+656Q, 3.94622553764411915381186808199466267e+743Q, 4.41554290953392996069257034424439949e+842Q, 7.62037777854651720247173134262034607e+954Q, 1.15650294539918196985498353779647134e+1082Q, 1.50761161209705395018419027031866347e+1226Q, 3.03485088181756935935831645680716816e+1389Q, 3.38561189018537177501905611143498298e+1574Q, 1.64407968993192526511230001818530622e+1784Q, 6.63148743223242467667800355907041029e+2021Q, 1.15911606715877477373516464924821476e+2291Q, }, + { 4.91151003502902493004859475143401791e-02Q, 1.48013149674360733270682895306542340e-01Q, 2.48938813740683685679302156785267041e-01Q, 3.53325423692668437764413545980527251e-01Q, 4.62733556612235325924240102411897269e-01Q, 5.78912068164096306746325958452873475e-01Q, 7.03870253386062779930091622585657886e-01Q, 8.39965859144650568772715366992985538e-01Q, 9.90015066424437614655918533324528544e-01Q, 1.15743257014369913143250540144278056e+00Q, 1.34641275918536176274682426896283388e+00Q, 1.56216711390133555099139972670978661e+00Q, 1.81123885278232337973709010374295886e+00Q, 2.10192441900655030086142289233010995e+00Q, 2.44484388558419793403331221069953203e+00Q, 2.85372074663291502355627105440782037e+00Q, 3.34645891095535078662878051589922609e+00Q, 3.94664582105783838715586741669722603e+00Q, 4.68567310159667852940801410152900804e+00Q, 5.60576223090815117543658276010994803e+00Q, 6.76433233683057420359243855855175747e+00Q, 8.24038317537998522052755780107530197e+00Q, 1.01439435612985772971719760903679427e+01Q, 1.26302471433889247197016543768391586e+01Q, 1.59213039578034525767683420917805218e+01Q, 2.03392186192185718515730871595417962e+01Q, 2.63584644576063375239063530328964372e+01Q, 3.46892633322415240903243772580777748e+01Q, 4.64129146701972896279022543245987086e+01Q, 6.32055079389042420324823016892494512e+01Q, 8.77149726180890637368701810147417239e+01Q, 1.24209692624041149789460094889690346e+02Q, 1.79718634784512755704082576283626343e+02Q, 2.66081728332790018970422286819998479e+02Q, 4.03727302957571284052623415274320934e+02Q, 6.28811306654590870314912279241546792e+02Q, 1.00707983750749059403228978538051896e+03Q, 1.66156822918511428805794334715835287e+03Q, 2.82965144078658259775800007408843245e+03Q, 4.98438626658566913853681230634186899e+03Q, 9.10154692764781089316711776560031531e+03Q, 1.72689265547504972749956316341831556e+04Q, 3.41309957877860119013952370617496464e+04Q, 7.04566897705309280220071327032864763e+04Q, 1.52340421776127912819322591860346971e+05Q, 3.46047978289794741370038030428999755e+05Q, 8.28472420923318300234685980449600520e+05Q, 2.09759614660119394556971994518988102e+06Q, 5.63695079886127323617800640982012165e+06Q, 1.61407141085560724511058572293479599e+07Q, 4.94473067891506035994359725043521250e+07Q, 1.62781051682099135552732962095205423e+08Q, 5.78533297163228083837980097936281368e+08Q, 2.23083854068195568971189557384768608e+09Q, 9.38239130606473964277252886929412279e+09Q, 4.32814954477655169232818147143370442e+10Q, 2.20307274404924290439096300978395664e+11Q, 1.24524506710913641251205336694034299e+12Q, 7.86900053495782237478847410099854059e+12Q, 5.59953143297942246131549106648666176e+13Q, 4.52148694990209087674492643778610401e+14Q, 4.17688951654829326508268412199901397e+15Q, 4.45286775965049665585698503105745526e+16Q, 5.52914285314049806809138826588984682e+17Q, 8.07573251656285427526228838811700627e+18Q, 1.40204691626046869792238856080062664e+20Q, 2.92579141283223985009947325351094360e+21Q, 7.42643302933541088612408356755400686e+22Q, 2.32199633124573536432554419147246735e+24Q, 9.06419425063844243203436385576505269e+25Q, 4.48127904881944560890552322697008678e+27Q, 2.84904630472699064463968599282594753e+29Q, 2.36738115918335597454764956918757980e+31Q, 2.61582557845512122680388807973635504e+33Q, 3.91476494826329080795479762913295296e+35Q, 8.09204244855592921872201325412806040e+37Q, 2.35892132094063033238721339006551614e+40Q, 9.91521864853533259120934844876236731e+42Q, 6.15285105934265876352030730244956160e+45Q, 5.78027634014451538840307809528507880e+48Q, 8.44375173418648862568787172019022001e+51Q, 1.97334335089976670761175825761931164e+55Q, 7.60524737855621997973474323106432459e+58Q, 4.99205710493951041807363394610235299e+62Q, 5.77586342390391231642398949899839793e+66Q, 1.22180820194535560304052518248291191e+71Q, 4.91291723038713381630505551954597084e+75Q, 3.91397181373220237220120723831917341e+80Q, 6.45638806990528678730571952330861768e+85Q, 2.31122506852801035759561549878351498e+91Q, 1.88745815771943133919251977215527414e+97Q, 3.70848316543845309405007424631179900e+103Q, 1.85519881228353863491690263658048910e+110Q, 2.50978787317170531780713813087390423e+117Q, 9.79042375559121661656574862110333881e+124Q, 1.17908880794405074709159757136517906e+133Q, 4.71463184672247661988055185868884361e+141Q, 6.76265778595971324046101731037889126e+150Q, 3.77863792934416463055998231270977695e+160Q, 8.97819133628477274891556066769979914e+170Q, 9.95914407403494739885505580434362313e+181Q, 5.69630798679205432723450802096176313e+193Q, 1.86743452325707784871951519925288377e+206Q, 3.92719945859412568046939678789391943e+219Q, 5.97262802266570558434581771213406728e+233Q, 7.46293577265068378653739984957785219e+248Q, 8.77620026161886682323882402399676732e+264Q, 1.12240955327637524990782988952974327e+282Q, 1.82091452946462555573948654780251641e+300Q, 4.41446070956615785669448222555093749e+319Q, 1.90397541953366074155779318767572880e+340Q, 1.75902281129585020130874703618203168e+362Q, 4.24169226543235148528312412985493520e+385Q, 3.29481560149200680874049429678412127e+410Q, 1.03135148368973063748422508803572335e+437Q, 1.65119340908368036904973428016231291e+465Q, 1.74266589416784110509614783944413581e+495Q, 1.58844581452329281145953920728196433e+527Q, 1.66707913260906132496128590135534752e+561Q, 2.73591938942385354685476950777714705e+597Q, 9.72579530056263762611950442873242859e+635Q, 1.05939976357545005153997575210948938e+677Q, 5.11518133258374954640812727174811520e+720Q, 1.62189977683387633564608415164137138e+767Q, 5.13160378352024380054652132361473058e+816Q, 2.52913238575275285564889845966314333e+869Q, 3.11944472707029467274111976509771118e+925Q, 1.59495166899855372832309254674677663e+985Q, 5.78489108811836645985010918537259212e+1048Q, 2.63682062563962607583302320466728244e+1116Q, 2.77639914729635446526568065100606294e+1188Q, 1.29100591117079370649785145859270604e+1265Q, 5.28444381883484729377275155781628201e+1346Q, 3.96822241951490935324304074734991606e+1433Q, 1.19450143809568524145027520220707370e+1526Q, 3.31232848440880307300003548888720354e+1624Q, 2.05165402811808892980123939590704909e+1729Q, 7.28745294435475474950235921073537827e+1840Q, 4.04980582052614743975213722266303496e+1959Q, 1.02489069982330185861864247663932840e+2086Q, 3.68323339665104313610706754895420191e+2220Q, 6.30765607309438726154024457882187086e+2363Q, }, + { 2.45471558362986365068916495863375252e-02Q, 7.37246687390334622422734853496288652e-02Q, 1.23152530941676654318795303724845312e-01Q, 1.73000137771924855589325108501317324e-01Q, 2.23440664959686000105440799041805360e-01Q, 2.74652654971851825832501290298110601e-01Q, 3.26821679298064666878532098621581949e-01Q, 3.80142100980478924532143540106066542e-01Q, 4.34818963721561494844111167726460593e-01Q, 4.91070036509942840677161193401564426e-01Q, 5.49128045948021544092182270959032951e-01Q, 6.09243132438265439671151238479162657e-01Q, 6.71685571202114806905814141850507988e-01Q, 7.36748804906793864301473114817726587e-01Q, 8.04752841633695064447122683633828025e-01Q, 8.76048080248205070538153903222362252e-01Q, 9.51019635182333225305914695670696308e-01Q, 1.03009224453247006650365629888427541e+00Q, 1.11373585958868076495962122155474153e+00Q, 1.20247203091805887562283157205483916e+00Q, 1.29688122649686375081031224280895230e+00Q, 1.39761124182837302592381732283067440e+00Q, 1.50538689136054520464181654424860094e+00Q, 1.62102120589479802996006107398491112e+00Q, 1.74542840336904457155639617870301735e+00Q, 1.87963895203102933109827214352261973e+00Q, 2.02481710760932852386806039721112499e+00Q, 2.18228138214788418140109912591097815e+00Q, 2.35352849482388135462737441996874099e+00Q, 2.54026146822962645747200253699005204e+00Q, 2.74442267217147811137997080576917741e+00Q, 2.96823278719060661900608946565759698e+00Q, 3.21423686952065766588900110700898117e+00Q, 3.48535895790773046725176601804623352e+00Q, 3.78496698311737282096444166343378976e+00Q, 4.11695013894029509955211911245969952e+00Q, 4.48581136938823171042685637747918431e+00Q, 4.89677824656200181220988391922608405e+00Q, 5.35593629082672594809503436864536474e+00Q, 5.87038976260095690701450882557564694e+00Q, 6.44845618913111760490837120481487939e+00Q, 7.09990245267955823638498704195342171e+00Q, 7.83623225328284126133289428371735767e+00Q, 8.67103729357523063452024155765264339e+00Q, 9.62042777798599036292354986394365067e+00Q, 1.07035619887679953097266587864897721e+01Q, 1.19433000813944102150187593166292839e+01Q, 1.33670142103849964717469335941905385e+01Q, 1.50075961591439634296262105146352627e+01Q, 1.69047154820352837629069726738079470e+01Q, 1.91063966873168959742774555727687289e+01Q, 2.16710044321657799400571191555580338e+01Q, 2.46697527469509919694460528848277171e+01Q, 2.81898902515784535507915179415086299e+01Q, 3.23387613242940174515264777910328241e+01Q, 3.72490075809724574016769417176033924e+01Q, 4.30852608490774199699508301986096898e+01Q, 5.00527964765470397507453905247128474e+01Q, 5.84087760725387652778097774354827947e+01Q, 6.84769282153423986221602875181609661e+01Q, 8.06668177706071484780398912645020900e+01Q, 9.54992727020024926023862465179431320e+01Q, 1.13640119576948788485338465195796676e+02Q, 1.35945194497660320895127779474436433e+02Q, 1.63520745187974444650772294136165162e+02Q, 1.97804968791258694996900535479466855e+02Q, 2.40678753588977666070114453459006852e+02Q, 2.94617029293055502283701272741864024e+02Q, 3.62896953214712533295812475420140158e+02Q, 4.49886178271559690246754005443952599e+02Q, 5.61444735313349610605402755114132063e+02Q, 7.05489247089927142932822047183046835e+02Q, 8.92790773279996411641203534672635638e+02Q, 1.13811142497947837649816383892464930e+03Q, 1.46183599156360536709532001371341489e+03Q, 1.89233262344471618571971876282268943e+03Q, 2.46939603618613347923158360306283371e+03Q, 3.24931156929882473061795067124714454e+03Q, 4.31236711317028301201344127304044700e+03Q, 5.77409475450013966113987691727433327e+03Q, 7.80224723750085184509285318864950930e+03Q, 1.06426753097580697178856711472253120e+04Q, 1.46591538353567498972551254799117195e+04Q, 2.03952854123975483493635354197048606e+04Q, 2.86717062242155626463726121489695136e+04Q, 4.07403376218345329677215262695648133e+04Q, 5.85318231059692339303875522971681880e+04Q, 8.50568926526520663990658694675860445e+04Q, 1.25064926984785661460287048343378461e+05Q, 1.86137394316674976633487938076388915e+05Q, 2.80525577745201092730917964861422661e+05Q, 4.28278248608476174804382253986989659e+05Q, 6.62634050612765730354133581004327179e+05Q, 1.03944323965033956450234998906270616e+06Q, 1.65385742611296131560210844780522467e+06Q, 2.67031565012527916099202454680251592e+06Q, 4.37721202662435879490158484533403820e+06Q, 7.28807171369841382127860775464397414e+06Q, 1.23317299340033169377433189565436518e+07Q, 2.12155728576993369873860452866846505e+07Q, 3.71308625486153538260132253550700609e+07Q, 6.61457937735213553402161639469475625e+07Q, 1.20005529169491711045823979192639236e+08Q, 2.21862941029688069011551388945586459e+08Q, 4.18228293992868770261761230703186170e+08Q, 8.04370413249371480388874614907492609e+08Q, 1.57939298942566811374336496311019268e+09Q, 3.16812241552410463468859624242708347e+09Q, 6.49660681154986132317647460889788282e+09Q, 1.36285198835644448552647856869429224e+10Q, 2.92686389700870770766115985553270450e+10Q, 6.43979866520949373493178830943697748e+10Q, 1.45275523377290302218030864454825923e+11Q, 3.36285445938924657613055409970261746e+11Q, 7.99420278543347927144872935893265787e+11Q, 1.95326423336229196043471517599153542e+12Q, 4.90958186824255456862636657247754379e+12Q, 1.27062273076501561032764305894113023e+13Q, 3.38907098674298576400746683674724217e+13Q, 9.32508403020884483292253012776198040e+13Q, 2.64948942383453414004877623922649545e+14Q, 7.78129518409495719454885394657867226e+14Q, 2.36471505252735563941195059995826485e+15Q, 7.44413803146595825477962585154187758e+15Q, 2.43021724068474963516185214140527324e+16Q, 8.23706864153435776160816132466078110e+16Q, 2.90211705066454883998576313308511774e+17Q, 1.06415767940403701307268606275625099e+18Q, 4.06627710606196001743762877107146413e+18Q, 1.62127423363035909653152786372227505e+19Q, 6.75415683091545001302004267324917730e+19Q, 2.94405684173378191865875139697985419e+20Q, 1.34464013954910781728162580030274237e+21Q, 6.44458615894472329986968048792306357e+21Q, 3.24621866755460893428420802873638947e+22Q, 1.72123457955665353317614924039447693e+23Q, 9.62253389024047439092145016046085843e+23Q, 5.68140726041795667144549981860838281e+24Q, 3.54889077999592818369666361009585253e+25Q, 2.34950642567226956175428754094351900e+26Q, 1.65161813060520564300895544060422208e+27Q, 1.23514742649311305869239755896991097e+28Q, 9.84594723979205755046350596451684287e+28Q, 8.38313078198461041780434493882428621e+29Q, 7.63964946139917244491542497186650823e+30Q, 7.46786273223388520123213229503835823e+31Q, 7.84769148200499366026301301860529069e+32Q, 8.88603255762645470434690507794367917e+33Q, 1.08673489067830243582954987160820285e+35Q, 1.43896777703653845844251806933839180e+36Q, 2.06816886547560352123602144529722761e+37Q, 3.23488532022391238528760911223890778e+38Q, 5.52123364154262851432456431974095092e+39Q, 1.03114823119466385539623421556538031e+41Q, 2.11327203581636598172202380321061095e+42Q, 4.76672434548507751952154119062281282e+43Q, 1.18696155099021828703717401094811909e+45Q, 3.27317216920584757332668902845797411e+46Q, 1.00282122676916775281745610945056481e+48Q, 3.42493390393515647893744567642140320e+49Q, 1.30843601702642873582064430681159468e+51Q, 5.61137833004842050312648039721074217e+52Q, 2.71142480632713929135631433480050921e+54Q, 1.48177179364406644198189668782951739e+56Q, 9.19428207104277880378138495715383545e+57Q, 6.50366145587535556181715778862405651e+59Q, 5.26632998686862730262822409628217101e+61Q, 4.90266280796934735938520451826335739e+63Q, 5.27051105728955705039001489033126495e+65Q, 6.57285651167058331634360929791632134e+67Q, 9.55395603001322538662375429270666445e+69Q, 1.62649191115941161585027771743899152e+72Q, 3.25941091550095122341298778408441950e+74Q, 7.72846031811361427986096662411063427e+76Q, 2.17988199690591805869859473392710071e+79Q, 7.35448438837150591476717971591286847e+81Q, 2.98483127080395774595532033544389202e+84Q, 1.46582826781343896171132281512590065e+87Q, 8.76335597262986426104836504228132778e+89Q, 6.41790966584783113047113716478179340e+92Q, 5.79495864922989350993450871503126827e+95Q, 6.49422447231190836548908540847688948e+98Q, 9.09500015601643369774077853623649258e+101Q, 1.60305849845529910220272077472033035e+105Q, 3.58209911911932052869313856359636456e+108Q, 1.02244122713985468653173668554645414e+112Q, 3.75687218501508605716480350749498176e+115Q, 1.79136346383284915921138840751400855e+119Q, 1.11764188203947212384081419514165395e+123Q, 9.20215956554652828530686799399533824e+126Q, 1.00871647482788856814534779759128531e+131Q, 1.48554648708930180487801088228218062e+135Q, 2.96696153483056609742176098165601109e+139Q, 8.11420728466436936033056414100674073e+143Q, 3.06917808750766973862958599324080278e+148Q, 1.62222368114779147260405024572949430e+153Q, 1.21094608845400598319807865894230970e+158Q, 1.29069460371207764384235331328282226e+163Q, 1.98663030134211110165437011771903132e+168Q, 4.46757261704134429970068624260491498e+173Q, 1.48564187771108280640829188970287255e+179Q, 7.39669065831627851911038512117013389e+184Q, 5.58477447271859974925476129175614574e+190Q, 6.47976647473179732779115257999520915e+196Q, 1.17117420317317171387535528766936277e+203Q, 3.34428267755162742939489398076764840e+209Q, 1.53076558056194845489001829008909627e+216Q, 1.14010185551912954998170816176845430e+223Q, 1.40319939603195121408389523582430293e+230Q, 2.89974936197123389451668716314083017e+237Q, 1.02284833216532051937856086912560392e+245Q, 6.26387216223145817942640023700922965e+252Q, 6.77735971213475345230129326178116125e+260Q, 1.31920032114466459135766725110063188e+269Q, 4.70640341492973980389482209817290571e+277Q, 3.13724441498341266441161693520329378e+286Q, 3.98571382107801782113811082484615717e+295Q, 9.85039693194582447444400924997258508e+304Q, 4.83687381317675554709367324551273400e+314Q, 4.82285202614019890234802453942628315e+324Q, 9.98703239968301934722476402798215616e+334Q, 4.39579560388542750852159646726102667e+345Q, 4.21213245293498773753031381258995955e+356Q, 9.00647826017501992250418906434620537e+367Q, 4.40820570973056960340923739077146754e+379Q, 5.07036496321109968512657627671150030e+391Q, 1.40820593625978850981984707085120209e+404Q, 9.71170922560303314648712317222502389e+416Q, 1.71185299004740150846260848238269630e+430Q, 7.94539187117702846067322763172557224e+443Q, 1.00135866851780201306228838620557915e+458Q, 3.53720801942577272956188201390769482e+472Q, 3.61856514873836509067172206947444182e+487Q, 1.10885899005952624619970603738429749e+503Q, 1.05391354932473165812334641476989979e+519Q, 3.22052822779158301893419142803165095e+535Q, 3.28354332174247719776999412908271692e+552Q, 1.16054782509911106933820737153108500e+570Q, 1.47919833966504706156198174688381009e+588Q, 7.08133783868969672071172398101964598e+606Q, 1.32792489232842472677863721400834701e+626Q, 1.01864740027867286775312222487805144e+646Q, 3.34261841519397423195159276540555265e+666Q, 4.91359232957804830460198547632977969e+687Q, 3.39338961080932963058551495328009206e+709Q, 1.15643101006244038688616288204262882e+732Q, 2.04580060100421448267115092746141073e+755Q, 1.97956226677236405650286559215774642e+779Q, 1.10576482674657666978217926798043956e+804Q, 3.76975534316002585938373910751464161e+829Q, 8.30723712530280347580443574905340732e+855Q, 1.25551214072288994426628885709173410e+883Q, 1.38340901524945057559377504414014724e+911Q, 1.18367583857036159478030255830898223e+940Q, 8.39312984240762796712708279978405886e+969Q, 5.27445408794117779852142535860614541e+1000Q, 3.14827291975085189890248083313318702e+1032Q, 1.91708860929520191993037622102307238e+1065Q, 1.28205230070904948620917170049585485e+1099Q, 1.01601053886738575799673411634857928e+1134Q, 1.03205637073787228175634527391820202e+1170Q, 1.45709248520841293241982349536788740e+1207Q, 3.10836026767661586110721101783586616e+1245Q, 1.09211875259058272695772315187071594e+1285Q, 6.90756042513315914107755467851436390e+1325Q, 8.62072629674515227183116754798059355e+1367Q, 2.33367455582609053817676883927592981e+1411Q, 1.51088703661957707064674032871094166e+1456Q, 2.58751847359969149251723060639056652e+1502Q, 1.30061395127966085145757755976532379e+1550Q, 2.13606222552299322654005297188550444e+1599Q, 1.28040046650693999927593879574416998e+1650Q, 3.14004479696111085451082602060045251e+1702Q, 3.54445798947819813290733040762684700e+1756Q, 2.07959058928044687396800353571401401e+1812Q, 7.18928436789152221379187719747515467e+1869Q, 1.66674057039586083195182422956301841e+1929Q, 2.96144319154423967308042996118314268e+1990Q, 4.62818622228372755683383431403798070e+2053Q, 7.33344579812102490343077358675798902e+2118Q, 1.36418147108226874642787854899398972e+2186Q, 3.46578234556914165783357030404723460e+2255Q, 1.40565670831906218450256157719581702e+2327Q, 1.06915717420033634558717882909227336e+2401Q, }, + { 1.22722791705463782987186673092730169e-02Q, 3.68272289449259047084662870963424169e-02Q, 6.14133762687107999107794380606156658e-02Q, 8.60515970877820790729887694832007789e-02Q, 1.10762884001784544594356091768970671e-01Q, 1.35568393495778548180370153140547366e-01Q, 1.60489493745433548938038568465534727e-01Q, 1.85547813164508949628358434474487020e-01Q, 2.10765289867070052445854835116288718e-01Q, 2.36164222221462626796458521613760417e-01Q, 2.61767320678549526133854585166690062e-01Q, 2.87597761063134290040469640683594256e-01Q, 3.13679239524903564719983726260388052e-01Q, 3.40036029353663277020320913399073202e-01Q, 3.66693039873181019259593465683200480e-01Q, 3.93675877638645179710808224562806486e-01Q, 4.21010910174684626844126582677407364e-01Q, 4.48725332504145034061613569614932171e-01Q, 4.76847236732482946224267058692370227e-01Q, 5.05405684968820937507178521019349537e-01Q, 5.34430785882522907921272727308422687e-01Q, 5.63953775213726713429575640521392073e-01Q, 5.94007100577754899987320597582638522e-01Q, 6.24624510926871605306723866692531653e-01Q, 6.55841151058639796949436231740377164e-01Q, 6.87693661588351492208131027097817883e-01Q, 7.20220284833868340062109216385730821e-01Q, 7.53460977094957222390047011401038344e-01Q, 7.87457527846096346070444259791519611e-01Q, 8.22253686402049937748559808122413409e-01Q, 8.57895296659582580760899947902549978e-01Q, 8.94430440566859300921740259698532581e-01Q, 9.31909591024743548462187459499302759e-01Q, 9.70385774981792065875818381502464879e-01Q, 1.00991474754772858364115613090157760e+00Q, 1.05055517801908314962647763431650363e+00Q, 1.09236884878609257919070489976671100e+00Q, 1.13542086817251430035405051069824787e+00Q, 1.17977989835042446581611499466432280e+00Q, 1.22551839957114260989771330348614290e+00Q, 1.27271289206202647251525071825625510e+00Q, 1.32144423705798506493224886295961288e+00Q, 1.37179793856724595345645859982391269e+00Q, 1.42386446761438409645831411537400020e+00Q, 1.47773961086120811494347321807905579e+00Q, 1.53352484567928885758582112389540236e+00Q, 1.59132774393835509765516748425726982e+00Q, 1.65126240698431007605515051243084836e+00Q, 1.71344993451128821134705183982006487e+00Q, 1.77801893028625685775809622156398356e+00Q, 1.84510604796472086962932266394457464e+00Q, 1.91485658054495189874749078346703174e+00Q, 1.98742509734901709257017841100790150e+00Q, 2.06297613279527528332657028179424398e+00Q, 2.14168493164291678457053660944377397e+00Q, 2.22373825584899452105160804133355977e+00Q, 2.30933525868721379620595550412858017e+00Q, 2.39868843234110382076332419963510302e+00Q, 2.49202463580835609502681428341212971e+00Q, 2.58958621064512275641789028727789739e+00Q, 2.69163219284683244353140722232296853e+00Q, 2.79843963001449729057960489638268331e+00Q, 2.91030501390256265160483634586060233e+00Q, 3.02754583949736496303590546881335550e+00Q, 3.15050230294691972178684607549631061e+00Q, 3.27953915196739433034632435779672485e+00Q, 3.41504770380541061125886820639123018e+00Q, 3.55744804745655073349177433143963235e+00Q, 3.70719144864977981720917442750632409e+00Q, 3.86476297812834212534134362353667523e+00Q, 4.03068438601653134401780732606469366e+00Q, 4.20551724758861383531605318041260028e+00Q, 4.38986640858517245778656669889477004e+00Q, 4.58438376139193074830218319449001571e+00Q, 4.78977238695068769484017601922716285e+00Q, 5.00679110126136326392507134554822932e+00Q, 5.23625944981527405022093792997629943e+00Q, 5.47906319833752315041593490985864953e+00Q, 5.73616037388481741547685088499196591e+00Q, 6.00858791672861985829483499535828449e+00Q, 6.29746901064886304750229195240462364e+00Q, 6.60402116738092913326417425575120773e+00Q, 6.92956515012467783689325375523493772e+00Q, 7.27553483138386097168028487959046984e+00Q, 7.64348809212349206445236344518102598e+00Q, 8.03511888250245928810782085772095077e+00Q, 8.45227057947818812962999536922397314e+00Q, 8.89695079364178531317631891553840631e+00Q, 9.37134779701639517335117345438905815e+00Q, 9.87784876557344603277558247754926945e+00Q, 1.04190600552776203680920477623835667e+01Q, 1.09978297590083170587228134865897514e+01Q, 1.16172728242395225830192073579898657e+01Q, 1.22807990484892461058359016635119689e+01Q, 1.29921443119669104778276499842319618e+01Q, 1.37554054553562588138800381241813305e+01Q, 1.45750792662062131604851118656361439e+01Q, 1.54561061010485246793800779406223808e+01Q, 1.64039187433830292507497745621200597e+01Q, 1.74244971815420897003963134996594183e+01Q, 1.85244300868843752575149709549249943e+01Q, 1.97109838837826649364051644134983470e+01Q, 2.09921804308096164753912694285306280e+01Q, 2.23768844801398294581745473457799699e+01Q, 2.38749022527007382030837433327528532e+01Q, 2.54970926638043046429091560004131137e+01Q, 2.72554929623253155508089897070407353e+01Q, 2.91634608111962498675086489719161981e+01Q, 3.12358351442328496157597338087371982e+01Q, 3.34891184913680511842485226603345913e+01Q, 3.59416838798546509869193271004218290e+01Q, 3.86140099030723073708193155942738501e+01Q, 4.15289481132930302349687386068430483e+01Q, 4.47120275544153339602356644078995085e+01Q, 4.81918020222491017368298630788454953e+01Q, 5.20002465436155875740198471916042599e+01Q, 5.61732106253738449367657038097317749e+01Q, 6.07509370691878207865695555214723350e+01Q, 6.57786566116800396636894823760941404e+01Q, 7.13072703735772134302608508415302565e+01Q, 7.73941341346580579448409414339011685e+01Q, 8.41039608526963339165414121007032304e+01Q, 9.15098606849673444816151204282990934e+01Q, 9.96945411354770401552161275609161166e+01Q, 1.08751693942601889700382157585301539e+02Q, 1.18787600064303753208251167345242212e+02Q, 1.29922989761451637135259469378151165e+02Q, 1.42295201505637253678660735501099867e+02Q, 1.56060691466500267146385748883961050e+02Q, 1.71397954932643240617797882975933747e+02Q, 1.88510932515483007342988031066863162e+02Q, 2.07632987774012593538662727768467525e+02Q, 2.29031559465458736990493497603665470e+02Q, 2.53013611565567646662052901877967628e+02Q, 2.79932028239889691165098106403660221e+02Q, 3.10193129976673089035599193653267696e+02Q, 3.44265522210752989223327890530839313e+02Q, 3.82690530328937838722167127466549147e+02Q, 4.26094526620760770127774483839356753e+02Q, 4.75203517589290204505256185266901137e+02Q, 5.30860436623905886389110002239619071e+02Q, 5.94045680537299500918768911865886523e+02Q, 6.65901542833877826224842736585170818e+02Q, 7.47761336730915387004112664458834008e+02Q, 8.41184173047134302254019501114516601e+02Q, 9.47996569801374152415232558717779048e+02Q, 1.07034233137588184029692740932268166e+03Q, 1.21074245751858265959674123771999362e+03Q, 1.37216724155220581953081355884482812e+03Q, 1.55812321218769272183468357733000347e+03Q, 1.77275818866271628150109400030205931e+03Q, 2.02098848541186298361330491694554409e+03Q, 2.30865325932916315664195536323762336e+03Q, 2.64270218981368427312930076396387941e+03Q, 3.03142418286921021219727597009903791e+03Q, 3.48472667698575601755930501247710368e+03Q, 4.01447750473397350451805793460750946e+03Q, 4.63492426404939475098008035447052569e+03Q, 5.36320994977343974892087068772061383e+03Q, 6.22000841211434280322218569985211936e+03Q, 7.23030933285302995642999721294241650e+03Q, 8.42439021673521778311062568091410678e+03Q, 9.83902287153854178745596238243054980e+03Q, 1.15189746308311398832174294139085014e+04Q, 1.35188809887437420186309997879371889e+04Q, 1.59055874546006694678895534154510667e+04Q, 1.87610857276481617624948313285750831e+04Q, 2.21862046239336627450920062330548753e+04Q, 2.63052620505491535696779646542992118e+04Q, 3.12719440194171105738301413156011152e+04Q, 3.72767546125665292256151356126569138e+04Q, 4.45564828031227324859783992706804335e+04Q, 5.34062659201890392985687357687040023e+04Q, 6.41950058038891812326608231510870856e+04Q, 7.73851264238682005972799669756325711e+04Q, 9.35579699398172596314688114151429601e+04Q, 1.13446537582066946954261668152086820e+05Q, 1.37977827220974171292929858459577092e+05Q, 1.68327748580788705255881136304020641e+05Q, 2.05992574612073530499207561599578962e+05Q, 2.52882202450315825396186949822484192e+05Q, 3.11442271834772591489327431348343937e+05Q, 3.84814591343557073602914002196809171e+05Q, 4.77048586496682264260701809258611041e+05Q, 5.93380932472474085420815642783399996e+05Q, 7.40606619035166611456854888146209865e+05Q, 9.27573047147064337154043416441694054e+05Q, 1.16584026094018041532121013906762681e+06Q, 1.47056632211824613527279037871707355e+06Q, 1.86169889901492197099442712763381073e+06Q, 2.36558487029835449538535481946926618e+06Q, 3.01715269550576487659856266530294113e+06Q, 3.86288257359992924875408921517049995e+06Q, 4.96486430558975035817682789982702410e+06Q, 6.40636282995973660643182932326803288e+06Q, 8.29948184726130211549565432685136745e+06Q, 1.07957589264240185368036619492890404e+07Q, 1.41008732747460409136778616182972970e+07Q, 1.84951472441825010015226156029368615e+07Q, 2.43622441967080550013889014979179789e+07Q, 3.22295113186394123446611158573926085e+07Q, 4.28249388238592533660285754208101809e+07Q, 5.71579339433926763705565010979377786e+07Q, 7.66343793274545163464956180626615373e+07Q, 1.03221272549848969879325123115356857e+08Q, 1.39683399197619484239843178827556776e+08Q, 1.89925149766489273996177039954695089e+08Q, 2.59486539646750585135581953531723138e+08Q, 3.56266474246450149668190479113931322e+08Q, 4.91582541317241347106730357233806750e+08Q, 6.81731647011695814167689014048918740e+08Q, 9.50299810520254143758401252895411400e+08Q, 1.33159829534327753848250753466160796e+09Q, 1.87580197601045983131635998256926235e+09Q, 2.65667390770973148718390348704244405e+09Q, 3.78324021561636590874538087942452353e+09Q, 5.41753184850013697899991815866441223e+09Q, 7.80169536989284750988699417135654043e+09Q, 1.12996536895509883334977946121306167e+10Q, 1.64614916139082192438237472977949088e+10Q, 2.41235399573668769368537292636420902e+10Q, 3.55648689543192709406699873104224405e+10Q, 5.27534501409376051919461374149743655e+10Q, 7.87357210832537817724326568648616226e+10Q, 1.18256902031786360426341053633539951e+11Q, 1.78754944250836346103770384839274996e+11Q, 2.71963306497998614239753953623599024e+11Q, 4.16512215311989794586279802552971310e+11Q, 6.42178185820513419673438138950789714e+11Q, 9.96872549757627591785162935837099498e+11Q, 1.55821232712296039863279650270498705e+12Q, 2.45280998490709378571967041325143017e+12Q, 3.88865623282814020969225986222930869e+12Q, 6.20986899050942490907341584961146266e+12Q, 9.98992421629798366453910164990598035e+12Q, 1.61915800137861135092472802019186093e+13Q, 2.64432451866992655897802160266314720e+13Q, 4.35201884790437478598011793154963363e+13Q, 7.21888468820274170949384690425513293e+13Q, 1.20699764072734953803867091697058471e+14Q, 2.03448372244520740184714594138600722e+14Q, 3.45755310287440291972421764598644671e+14Q, 5.92524851195750570615520553006806424e+14Q, 1.02405779371303867152496937066868237e+15Q, 1.78517404594164216208571127025070841e+15Q, 3.13930698866849469593365078009075683e+15Q, 5.56985627017489012771720073467849986e+15Q, 9.97176335383446032822138577325280050e+15Q, 1.80168749111488309180201148764368470e+16Q, 3.28570985832256554206799328627718020e+16Q, 6.04901854091075971038418094513619254e+16Q, 1.12437528321136957183940077137648079e+17Q, 2.11044512595243530534854315009251863e+17Q, 4.00073700789122999206498186212756047e+17Q, 7.66084936156432930897007145016954725e+17Q, 1.48201877099617670026480296368024580e+18Q, 2.89694543391085794507262308584519511e+18Q, 5.72279016569347049314117808244814073e+18Q, 1.14268996043992146219736887475145416e+19Q, 2.30661655998410672274449611000740199e+19Q, 4.70785718461609386331913071438798214e+19Q, 9.71734634749534281292184698073106843e+19Q, 2.02873560562258544354738566036230939e+20Q, 4.28484025417100058060231110755876699e+20Q, 9.15702732902162383627232801008773485e+20Q, 1.98045783476641177674243338550380776e+21Q, 4.33560488670225200389961701585516223e+21Q, 9.60925855971422399500251930072135526e+21Q, 2.15660463060858699692371033788512835e+22Q, 4.90204590969527028901267517972005859e+22Q, 1.12874922712132846722486415215181510e+23Q, 2.63341462304993087921430516281962614e+23Q, 6.22633568449099854312810660038498408e+23Q, 1.49220527901414892100221726222044247e+24Q, 3.62576824971759010933939677750446994e+24Q, 8.93389976496144488245242728630867648e+24Q, 2.23278698168226238263925345166626442e+25Q, 5.66129533629398673236467837398265907e+25Q, 1.45661671029813314161310452512420504e+26Q, 3.80395985286848824540247897299973294e+26Q, 1.00853158560303648965770564091212618e+27Q, 2.71524742512942335771421173573350598e+27Q, 7.42507176676665196668682930989072343e+27Q, 2.06286071217322500340710263294206778e+28Q, 5.82405545879941331172090843001915861e+28Q, 1.67138883669643664401793246595736207e+29Q, 4.87683063202395639212825400688637822e+29Q, 1.44717007114610715647680482586441902e+30Q, 4.36856220892558378299543245366740004e+30Q, 1.34187380624925133807232471810065508e+31Q, 4.19525163275433868171703825329949387e+31Q, 1.33536013482821413616157861182819558e+32Q, 4.32868135071513633988478443702722304e+32Q, 1.42940186615031918577626278068758606e+33Q, 4.80973614622718069618478648576546160e+33Q, 1.64962411456760257539667516081290921e+34Q, 5.76867749241980146921395997917892869e+34Q, 2.05744285416276135030539237103441019e+35Q, 7.48642350991781106283346301415985262e+35Q, 2.78005279179115505131111680664033100e+36Q, 1.05390834766008187386632631340309755e+37Q, 4.08004633423575422346694643614725290e+37Q, 1.61355331159280537271141620030872711e+38Q, 6.52083633299761509812680604349515166e+38Q, 2.69384818625751099248700493623895698e+39Q, 1.13800240843071080011666704740931517e+40Q, 4.91774800881392461265365745148130197e+40Q, 2.17469107319135867637675221560360895e+41Q, 9.84452374543052650164816403972682005e+41Q, 4.56370746759011673249611086081412694e+42Q, 2.16735207370837913732627450052443800e+43Q, 1.05486019388717075432105322007580054e+44Q, 5.26358822556684736475437714203858810e+44Q, 2.69377245879791662278222405278060831e+45Q, 1.41450676056016307353065763949943988e+46Q, 7.62412676351201661991424110428992680e+46Q, 4.21982814876279441119734812029287822e+47Q, 2.39938766583179326419454951543637572e+48Q, 1.40213994725411743432292186837126106e+49Q, 8.42470632552542294312824936421510125e+49Q, 5.20691847994261931825305937850643235e+50Q, 3.31178786647771615130587348221001406e+51Q, 2.16868329550985915487173624396649870e+52Q, 1.46278636877920671278346292184781720e+53Q, 1.01676178457583836251098427369753410e+54Q, 7.28646099514504318390031595979099009e+54Q, 5.38619423744886540736133132036039525e+55Q, 4.10891748052874064027571987877723004e+56Q, 3.23644562594555272761751761693655719e+57Q, 2.63344065241761966896134121065725150e+58Q, 2.21470233935793926784783273212022849e+59Q, 1.92605899594826839190384056135440397e+60Q, 1.73306774041417493183516299971659594e+61Q, 1.61430716012442696900215232150692807e+62Q, 1.55746432848635213822960416335985349e+63Q, 1.55722615519719203130606727886637242e+64Q, 1.61447396270799534426677571780472075e+65Q, 1.73661740632738610492724345532304845e+66Q, 1.93920124345119052093186699988150897e+67Q, 2.24927773293662287552890832545827854e+68Q, 2.71159379871976559871119761600619238e+69Q, 3.39962873204868711911086284140566930e+70Q, 4.43538969673020629145547409643969707e+71Q, 6.02556607616400398134689309091612155e+72Q, 8.52916142538377984909758513093573554e+73Q, 1.25874632299298868846704179091958707e+75Q, 1.93811217518656021005493439215804850e+76Q, 3.11543236357261066088271223403230465e+77Q, 5.23179767443439001771782033104475730e+78Q, 9.18493020786068075728039142759876527e+79Q, 1.68692940478037877214426031162304858e+81Q, 3.24356562447423263461643222429327622e+82Q, 6.53381249893022007452896440352725950e+83Q, 1.37989882314462031449133502146398295e+85Q, 3.05765044484283991620932285441735220e+86Q, 7.11405054583917124472478320152556329e+87Q, 1.73927502444225867447030753694640018e+89Q, 4.47178291585317780365328749453520010e+90Q, 1.21003678949402814425759810458701117e+92Q, 3.44882804459086235858169840236819767e+93Q, 1.03622678375056156465794049465547871e+95Q, 3.28480191475120603834848118907352203e+96Q, 1.09951493360222463836336540053884847e+98Q, 3.88958173137824259730333790282903582e+99Q, 1.45543428790106999149108053530575702e+101Q, 5.76572993438741901863543434592570728e+102Q, 2.42034956874547558153049344213268717e+104Q, 1.07760662592977753585432532225577347e+106Q, 5.09334698869585184485524316150431382e+107Q, 2.55809082411032399725764692067377039e+109Q, 1.36651250871904796376617702296414102e+111Q, 7.77173580076352640634836399351925362e+112Q, 4.71039863879301491830684051990330316e+114Q, 3.04556388558701395434830609997782218e+116Q, 2.10276255286144299282309486039761104e+118Q, 1.55193753621259613591555622965540441e+120Q, 1.22567635442607596952721498552003566e+122Q, 1.03695094616970371146721395255392215e+124Q, 9.40788526897082771733750170914488215e+125Q, 9.16336910778509317089313688240113814e+127Q, 9.59253109567116892554520172575780003e+129Q, 1.08048629336182387529116109869898182e+132Q, 1.31103482955778245018110865569797769e+134Q, 1.71564297593263918799907327094023177e+136Q, 2.42423174270788187824126863980761699e+138Q, 3.70323122333312791897064549131589865e+140Q, 6.12322502740998890169801438496313135e+142Q, 1.09727104077119676484946099784861221e+145Q, 2.13369364324129597715060714813970067e+147Q, 4.50809918489577732767734472523944713e+149Q, 1.03625280668629118864461701581877696e+152Q, 2.59492839368798847123238762058931299e+154Q, 7.08856065084285960511459463166728250e+156Q, 2.11523492515131956204689196091626210e+159Q, 6.90448414659433816403326070235535578e+161Q, 2.46882138492543386747726128195908117e+164Q, 9.68405620339094731040251680095733169e+166Q, 4.17318211031646842247767173261932179e+169Q, 1.97862256312448325694613011941349554e+172Q, 1.03370703084875834422987498885049116e+175Q, 5.95983823379168614646426490979367954e+177Q, 3.79793920709700480341002000892325755e+180Q, 2.67930862060725892983600714882836079e+183Q, 2.09582063696050703960100191266610779e+186Q, 1.82074244214148973928235757920582367e+189Q, 1.75963855825241574501304502726864570e+192Q, 1.89499379332809905379546394212298551e+195Q, 2.27793735309853697376707463982899100e+198Q, 3.06180392186430523426845441481052145e+201Q, 4.60976071298011598021963844074936266e+204Q, 7.78790454205446308413194702704532804e+207Q, 1.47908157180353184742483342055946619e+211Q, 3.16368583872054810499056635486446885e+214Q, 7.63549763158546449019055671859541326e+217Q, 2.08329116709848069811436257881072129e+221Q, 6.43828341650089537912773112646579654e+224Q, 2.25813433461443519689405569138116459e+228Q, 9.00646808360283887236786414348123292e+231Q, 4.09320439419929471708152017376102969e+235Q, 2.12407325647515198386324613590453899e+239Q, 1.26118767744139661919617876453932054e+243Q, 8.58648519817790365555570528355195441e+246Q, 6.71757354945431655557160007037610215e+250Q, 6.05231172230061504649457274179966269e+254Q, 6.29372154343611302741074349158106138e+258Q, 7.57097597581835804454005529249965405e+262Q, 1.05596735728342565613175490019879868e+267Q, 1.71165116794080014782255848570375371e+271Q, 3.23201945416757368365209341689336569e+275Q, 7.12640648337469193163827718081711822e+279Q, 1.83935498907936650155252747841577857e+284Q, 5.57103618187823353431701691950875589e+288Q, 1.98507054903582594730288556561442957e+293Q, 8.34251060679185969108286852637314516e+297Q, 4.14598050279815660053056892060055710e+302Q, 2.44294673707515955659314553816687272e+307Q, 1.71128222954502480992240259231707340e+312Q, 1.42900308749681080618580596429329500e+317Q, 1.42642910690539638749189376290614404e+322Q, 1.70684173154227881505687976959428819e+327Q, 2.45528610324097413976825941240621397e+332Q, 4.25829782132342793910509184917611473e+337Q, 8.93046646026781112771479518830708119e+342Q, 2.27151544737307916343177075009962798e+348Q, 7.02878727199449743249339960113532074e+353Q, 2.65404789370370153123009487802961972e+359Q, 1.22676780524208968705932842819459632e+365Q, 6.96344727462083702750636558199408867e+370Q, 4.86966795424296645258294731476827244e+376Q, 4.20934473165669380666938166564826622e+382Q, 4.51252011030278817555903939588122000e+388Q, 6.01984854233799583525556662766352847e+394Q, 1.00278809583154248088779511185941092e+401Q, 2.09319142855536626778348201007914114e+407Q, 5.49449523120000769396463190666315855e+413Q, 1.82025791721843330667826837307018788e+420Q, 7.63864295498675379110157901286555290e+426Q, 4.07562853905456437955133694031162566e+433Q, 2.77530355159307878582751292111532382e+440Q, 2.42120842363222072539668100784464301e+447Q, 2.71677827391519917988250533365057684e+454Q, 3.93638693069501511102210790122717956e+461Q, 7.39454183839498133330514511562965145e+468Q, 1.80830021083203927258676228302841634e+476Q, 5.78068632124848075130373030745294118e+483Q, 2.42588452835387252450192322587436972e+491Q, 1.34215845252903171028854514732509154e+499Q, 9.83265508980143417319549250479290229e+506Q, 9.58056982887069577741485477351756765e+514Q, 1.24714172045678509784766926344381810e+523Q, 2.17883996343750012869434076146952309e+531Q, 5.13253875779605180900218275684122450e+539Q, 1.63787417999262086647656267832207076e+548Q, 7.11453353628067905769574986613707006e+556Q, 4.22706394134172663816196292889312018e+565Q, 3.45223064191878555675199989739485645e+574Q, 3.89497996822823191874712723630878414e+583Q, 6.10190158010921783812771061850774756e+592Q, 1.33421132288849391233542855134113771e+602Q, 4.09320749021551498574887738660496448e+611Q, 1.77132716471266560117452274418925035e+621Q, 1.08713213788405301831391213988591367e+631Q, 9.51489736810900467024086259204897883e+640Q, 1.19423949258625915586962226198410651e+651Q, 2.16177179741543970148744161752725437e+661Q, 5.67627906160460395827390123125168239e+671Q, 2.17468780419782497779087319492719363e+682Q, 1.22290652527655281598138666471594618e+693Q, 1.01549393259398829829790551999023256e+704Q, 1.25289600863132317250645757199143453e+715Q, 2.31107594661956354485796436668094840e+726Q, 6.41394790132987132728494077504399223e+737Q, 2.69551958118799603835043225368071745e+749Q, 1.72664572305999101481397361296053504e+761Q, 1.69703260411568714431268560545429241e+773Q, 2.57650655058878846949421879421719884e+785Q, 6.08415755628422694511089641903676709e+797Q, 2.25018717111577650332251351426363709e+810Q, 1.31266605271635406458566527913919394e+823Q, 1.21653337436496205608516398221959572e+836Q, 1.80423787152105848481394522091997928e+849Q, 4.31399102346512532331941966328171850e+862Q, 1.67550866484958200095075315692314084e+876Q, 1.06515761703845778105889680563699868e+890Q, 1.11699400379133199608851392356049526e+904Q, 1.94751426714424559351617923238456424e+918Q, 5.69089114062808012687080164398087070e+932Q, 2.80983921519267570591812248264495618e+947Q, 2.36358690419951504134253704409272547e+962Q, 3.41581578617948637677662230945252306e+977Q, 8.55364646944583859412326553382242541e+992Q, 3.74370530455423912034790817625191291e+1008Q, 2.88911104228589616462565573594290893e+1024Q, 3.96659525977064102663870040642245025e+1040Q, 9.77693110684684436928410437465483271e+1056Q, 4.36636679166615668883990202463770904e+1073Q, 3.56644781478399708285654633626787310e+1090Q, 5.37871519143314493436384142989505797e+1107Q, 1.51231507376826438439352643482625072e+1125Q, 8.00547597409214659416862336552752652e+1142Q, 8.05824292014776003962551051182620642e+1160Q, 1.55810667707874651581920999067306413e+1179Q, 5.84685322894210562805362663900103590e+1197Q, 4.30279053871861463775007328286068764e+1216Q, 6.27606568696844727186804750244767860e+1235Q, 1.83405691639178257209003812558712559e+1255Q, 1.08562206577049472147312923532596973e+1275Q, 1.31617110088183556471407953592008454e+1295Q, 3.30534811890625751178778666339188597e+1315Q, 1.73929710751143724152073404455311704e+1336Q, 1.94017558758640506527365311633351598e+1357Q, 4.64256117877888468390840687039281473e+1378Q, 2.41181028167559547953976181592626603e+1400Q, 2.75359028326650146526233980288420348e+1422Q, 6.99538184026698121966983693939988891e+1444Q, 4.00451124186760586509360315430592520e+1467Q, 5.23202484555080004711423052985251790e+1490Q, 1.58057811961053246035386581678791248e+1514Q, 1.11871792077110492782575037665515064e+1538Q, 1.88021076704060084216083677757823795e+1562Q, 7.60656064089491206752552083826812435e+1586Q, 7.51058336307020750806534892000369186e+1611Q, 1.83554419567039732901090730190332067e+1637Q, 1.12631598317224168716420027493130577e+1663Q, 1.76058045324267978077071148859252887e+1689Q, 7.11454090252573253550862708170430267e+1715Q, 7.54447665013986581882495689819567483e+1742Q, 2.13157561258614754140817896581925999e+1770Q, 1.62953544267683384450064825605699335e+1798Q, 3.42393824570039208761545128642814549e+1826Q, 2.00910152737038919233657554807306054e+1855Q, 3.34591874171713502502193846562110253e+1884Q, 1.60768420173566681503057284560969387e+1914Q, 2.26623321264716591681578650589551852e+1944Q, 9.53208108881430895613749023747672822e+1974Q, 1.21710154769951529957336846304572308e+2006Q, 4.80082954212402831503263841738379326e+2037Q, 5.95484092414598408997112765002169497e+2069Q, 2.36496081234284780469612914593602194e+2102Q, 3.06292618387296708176633714456063693e+2135Q, 1.31792936450130144017383754294435167e+2169Q, 1.92000470996606623202622993195686002e+2203Q, 9.65401246356529853165036795448719991e+2237Q, 1.70836636787270782624240314280943940e+2273Q, 1.08524396756651055665425968680627268e+2309Q, 2.52515527758383642102305453689375992e+2345Q, 2.19655419566926380800477364631433717e+2382Q, 7.29302139222844158929601074949211737e+2419Q, 9.43942215540978305304206842223557338e+2457Q, }, + }; + m_weights = { + { 7.86824160483962150718731247753528972e+00Q, 8.80516388073301111614873617217928009e+02Q, 5.39627832352070566780640331455747505e+07Q, 8.87651189696816131653619534136597185e+19Q, 2.43279187926922555339407396412240848e+52Q, 6.39971351208020291074628474066382445e+139Q, 4.88537754925138382971529406336289926e+376Q, 7.16883681174178397147232888689884595e+1019Q, }, + { 2.39852427630263521821751964327863340e+00Q, 5.24459642372668102196104972893810164e+01Q, 6.45788781959820175983419155536535220e+04Q, 2.50998524251137450575088710958358197e+12Q, 1.77402926932713870128394504873348147e+32Q, 2.78140611598309731397930137939524577e+85Q, 1.96038425539892219077400134901764646e+229Q, 3.66150166331050442649946863740591804e+619Q, 4.83160223742266359875093017291942249e+1679Q, }, + { 1.74936958310838685164948357553735581e+00Q, 3.97965898193460781260142246747934196e+00Q, 1.84851459857444957000370375296526856e+01Q, 1.86488071893206798762140574520079510e+02Q, 5.97420569526326585534733485801413054e+03Q, 1.27041263514462334076609190768051333e+06Q, 6.16419301429598407050713079962266577e+09Q, 5.23085003181122252980303620742723664e+15Q, 2.22626092994336977442577822584431966e+25Q, 1.19993110204218159156995352671876189e+41Q, 7.47060214427514621386633671542416223e+66Q, 1.81446586052841067579857900138568293e+109Q, 9.97368828205170536427067380214302839e+178Q, 6.91104863699861841609881512683369620e+293Q, 1.09318211394169115127064538702854062e+483Q, 6.82844528756738528157668552351754659e+794Q, 5.72058982179767644458682394627277737e+1308Q, 8.56032690374774097638382410967859196e+2155Q, }, + { 1.61385906218836617287347897159238284e+00Q, 1.99776729186967326240633804225996920e+00Q, 3.02023197990883422014272607858586524e+00Q, 5.47764184385905776136260784219973923e+00Q, 1.17966091649267167180700675171097629e+01Q, 3.03550484851859829445106624470076282e+01Q, 9.58442179379492086007230677188042206e+01Q, 3.89387023822999207648300659707623000e+02Q, 2.17919325035791134362027855479039721e+03Q, 1.83920812396413285238691815996130729e+04Q, 2.63212061259985616674528417452471371e+05Q, 7.42729650716946820985576548297567563e+06Q, 5.01587564834123235599460194208596041e+08Q, 1.03961086724154411336246801784030341e+11Q, 9.10032891181809197707572646881781254e+13Q, 5.06865116389023157141527800972456655e+17Q, 3.03996652071490261550678134010186516e+22Q, 3.85774019467200796234141077624516370e+28Q, 2.46554276366658108662483315347592086e+36Q, 2.41643944916779946083480638296809418e+46Q, 1.51709155392660414912154078562432491e+59Q, 3.82504341202141137966304147261186085e+75Q, 4.08958239682159863968142401533332977e+96Q, 3.82377589429556404969214069508991010e+123Q, 1.52310131188389950567280579870007714e+158Q, 3.79636429591225792206340580596443044e+202Q, 3.58806569407775804668752012761380285e+259Q, 4.80771394235873283225580334249205764e+332Q, 3.53246347094395956018650264083397114e+426Q, 1.10588270611697913736223556513462127e+547Q, 5.39876096236024571737551333865366627e+701Q, 2.11595993056851385189640470523173475e+900Q, 1.96510021934867185245970661270267904e+1155Q, 4.44393205109502635384704176698510343e+1482Q, 8.87699807096655545789464168899561262e+1902Q, 3.92593109193326452307669545677335709e+2442Q, }, + { 1.58146595953669474418006927755018553e+00Q, 1.66914991043853474595928766810899114e+00Q, 1.85752318859500577038805456054280667e+00Q, 2.17566262362699411973750280579195666e+00Q, 2.67590137521102056412774254907718688e+00Q, 3.44773868249879174414308452011308777e+00Q, 4.64394654035546412593428923628065357e+00Q, 6.53020449657424861626175040050215115e+00Q, 9.58228501556680496101434956408351228e+00Q, 1.46836140751544096048943311347045852e+01Q, 2.35444954874098753301967806270994218e+01Q, 3.96352727330516670475446596081886449e+01Q, 7.03763520626753854729866526912608057e+01Q, 1.32588012478483886772029444321222706e+02Q, 2.66962564954156917240259777486475719e+02Q, 5.79374919850847267642551329761882844e+02Q, 1.36869192832130360517783396696756604e+03Q, 3.55943572153313055370459329132660088e+03Q, 1.03218667727076331844496375241465304e+04Q, 3.38662130285874148722242481662728477e+04Q, 1.27816625984024682983932609690817446e+05Q, 5.65408251392669309819682774275375355e+05Q, 2.99446204478172183285915112991350446e+06Q, 1.94497502342191494704216422938073734e+07Q, 1.59219300769056058775193216743984073e+08Q, 1.69428881861745991307405037132734657e+09Q, 2.42715618231130327064401251217732118e+10Q, 4.87031784819945548978505622564878836e+11Q, 1.43181965622918179279761684530563788e+13Q, 6.48947152309930125567236832263111486e+14Q, 4.80375775250898910621624420686976943e+16Q, 6.20009636130533154063228597685772759e+18Q, 1.50256856243991489872472363253210358e+21Q, 7.43606136718968825065770257988550430e+23Q, 8.26476121867792860277670169213789988e+26Q, 2.29773502789780434527854280137181506e+30Q, 1.80544977956953499695878114747293447e+34Q, 4.60447236019906193095622500171344417e+38Q, 4.45837121203062685356208723886733392e+43Q, 1.95763826111480930920135175891530462e+49Q, 4.76736813716250076391436967954985413e+55Q, 8.08882013947672128478290968549029064e+62Q, 1.23826089734928635728800137667726115e+71Q, 2.29227250527884206154485624438166937e+80Q, 7.15139237374919354944182099110281069e+90Q, 5.47671485015604443103262357109062276e+102Q, 1.57665561837070068115746726288773175e+116Q, 2.76544859595785195782707224216472471e+131Q, 5.10805125528313267335507302418826239e+148Q, 1.84712724771593770593326127127227089e+168Q, 2.64019849791365137425805671512502957e+190Q, 3.30712207665004277982044248938187504e+215Q, 8.94854908018147130170828014681013313e+243Q, 1.45387781135416845215757148230318159e+276Q, 4.51726707740089625471551690811905600e+312Q, 9.97430447590682462482304866834403173e+353Q, 6.92693028486990716815899177110112886e+400Q, 8.16310561774970561761094556639568748e+453Q, 1.10229203674018117764688357752075301e+514Q, 1.48517414340573263317638725427854581e+582Q, 2.31930659130340479680373862468017961e+659Q, 6.75943980795305614491339585238335763e+746Q, 8.57037256903489416057847741388693004e+845Q, 1.67601881139415883633596646631875881e+958Q, 2.88227840597067494281761984210848274e+1085Q, 4.25760590360997372209644858208981618e+1229Q, 9.71180927884114514977776411099980676e+1392Q, 1.22768447544318231419683656745290694e+1578Q, 6.75552744777466879522724469574589977e+1787Q, 3.08769330528996647489562213811332711e+2025Q, 6.11556995885701147380172201043083647e+2294Q, }, + { 1.57345777357310838646187303563867071e+00Q, 1.59489275503866378652125176234375753e+00Q, 1.63853651553023474161201404240726646e+00Q, 1.70598040821221362042267472116012952e+00Q, 1.79972439460873727464624167982278042e+00Q, 1.92332285442565630724716834865923523e+00Q, 2.08159737331326817824115844787944556e+00Q, 2.28093488379007051069614759371332643e+00Q, 2.52969785238770465522974588384012833e+00Q, 2.83878478255295118549225363326336900e+00Q, 3.22239574502098061154099310373833179e+00Q, 3.69908135885423511174795221061725889e+00Q, 4.29318827433052679979662014839909054e+00Q, 5.03686535632233007617225633242190622e+00Q, 5.97287114091093219903794699750262296e+00Q, 7.15853842431107756435392592099817447e+00Q, 8.67142780089207638456187671594514668e+00Q, 1.06174736029792232565670017416978690e+01Q, 1.31428500226023559963724543395522033e+01Q, 1.64514562566842803959315507240301356e+01Q, 2.08309944999818906870911848992408145e+01Q, 2.66923598979164019005652953856219015e+01Q, 3.46299351479137818875120770497256101e+01Q, 4.55151836265366257897259922581190951e+01Q, 6.06440808776439211617961123881399848e+01Q, 8.19729691748584679772374579308014156e+01Q, 1.12502046808165256396405270593673624e+02Q, 1.56909655284471412314380735570422525e+02Q, 2.22620434786863827630193937721495593e+02Q, 3.21638548950407775497940425181412035e+02Q, 4.73757450594546173931972158718216152e+02Q, 7.12299454814699763671577043536625350e+02Q, 1.09460965268637655307120839628626644e+03Q, 1.72169778917604957594996919520027157e+03Q, 2.77592490925383514631415480161515100e+03Q, 4.59523006626814934713366494475518926e+03Q, 7.82342758664157367197225266771664916e+03Q, 1.37235743526910540538254088034330370e+04Q, 2.48518896164511955326091118611007805e+04Q, 4.65553874542597278270867281925971401e+04Q, 9.04176678213568688399001015321300800e+04Q, 1.82484396486272839208899824313480775e+05Q, 3.83680026409461402659414641247062580e+05Q, 8.42627197024516802563287310497296237e+05Q, 1.93843257415878263434890786889254173e+06Q, 4.68511284935648552770705724295731096e+06Q, 1.19352866721860792702129481323969824e+07Q, 3.21564375224798931587480096707273872e+07Q, 9.19600892838660038574630990314077029e+07Q, 2.80222317845755996380600711673673348e+08Q, 9.13611082526745888639724836491288094e+08Q, 3.20091090078314859097182280497599932e+09Q, 1.21076526423472368892320719657876832e+10Q, 4.96902474509310180847282308967509245e+10Q, 2.22431575186385521573661995325533148e+11Q, 1.09212534444931366008730317965795763e+12Q, 5.91688298001991935913437013926087352e+12Q, 3.55974343849457724875846980164154730e+13Q, 2.39435365294546519110955303872941851e+14Q, 1.81355107351750191688958030705258863e+15Q, 1.55873670616616573768075986251057862e+16Q, 1.53271487555511433265791312985848665e+17Q, 1.73927477619078921206684554401295421e+18Q, 2.29884121680221631264260395223605839e+19Q, 3.57403069883776266374408947394989771e+20Q, 6.60489970545141907950722926660909000e+21Q, 1.46715587959182065910258109064501314e+23Q, 3.96409496439850938104106380506197921e+24Q, 1.31934284059534879276193138323357204e+26Q, 5.48225197134040074244755342952808857e+27Q, 2.88513789472382751842871762855110475e+29Q, 1.95253984076539210960955400019857653e+31Q, 1.72705148903222279729658337426192599e+33Q, 2.03134350709543939580166226396358099e+35Q, 3.23607414697259998035422932108168633e+37Q, 7.12048741298349720027592249584649287e+39Q, 2.20955270741101726546978031488466999e+42Q, 9.88628264779138464833350749737352873e+44Q, 6.53051404878827352855218417636385136e+47Q, 6.53070667248154652797117704066842547e+50Q, 1.01551880743128195070423638840822631e+54Q, 2.52636677316239450980056816553072407e+57Q, 1.03645051990679029664966085872637264e+61Q, 7.24196603262713586073897504016245799e+64Q, 8.91940252076971493816577515322150818e+68Q, 2.00846361915299290502283821529295631e+73Q, 8.59691476483026002005094018998424562e+77Q, 7.29059954682949521964023913634428261e+82Q, 1.28019956321641911210408802307006043e+88Q, 4.87834928560320114983891893560226105e+93Q, 4.24082824806412793978885646592598549e+99Q, 8.86977176472159872046976711615695992e+105Q, 4.72334257574141766931261505651248075e+112Q, 6.80203596332618858057580041658814811e+119Q, 2.82453118099000954895979587744113614e+127Q, 3.62104921674598225195529453488856248e+135Q, 1.54127015033494251978994281882356439e+144Q, 2.35337699517436278507886852532825112e+153Q, 1.39975657916895026384257958622345253e+163Q, 3.54037503829826541837221286091526442e+173Q, 4.18047500721395810079642214620070836e+184Q, 2.54530778191403081572971577964641848e+196Q, 8.88250526322285889574436025179770286e+208Q, 1.98845751036127430533908054978079217e+222Q, 3.21915661509946819003841034873947498e+236Q, 4.28183215516658291456439674095688919e+251Q, 5.36006145974509206228714676601426569e+267Q, 7.29722806821457796264952588871034685e+284Q, 1.26019994797636341237075623262002305e+303Q, 3.25215241711283834871808603425369243e+322Q, 1.49313102632599158215031971670664716e+343Q, 1.46842377691796129245813472736592684e+365Q, 3.76931518236156669675469780787997744e+388Q, 3.11671991143285521404945273561352902e+413Q, 1.03852445906488241953781523768340610e+440Q, 1.76991068936691550622045923706396857e+468Q, 1.98843278522413458075823481121326426e+498Q, 1.92935688449069146367365017414279935e+530Q, 2.15545898606278242992831028009446695e+564Q, 3.76556572065746315676705102085514331e+600Q, 1.42493629186903074753303377268119903e+639Q, 1.65224172380259971159552714105694350e+680Q, 8.49215944410421946026158352935784666e+723Q, 2.86631893981320588349507785370693896e+770Q, 9.65377141044877270160840903468092119e+819Q, 5.06475979937176267805686278644876593e+872Q, 6.64979079902917739733555562625190968e+928Q, 3.61927525412094487856735509111512169e+988Q, 1.39737404381894022658529893979427383e+1052Q, 6.78018387620311055320186127570560827e+1119Q, 7.59952044103401209205510909410129754e+1191Q, 3.76162862667265940011010617225061429e+1268Q, 1.63904309514033654209643026524489542e+1350Q, 1.31017858257252889370615733020834140e+1437Q, 4.19821396072116298475329351264459339e+1529Q, 1.23923791809549425227491870065845752e+1628Q, 8.17087984671936465200033730232853592e+1732Q, 3.08946915513007963115203650683840400e+1844Q, 1.82761916569338643673217752139790470e+1963Q, 4.92348318803338950087945240543349430e+2089Q, 1.88350835331965060456271693216651123e+2224Q, 3.43360015586068277793841059306542129e+2367Q, }, + { 1.57146131655078329437644376888801138e+00Q, 1.57679016631693834484126246342345329e+00Q, 1.58749564037038331646069625234555521e+00Q, 1.60367395634137020950291269057600307e+00Q, 1.62547112545749394267938666988196139e+00Q, 1.65308501191593930171844822364141731e+00Q, 1.68676814252591123625053019619255158e+00Q, 1.72683132353751620184313195813656600e+00Q, 1.77364813866723660171326886678529701e+00Q, 1.82766042147866144821632902536146347e+00Q, 1.88938481704401819562549601165115021e+00Q, 1.95942057285503709111658357403615203e+00Q, 2.03845872804790892275259742585569433e+00Q, 2.12729290408384722476899855222432786e+00Q, 2.22683194019907694104850876757126753e+00Q, 2.33811466455513029581902771513343722e+00Q, 2.46232714872299130380967769641847017e+00Q, 2.60082286092708516436098022317536381e+00Q, 2.75514621481455435937229822050004007e+00Q, 2.92706010842448355516791030533685920e+00Q, 3.11857816624092195149666191379786472e+00Q, 3.33200254033950662971711811118318338e+00Q, 3.56996830041074027550628111498923678e+00Q, 3.83549565399644726181552365400966870e+00Q, 4.13205149651293488468153425460318353e+00Q, 4.46362210669906788115667211361364802e+00Q, 4.83479919100800655701530131187647507e+00Q, 5.25088195776567960767293727240320892e+00Q, 5.71799849087533312421158643544587353e+00Q, 6.24325042159856810533215887376856930e+00Q, 6.83488580122654183866366620676303900e+00Q, 7.50250620278934080195915244309172491e+00Q, 8.25731548449354420110207897041998984e+00Q, 9.11241940586464263380079984086513597e+00Q, 1.00831874954399775830998395457182684e+01Q, 1.11876913499386520162594085796167645e+01Q, 1.24472370591410688131760615976965093e+01Q, 1.38870139060550758665255786705519681e+01Q, 1.55368871591590018952847646637454593e+01Q, 1.74323700068094283108112572669239084e+01Q, 1.96158189482399342378436216339159090e+01Q, 2.21379088635427380602824337731297019e+01Q, 2.50594593467713760968808829296439171e+01Q, 2.84537037774213756120135736520435304e+01Q, 3.24091184596952483433430577491101072e+01Q, 3.70329628948023016142035941015485370e+01Q, 4.24557264474626791146220920324192917e+01Q, 4.88367348033798558171280311705362727e+01Q, 5.63712464058697542020818458752120814e+01Q, 6.52994709275261034008086934786702551e+01Q, 7.59180775569412283714380617539343408e+01Q, 8.85949425239166382162609558265821220e+01Q, 1.03788129500578812415162165531670704e+02Q, 1.22070426396922674625756853326498468e+02Q, 1.44161209813120053456742433728771078e+02Q, 1.70968019124577351122499690038707734e+02Q, 2.03641059384357556999222931732850856e+02Q, 2.43645005870872364316059216110059642e+02Q, 2.92854081218207610543177302881458406e+02Q, 3.53678601915225339202500542949917795e+02Q, 4.29234308396729693907268968564609660e+02Q, 5.23570184048873302665650155276206906e+02Q, 6.41976689800302457508415746115180260e+02Q, 7.91405208366875928332161102969868782e+02Q, 9.81042208908193163688535235538889459e+02Q, 1.22309999499974039331272100414750813e+03Q, 1.53391255542711212726525490457861725e+03Q, 1.93546401360583033885511419988831009e+03Q, 2.45753454991288685207196097797062484e+03Q, 3.14073373162363551894782974867325472e+03Q, 4.04081818856465189750723035050638141e+03Q, 5.23488159971222568136194576211612571e+03Q, 6.83029445760732922582000345557383347e+03Q, 8.97771322864988714349790288910627671e+03Q, 1.18901592096732683947870697270695144e+04Q, 1.58712238704434696215746702894136306e+04Q, 2.13571110644578933143540830593360855e+04Q, 2.89798370518968143718297906801146350e+04Q, 3.96630672679554794954087134590560762e+04Q, 5.47687519375000078688553248953764732e+04Q, 7.63235653938805568016142182690471993e+04Q, 1.07371914975497695062170132456450593e+05Q, 1.52531667455557415180420019888676134e+05Q, 2.18877843474421658617449971461581691e+05Q, 3.17362449601929560775572985879585343e+05Q, 4.65120152586932846156175983364596723e+05Q, 6.89253765628058057206329188782990860e+05Q, 1.03311988512001998186230013733752720e+06Q, 1.56688798104325249948154338241641806e+06Q, 2.40549202702653179507492073842261453e+06Q, 3.73952896481591033994026114668796352e+06Q, 5.88912115489558003244667233279563785e+06Q, 9.39904635192234203007457377008255614e+06Q, 1.52090327612965351790614542733698474e+07Q, 2.49628718729357616773929842263043964e+07Q, 4.15775925996307484022703929049831425e+07Q, 7.03070536695026731176158877103497776e+07Q, 1.20759855845249336607363637052870598e+08Q, 2.10788250946484683324104572583041111e+08Q, 3.74104719902345786397351281755078701e+08Q, 6.75449459498741557237788387723071522e+08Q, 1.24131674041588053743260021864117384e+09Q, 2.32331003264955286246594304305695965e+09Q, 4.43117601902662575879840759020751450e+09Q, 8.61744648740090012951326726568665021e+09Q, 1.70983690660403151330619158427281665e+10Q, 3.46357452188017133850611855017361923e+10Q, 7.16760712379927072634183907084755700e+10Q, 1.51634762091005407908273857408800162e+11Q, 3.28172932323895052570169126695951209e+11Q, 7.27110260029828078950026409435831711e+11Q, 1.65049955237878037840731169761272102e+12Q, 3.84133814950880391685509371196326109e+12Q, 9.17374426778517657484962791255187134e+12Q, 2.24990194635751997880832549111511175e+13Q, 5.67153508990061173097292032404781538e+13Q, 1.47074225030769701852963232235912597e+14Q, 3.92701251846431177545392497147427712e+14Q, 1.08063997739121282020832802862957248e+15Q, 3.06767146672047518894275739534732971e+15Q, 8.99238678919832842771174638355746631e+15Q, 2.72472253652459211109041460799535823e+16Q, 8.54294612226338925817358060817490416e+16Q, 2.77461371872557475533476908014408616e+17Q, 9.34529947938202912146296976663431863e+17Q, 3.26799612298773188163350554315742192e+18Q, 1.18791443345546831451732293519928714e+19Q, 4.49405340841856421397062311314705655e+19Q, 1.77170665219548674305185389795833488e+20Q, 7.28810255288593152697603764235601397e+20Q, 3.13251243081662534865188632436805529e+21Q, 1.40874376795107311038838007000777184e+22Q, 6.63829426823606041441317767891166205e+22Q, 3.28254360840356501289107248021554584e+23Q, 1.70592009803839406409667145645666005e+24Q, 9.33225938514852428454935743602712728e+24Q, 5.38272717587488831207327363463407970e+25Q, 3.27895423512209324910006662705296242e+26Q, 2.11319169795745809927716305122705952e+27Q, 1.44341104149964304009687846325713305e+28Q, 1.04686439465498242316197235200069352e+29Q, 8.07731922695890570023291958025986094e+29Q, 6.64314696343261627707440459400107155e+30Q, 5.83567012135998626006817430636714368e+31Q, 5.48689029679023079776199817150941362e+32Q, 5.53372696850826161418229677716330718e+33Q, 5.99973499641835283449509393028972981e+34Q, 7.00917611946612256941556198729562373e+35Q, 8.84406196642459749869759626748371565e+36Q, 1.20822686086960596115573575744502341e+38Q, 1.79164851431106333799499432947126299e+39Q, 2.89131391671320576216903362266762013e+40Q, 5.09145786021152729801159516043566174e+41Q, 9.81063058840249655325327952160218101e+42Q, 2.07444123914737886022245738089968362e+44Q, 4.82765011693770054022189143000576390e+45Q, 1.24028793911154902904261886940649724e+47Q, 3.52878285864478461616951002487254771e+48Q, 1.11544949047169665881036414807872651e+50Q, 3.93051064332819631369914292573124112e+51Q, 1.54924371295785233686867649142553059e+53Q, 6.85499823804130100151231679166543611e+54Q, 3.41747996158320770357877327002949632e+56Q, 1.92690549864107998957222500013304086e+58Q, 1.23358096300491944958557136475962190e+60Q, 9.00281990289807691528078151573158069e+61Q, 7.52141514125344164522463463202808470e+63Q, 7.22427755490057899279344696654950663e+65Q, 8.01283283053507860974456727997488253e+67Q, 1.03099962028638036919997632019550562e+70Q, 1.54617495707674867923983623892142209e+72Q, 2.71580377261324869371341160824868908e+74Q, 5.61508992057174643750226165228505259e+76Q, 1.37366785934534333692942668275259398e+79Q, 3.99754102076962512613158938364235073e+81Q, 1.39150058933980008745266389466237314e+84Q, 5.82669384491202289249159160687839973e+86Q, 2.95227482092954909582266634062763990e+89Q, 1.82102306147846628152669685943631657e+92Q, 1.37597302213794152564743989887492097e+95Q, 1.28185236754341294523601004808033157e+98Q, 1.48213012720199050337233086306566580e+101Q, 2.14157427379243531419232668034147566e+104Q, 3.89449554094711237984570195229015661e+107Q, 8.97864636258010296104790318951217808e+110Q, 2.64413158980724405044777067425347595e+114Q, 1.00240353984191383430257305957041439e+118Q, 4.93141280490390525871801097705197944e+121Q, 3.17440111243586504420672164931106998e+125Q, 2.69662400176189239027511019786185589e+129Q, 3.04979932232044716644635827452454425e+133Q, 4.63404152681868778475392087605038845e+137Q, 9.54898313480310651224157422560754643e+141Q, 2.69440486619208982853089677098686964e+146Q, 1.05150272003639532507210605903884076e+151Q, 5.73417064062624495509840837865743050e+155Q, 4.41627650777870044428827641421915327e+160Q, 4.85653500442164862297918118887566388e+165Q, 7.71243776020172406235461422008761914e+170Q, 1.78944284768135145352387398006192815e+176Q, 6.13948504948193852500464630902178966e+181Q, 3.15374719244414866832063986813364807e+187Q, 2.45678229633130089072342575625791640e+193Q, 2.94097956743157560377748279040964662e+199Q, 5.48435772238022826264635788020315114e+205Q, 1.61576755939787162649511106856450099e+212Q, 7.63055674811964328822328719215905762e+218Q, 5.86357963426750903008317058039636736e+225Q, 7.44578009523250679265610908767109796e+232Q, 1.58753358925950887380498944645468602e+240Q, 5.77757179750005470017336807397418313e+247Q, 3.65046885264085030960970127282511879e+255Q, 4.07509702021276189043935129812053895e+263Q, 8.18389073292535025618266801702554839e+271Q, 3.01238089652162618211263051563523370e+280Q, 2.07176624104483264053704912869659325e+289Q, 2.71562735784398218302697011744202385e+298Q, 6.92451661016398143622710849660362520e+307Q, 3.50810155650162047040906671177815417e+317Q, 3.60896781300246599975888048597671985e+327Q, 7.71058277826701049982730585006218034e+337Q, 3.50154660288711246272389096490054302e+348Q, 3.46175331564137723439223486579386975e+359Q, 7.63696466254316472130052183903629062e+370Q, 3.85655304044390258996784681505914035e+382Q, 4.57665692577932081843759029527968784e+394Q, 1.31143566628034307965133274338127595e+407Q, 9.33142940209453779649608781259673613e+419Q, 1.69703443400488874615229289912465401e+433Q, 8.12664327627950884948530966790210152e+446Q, 1.05671342182667061564323377987059929e+461Q, 3.85123350151333031094457679550412807e+475Q, 4.06487630836024540948583469098247829e+490Q, 1.28516517984503545753808504263016648e+506Q, 1.26025754690341684764700072541766676e+522Q, 3.97331612896914344554453503890576277e+538Q, 4.17965516524315248567041014799432863e+555Q, 1.52416658652941127494202186163265994e+573Q, 2.00432202283496263048589917253126663e+591Q, 9.89983817930114056039301724151237036e+609Q, 1.91539340453423886973992445388091844e+629Q, 1.51593315523153267229971976448703684e+649Q, 5.13233111267478387648166311677061530e+669Q, 7.78392571224632702458474933380523830e+690Q, 5.54632077048043201021342066119640603e+712Q, 1.95012604607548018918112113273623192e+735Q, 3.55940947870861006830654543397286882e+758Q, 3.55349341454925685547195460273265331e+782Q, 2.04795692045857243226580641802720017e+807Q, 7.20348918974342452885439546130773017e+832Q, 1.63778937282231874342883712446170710e+859Q, 2.55384218509638087014670377175798088e+886Q, 2.90332357089198897009653578594580665e+914Q, 2.56300421336271050326091753908665515e+943Q, 1.87504708602076913446948153935468528e+973Q, 1.21573089114719501597325465689193734e+1004Q, 7.48693407429699486755736805187051392e+1035Q, 4.70376397570597947605315058283235338e+1068Q, 3.24549375035327607806235059706162609e+1102Q, 2.65365798053210741189633750297123713e+1137Q, 2.78113361306514574568406809189880354e+1173Q, 4.05114001708803517429009145027606492e+1210Q, 8.91647476482514121118371429882160487e+1248Q, 3.23223851331898724884680382253593571e+1288Q, 2.10925909168894371224120829576314259e+1329Q, 2.71594389750881594498007515800169231e+1371Q, 7.58558239286242519535157411695442827e+1414Q, 5.06701669031717221741926320252846248e+1459Q, 8.95314256637167381172114473249653533e+1505Q, 4.64314397380853725563695225910483395e+1553Q, 7.86772811149376784892131781209226509e+1602Q, 4.86578559687970087801384706555207321e+1653Q, 1.23116054769360594876926981962811083e+1706Q, 1.43383897399728293235616506956599019e+1760Q, 8.67960762728500385489074199138374599e+1815Q, 3.09584788327503858182429306492345781e+1873Q, 7.40514657822678853879551103162851562e+1932Q, 1.35750288266752565171774149402837640e+1994Q, 2.18886955807028168114167639122307268e+2057Q, 3.57839966436010585653478204799948336e+2122Q, 6.86791017358151132323155526430183469e+2189Q, 1.80021943882415618419042799861559854e+2259Q, 7.53312429569410546159363413753399067e+2330Q, 5.91165553375547478649257686857639971e+2404Q, }, + { 1.57096255099783261137673508918980377e+00Q, 1.57229290236721196082451564636254803e+00Q, 1.57495658191266675503402671533627186e+00Q, 1.57895955363616398471678434379990522e+00Q, 1.58431078956361430514416599492388597e+00Q, 1.59102230111703510742216272394562613e+00Q, 1.59910918118616033722590556649394763e+00Q, 1.60858965710906746764504456185444654e+00Q, 1.61948515482641974319339137784305225e+00Q, 1.63182037453073931785527493516038124e+00Q, 1.64562337819112567903033806653906069e+00Q, 1.66092568939542410935608828998468834e+00Q, 1.67776240601646371733138779357535047e+00Q, 1.69617232627708297296989766202480515e+00Q, 1.71619808886073246730768842066355199e+00Q, 1.73788632779101456236627555096372654e+00Q, 1.76128784288515241044102589887617560e+00Q, 1.78645778667368642025315725404601102e+00Q, 1.81345586877233558659749539967614045e+00Q, 1.84234657879265254187280543490489739e+00Q, 1.87319942898662752121993510591579920e+00Q, 1.90608921793761261888076943857856180e+00Q, 1.94109631673677945144587926354356120e+00Q, 1.97830697922181656566949720098719647e+00Q, 2.01781367800384433737712026561151498e+00Q, 2.05971546817081389507270282494773392e+00Q, 2.10411838073232749275747224342524909e+00Q, 2.15113584806337555354918618566085438e+00Q, 2.20088916381459141771044083611555369e+00Q, 2.25350797998611420231160903572594743e+00Q, 2.30913084411305337537709048855358397e+00Q, 2.36790577978511333384857209921738492e+00Q, 2.42999091402365295350102767412517845e+00Q, 2.49555515536908558968587982458158759e+00Q, 2.56477892689313451429557802920827974e+00Q, 2.63785495874745168415081659796280588e+00Q, 2.71498914529626806741705564771250802e+00Q, 2.79640147236028053619149909690973720e+00Q, 2.88232702062657870038560203490158574e+00Q, 2.97301705186029380311201985278736098e+00Q, 3.06874018519362823755119514588303156e+00Q, 3.16978367147348738564623946178566521e+00Q, 3.27645477442732860056345607892739085e+00Q, 3.38908226826615609816107421136979984e+00Q, 3.50801806229286913554992299494422526e+00Q, 3.63363896413353027399263692498221540e+00Q, 3.76634859436988420367634452674074607e+00Q, 3.90657946663630928939225987850575005e+00Q, 4.05479524866754112035397645627643742e+00Q, 4.21149322136091780158052739625729631e+00Q, 4.37720695466646221916071477112304019e+00Q, 4.55250922105994638849140210916632132e+00Q, 4.73801516951078282566987752649050466e+00Q, 4.93438578525358788671420711795537458e+00Q, 5.14233166333819107447595069798421539e+00Q, 5.36261712689997622445803908396748884e+00Q, 5.59606472439710019418213140693069575e+00Q, 5.84356014374437330661446789126222075e+00Q, 6.10605758538173469317727364122669467e+00Q, 6.38458564090067143612732202429488542e+00Q, 6.68025372897382444864907987044889317e+00Q, 6.99425914605841270881961646990609410e+00Q, 7.32789479574890106033548644768353338e+00Q, 7.68255766782458876413667730681699443e+00Q, 8.05975814607113727007240055318338450e+00Q, 8.46113023296234288939356989479671723e+00Q, 8.88844278939567108027044653070693778e+00Q, 9.34361189902548515485066576358196470e+00Q, 9.82871447949462202212030994384949241e+00Q, 1.03460032772138062549383568058709409e+01Q, 1.08979233984912291622835480030167114e+01Q, 1.14871305480132578973614919602781370e+01Q, 1.21165111661978855517781913327317255e+01Q, 1.27892046801009632078942555615288463e+01Q, 1.35086281087128109623831457304510920e+01Q, 1.42785032930533442126932924888187804e+01Q, 1.51028870549318132669071327511660921e+01Q, 1.59862046261270319640752848374642080e+01Q, 1.69332867326908112807352382039426796e+01Q, 1.79494107678000050622926329104204826e+01Q, 1.90403465419082315888820165929975494e+01Q, 2.02124071618296433363312214170232623e+01Q, 2.14725056619224736964251610816575600e+01Q, 2.28282180919971350546248653847563966e+01Q, 2.42878538594168042463845071817020910e+01Q, 2.58605342287811778487151334440784950e+01Q, 2.75562800035467442565131080245429614e+01Q, 2.93861095522110956389210768876799587e+01Q, 3.13621484999095132865600012683857137e+01Q, 3.34977525874991258153646142408367963e+01Q, 3.58076454079962546803810835720597110e+01Q, 3.83080729687253016658377309622401176e+01Q, 4.10169773015547344709659456503154667e+01Q, 4.39541916587611362308342994483809472e+01Q, 4.71416601949419692729062784327679986e+01Q, 5.06036854536665922553724504470269960e+01Q, 5.43672074601944525232284101611170030e+01Q, 5.84621187791213843904071404608607478e+01Q, 6.29216205405812878410372213510070276e+01Q, 6.77826251851241666263837617897404532e+01Q, 7.30862125426522301461255132629846162e+01Q, 7.88781468648814729209715096907821639e+01Q, 8.52094635973465833426799692679733796e+01Q, 9.21371360338777471668559829773781201e+01Q, 9.97248335767075464896305315099053068e+01Q, 1.08043785167904642576949987865910954e+02Q, 1.17173763608862169247776700625586421e+02Q, 1.27204208998868737227575356110541727e+02Q, 1.38235512466410237338282474486031692e+02Q, 1.50380484815148331050381123359927804e+02Q, 1.63766038752610274212021042234298836e+02Q, 1.78535118123338340289613569013808793e+02Q, 1.94848913160728060357302969254459805e+02Q, 2.12889407359835266977366307026062112e+02Q, 2.32862309344799079018746113493039633e+02Q, 2.55000432284328199435640048881527463e+02Q, 2.79567594267244578195192766207761694e+02Q, 3.06863125912428093434496643114651412e+02Q, 3.37227086745120087399301385427960651e+02Q, 3.71046309996557625549265358225650347e+02Q, 4.08761417046617491055856040237506316e+02Q, 4.50874968419459367009632339064163929e+02Q, 4.97960948895977349122916983180817637e+02Q, 5.50675820938578587679472462796822793e+02Q, 6.09771424466317909206822143572649707e+02Q, 6.76110053572647368547479902312230309e+02Q, 7.50682103874142244645724064576848341e+02Q, 8.34626760051808119187547981730818179e+02Q, 9.29256284531554199823656475151338963e+02Q, 1.03608457849823472804207172846963877e+03Q, 1.15686081966189765730466332807313547e+03Q, 1.29360914245380859999201252074469995e+03Q, 1.44867552185420514387789438088656434e+03Q, 1.62478325953219761549580736728832563e+03Q, 1.82509875991531856022535679631713756e+03Q, 2.05330963597261755441688599655848892e+03Q, 2.31371761449477720025881552764731872e+03Q, 2.61134923664018699944734187657483567e+03Q, 2.95208799409362429898911389656789101e+03Q, 3.34283233256054817982471990245472659e+03Q, 3.79168492775659509883214798303432158e+03Q, 4.30817983871631895490690508451026040e+03Q, 4.90355562457020167332670064217006554e+03Q, 5.59108434363481145162671079876733528e+03Q, 6.38646862557124634146730890858054275e+03Q, 7.30832182941297944038809179971510199e+03Q, 8.37874981279970356111509048453001571e+03Q, 9.62405721874963805881171453111047092e+03Q, 1.10756066619114600841076275282388063e+04Q, 1.27708660544590438787794590107117849e+04Q, 1.47546879201948945213025955616435132e+04Q, 1.70808753741706634268551294101897318e+04Q, 1.98141030969548505096681178137364270e+04Q, 2.30322788820475490754732581365999861e+04Q, 2.68294531792863253502182123460963590e+04Q, 3.13194117839842820030641964449539820e+04Q, 3.66401220970699799668192565829190288e+04Q, 4.29592483666869017028607105165763804e+04Q, 5.04810088263984357248209974578040223e+04Q, 5.94547213318005529011388227962133751e+04Q, 7.01854787517268957919092596317475529e+04Q, 8.30475172617569400265716546608431303e+04Q, 9.85009980505357544638949542794405193e+04Q, 1.17113126626176606026864191754698095e+05Q, 1.39584798216058984483938678946454092e+05Q, 1.66784301639307755633312351999980104e+05Q, 1.99790062652052468605951710457597772e+05Q, 2.39944994603299218686253514351518948e+05Q, 2.88925793983801323167992289814829493e+05Q, 3.48831530919430454806103930858415528e+05Q, 4.22297220149677844682618484564386312e+05Q, 5.12639824636925361908056913471196846e+05Q, 6.24046487622198979196137566922551170e+05Q, 7.61817907323361594136262168936978923e+05Q, 9.32683930022411925704630601110030182e+05Q, 1.14521400777429753902355978052778602e+06Q, 1.41035264627423311876298925540665884e+06Q, 1.74212004187586338510201667214170577e+06Q, 2.15853171693428701405141183541166264e+06Q, 2.68280941012642673073659887232388938e+06Q, 3.34498056359541886091597912499527306e+06Q, 4.18399797233770604788689812330719069e+06Q, 5.25055800816550175243256559083639418e+06Q, 6.61086017414168098803951872291131863e+06Q, 8.35163942396755869310534556270941378e+06Q, 1.05869253239392990034806970327887878e+07Q, 1.34671523510623940861241599892229316e+07Q, 1.71914827102426302145958883698307763e+07Q, 2.20245344902770169422620623417295079e+07Q, 2.83191730172433779681268016861978467e+07Q, 3.65476782026834493187990343694010282e+07Q, 4.73445265723062610640363034466641760e+07Q, 6.15653406350951387288804933390908042e+07Q, 8.03684302689786924828741611740519293e+07Q, 1.05328028435969028854761469747289545e+08Q, 1.38592168908412628618546923035162247e+08Q, 1.83103698592568352374304770508191971e+08Q, 2.42910945745864082034287213456845086e+08Q, 3.23606239375966746282831194186614169e+08Q, 4.32947521859998666323053129499091577e+08Q, 5.81743296796292947920442886775592966e+08Q, 7.85117978938819178602650773642870262e+08Q, 1.06432919762707530726575966438229782e+09Q, 1.44938958291294548467516226794019366e+09Q, 1.98286646937799184909776706883985509e+09Q, 2.72541431469809432350206616813747393e+09Q, 3.76386796411162144400474070771015333e+09Q, 5.22313881495099093715899688078276720e+09Q, 7.28378581064439770444275729738468286e+09Q, 1.02080964238115874250636198090464363e+10Q, 1.43789931847051052135186583023967432e+10Q, 2.03583681254363357780032810961889254e+10Q, 2.89749982708002744366825785538936402e+10Q, 4.14577375164549487752492409798515416e+10Q, 5.96383768387242628650336526594122215e+10Q, 8.62622848391553079951805623395652598e+10Q, 1.25466704538982518000690409655705216e+11Q, 1.83521298226491318558080545133554232e+11Q, 2.69981220740015160361114268684563366e+11Q, 3.99492845215192295441294253418780644e+11Q, 5.94638055870143455023933020703444642e+11Q, 8.90440996742409110650533033931653292e+11Q, 1.34155194167777583831947241717631506e+12Q, 2.03376855033215189170105222958089604e+12Q, 3.10262795987575321360135087196684567e+12Q, 4.76359832170586206290082815387968037e+12Q, 7.36142036056081358397678626842794083e+12Q, 1.14512696145655742338758840735549183e+13Q, 1.79331418699627392634462052642542749e+13Q, 2.82758550128579223200239017529280909e+13Q, 4.48929705367844466861372765075631687e+13Q, 7.17780287265849957064212371548037347e+13Q, 1.15585509854582062520354852997620279e+14Q, 1.87483388636788309288478433629583664e+14Q, 3.06351035640217445409310567498133847e+14Q, 5.04340065300597024230361727189343426e+14Q, 8.36616339689242989007881200440488764e+14Q, 1.39855635164094728875364679627485304e+15Q, 2.35633574951616468243164849507855064e+15Q, 4.00176516738263745645278590345795707e+15Q, 6.85137512840494144543571512545601884e+15Q, 1.18269011176154399046326619510431010e+16Q, 2.05867352701380644281110910622942185e+16Q, 3.61396878431490463311666873476678412e+16Q, 6.39911218439421355095519025524482256e+16Q, 1.14301618562837692261569180960886276e+17Q, 2.05988138391566644299797673070467922e+17Q, 3.74584678835368091393630059068193045e+17Q, 6.87444303468314906803024757565005462e+17Q, 1.27340764361348531366853034790770231e+18Q, 2.38124191682989536626992792404294190e+18Q, 4.49583561730710839927340662784958898e+18Q, 8.57144202490195270096830399067728169e+18Q, 1.65044358418165696532477771893166700e+19Q, 3.21010035242131785085169993033188229e+19Q, 6.30778012444270309076492866733769742e+19Q, 1.25240403115766127899628450500249765e+20Q, 2.51300529564998539443832117224536420e+20Q, 5.09677625569083843571268035202853929e+20Q, 1.04501920001667304566512216455267827e+21Q, 2.16647647926087846601520265828431353e+21Q, 4.54213814567839546278770815494416868e+21Q, 9.63208232444913712819259248595549405e+21Q, 2.06638653668825452816630915727527426e+22Q, 4.48552978555442825059406438230470388e+22Q, 9.85387957361097750825498509227133701e+22Q, 2.19115887446437440814640517501285189e+23Q, 4.93283596439097166796547625560314132e+23Q, 1.12450152997177436346173556893175508e+24Q, 2.59626913615675600812300017445220112e+24Q, 6.07229293831362550112108555687653017e+24Q, 1.43898906630800383562329122001513450e+25Q, 3.45584195640657046905140678735606870e+25Q, 8.41265519171357648977229820858109463e+25Q, 2.07628906165081651016090959669418757e+26Q, 5.19651502464022032237151119613068945e+26Q, 1.31917319408964404296057699402007921e+27Q, 3.39745589598038079361346075350889747e+27Q, 8.87905745443850359109225209251728000e+27Q, 2.35527236149206412607849676379867126e+28Q, 6.34276200772262482389475687836384423e+28Q, 1.73453109399085970484897533524593455e+29Q, 4.81789317060683087119323058524624972e+29Q, 1.35959734649014823198654051259347560e+30Q, 3.89896968990650039174705544740914822e+30Q, 1.13654298652998993600898528562905634e+31Q, 3.36845004399178001650511659074612092e+31Q, 1.01530408470981725989945294876828360e+32Q, 3.11314437622191823730222798219255685e+32Q, 9.71307273973014040273869048577801862e+32Q, 3.08451764358172594571945077912559223e+33Q, 9.97268213982049728423469082288644341e+33Q, 3.28362505228849158612675319471610094e+34Q, 1.10137878539082753552686700652535380e+35Q, 3.76433336759271429732220889611944227e+35Q, 1.31140346593824292621577115225698644e+36Q, 4.65813571068281367213354863266427946e+36Q, 1.68751734747051139203189162215633629e+37Q, 6.23705368501832349017363870039959902e+37Q, 2.35257131442774486893301429598817553e+38Q, 9.05893824021969993626817980294413695e+38Q, 3.56224909761113607077591549609142868e+39Q, 1.43095929157855820977839447284784020e+40Q, 5.87397458498437504922632656680942932e+40Q, 2.46482854981128378684502286098690220e+41Q, 1.05764920309085562822396787743332401e+42Q, 4.64247563928107803530506772359734012e+42Q, 2.08528711827242177927156523287132065e+43Q, 9.58843998518663217709277358040461543e+43Q, 4.51498201124609227956079072858258677e+44Q, 2.17797404834197320411588567916752909e+45Q, 1.07672097682290045825361349736107198e+46Q, 5.45726743292908558875367244655615249e+46Q, 2.83686927045578113375020568154351117e+47Q, 1.51310320139201162564313806536303971e+48Q, 8.28397466722561707458255405781541923e+48Q, 4.65723949199597134403065145457979764e+49Q, 2.68979637071283693718739500357715726e+50Q, 1.59659784691197038762901224386099403e+51Q, 9.74415453825658662874112107295166701e+51Q, 6.11723839484331306452493250946377612e+52Q, 3.95204965058524182677586041680204451e+53Q, 2.62870159207425821306145211826683375e+54Q, 1.80099019650267939321809025642439880e+55Q, 1.27155446256306838318997486480890087e+56Q, 9.25588010447776071059464920928086632e+56Q, 6.94973792013391939342588109222317053e+57Q, 5.38516720076996562080859176422021036e+58Q, 4.30849366810297877444039522534393308e+59Q, 3.56095155754217837059656555899190815e+60Q, 3.04188852838464999204043663335571874e+61Q, 2.68709444193083718922293037351168007e+62Q, 2.45592053890000085507656649738841713e+63Q, 2.32364825416864153745578539849845717e+64Q, 2.27712974158489233058096874867974690e+65Q, 2.31263355291322473374027008502422191e+66Q, 2.43540759298129112939388619780518297e+67Q, 2.66091038882246524570905302589811279e+68Q, 3.01810594342353392025458974267831671e+69Q, 3.55582348951019250289525994888733340e+70Q, 4.35418887779384901315251041444022899e+71Q, 5.54497579551181331524599144834616000e+72Q, 7.34827648190988633565298908145357523e+73Q, 1.01399802572242326074394064208241565e+75Q, 1.45791146224460794340779409761344050e+76Q, 2.18548887681950529537081926891986328e+77Q, 3.41802215328662300798456454917771592e+78Q, 5.58084392060183572830239216435019125e+79Q, 9.51958650279973390758331753317257950e+80Q, 1.69757357824719778562747265505252946e+82Q, 3.16690667099018001388115076193097403e+83Q, 6.18509910641867543038652223056425804e+84Q, 1.26554113438693437654962757714903554e+86Q, 2.71482896587775689871692274985919286e+87Q, 6.11038680296449408162222719197467046e+88Q, 1.44405408617108323852658132530082074e+90Q, 3.58608372663838816495703910754396082e+91Q, 9.36523186806323959966772742491929522e+92Q, 2.57408011620512244881601880029319908e+94Q, 7.45213468986230271920125476429174422e+95Q, 2.27430990383616981910627355587444817e+97Q, 7.32301113412116474943463116371095103e+98Q, 2.48981642173793246167799170730006141e+100Q, 8.94653338635928158843209476986997508e+101Q, 3.40040137239116597862336436061445989e+103Q, 1.36828818620892821730981225660157834e+105Q, 5.83427748982959193060571787534606697e+106Q, 2.63848693767238342424340754241860221e+108Q, 1.26672888276713952132156406152434700e+110Q, 6.46222517831418280306046165038174027e+111Q, 3.50643232060757360375065377104810475e+113Q, 2.02560893394326816509670349356333828e+115Q, 1.24704167708478470702273287091045609e+117Q, 8.18986518840527903795498196049278255e+118Q, 5.74361089440609996487936977642920132e+120Q, 4.30580893408448976261136511421423734e+122Q, 3.45415696607949675499703108821962730e+124Q, 2.96831660153035273688363706593385374e+126Q, 2.73545624237218359223636851390580041e+128Q, 2.70631717669007784745026117275242499e+130Q, 2.87767991634206038473084413615742294e+132Q, 3.29241287826810639047033778585737812e+134Q, 4.05784096195372596931902665934287382e+136Q, 5.39378304910573732382585500687737807e+138Q, 7.74152390167223540621293648465491842e+140Q, 1.20120996231066845642412985516875175e+143Q, 2.01745607955680730064740044686640147e+145Q, 3.67217662348306252636962893865111425e+147Q, 7.25316379805857762968710347450256630e+149Q, 1.55659153530257056999948366173645285e+152Q, 3.63439983279039488510674235872123571e+154Q, 9.24438760046827764031744167566698413e+156Q, 2.56505460126015154661078513762260065e+159Q, 7.77468767447849521051212939671796074e+161Q, 2.57775340952739965069105894604883404e+164Q, 9.36236559200171990439286451934391539e+166Q, 3.73025928974609135812613567068392186e+169Q, 1.63280699411172483017448754437467171e+172Q, 7.86350685466830069681739337700194312e+174Q, 4.17288659053103260909421860789088638e+177Q, 2.44376468354452976432259429734905692e+180Q, 1.58182604983516221850901239956537929e+183Q, 1.13349408906485996833819126879692168e+186Q, 9.00609317867158059779746161516574861e+188Q, 7.94724581006520631483760616875503191e+191Q, 7.80148734070770210787180909072341250e+194Q, 8.53389980133319877537947288273508168e+197Q, 1.04199907704816359699116619452657846e+201Q, 1.42261945983107616739713958471131412e+204Q, 2.17558254343347922345039318825837040e+207Q, 3.73339221107050141050095672544726852e+210Q, 7.20212971416878494124587287789857735e+213Q, 1.56476087980246841023430707631510252e+217Q, 3.83599289170088247519036274601375492e+220Q, 1.06310518934360483187879118646180568e+224Q, 3.33719954606082150504485397744546787e+227Q, 1.18890644129926367056386614030943443e+231Q, 4.81657405194041613555936914144916344e+234Q, 2.22347874123114616622582251703709887e+238Q, 1.17199258523361213934517364652872480e+242Q, 7.06839671131322838482398929154588609e+245Q, 4.88812662946732326430886472870070228e+249Q, 3.88441192207630934518298772235960268e+253Q, 3.55483921979499015020713995580889030e+257Q, 3.75484510816250928148708038190395303e+261Q, 4.58798720933643387311573482445886110e+265Q, 6.49989966050568126079524541048529496e+269Q, 1.07018103272413666142402906179157598e+274Q, 2.05258799808849457042833394124187317e+278Q, 4.59710306190259625117029822247574448e+282Q, 1.20521640888055636836192268959955157e+287Q, 3.70784262206985650361726040790594581e+291Q, 1.34198324051735290325452259089861845e+296Q, 5.72866922601176092550850127280325304e+300Q, 2.89181208605318627652310091586335359e+305Q, 1.73078309894901278503683645288680165e+310Q, 1.23150483936231719457381379774516673e+315Q, 1.04456022524616506171048138618772005e+320Q, 1.05909848234544418123752752792015094e+325Q, 1.28725694153849592436889057738754649e+330Q, 1.88087499295689639308903342601320607e+335Q, 3.31344446614783992260480183208324732e+340Q, 7.05835740270200829603933852702222207e+345Q, 1.82360609116987101874149506325271866e+351Q, 5.73167527316999715111499624522524490e+356Q, 2.19834460849656433024448179756162490e+362Q, 1.03213196012299389398122351217909554e+368Q, 5.95090459142945173642877532664315820e+373Q, 4.22711326689560391486862730288730260e+379Q, 3.71146073815998244096864189178283440e+385Q, 4.04143285030597516778349567433491877e+391Q, 5.47630493200706306950643242188138639e+397Q, 9.26610183846830899934754118194991047e+403Q, 1.96463867218278875638951764233831097e+410Q, 5.23826401399289488725708314794013273e+416Q, 1.76269979359229195206462702562496087e+423Q, 7.51358974574222029659643352716721030e+429Q, 4.07203690042780566335825621191079282e+436Q, 2.81652392485993763998682010256080428e+443Q, 2.49586432083962995754217338958145192e+450Q, 2.84464997550187838898841424132533307e+457Q, 4.18656911271834268911740204159815337e+464Q, 7.98835944729121866190974499356597568e+471Q, 1.98427885725374523364086923738598523e+479Q, 6.44313780728812316513345459942694301e+486Q, 2.74646447436726496994650106679472135e+494Q, 1.54345331097536381511922890966406624e+502Q, 1.14854061177091306735355343708426610e+510Q, 1.13671799925771100929831048483235430e+518Q, 1.50301408173820906903238314130252343e+526Q, 2.66721742401349021977265127553699936e+534Q, 6.38191727827371990119668697526910696e+542Q, 2.06864189323929509313332139375745418e+551Q, 9.12718925758572793769909253655546363e+559Q, 5.50827087084343716443556503345322384e+568Q, 4.56943096951975523591483538202467049e+577Q, 5.23664812769936727945516120554813767e+586Q, 8.33295831969513770916127078276468196e+595Q, 1.85073603040006635508770638738735213e+605Q, 5.76725912854578779706265298662279369e+614Q, 2.53507221317613667093309510235117825e+624Q, 1.58037348241924263546145926074674624e+634Q, 1.40497098317887844492262106048698980e+644Q, 1.79118532756424559114150403858023467e+654Q, 3.29340233091271285034548969456076701e+664Q, 8.78384225704905897945003526718634352e+674Q, 3.41824790512159692619674889187554870e+685Q, 1.95247619547378795632466874007982924e+696Q, 1.64685615123975037569921507294781182e+707Q, 2.06385512057306929298128483493412318e+718Q, 3.86691162964076111860523245198584961e+729Q, 1.09008736553561747232882422664193409e+741Q, 4.65333391196364819411904308657257877e+752Q, 3.02768585771015415481330091322447912e+764Q, 3.02262040534180824988954474846992913e+776Q, 4.66133722640174567906974646266839244e+788Q, 1.11806119156969171229108916233644999e+801Q, 4.20019655376202192049844032418033555e+813Q, 2.48880615873773868126893696694455625e+826Q, 2.34286193142054643224145247339492426e+839Q, 3.52941162196327496812531706159176164e+852Q, 8.57183106082165907783781027353105401e+865Q, 3.38163627323872188047900717079347979e+879Q, 2.18363447282104345585022834572887531e+893Q, 2.32596275137292895223293068081362090e+907Q, 4.11925247272574761366980289309686003e+921Q, 1.22265489460258041690738897372130823e+936Q, 6.13184165651799059701146847592463464e+950Q, 5.23922303275545560334122760478493484e+965Q, 7.69087233862553980667730597006685190e+980Q, 1.95622275953749870274795206909257068e+996Q, 8.69670052895401378378113763338699958e+1011Q, 6.81715148318539616903616353647181598e+1027Q, 9.50697711954141544724599553989093262e+1043Q, 2.38019733682587370869498352841844428e+1060Q, 1.07973324919847346937291516197684901e+1077Q, 8.95814284819025403820872820042945790e+1093Q, 1.37229192661307043018958002675397831e+1111Q, 3.91918794622242371528673544888524419e+1128Q, 2.10730218913863433412315532873510194e+1146Q, 2.15459607934366008026324206138837528e+1164Q, 4.23163839295623007237154131840451677e+1182Q, 1.61294441956204958952970453918741185e+1201Q, 1.20568335528354973250479511763057854e+1220Q, 1.78630819666459637235669417819650103e+1239Q, 5.30233997012953850434143324467683139e+1258Q, 3.18800705045665419646272046839479382e+1278Q, 3.92589619613994835597705628928304867e+1298Q, 1.00145056975313260959947278741812233e+1319Q, 5.35268808912615454171856125906228237e+1339Q, 6.06491960606218539467705074145131193e+1360Q, 1.47410187506507259371724909079906759e+1382Q, 7.77855372825975976779550291054389078e+1403Q, 9.02071339187528665617085297107535931e+1425Q, 2.32776342394968427168699373890370933e+1448Q, 1.35351409374730203846799381939288903e+1471Q, 1.79625881886715571166142200348072039e+1494Q, 5.51189494978629938318487744451579809e+1517Q, 3.96270198063441303687686251379779681e+1541Q, 6.76492837567767494547614386605795924e+1565Q, 2.77991073110506719318274536923711255e+1590Q, 2.78805951202715437087943440518839779e+1615Q, 6.92116280606414755524296394791409952e+1640Q, 4.31380309053366092943951122004431463e+1666Q, 6.84923073262139995438889690748178280e+1692Q, 2.81137418164430829179092468240459910e+1719Q, 3.02821524237655652451836921974619657e+1746Q, 8.69048903533522694231765189726868666e+1773Q, 6.74828063313306417588175763238310325e+1801Q, 1.44026065844141159256872926595644247e+1830Q, 8.58426091495439408178371839859019039e+1858Q, 1.45211919400936944187225846047638548e+1888Q, 7.08718013380970011842483247147601395e+1917Q, 1.01475962220405902523641440040104610e+1948Q, 4.33542978691578087509838132034723750e+1978Q, 5.62285772227295495777726116212032065e+2009Q, 2.25285072921565445630031609130087435e+2041Q, 2.83839050906274298341210206309759282e+2073Q, 1.14501659579022194588844609345877849e+2106Q, 1.50629562239998305958408533546634030e+2139Q, 6.58342161306998815751663631350733541e+2172Q, 9.74198999952210922892973281379349494e+2206Q, 4.97552704772088889228035264268694867e+2241Q, 8.94330619882842342247706838649878784e+2276Q, 5.77072420156026800834371478648673792e+2312Q, 1.36388225285320494361282201451878478e+2349Q, 1.20508189950290985406298094670730466e+2386Q, 4.06413362486490272506766749982212198e+2423Q, 5.34308092015215251528601382597439463e+2461Q, }, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_weights.size() - 1); +#else + m_committed_refinements = m_weights.size() - 1; +#endif + m_t_max = 8.88600744303961370002819023592353264e+00Q; + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } +} +#endif + +}}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/detail/tanh_sinh_detail.hpp b/libcxx/src/third-party/boost/math/quadrature/detail/tanh_sinh_detail.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/detail/tanh_sinh_detail.hpp @@ -0,0 +1,867 @@ +// Copyright Nick Thompson, 2017 +// 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_QUADRATURE_DETAIL_TANH_SINH_DETAIL_HPP +#define BOOST_MATH_QUADRATURE_DETAIL_TANH_SINH_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#endif + +namespace boost{ namespace math{ namespace quadrature { namespace detail{ + + +// Returns the tanh-sinh quadrature of a function f over the open interval (-1, 1) + +template +class tanh_sinh_detail +{ + static const int initializer_selector = + !std::numeric_limits::is_specialized || (std::numeric_limits::radix != 2) ? + 0 : + (std::numeric_limits::digits < 30) && (std::numeric_limits::max_exponent <= 128) ? + 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= std::numeric_limits::max_exponent) ? + 2 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && (std::numeric_limits::max_exponent <= 16384) ? + 3 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && (std::numeric_limits::max_exponent <= 16384) ? + 4 : +#endif + 0; +public: + tanh_sinh_detail(size_t max_refinements, const Real& min_complement) : m_max_refinements(max_refinements) + { + typedef std::integral_constant tag_type; + init(min_complement, tag_type()); + } + + template + decltype(std::declval()(std::declval(), std::declval())) integrate(const F f, Real* error, Real* L1, const char* function, Real left_min_complement, Real right_min_complement, Real tolerance, std::size_t* levels) const; + +private: + const std::vector& get_abscissa_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_abscissas[n]; + } + const std::vector& get_weight_row(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_weights[n]; + } + std::size_t get_first_complement_index(std::size_t n)const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements.load() >= n); +#else + if (m_committed_refinements < n) + extend_refinements(); + BOOST_MATH_ASSERT(m_committed_refinements >= n); +#endif + return m_first_complements[n]; + } + + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); + void init(const Real& min_complement, const std::integral_constant&); +#ifdef BOOST_HAS_FLOAT128 + void init(const Real& min_complement, const std::integral_constant&); +#endif + void prune_to_min_complement(const Real& m); + void extend_refinements()const + { +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + std::lock_guard guard(m_mutex); +#endif + // + // Check some other thread hasn't got here after we read the atomic variable, but before we got here: + // +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + if (m_committed_refinements.load() >= m_max_refinements) + return; +#else + if (m_committed_refinements >= m_max_refinements) + return; +#endif + + using std::ldexp; + using std::ceil; + ++m_committed_refinements; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + std::size_t row = m_committed_refinements.load(); +#else + std::size_t row = m_committed_refinements; +#endif + Real h = ldexp(static_cast(1), -static_cast(row)); + std::size_t first_complement = 0; + std::size_t n = boost::math::itrunc(ceil((m_t_max - h) / (2 * h))); + m_abscissas[row].reserve(n); + m_weights[row].reserve(n); + for (Real pos = h; pos < m_t_max; pos += 2 * h) + { + if (pos < m_t_crossover) + ++first_complement; + m_abscissas[row].push_back(pos < m_t_crossover ? abscissa_at_t(pos) : -abscissa_complement_at_t(pos)); + } + m_first_complements[row] = first_complement; + for (Real pos = h; pos < m_t_max; pos += 2 * h) + m_weights[row].push_back(weight_at_t(pos)); + } + + static inline Real abscissa_at_t(const Real& t) + { + using std::tanh; + using std::sinh; + using boost::math::constants::half_pi; + return tanh(half_pi()*sinh(t)); + } + static inline Real weight_at_t(const Real& t) + { + using std::cosh; + using std::sinh; + using boost::math::constants::half_pi; + Real cs = cosh(half_pi() * sinh(t)); + return half_pi() * cosh(t) / (cs * cs); + } + static inline Real abscissa_complement_at_t(const Real& t) + { + using std::cosh; + using std::exp; + using std::sinh; + using boost::math::constants::half_pi; + Real u2 = half_pi() * sinh(t); + return 1 / (exp(u2) *cosh(u2)); + } + static inline Real t_from_abscissa_complement(const Real& x) + { + using std::log; + using std::sqrt; + using boost::math::constants::pi; + Real l = log(2-x) - log(x); + return log((sqrt(l * l + pi() * pi()) + l) / pi()); + }; + + + mutable std::vector> m_abscissas; + mutable std::vector> m_weights; + mutable std::vector m_first_complements; + std::size_t m_max_refinements, m_inital_row_length{}; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + mutable boost::math::detail::atomic_unsigned_type m_committed_refinements{}; + mutable std::mutex m_mutex; +#else + mutable unsigned m_committed_refinements; +#endif + Real m_t_max, m_t_crossover; +}; + +template +template +decltype(std::declval()(std::declval(), std::declval())) tanh_sinh_detail::integrate(const F f, Real* error, Real* L1, const char* function, Real left_min_complement, Real right_min_complement, Real tolerance, std::size_t* levels) const +{ + using std::abs; + using std::fabs; + using std::floor; + using std::tanh; + using std::sinh; + using std::sqrt; + using boost::math::constants::half; + using boost::math::constants::half_pi; + + // + // The type of the result: + typedef decltype(std::declval()(std::declval(), std::declval())) result_type; + + Real h = m_t_max / m_inital_row_length; + result_type I0 = half_pi() * f(0, 1); + Real L1_I0 = abs(I0); + // + // We maintain 4 integer values: + // max_left_position is the logical index of the abscissa value closest to the + // left endpoint of the range that we can call f(x_i) on without rounding error + // inside f(x_i) causing evaluation at the endpoint. + // max_left_index is the actual position in the current row that has a logical index + // no higher than max_left_position. Remember that since we only store odd numbered + // indexes in each row, this may actually be one position to the left of max_left_position + // in the case that is even. Then, if we only evaluate f(-x_i) for abscissa values + // i <= max_left_index we will never evaluate f(-x_i) at the left endpoint. + // max_right_position and max_right_index are defined similarly for the right boundary + // and are used to guard evaluation of f(x_i). + // + // max_left_position and max_right_position start off as the last element in row zero: + // + std::size_t max_left_position(m_abscissas[0].size() - 1); + std::size_t max_left_index, max_right_position(max_left_position), max_right_index; + // + // Decrement max_left_position and max_right_position until the complement + // of the abscissa value is greater than the smallest permitted (as specified + // by the function caller): + // + while (max_left_position && fabs(m_abscissas[0][max_left_position]) < left_min_complement) + --max_left_position; + while (max_right_position && fabs(m_abscissas[0][max_right_position]) < right_min_complement) + --max_right_position; + // + // Check for non-finite values at the end points: + // + result_type yp, ym, tail_tolerance((std::max)(boost::math::tools::epsilon(), Real(tolerance * tolerance))); + do + { + yp = f(-1 - m_abscissas[0][max_left_position], m_abscissas[0][max_left_position]); + if ((boost::math::isfinite)(yp)) + break; + --max_left_position; + } while (m_abscissas[0][max_left_position] < 0); + // + // Also remove points which are insignificant or zero: + // + while (max_left_position > 1) + { + if (abs(yp * m_weights[0][max_left_position]) > abs(L1_I0 * tail_tolerance)) + break; + --max_left_position; + yp = f(-1 - m_abscissas[0][max_left_position], m_abscissas[0][max_left_position]); + } + // + // Over again for the right hand side: + // + do + { + ym = f(1 + m_abscissas[0][max_right_position], -m_abscissas[0][max_right_position]); + if ((boost::math::isfinite)(ym)) + break; + --max_right_position; + } while (m_abscissas[0][max_right_position] < 0); + while (max_right_position > 1) + { + if (abs(ym * m_weights[0][max_right_position]) > abs(L1_I0 * tail_tolerance)) + break; + --max_right_position; + ym = f(1 + m_abscissas[0][max_right_position], -m_abscissas[0][max_right_position]); + } + + if ((max_left_position == 0) && (max_right_position == 0)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature found your function to be non-finite everywhere! Please check your function for singularities.", ym, Policy()); + } + + I0 += yp * m_weights[0][max_left_position] + ym * m_weights[0][max_right_position]; + L1_I0 += abs(yp * m_weights[0][max_left_position]) + abs(ym * m_weights[0][max_right_position]); + // + // Assumption: left_min_complement/right_min_complement are sufficiently small that we only + // ever decrement through the stored values that are complements (the negative ones), and + // never ever hit the true abscissa values (positive stored values). + // + BOOST_MATH_ASSERT(m_abscissas[0][max_left_position] < 0); + BOOST_MATH_ASSERT(m_abscissas[0][max_right_position] < 0); + + for(size_t i = 1; i < m_abscissas[0].size(); ++i) + { + if ((i >= max_right_position) && (i >= max_left_position)) + break; + Real x = m_abscissas[0][i]; + Real xc = x; + Real w = m_weights[0][i]; + if ((boost::math::signbit)(x)) + { + // We have stored x - 1: + x = 1 + xc; + } + else + xc = x - 1; + yp = i < max_right_position ? f(x, -xc) : 0; + ym = i < max_left_position ? f(-x, xc) : 0; + I0 += (yp + ym)*w; + L1_I0 += (abs(yp) + abs(ym))*w; + } + // + // We have: + // k = current row. + // I0 = last integral value. + // I1 = current integral value. + // L1_I0 and L1_I1 are the absolute integral values. + // + size_t k = 1; + result_type I1 = I0; + Real L1_I1 = L1_I0; + Real err = 0; + // + // thrash_count is a heuristic - it counts how many time the error has actually increased + // rather than decreased, if this gets too high we abort... + // + unsigned thrash_count = 0; + + while (k < 4 || (k < m_weights.size() && k < m_max_refinements) ) + { + I0 = I1; + L1_I0 = L1_I1; + + I1 = half()*I0; + L1_I1 = half()*L1_I0; + h *= half(); + result_type sum = 0; + Real absum = 0; + Real endpoint_error = 0; + auto const& abscissa_row = this->get_abscissa_row(k); + auto const& weight_row = this->get_weight_row(k); + std::size_t first_complement_index = this->get_first_complement_index(k); + // + // At the start of each new row we need to update the max left/right indexes + // at which we can evaluate f(x_i). The new logical position is simply twice + // the old value. The new max index is one position to the left of the new + // logical value (remember each row contains only odd numbered positions). + // Then we have to make a single check, to see if one position to the right + // is also in bounds (this is the new abscissa value in this row which is + // known to be in between a value known to be in bounds, and one known to be + // not in bounds). + // Thus, we filter which abscissa values generate a call to f(x_i), with a single + // floating point comparison per loop. Everything else is integer logic. + // + max_left_index = max_left_position - 1; + max_left_position *= 2; + max_right_index = max_right_position - 1; + max_right_position *= 2; + if ((abscissa_row.size() > max_left_index + 1) && (fabs(abscissa_row[max_left_index + 1]) > left_min_complement)) + { + ++max_left_position; + ++max_left_index; + } + if ((abscissa_row.size() > max_right_index + 1) && (fabs(abscissa_row[max_right_index + 1]) > right_min_complement)) + { + ++max_right_position; + ++max_right_index; + } + // + // We also check that our endpoints don't hit singularities: + // + do + { + yp = f(-1 - abscissa_row[max_left_index], abscissa_row[max_left_index]); + if ((boost::math::isfinite)(yp)) + break; + max_left_position -= 2; + --max_left_index; + } while (abscissa_row[max_left_index] < 0); + bool truncate_left(false), truncate_right(false); + if (abs(L1_I1 * tail_tolerance) > abs(yp * weight_row[max_left_index])) + truncate_left = true; + do + { + ym = f(1 + abscissa_row[max_right_index], -abscissa_row[max_right_index]); + if ((boost::math::isfinite)(ym)) + break; + --max_right_index; + max_right_position -= 2; + } while (abscissa_row[max_right_index] < 0); + if (abs(L1_I1 * tail_tolerance) > abs(ym * weight_row[max_right_index])) + truncate_right = true; + + sum += yp * weight_row[max_left_index] + ym * weight_row[max_right_index]; + absum += abs(yp * weight_row[max_left_index]) + abs(ym * weight_row[max_right_index]); + // + // We estimate the error due to truncation as the value contributed by the two most extreme points. + // In most cases this is tiny and can be ignored, if it is significant then either the area of the + // integral is so far our in the tails that our exponent range can't reach it (example x^-p at double + // precision and p ~ 1), or our function is truncated near epsilon, and we have had to narrow our endpoints. + // In this latter case we may over-estimate the error, but this is the best we can do. + // In any event, we do not add endpoint_error to the error estimate until we terminate the main loop, + // otherwise it can make things appear to be non-converged, when in reality, they are as converged as they + // will ever be. + // + endpoint_error = absum; + + for(size_t j = 0; j < weight_row.size(); ++j) + { + // If both left and right abscissa values are out of bounds at this step + // we can just stop this loop right now: + if ((j >= max_left_index) && (j >= max_right_index)) + break; + Real x = abscissa_row[j]; + Real xc = x; + Real w = weight_row[j]; + if (j >= first_complement_index) + { + // We have stored x - 1: + BOOST_MATH_ASSERT(x < 0); + x = 1 + xc; + } + else + { + BOOST_MATH_ASSERT(x >= 0); + xc = x - 1; + } + + yp = j >= max_right_index ? 0 : f(x, -xc); + ym = j >= max_left_index ? 0 : f(-x, xc); + result_type term = (yp + ym)*w; + sum += term; + + // A question arises as to how accurately we actually need to estimate the L1 integral. + // For simple integrands, computing the L1 norm makes the integration 20% slower, + // but for more complicated integrands, this calculation is not noticeable. + Real abterm = (abs(yp) + abs(ym))*w; + absum += abterm; + } + + I1 += sum*h; + L1_I1 += absum*h; + + ++k; + Real last_err = err; + err = abs(I0 - I1); + + if (!(boost::math::isfinite)(I1)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Please narrow the bounds of integration or check your function for singularities.", I1, Policy()); + } + // + // If the error is increasing, and we're past level 4, something bad is very likely happening: + // + if ((err * 1.5 > last_err) && (k > 4)) + { + bool terminate = false; + if ((++thrash_count > 1) && (last_err < 1e-3)) + // Probably just thrashing, abort: + terminate = true; + else if(thrash_count > 2) + // OK, terrible error, but giving up anyway! + terminate = true; + else if (last_err < boost::math::tools::root_epsilon()) + // Trying to squeeze precision that probably isn't there, abort: + terminate = true; + else + { + // Take a look at the end points, if there's significant new area being + // discovered, then we're not able to get close enough to the endpoints + // to ever find the integral: + if (abs(endpoint_error / sum) > err) + terminate = true; + } + + if (terminate) + { + // We could raise an evaluation_error, but since we likely have some sort of result, just return the last one + // (ie before the error started going up) + I1 = I0; + L1_I1 = L1_I0; + --k; + err = last_err + endpoint_error; + break; + } + // Fall through and keep going, assume we've discovered a new feature of f(x).... + } + // + // Termination condition: + // No more levels are considered once the error is less than the specified tolerance. + // Note however, that we always go down at least 4 levels, otherwise we risk missing + // features of interest in f() - imagine for example a function which flatlines, except + // for a very small "spike". An example would be the incomplete beta integral with large + // parameters. We could keep hunting until we find something, but that would handicap + // integrals which really are zero.... so a compromise then! + // + if ((err <= abs(tolerance*L1_I1)) && (k >= 4)) + { + // + // A quick sanity check: have we at some point narrowed our boundaries as a result + // of non-finite values? If so let's check that the area isn't on an increasing + // trajectory at our new end point, and increase our error estimate by the last + // good value as an estimate for what we may have discarded. + // + if ((max_left_index < abscissa_row.size() - 1) && (abs(abscissa_row[max_left_index + 1]) > left_min_complement)) + { + yp = f(-1 - abscissa_row[max_left_index], abscissa_row[max_left_index]) * weight_row[max_left_index]; + ym = f(-1 - abscissa_row[max_left_index - 1], abscissa_row[max_left_index - 1]) * weight_row[max_left_index - 1]; + if (abs(yp) > abs(ym)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Integration bounds were automatically narrowed, but the integral was found to be increasing at the new endpoint. Please check your function, and consider providing a 2-argument functor.", I1, Policy()); + } + } + if ((max_right_index < abscissa_row.size() - 1) && (abs(abscissa_row[max_right_index + 1]) > right_min_complement)) + { + yp = f(1 + abscissa_row[max_right_index], -abscissa_row[max_right_index]) * weight_row[max_right_index]; + ym = f(1 + abscissa_row[max_right_index - 1], -abscissa_row[max_right_index - 1]) * weight_row[max_right_index - 1]; + if (abs(yp) > abs(ym)) + { + return policies::raise_evaluation_error(function, "The tanh_sinh quadrature evaluated your function at a singular point and got %1%. Integration bounds were automatically narrowed, but the integral was found to be increasing at the new endpoint. Please check your function, and consider providing a 2-argument functor.", I1, Policy()); + } + } + err += endpoint_error; + break; + } + + if (truncate_left) + --max_left_position; + if (truncate_right) + --max_right_position; + + } + if (error) + { + *error = err; + } + + if (L1) + { + *L1 = L1_I1; + } + + if (levels) + { + *levels = k; + } + + return I1; +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + using std::tanh; + using std::sinh; + using std::asinh; + using std::atanh; + using std::ceil; + using boost::math::constants::half_pi; + using boost::math::constants::pi; + using boost::math::constants::two_div_pi; + using boost::math::lltrunc; + + m_committed_refinements = 4; + // + // Initial row length is one step to the right of the abscissa value + // that would go to the full extent of the requested range, we need this + // to ensure full precision as otherwise we chop off quite a chunk of the + // range in *subsequent* rows. + // + m_inital_row_length = lltrunc(ceil(t_from_abscissa_complement(min_complement))); + std::size_t first_complement = 0; + m_t_max = m_inital_row_length; + m_t_crossover = t_from_abscissa_complement(Real(0.5f)); + + m_abscissas.assign(m_max_refinements + 1, std::vector()); + m_weights.assign(m_max_refinements + 1, std::vector()); + m_first_complements.assign(m_max_refinements + 1, 0); + // + // First row is special: + // + Real h = m_t_max / m_inital_row_length; + + std::vector temp(m_inital_row_length + 1, Real(0)); + for (std::size_t i = 0; i < m_inital_row_length; ++i) + { + Real t = h * i; + if (t < m_t_crossover) + ++first_complement; + temp[i] = t < m_t_crossover ? abscissa_at_t(t) : -abscissa_complement_at_t(t); + } + temp[m_inital_row_length] = -abscissa_complement_at_t(m_t_max); + m_abscissas[0].swap(temp); + m_first_complements[0] = first_complement; + temp.assign(m_inital_row_length + 1, Real(0)); + for (std::size_t i = 0; i < m_inital_row_length; ++i) + temp[i] = weight_at_t(Real(h * i)); + temp[m_inital_row_length] = weight_at_t(m_t_max); + m_weights[0].swap(temp); + +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + for (std::size_t row = 1; row <= m_committed_refinements.load(); ++row) +#else + for (std::size_t row = 1; row <= m_committed_refinements; ++row) +#endif + { + h /= 2; + first_complement = 0; + + for (Real pos = h; pos < m_t_max; pos += 2 * h) + { + if (pos < m_t_crossover) + ++first_complement; + temp.push_back(pos < m_t_crossover ? abscissa_at_t(pos) : -abscissa_complement_at_t(pos)); + } + m_abscissas[row].swap(temp); + m_first_complements[row] = first_complement; + for (Real pos = h; pos < m_t_max; pos += 2 * h) + temp.push_back(weight_at_t(pos)); + m_weights[row].swap(temp); + } +} + +#ifdef __GNUC__ +// Selective warning disabling via: +// #pragma GCC diagnostic ignored "-Wliteral-range" +// #pragma GCC diagnostic ignored "-Woverflow" +// Seems not to work, so we're left with this: +#pragma GCC system_header +#endif + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 4; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0f, -0.04863203593f, -2.252280754e-05f, -4.294161056e-14f, -1.167648898e-37f, }, + { -0.3257285078f, -0.002485143543f, -1.112433512e-08f, -5.378491591e-23f, }, + { 0.3772097382f, -0.1404309413f, -0.01295943949f, -0.0003117359716f, -7.952628853e-07f, -4.714355182e-11f, -5.415222824e-18f, -2.040300394e-29f, }, + { 0.1943570033f, -0.4608532946f, -0.219392561f, -0.08512073674f, -0.0260331318f, -0.005944493369f, -0.0009348035442f, -9.061530486e-05f, -4.683958779e-06f, -1.072183876e-07f, -8.572949078e-10f, -1.767834693e-12f, -6.374878495e-16f, -2.442937279e-20f, -5.251546473e-26f, -2.789467162e-33f, }, + { 0.09792388529f, 0.2878799327f, 0.4612535439f, -0.3897263425f, -0.2689819652f, -0.1766829945f, -0.1101085972f, -0.06483914248f, -0.03588783578f, -0.01854517332f, -0.008873007558f, -0.003891334562f, -0.001545791232f, -0.0005485655647f, -0.0001711779271f, -4.612899437e-05f, -1.051798518e-05f, -1.982859405e-06f, -3.011058474e-07f, -3.576091908e-08f, -3.212800902e-09f, -2.102671378e-10f, -9.606066479e-12f, -2.919026641e-13f, -5.586116639e-15f, -6.328207135e-17f, -3.956461339e-19f, -1.260975845e-21f, -1.872492175e-24f, -1.170030294e-27f, -2.740986178e-31f, -2.112282721e-35f, }, + { 0.04905596731f, 0.1464179843f, 0.2415663195f, 0.3331422646f, 0.4199521113f, -0.4989866106f, -0.4244155094f, -0.356823241f, -0.2964499949f, -0.2433060914f, -0.1972012587f, -0.1577807536f, -0.1245646024f, -0.09698671849f, -0.07443136593f, -0.05626521395f, -0.04186397729f, -0.0306332671f, -0.02202376481f, -0.01554116883f, -0.01075156891f, -0.007283002803f, -0.004823973845f, -0.003119681872f, -0.001966663685f, -0.001206465701f, -0.0007188880782f, -0.0004152496485f, -0.0002320284004f, -0.0001251349512f, -6.498007492e-05f, -3.240693206e-05f, -1.548009773e-05f, -7.062123337e-06f, -3.06755081e-06f, -1.264528134e-06f, -4.929942806e-07f, -1.811062872e-07f, -6.244592163e-08f, -2.01254968e-08f, -6.035865798e-09f, -1.676638052e-09f, -4.292122274e-10f, -1.007222767e-10f, -2.154466259e-11f, -4.175393124e-12f, -7.284737264e-13f, -1.136386985e-13f, -1.57355351e-14f, -1.91921891e-15f, -2.044959541e-16f, -1.886958307e-17f, -1.493871649e-18f, -1.00469381e-19f, -5.679929178e-21f, -2.669103953e-22f, -1.030178138e-23f, -3.224484876e-25f, -8.0747829e-27f, -1.594654602e-28f, -2.445723975e-30f, -2.865919772e-32f, -2.521682525e-34f, -1.63551444e-36f, }, + { 0.02453976357f, 0.07352512299f, 0.1222291222f, 0.1704679724f, 0.2180634735f, 0.2648450766f, 0.3106517806f, 0.3553338252f, 0.3987541505f, 0.440789599f, 0.4813318461f, -0.4797119493f, -0.4424187717f, -0.4068496464f, -0.3730497919f, -0.3410490083f, -0.3108622749f, -0.2824905325f, -0.2559216165f, -0.2311313132f, -0.2080845076f, -0.1867363915f, -0.1670337061f, -0.148915992f, -0.1323168242f, -0.1171650118f, -0.1033857457f, -0.09090168184f, -0.07963394697f, -0.069503062f, -0.06042977607f, -0.05233580938f, -0.04514450419f, -0.03878138485f, -0.03317462969f, -0.02825545843f, -0.02395843974f, -0.0202217242f, -0.01698720852f, -0.01420063697f, -0.0118116462f, -0.009773759532f, -0.008044336997f, -0.006584486831f, -0.005358944287f, -0.004335923183f, -0.00348694536f, -0.002786652957f, -0.002212608041f, -0.001745083828f, -0.001366851359f, -0.001062965166f, -0.0008205510651f, -0.0006285988591f, -0.0004777623488f, -0.0003601686544f, -0.0002692384802f, -0.0001995185689f, -0.0001465272269f, -0.0001066134524f, -7.682987071e-05f, -5.481938554e-05f, -3.871519214e-05f, -2.705357477e-05f, -1.869872988e-05f, -1.2778718e-05f, -8.631551655e-06f, -5.760372383e-06f, -3.796652834e-06f, -2.470376195e-06f, -1.586189035e-06f, -1.00458931e-06f, -6.272926646e-07f, -3.860114498e-07f, -2.339766676e-07f, -1.396287854e-07f, -8.199520529e-08f, -4.735733554e-08f, -2.688676406e-08f, -1.499692369e-08f, -8.213543901e-09f, -4.414366384e-09f, -2.326763262e-09f, -1.2020165e-09f, -6.082231242e-10f, -3.012456307e-10f, -1.459438845e-10f, -6.911160499e-11f, -3.196678326e-11f, -1.443120992e-11f, -6.353676128e-12f, -2.725950519e-12f, -1.138734572e-12f, -4.627734622e-13f, -1.827990225e-13f, -7.012046738e-14f, -2.609605366e-14f, -9.413361335e-15f, -3.287925695e-15f, -1.11086294e-15f, -3.626602264e-16f, -1.142787653e-16f, -3.471902269e-17f, -1.015781907e-17f, -2.858532825e-18f, -7.727834787e-19f, -2.004423992e-19f, -4.981568376e-20f, -1.184668492e-20f, -2.691984904e-21f, -5.836667442e-22f, -1.205661589e-22f, -2.369109351e-23f, -4.421339462e-24f, -7.823835004e-25f, -1.310533144e-25f, -2.074345013e-26f, -3.096968326e-27f, -4.353200528e-28f, -5.749955668e-29f, -7.122715927e-30f, -8.25783542e-31f, -8.941541007e-32f, -9.02279665e-33f, -8.46603012e-34f, -7.369272807e-35f, -5.936632356e-36f, -4.415277839e-37f, }, + { 0.01227135512f, 0.03680228095f, 0.06129788941f, 0.08573475488f, 0.1100896299f, 0.1343395153f, 0.1584617283f, 0.1824339697f, 0.2062343883f, 0.2298416433f, 0.2532349634f, 0.2763942036f, 0.2992998981f, 0.3219333097f, 0.3442764756f, 0.3663122492f, 0.3880243378f, 0.4093973357f, 0.4304167537f, 0.4510690435f, 0.4713416183f, 0.4912228687f, -0.489297826f, -0.4702300899f, -0.4515825479f, -0.4333628262f, -0.4155775577f, -0.39823239f, -0.3813319982f, -0.3648801001f, -0.3488794756f, -0.3333319877f, -0.318238608f, -0.3035994429f, -0.2894137636f, -0.275680037f, -0.2623959593f, -0.2495584902f, -0.2371638893f, -0.2252077531f, -0.2136850525f, -0.2025901721f, -0.1919169483f, -0.1816587092f, -0.1718083133f, -0.1623581887f, -0.1533003716f, -0.1446265448f, -0.1363280753f, -0.1283960505f, -0.120821315f, -0.113594505f, -0.1067060822f, -0.1001463668f, -0.09390556883f, -0.08797381831f, -0.08234119416f, -0.07699775172f, -0.07193354881f, -0.06713867034f, -0.0626032516f, -0.0583175f, -0.0542717154f, -0.050456309f, -0.0468618209f, -0.0434789361f, -0.0402984993f, -0.03731152826f, -0.0345092259f, -0.03188299107f, -0.02942442821f, -0.02712535566f, -0.02497781299f, -0.02297406711f, -0.02110661737f, -0.01936819969f, -0.01775178968f, -0.01625060483f, -0.01485810598f, -0.01356799776f, -0.01237422849f, -0.01127098916f, -0.01025271192f, -0.009314067826f, -0.008449964034f, -0.007655540506f, -0.006926166179f, -0.006257434709f, -0.005645159804f, -0.005085370197f, -0.004574304294f, -0.004108404533f, -0.003684311494f, -0.003298857801f, -0.002949061834f, -0.002632121306f, -0.002345406714f, -0.002086454715f, -0.001852961444f, -0.001642775797f, -0.001453892723f, -0.001284446528f, -0.001132704236f, -0.0009970590063f, -0.0008760236476f, -0.0007682242321f, -0.0006723938372f, -0.000587366425f, -0.0005120708762f, -0.0004455251889f, -0.0003868308567f, -0.0003351674323f, -0.0002897872882f, -0.0002500105784f, -0.0002152204083f, -0.0001848582177f, -0.0001584193765f, -0.0001354489984f, -0.0001155379702f, -9.8319198e-05f, -8.346406605e-05f, -7.067910812e-05f, -5.970288552e-05f, -5.030306831e-05f, -4.227371392e-05f, -3.543273737e-05f, -2.961956641e-05f, -2.469297451e-05f, -2.052908425e-05f, -1.701953324e-05f, -1.406979453e-05f, -1.159764317e-05f, -9.531760786e-06f, -7.810469566e-06f, -6.380587461e-06f, -5.196396351e-06f, -4.218715072e-06f, -3.414069429e-06f, -2.753951574e-06f, -2.214161365e-06f, -1.774222689e-06f, -1.416868016e-06f, -1.127584838e-06f, -8.942180042e-07f, -7.066223315e-07f, -5.563602711e-07f, -4.364397681e-07f, -3.410878407e-07f, -2.65555767e-07f, -2.059521239e-07f, -1.591002641e-07f, -1.224171449e-07f, -9.381073151e-08f, -7.159348586e-08f, -5.440972705e-08f, -4.117489851e-08f, -3.102500976e-08f, -2.327473287e-08f, -1.738282654e-08f, -1.292373523e-08f, -9.564367214e-09f, -7.045195508e-09f, -5.164949276e-09f, -3.768272997e-09f, -2.735826254e-09f, -1.976380568e-09f, -1.420541964e-09f, -1.015790099e-09f, -7.225780068e-10f, -5.112816947e-10f, -3.598270551e-10f, -2.518536224e-10f, -1.753014775e-10f, -1.213298105e-10f, -8.349395075e-11f, -5.712266027e-11f, -3.8849686e-11f, -2.626342738e-11f, -1.764649978e-11f, -1.178329832e-11f, -7.818680628e-12f, -5.154836404e-12f, -3.376501461e-12f, -2.19707447e-12f, -1.420047367e-12f, -9.115800793e-13f, -5.811306251e-13f, -3.67867911e-13f, -2.312068904e-13f, -1.442617249e-13f, -8.934966665e-14f, -5.492567772e-14f, -3.35078831e-14f, -2.02840764e-14f, -1.218279513e-14f, -7.258853736e-15f, -4.290062787e-15f, -2.514652539e-15f, -1.461687113e-15f, -8.424330958e-16f, -4.81351759e-16f, -2.726317943e-16f, -1.530442297e-16f, -8.513785725e-17f, -4.692795039e-17f, -2.562597595e-17f, -1.386133467e-17f, -7.425750192e-18f, -3.939309402e-18f, -2.069079146e-18f, -1.075828622e-18f, -5.536671017e-19f, -2.819834004e-19f, -1.421006375e-19f, -7.084243878e-20f, -3.493350557e-20f, -1.703597751e-20f, -8.214706044e-21f, -3.915973438e-21f, -1.845149816e-21f, -8.591874581e-22f, -3.953006958e-22f, -1.7966698e-22f, -8.065408821e-23f, -3.575337212e-23f, -1.564782132e-23f, -6.760041764e-24f, -2.882136323e-24f, -1.212436233e-24f, -5.031421831e-25f, -2.059286312e-25f, -8.310787798e-26f, -3.306518068e-26f, -1.296597346e-26f, -5.010091032e-27f, -1.907179385e-27f, -7.150567334e-28f, -2.639906037e-28f, -9.594664542e-29f, -3.432078099e-29f, -1.207985066e-29f, -4.182464721e-30f, -1.424153707e-30f, -4.767833382e-31f, -1.568949178e-31f, -5.073438855e-32f, -1.611691916e-32f, -5.028356694e-33f, -1.540320437e-33f, -4.631392443e-34f, -1.366470225e-34f, -3.955008527e-35f, -1.122591825e-35f, -3.123848743e-36f, -8.519540247e-37f, -2.276473481e-37f, }, + }; + m_weights = { + { 1.570796327f, 0.2300223945f, 0.0002662005138f, 1.358178427e-12f, 1.001741678e-35f, }, + { 0.9659765794f, 0.01834316699f, 2.143120456e-07f, 2.800315102e-21f, }, + { 1.389614759f, 0.5310782754f, 0.07638574357f, 0.002902517748f, 1.198370136e-05f, 1.163116581e-09f, 2.197079236e-16f, 1.363510331e-27f, }, + { 1.523283719f, 1.193463026f, 0.7374378484f, 0.3604614185f, 0.1374221077f, 0.03917500549f, 0.007742601026f, 0.0009499468043f, 6.248255924e-05f, 1.826332059e-06f, 1.868728227e-08f, 4.937853878e-11f, 2.28349267e-14f, 1.122753143e-18f, 3.09765397e-24f, 2.112123344e-31f, }, + { 1.558773356f, 1.466014427f, 1.29747575f, 1.081634985f, 0.8501728565f, 0.6304051352f, 0.4408332363f, 0.2902406793f, 0.1793244121f, 0.1034321542f, 0.05528968374f, 0.02713351001f, 0.0120835436f, 0.004816298144f, 0.001690873998f, 0.0005133938241f, 0.0001320523413f, 2.811016433e-05f, 4.823718203e-06f, 6.477756604e-07f, 6.583518513e-08f, 4.876006097e-09f, 2.521634792e-10f, 8.675931415e-12f, 1.880207173e-13f, 2.412423038e-15f, 1.708453277e-17f, 6.168256849e-20f, 1.037679724e-22f, 7.345984103e-26f, 1.949783362e-29f, 1.702438776e-33f, }, + { 1.567781431f, 1.543881116f, 1.497226223f, 1.430008355f, 1.345278885f, 1.246701207f, 1.138272243f, 1.024044933f, 0.9078793792f, 0.7932427008f, 0.6830685163f, 0.5796781031f, 0.4847580912f, 0.3993847415f, 0.3240825396f, 0.2589046395f, 0.2035239989f, 0.1573262035f, 0.1194974113f, 0.08910313924f, 0.06515553343f, 0.04666820805f, 0.03269873273f, 0.02237947106f, 0.0149378351f, 0.009707223739f, 0.006130037632f, 0.003754250977f, 0.002225082706f, 0.001273327945f, 0.0007018595157f, 0.0003716669362f, 0.0001885644298f, 9.139081749e-05f, 4.218318384e-05f, 1.84818136e-05f, 7.659575853e-06f, 2.991661588e-06f, 1.096883513e-06f, 3.759541186e-07f, 1.199244278e-07f, 3.543477717e-08f, 9.649888896e-09f, 2.409177326e-09f, 5.48283578e-10f, 1.130605535e-10f, 2.09893354e-11f, 3.484193767e-12f, 5.134127525e-13f, 6.663992283e-14f, 7.556721776e-15f, 7.420993231e-16f, 6.252804845e-17f, 4.475759507e-18f, 2.693120661e-19f, 1.346994157e-20f, 5.533583499e-22f, 1.843546975e-23f, 4.913936871e-25f, 1.032939131e-26f, 1.686277004e-28f, 2.103305749e-30f, 1.96992098e-32f, 1.359989462e-34f, }, + { 1.570042029f, 1.564021404f, 1.55205317f, 1.534281738f, 1.510919723f, 1.482243298f, 1.448586255f, 1.410332971f, 1.367910512f, 1.321780117f, 1.272428346f, 1.22035811f, 1.16607987f, 1.110103194f, 1.05292888f, 0.995041804f, 0.9369046127f, 0.8789523456f, 0.8215880353f, 0.7651792989f, 0.7100559012f, 0.6565082461f, 0.6047867306f, 0.555101878f, 0.5076251588f, 0.4624903981f, 0.4197956684f, 0.3796055694f, 0.3419537959f, 0.3068459094f, 0.2742622297f, 0.2441607779f, 0.2164802091f, 0.1911426841f, 0.1680566379f, 0.1471194133f, 0.1282197336f, 0.111239999f, 0.09605839187f, 0.08255078811f, 0.07059246991f, 0.06005964236f, 0.05083075757f, 0.04278765216f, 0.0358165056f, 0.02980862812f, 0.02466108731f, 0.02027718382f, 0.01656678625f, 0.01344653661f, 0.01083993717f, 0.00867733075f, 0.006895785969f, 0.005438899798f, 0.004256529599f, 0.003304466994f, 0.002544065768f, 0.001941835776f, 0.00146901436f, 0.001101126113f, 0.0008175410133f, 0.0006010398799f, 0.0004373949562f, 0.0003149720919f, 0.0002243596521f, 0.000158027884f, 0.0001100211285f, 7.568399659e-05f, 5.142149745e-05f, 3.449212476e-05f, 2.283211811e-05f, 1.490851403e-05f, 9.598194128e-06f, 6.089910032e-06f, 3.806198326e-06f, 2.342166721e-06f, 1.418306716e-06f, 8.447375638e-07f, 4.94582887e-07f, 2.844992366e-07f, 1.606939458e-07f, 8.907139514e-08f, 4.84209502e-08f, 2.579956823e-08f, 1.346464552e-08f, 6.878461096e-09f, 3.437185674e-09f, 1.678889768e-09f, 8.009978448e-10f, 3.729950184e-10f, 1.693945779e-10f, 7.496739757e-11f, 3.230446433e-11f, 1.354251291e-11f, 5.518236947e-12f, 2.18359221e-12f, 8.383128961e-13f, 3.119497729e-13f, 1.124020896e-13f, 3.917679451e-14f, 1.319434223e-14f, 4.289196222e-15f, 1.344322288e-15f, 4.057557702e-16f, 1.177981213e-16f, 3.285386163e-17f, 8.791316559e-18f, 2.25407483e-18f, 5.530176913e-19f, 1.296452714e-19f, 2.899964556e-20f, 6.180143249e-21f, 1.252867643e-21f, 2.412250547e-22f, 4.4039067e-23f, 7.610577808e-24f, 1.242805165e-24f, 1.91431069e-25f, 2.776125103e-26f, 3.783124073e-27f, 4.834910155e-28f, 5.783178697e-29f, 6.460575703e-30f, 6.72603739e-31f, 6.511153451e-32f, 5.847409075e-33f, 4.860046055e-34f, 3.72923953e-35f, }, + { 1.570607717f, 1.569099695f, 1.566088239f, 1.561582493f, 1.555596115f, 1.548147191f, 1.539258145f, 1.528955608f, 1.517270275f, 1.504236738f, 1.489893298f, 1.474281762f, 1.457447221f, 1.439437815f, 1.420304486f, 1.400100716f, 1.378882264f, 1.35670689f, 1.333634075f, 1.309724744f, 1.285040985f, 1.259645765f, 1.233602657f, 1.206975567f, 1.179828472f, 1.152225159f, 1.124228984f, 1.09590263f, 1.067307886f, 1.038505436f, 1.00955466f, 0.9805134517f, 0.951438051f, 0.9223828892f, 0.8934004523f, 0.8645411596f, 0.8358532563f, 0.807382723f, 0.7791731997f, 0.7512659245f, 0.723699687f, 0.6965107951f, 0.6697330554f, 0.6433977657f, 0.6175337199f, 0.5921672237f, 0.5673221206f, 0.5430198278f, 0.5192793805f, 0.4961174844f, 0.4735485755f, 0.4515848861f, 0.4302365164f, 0.4095115109f, 0.3894159397f, 0.3699539819f, 0.3511280132f, 0.3329386948f, 0.3153850641f, 0.2984646265f, 0.2821734476f, 0.2665062456f, 0.2514564831f, 0.2370164583f, 0.2231773949f, 0.2099295305f, 0.1972622032f, 0.1851639366f, 0.1736225217f, 0.1626250975f, 0.1521582278f, 0.1422079761f, 0.1327599774f, 0.1237995069f, 0.1153115463f, 0.1072808458f, 0.09969198461f, 0.09252942711f, 0.08577757654f, 0.0794208254f, 0.07344360286f, 0.06783041903f, 0.06256590638f, 0.05763485811f, 0.05302226366f, 0.04871334138f, 0.04469356846f, 0.04094870813f, 0.0374648342f, 0.03422835312f, 0.03122602351f, 0.02844497325f, 0.02587271434f, 0.02349715546f, 0.02130661237f, 0.01928981624f, 0.01743592007f, 0.01573450311f, 0.01417557353f, 0.01274956936f, 0.01144735783f, 0.01026023317f, 0.009179912924f, 0.008198533005f, 0.007308641451f, 0.006503191044f, 0.005775530877f, 0.005119396961f, 0.004528901979f, 0.003998524263f, 0.00352309611f, 0.003097791523f, 0.002718113458f, 0.002379880688f, 0.002079214354f, 0.001812524299f, 0.001576495262f, 0.00136807301f, 0.001184450486f, 0.001023054043f, 0.0008815298242f, 0.0007577303578f, 0.0006497014187f, 0.0005556692074f, 0.000474027894f, 0.0004033275645f, 0.0003422626065f, 0.0002896605611f, 0.0002444714673f, 0.0002057577147f, 0.0001726844199f, 0.0001445103343f, 0.0001205792873f, 0.0001003121646f, 8.319941724e-05f, 6.879409311e-05f, 5.670537985e-05f, 4.659264463e-05f, 3.815995412e-05f, 3.115105568e-05f, 2.534479897e-05f, 2.055097594e-05f, 1.660655598e-05f, 1.337229228e-05f, 1.072967541e-05f, 8.578209354e-06f, 6.832986277e-06f, 5.422535892e-06f, 4.286926494e-06f, 3.376095235e-06f, 2.648386225e-06f, 2.069276126e-06f, 1.610268009e-06f, 1.247935512e-06f, 9.631005212e-07f, 7.401289349e-07f, 5.66330284e-07f, 4.314482559e-07f, 3.272303733e-07f, 2.470662451e-07f, 1.856849137e-07f, 1.3890287e-07f, 1.034152804e-07f, 7.662387397e-08f, 5.649576387e-08f, 4.144823356e-08f, 3.025519646e-08f, 2.197164892e-08f, 1.587297809e-08f, 1.140646555e-08f, 8.152746483e-09f, 5.795349573e-09f, 4.096757914e-09f, 2.879701346e-09f, 2.012621022e-09f, 1.398441431e-09f, 9.659485186e-10f, 6.632086347e-10f, 4.52575761e-10f, 3.069270208e-10f, 2.068420354e-10f, 1.385028753e-10f, 9.214056423e-11f, 6.089338706e-11f, 3.997338952e-11f, 2.60619605e-11f, 1.687451934e-11f, 1.084916183e-11f, 6.925528015e-12f, 4.38886519e-12f, 2.760858767e-12f, 1.723764404e-12f, 1.068075044e-12f, 6.56694435e-13f, 4.00598538e-13f, 2.424296605e-13f, 1.455249916e-13f, 8.663812725e-14f, 5.114974901e-14f, 2.99421776e-14f, 1.737681695e-14f, 9.99642401e-15f, 5.699626666e-15f, 3.220432513e-15f, 1.802958964e-15f, 9.999957344e-16f, 5.493978397e-16f, 2.989420886e-16f, 1.610765424e-16f, 8.593209748e-17f, 4.538246827e-17f, 2.372253167e-17f, 1.227167167e-17f, 6.281229049e-18f, 3.180614714e-18f, 1.593049257e-18f, 7.890855159e-19f, 3.864733103e-19f, 1.87127733e-19f, 8.955739455e-20f, 4.235742852e-20f, 1.979436202e-20f, 9.138078558e-21f, 4.166641158e-21f, 1.876075055e-21f, 8.339901949e-22f, 3.659575236e-22f, 1.584785218e-22f, 6.771575694e-23f, 2.854281708e-23f, 1.186583858e-23f, 4.864069936e-24f, 1.965643419e-24f, 7.829165625e-25f, 3.072789229e-25f, 1.188107615e-25f, 4.524619749e-26f, 1.696710187e-26f, 6.263641003e-27f, 2.275790793e-27f, 8.136077716e-28f, 2.861306549e-28f, 9.896184197e-29f, 3.365200893e-29f, 1.124807055e-29f, 3.694460433e-30f, 1.192093301e-30f, 3.777757876e-31f, 1.175436379e-31f, 3.589879078e-32f, 1.075842686e-32f, 3.162835126e-33f, 9.118674189e-34f, 2.577393168e-34f, 7.139829504e-35f, 1.937828921e-35f, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5f)); + + prune_to_min_complement(min_complement); + +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 6; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0, -0.0486320359272530543, -2.25228075384071351e-05, -4.29416105587824078e-14, -1.16764889750986093e-37, -1.14795299162938991e-101, -1.22565381365848647e-275, }, + { -0.325728507751564174, -0.00248514354277561317, -1.1124335118015332e-08, -5.37849159139368877e-23, -7.9430213192221161e-62, -2.38712281858192662e-167, }, + { 0.377209738164034174, -0.140430941310103365, -0.0129594394926231083, -0.000311735971646790949, -7.95262885287335534e-07, -4.71435518232225751e-11, -5.41522282380723085e-18, -2.04030039435249433e-29, -3.05969013536445003e-48, -2.86219841925875116e-79, -2.00703306915332264e-130, -9.24799327395281672e-215, }, + { 0.194357003324935432, -0.460853294612032231, -0.219392561016799701, -0.0851207367354253891, -0.0260331318043225514, -0.00594449336859785671, -0.000934803544214153575, -9.06153048560001614e-05, -4.68395877947156992e-06, -1.07218387581618094e-07, -8.57294907821677329e-10, -1.76783469283872037e-12, -6.37487849504443965e-16, -2.44293727908521732e-20, -5.25154647301957486e-26, -2.78946716228941774e-33, -1.2781108980938045e-42, -1.3082723368531808e-54, -5.27997812261025438e-70, -9.06191040541810149e-90, -3.79031527880246479e-115, -9.83017699648704421e-148, -1.41780355464723683e-189, -2.67381847626328947e-243, }, + { 0.0979238852878323333, 0.287879932742715915, 0.461253543939585704, -0.389726342499361055, -0.268981965207438489, -0.17668299449359763, -0.110108597215739802, -0.0648391424780153168, -0.0358878357764527081, -0.01854517332266483, -0.00887300755830119777, -0.00389133456249145746, -0.00154579123230226249, -0.000548565564725394158, -0.00017117792712505834, -4.61289943720392527e-05, -1.05179851814963885e-05, -1.98285940456792063e-06, -3.01105847388779655e-07, -3.57609190846577144e-08, -3.2128009016957605e-09, -2.10267137764114881e-10, -9.606066478508465e-12, -2.91902664101751393e-13, -5.58611663883822752e-15, -6.32820713468316824e-17, -3.95646133946764783e-19, -1.26097584471654847e-21, -1.87249217452760828e-24, -1.17003029391311908e-27, -2.74098617835124095e-31, -2.11228272144761198e-35, -4.61722394825950171e-40, -2.42036219762624008e-45, -2.5155618638019452e-51, -4.17863906970219404e-58, -8.6898180082116723e-66, -1.71543577650024789e-74, -2.34930324121953381e-84, -1.56454323889425122e-95, -3.38734020478683648e-108, -1.51081664710078465e-122, -8.27800009567041668e-139, -3.10160298195808184e-157, -4.09173469287244044e-178, -8.9581681449485487e-202, -1.3878968774299745e-228, -5.79257421293503894e-259, }, + { 0.0490559673050778863, 0.146417984290587941, 0.241566319538883658, 0.333142264577638092, 0.419952111278447158, -0.498986610620690898, -0.42441550936484834, -0.356823241014795299, -0.296449994852857984, -0.243306091366270051, -0.197201258656758734, -0.157780753649243136, -0.124564602369591322, -0.0969867184864261294, -0.0744313659313873335, -0.0562652139472428431, -0.0418639772897863099, -0.0306332671030826648, -0.022023764813335027, -0.0155411688325691691, -0.010751568909866104, -0.00728300280317271462, -0.00482397384467264574, -0.00311968187180812628, -0.00196666368456624598, -0.00120646570119410071, -0.000718888078208044591, -0.000415249648482412683, -0.000232028400439164939, -0.000125134951219653515, -6.49800749175763138e-05, -3.24069320565402357e-05, -1.5480097729175578e-05, -7.06212333711435226e-06, -3.06755080964249425e-06, -1.26452813409045827e-06, -4.92994280563111161e-07, -1.81106287232991369e-07, -6.24459216262249756e-08, -2.01254967982457957e-08, -6.03586579835227638e-09, -1.67663805174219429e-09, -4.29212227386388064e-10, -1.00722276743730848e-10, -2.15446625890420237e-11, -4.1753931241965133e-12, -7.28473726428773404e-13, -1.13638698543921915e-13, -1.57355350979265302e-14, -1.91921890971076214e-15, -2.04495954084673556e-16, -1.88695830672934097e-17, -1.4938716488357229e-18, -1.00469381000375765e-19, -5.6799291780731967e-21, -2.66910395261351514e-22, -1.03017813818941147e-23, -3.22448487639124621e-25, -8.07478290042168868e-27, -1.59465460199328555e-28, -2.44572397527528259e-30, -2.86591977190786557e-32, -2.52168252518289941e-34, -1.63551444031007274e-36, -7.66665909906783572e-39, -2.54357712881376935e-41, -5.84094722807164823e-44, -9.06586956479397026e-47, -9.27356981605885259e-50, -6.08571480420522776e-53, -2.48980897367221466e-56, -6.15986208631705443e-60, -8.92141270722267119e-64, -7.30722432600404514e-68, -3.26256086255138585e-72, -7.6357851449836225e-77, -8.9855174690288197e-82, -5.085871851548729e-87, -1.3207396001984761e-92, -1.49648649356105213e-98, -7.01292336693108804e-105, -1.2839990161964175e-111, -8.64456838410520022e-119, -2.00636948968315553e-126, -1.49877407961844478e-134, -3.34937621495896108e-143, -2.07152943814344815e-152, -3.26388325933199651e-162, -1.19947375988972346e-172, -9.36020855840271015e-184, -1.40350944280078664e-195, -3.63561076394912477e-208, -1.45274399574122646e-221, -7.93772358209223086e-236, -5.21635362297544998e-251, -3.59647437525778163e-267, }, + { 0.0245397635746491604, 0.0735251229856712945, 0.122229122201557642, 0.170467972382010518, 0.218063473469712005, 0.26484507658344795, 0.310651780552845961, 0.355333825165074533, 0.398754150467237756, 0.440789599033900866, 0.481331846116905044, -0.47971194930876984, -0.442418771739221769, -0.406849646408046841, -0.373049791948957121, -0.341049008256649876, -0.310862274938332328, -0.282490532512675873, -0.255921616452652601, -0.231131313231753415, -0.208084507623857886, -0.186736391497026148, -0.167033706080589124, -0.148915992012151267, -0.132316824224354013, -0.117165011755331045, -0.103385745719923974, -0.0909016818369795649, -0.0796339469680471977, -0.0695030620028465937, -0.0604297760667252446, -0.0523358093848469027, -0.0451445041949773146, -0.0387813848488835925, -0.0331746296876441472, -0.0282554584345126911, -0.0239584397434232607, -0.0202217241993842374, -0.0169872085188988944, -0.014200636974716564, -0.0118116461992573576, -0.00977375953247225306, -0.00804433699732238438, -0.006584486830735961, -0.00535894428748880328, -0.00433592318304683035, -0.00348694535974622683, -0.00278665295653129776, -0.00221260804109346917, -0.00174508382800370656, -0.00136685135932252238, -0.00106296516648782627, -0.000820551065114082842, -0.000628598859062313104, -0.000477762348782795776, -0.00036016865439963481, -0.00026923848019151737, -0.000199518568861613698, -0.000146527226888588285, -0.000106613452407435744, -7.68298707106713057e-05, -5.48193855413069104e-05, -3.87151921433338684e-05, -2.70535747677634357e-05, -1.86987298792732083e-05, -1.27787179993718896e-05, -8.63155165512655592e-06, -5.76037238336521799e-06, -3.79665283382324692e-06, -2.47037619483206967e-06, -1.5861890352645758e-06, -1.00458931003037651e-06, -6.27292664630529592e-07, -3.86011449757251023e-07, -2.33976667566879521e-07, -1.39628785400592289e-07, -8.19952052894377486e-08, -4.7357335538151974e-08, -2.68867640563769168e-08, -1.49969236882666325e-08, -8.21354390092801904e-09, -4.4143663841612464e-09, -2.32676326210046123e-09, -1.20201649960114077e-09, -6.08223124167786151e-10, -3.01245630748323226e-10, -1.45943884500128571e-10, -6.91116049852310787e-11, -3.19667832644453697e-11, -1.44312099240426525e-11, -6.35367612849118143e-12, -2.72595051887251972e-12, -1.13873457224078497e-12, -4.62773462176931343e-13, -1.82799022484311048e-13, -7.01204673849056861e-14, -2.60960536613795464e-14, -9.41336133528885558e-15, -3.28792569493649342e-15, -1.11086294018218984e-15, -3.6266022642032122e-16, -1.14278765250526699e-16, -3.47190226924949368e-17, -1.01578190683051246e-17, -2.85853282450814817e-18, -7.72783478738925526e-19, -2.00442399221751722e-19, -4.98156837646991149e-20, -1.18466849242234024e-20, -2.69198490361039057e-21, -5.83666744193394141e-22, -1.20566158865487235e-22, -2.36910935080780677e-23, -4.42133946172800178e-24, -7.82383500410868582e-25, -1.31053314412547815e-25, -2.07434501307351507e-26, -3.09696832555074958e-27, -4.35320052819675598e-28, -5.74995566807039229e-29, -7.12271592663817274e-30, -8.25783542035580458e-31, -8.94154100662495554e-32, -9.02279665003086697e-33, -8.46603011953159718e-34, -7.36927280656452982e-35, -5.93663235600887498e-36, -4.41527783869469595e-37, -3.02396013586353149e-38, -1.90220379165770488e-39, -1.09604332860345779e-40, -5.76869559800406948e-42, -2.76539938173771022e-43, -1.20387095285625741e-44, -4.74476232533549872e-46, -1.68767912810533091e-47, -5.39996699829972848e-49, -1.54902404944808261e-50, -3.96994725525613498e-52, -9.05767492652393586e-54, -1.83295043348369314e-55, -3.27742233239736439e-57, -5.15768715308393636e-59, -7.114715221408198e-61, -8.56688901712102493e-63, -8.96555855421136186e-65, -8.11869379690547438e-67, -6.33219388590773392e-69, -4.23372634246032809e-71, -2.41472604643767902e-73, -1.16895559109482145e-75, -4.77806689855264461e-78, -1.6402035716952159e-80, -4.70248914876421051e-83, -1.11959046700779807e-85, -2.2005433507330025e-88, -3.54892402406326365e-91, -4.66694093688365186e-94, -4.97190667459303363e-97, -4.26251200323736193e-100, -2.92055254102694012e-103, -1.58792835205206735e-106, -6.80103287742115697e-110, -2.2772324163917692e-113, -5.91472228162959818e-117, -1.18209982177688408e-120, -1.80282622739513989e-124, -2.08020413351101242e-128, -1.79996701563969356e-132, -1.15734196606825454e-136, -5.477766654144099e-141, -1.8900190812332373e-145, -4.70643183557466755e-150, -8.37112913643764166e-155, -1.05221390088176585e-159, -9.2441193400981258e-165, -5.61216501813263789e-170, -2.32703984243702941e-175, -6.5107211867430156e-181, -1.2138997008699256e-186, -1.48891299935269587e-192, -1.18553781867001071e-198, -6.04455846579323287e-205, -1.94567931886735567e-211, -3.8966805747095114e-218, -4.78292200095461437e-225, -3.54255959173241182e-232, -1.55812601911741406e-239, -4.00280716389675087e-247, -5.90460003827621713e-255, -4.91396180352002352e-263, -2.26567446980557423e-271, }, + { 0.012271355118082202, 0.036802280950025085, 0.0612978894136599758, 0.0857347548776510558, 0.110089629932628013, 0.134339515287672237, 0.158461728289299504, 0.18243396969028915, 0.206234388311028769, 0.229841643254360754, 0.253234963356000236, 0.276394203576178614, 0.299299898063960473, 0.321933309653369166, 0.344276475579704919, 0.366312249234904082, 0.388024337812117748, 0.409397335721529489, 0.430416753691437064, 0.451069043500451995, 0.471341618317998466, 0.491222868660811487, -0.489297825997441858, -0.470230089898225442, -0.451582547860207645, -0.433362826214981142, -0.415577557677336058, -0.398232389990366541, -0.381331998167271939, -0.364880100135578164, -0.34887947557569577, -0.333331987734262319, -0.318238607983572687, -0.303599442891540793, -0.289413763561994213, -0.27568003700259252, -0.262395959277174755, -0.249558490200759565, -0.237163889338607631, -0.22520775307556463, -0.213685052528180394, -0.202590172079687753, -0.191916948326661462, -0.181658709235902172, -0.171808313320642901, -0.162358188656399975, -0.153300371568536304, -0.144626544835728469, -0.136328075265894765, -0.128396050513622281, -0.12082131502061063, -0.113594504973021298, -0.106706082181789018, -0.100146366803829869, -0.0939055688335957994, -0.0879738183055131808, -0.0823411941584506602, -0.0769977517234455965, -0.0719335488054448738, -0.0671386703387599459, -0.0626032516042808619, -0.0583175000042306645, -0.0542717153973677599, -0.0504563090040636404, -0.0468618208966061973, -0.0434789360954190696, -0.0402984992966633908, -0.03731152826092173, -0.0345092258963795269, -0.0318829910731436838, -0.0294244282080995797, -0.0271253556620361184, -0.0249778129926936505, -0.0229740671089420425, -0.0211066173725059709, -0.019368199694551295, -0.0177517896750589349, -0.0162506048332687547, -0.0148581059776019712, -0.0135679977633915537, -0.0123742284864893156, -0.0112709891603976381, -0.0102527119240129037, -0.00931406782638492783, -0.00844996403410826525, -0.00765554050608182456, -0.00692616617941556874, -0.00625743470923838919, -0.00564515980407910996, -0.0050853701973611284, -0.00457430429437719331, -0.00410840453289979854, -0.00368431149433907478, -0.00329885780108739487, -0.00294906183439087047, -0.00263212130576456563, -0.0023454067136221407, -0.00208645471542297342, -0.0018529614442515744, -0.00164277579733623578, -0.00145389272258728331, -0.00128444652779115701, -0.0011327042356361947, -0.000997059006271141487, -0.000876023647610171022, -0.000768224232101148019, -0.00067239383717004608, -0.000587366425047420931, -0.000512070876176692876, -0.0004455251889032602, -0.00038683085665314189, -0.00033516743233532264, -0.000289787288248965581, -0.000250010578351141274, -0.000215220408348834122, -0.000184858217726938954, -0.000158419376517931266, -0.000135448998364931342, -0.000115537970233795639, -9.83191979971305535e-05, -8.3464066048770978e-05, -7.06791081158112189e-05, -5.97028855206253867e-05, -5.03030683106995953e-05, -4.22737139220181204e-05, -3.54327373739233618e-05, -2.96195664107243162e-05, -2.46929745079623587e-05, -2.05290842484436199e-05, -1.7019533243403755e-05, -1.40697945252075011e-05, -1.1597643166806137e-05, -9.53176078612253345e-06, -7.8104695663539219e-06, -6.38058746110851941e-06, -5.19639635112362769e-06, -4.21871507150727724e-06, -3.41406942921033546e-06, -2.75395157382161437e-06, -2.21416136477003485e-06, -1.77422268862384164e-06, -1.41686801551279912e-06, -1.12758483806512337e-06, -8.94218004200267166e-07, -7.066223315196142e-07, -5.56360271123123226e-07, -4.36439768090839962e-07, -3.41087840680835234e-07, -2.65555767043837624e-07, -2.0595212394180991e-07, -1.59100264054130123e-07, -1.22417144893368773e-07, -9.38107315112986677e-08, -7.15934858568207488e-08, -5.44097270488153164e-08, -4.11748985097450346e-08, -3.10250097588474058e-08, -2.32747328650517169e-08, -1.7382826537542006e-08, -1.29237352250289432e-08, -9.5643672141012476e-09, -7.04519550806302257e-09, -5.1649492757248395e-09, -3.76827299743367321e-09, -2.73582625416470426e-09, -1.97638056812945901e-09, -1.42054196354815056e-09, -1.01579009878587221e-09, -7.22578006796989773e-10, -5.11281694668026368e-10, -3.59827055120401645e-10, -2.51853622445542102e-10, -1.75301477503092556e-10, -1.21329810513247054e-10, -8.34939507523206686e-11, -5.71226602674819584e-11, -3.88496860027937659e-11, -2.62634273799497214e-11, -1.76464997763789762e-11, -1.17832983201206309e-11, -7.81868062832536264e-12, -5.15483640427513504e-12, -3.37650146080002947e-12, -2.19707446995923426e-12, -1.42004736695181269e-12, -9.11580079335777287e-13, -5.81130625055868083e-13, -3.6786791102075634e-13, -2.31206890357644477e-13, -1.44261724859223088e-13, -8.93496666512989392e-14, -5.49256777212567905e-14, -3.35078830951587706e-14, -2.02840764024440399e-14, -1.21827951289796445e-14, -7.25885373620523418e-15, -4.29006278660366691e-15, -2.51465253948077134e-15, -1.46168711284753358e-15, -8.42433095837469831e-16, -4.81351759040153145e-16, -2.7263179430684055e-16, -1.53044229739659322e-16, -8.5137857250384434e-17, -4.69279503896114271e-17, -2.56259759503200895e-17, -1.38613346679503967e-17, -7.42575019213846423e-18, -3.93930940244456018e-18, -2.06907914597742282e-18, -1.07582862164931383e-18, -5.53667101730119995e-19, -2.81983400378589843e-19, -1.42100637503135938e-19, -7.08424387814173802e-20, -3.49335055730950445e-20, -1.70359775108200994e-20, -8.21470604421218778e-21, -3.91597343841569897e-21, -1.84514981562718714e-21, -8.59187458062354013e-22, -3.95300695770657649e-22, -1.79666979951342614e-22, -8.06540882083892199e-23, -3.57533721226205606e-23, -1.5647821323387364e-23, -6.76004176421736964e-24, -2.88213632330255471e-24, -1.21243623290624178e-24, -5.03142183078805999e-25, -2.05928631224500678e-25, -8.31078779763998548e-26, -3.30651806761459413e-26, -1.29659734624673994e-26, -5.01009103239855231e-27, -1.90717938473556322e-27, -7.15056733398109736e-28, -2.63990603736826823e-28, -9.59466454215915903e-29, -3.43207809913106496e-29, -1.20798506630670813e-29, -4.18246472148817528e-30, -1.42415370668448176e-30, -4.76783338169881336e-31, -1.56894917819580623e-31, -5.07343885484964435e-32, -1.61169191609392457e-32, -5.02835669425437807e-33, -1.54032043714714164e-33, -4.63139244348179017e-34, -1.36647022505741948e-34, -3.95500852699898458e-35, -1.12259182536440082e-35, -3.12384874336168341e-36, -8.51954024720649026e-37, -2.27647348137758297e-37, -5.95784738583498423e-38, -1.5267023004586064e-38, -3.82924523738836913e-39, -9.39764841233127425e-40, -2.25591870233912475e-40, -5.29510577400702735e-41, -1.21484005139195805e-41, -2.72333290575638595e-42, -5.96294747245500166e-43, -1.27479045632084017e-43, -2.65993246477400726e-44, -5.41489757055003388e-45, -1.07505067837929222e-45, -2.0807277332937164e-46, -3.9244163140436388e-47, -7.20993781004693903e-48, -1.28974823309181237e-48, -2.24549897001720529e-49, -3.80338177519323738e-50, -6.2645207667921989e-51, -1.00294108349246457e-51, -1.5600495091009387e-52, -2.35656502929127819e-53, -3.45539861530099585e-54, -4.91576367443963002e-55, -6.78189690060837789e-56, -9.06919402024436437e-57, -1.17497924435643381e-57, -1.47407303120625938e-58, -1.78984329859422798e-59, -2.1022998433631042e-60, -2.3874311701754331e-61, -2.61994971132693976e-62, -2.77681312539698556e-63, -2.84088709628858008e-64, -2.80396888834653826e-65, -2.66844816022605403e-66, -2.44715408087085735e-67, -2.16136193986109549e-68, -1.83738434241422263e-69, -1.50251039384538056e-70, -1.18117553050091616e-71, -8.92115779194300367e-73, -6.469398720148732e-74, -4.50157318845664738e-75, -3.00358422099143309e-76, -1.92045159974146096e-77, -1.17588108496782645e-78, -6.89007215715517382e-80, -3.86085633874422728e-81, -2.06746164750454894e-82, -1.05724310335546675e-83, -5.159178839138868e-85, -2.40068073513892583e-86, -1.06441521301761484e-87, -4.49345292323654518e-89, -1.80470487227992129e-90, -6.89045955067325497e-92, -2.49896371014878691e-93, -8.60180884698632756e-95, -2.8078924862967821e-96, -8.68498675197961289e-98, -2.54323961092475611e-99, -7.04466689786197244e-101, -1.84420182558676709e-102, -4.55874167252535593e-104, -1.06310885552045921e-105, -2.33672817489640356e-107, -4.83650426311308612e-109, -9.41752356208775621e-111, -1.72347894616941773e-112, -2.96152337973418694e-114, -4.77346095185853133e-116, -7.20979528228986404e-118, -1.0193874335777637e-119, -1.34781669991634323e-121, -1.66471130073245645e-123, -1.91865839504763309e-125, -2.06126480152885691e-127, -2.06189537886634895e-129, -1.91826195552363599e-131, -1.65791287785192226e-133, -1.32960990700944959e-135, -9.8828871549374804e-138, -6.80018519366801829e-140, -4.32620427633799334e-142, -2.54159552852297217e-144, -1.37712796594958211e-146, -6.87317396243845786e-149, -3.15568448417183025e-151, -1.33110460150070095e-153, -5.15149580050109184e-156, -1.82670376280564422e-158, -5.92677285398580171e-161, -1.75701790578206368e-163, -4.75252736446443541e-166, -1.17121511806343118e-168, -2.62588387222030548e-171, -5.34803615842019053e-174, -9.87952606199786798e-177, -1.65285015577763281e-179, -2.50039475650869583e-182, -3.41485961919321622e-185, -4.20365360545913323e-188, -4.65650825702166728e-191, -4.63395309965355254e-194, -4.13587819260496962e-197, -3.30494472949500722e-200, -2.36039562085899995e-203, -1.5040470140688354e-206, -8.53520219585080464e-210, -4.3057568200632215e-213, -1.92736281851211248e-216, -7.64078684884150441e-220, -2.6775820096831777e-223, -8.27816250430073493e-227, -2.2534850368391124e-230, -5.39056859020767355e-234, -1.13080972768156503e-237, -2.07597218137054105e-241, -3.32826876045839753e-245, -4.65000671354536966e-249, -5.64918736922395969e-253, -5.95469666263319233e-257, -5.43379904255349279e-261, -4.28283635376386341e-265, -2.90898542515205486e-269, -1.69869798350729535e-273, }, + }; + m_weights = { + { 1.57079632679489662, 0.230022394514788685, 0.000266200513752716909, 1.35817842745390908e-12, 1.0017416784066253e-35, 2.6763080920617461e-99, 7.76707068863340629e-273, }, + { 0.965976579412301148, 0.0183431669899278421, 2.14312045569430394e-07, 2.80031510197758896e-21, 1.12327053454869188e-59, 9.17532687500178413e-165, }, + { 1.38961475924725632, 0.531078275428053975, 0.0763857435708323042, 0.00290251774790131359, 1.198370136317072e-05, 1.16311658142557828e-09, 2.19707923629797992e-16, 1.36351033076376154e-27, 3.3700568540419265e-46, 5.19697838008985521e-77, 6.00803417057135015e-128, 4.5642040563555991e-212, }, + { 1.52328371863470521, 1.19346302584915696, 0.737437848361547841, 0.360461418469343674, 0.137422107733167723, 0.0391750054936007791, 0.00774260102606424071, 0.000949946804283468717, 6.24825592407440829e-05, 1.82633205937106597e-06, 1.86872822687364101e-08, 4.9378538776631927e-11, 2.2834926702613954e-14, 1.12275314281815515e-18, 3.09765397011735437e-24, 2.11212334353722559e-31, 1.24241475706160524e-40, 1.63277073317994932e-52, 8.4606887310962138e-68, 1.86444920795886503e-87, 1.00131284686664302e-112, 3.33444354118689902e-145, 6.17515762254877653e-187, 1.49532400222570759e-240, }, + { 1.55877335553333015, 1.46601442671696578, 1.297475750424978, 1.08163498549007041, 0.850172856456620069, 0.630405135164743691, 0.440833236273858237, 0.290240679312454185, 0.179324412110728293, 0.103432154223332901, 0.0552896837422405838, 0.0271335100137120032, 0.0120835435991579535, 0.00481629814392846302, 0.00169087399814263965, 0.00051339382406790336, 0.000132052341256099749, 2.81101643279401347e-05, 4.82371820326155021e-06, 6.47775660359297199e-07, 6.58351851271833967e-08, 4.87600609742406259e-09, 2.52163479185301486e-10, 8.67593141497960465e-12, 1.88020717307506498e-13, 2.41242303843087864e-15, 1.70845327724057017e-17, 6.16825684907623826e-20, 1.03767972385287062e-22, 7.34598410322269356e-26, 1.94978336243351748e-29, 1.70243877612575472e-33, 4.21648637094842789e-38, 2.50442771162752843e-43, 2.94936014574619331e-49, 5.55133235696537106e-56, 1.30811651202108216e-63, 2.92608244638239753e-72, 4.54077346699978241e-82, 3.42656356920869877e-93, 8.406435948883177e-106, 4.24861926881986944e-120, 2.63782082635045215e-136, 1.11992914558412798e-154, 1.67415937867108893e-175, 4.15330608101949222e-199, 7.29151266090566043e-226, 3.44840283588682197e-256, }, + { 1.56778143130722186, 1.54388111617695922, 1.49722622254103629, 1.43000835487229967, 1.34527888476625166, 1.2467012074518577, 1.13827224337630537, 1.02404493311181145, 0.907879379154895317, 0.793242700820516718, 0.683068516344263755, 0.579678103087787647, 0.484758091214755393, 0.399384741525717135, 0.324082539611528904, 0.258904639514053516, 0.203523998858601745, 0.15732620348436615, 0.119497411288695924, 0.0891031392409414628, 0.065155533432536205, 0.0466682080548466136, 0.0326987327266090311, 0.0223794710636484765, 0.0149378350960501297, 0.00970722373939168927, 0.00613003763208303013, 0.0037542509774318343, 0.0022250827064786427, 0.0012733279447082382, 0.000701859515684242271, 0.000371666936216777603, 0.000188564429767003186, 9.13908174907101227e-05, 4.21831838417576006e-05, 1.84818135998792171e-05, 7.65957585252031626e-06, 2.99166158781387871e-06, 1.09688351259012647e-06, 3.75954118623606301e-07, 1.19924427829027702e-07, 3.5434777171421953e-08, 9.64988889610896336e-09, 2.40917732564759408e-09, 5.48283577970949776e-10, 1.13060553474946805e-10, 2.09893354045114691e-11, 3.48419376702610597e-12, 5.13412752450142075e-13, 6.66399228330876532e-14, 7.55672177578056519e-15, 7.42099323099221676e-16, 6.25280484461045536e-17, 4.47575950666909697e-18, 2.69312066148696951e-19, 1.34699415695422861e-20, 5.53358349941557115e-22, 1.84354697471814938e-23, 4.91393687126490401e-25, 1.03293913069285754e-26, 1.68627700384926065e-28, 2.10330574900180895e-30, 1.96992097962323433e-32, 1.35998946163037957e-34, 6.78597883755924791e-37, 2.39650636994432174e-39, 5.85795694830842108e-42, 9.67839277557170956e-45, 1.05383611325642088e-47, 7.36158583097876492e-51, 3.20597853528338661e-54, 8.44308926618642561e-58, 1.3016694874428173e-61, 1.13489850483720466e-65, 5.39388136951158084e-70, 1.3438019476233711e-74, 1.68330959366332403e-79, 1.01420590744681585e-84, 2.80361361934498745e-90, 3.38153878938366947e-96, 1.68686995979731349e-102, 3.28767160546365504e-109, 2.35618039758663049e-116, 5.82127142688641827e-124, 4.62897694169420155e-132, 1.10117124175309668e-140, 7.2497708296024464e-150, 1.2159344493950079e-159, 4.75673322877850563e-170, 3.95135613192899529e-181, 6.3069398037899023e-193, 1.73909581157725484e-205, 7.39738244904451982e-219, 4.3025693007354699e-233, 3.00982956958324877e-248, 2.20899573159075297e-264, }, + { 1.57004202927959315, 1.5640214037732321, 1.55205316984541212, 1.53428173815430343, 1.51091972307416971, 1.48224329788553807, 1.44858625496132259, 1.41033297144625901, 1.36791051168089649, 1.32178011744377286, 1.27242834553786271, 1.22035810957935822, 1.16607986993243458, 1.11010319396534038, 1.05292887995526666, 0.995041804046132715, 0.936904612745667934, 0.87895234555278212, 0.821588035266964703, 0.765179298908956137, 0.710055901205468984, 0.656508246131627531, 0.604786730578403622, 0.55510187800363351, 0.5076251588319081, 0.462490398055367761, 0.419795668445015481, 0.37960556938665161, 0.341953795923016832, 0.306845909417916949, 0.274262229689068106, 0.244160777869839909, 0.21648020911729617, 0.191142684133427495, 0.168056637948269162, 0.147119413257856932, 0.128219733631200987, 0.11123999898874453, 0.0960583918651894678, 0.0825507881107017377, 0.0705924699068669994, 0.0600596423586363003, 0.0508307575725704711, 0.042787652157725676, 0.0358165056041964365, 0.029808628117310127, 0.0246610873147532825, 0.0202771838175001239, 0.0165667862542475754, 0.0134465366052857307, 0.0108399371682559072, 0.00867733074953918159, 0.00689578596906600353, 0.00543889979762399843, 0.00425652959901785802, 0.00330446699403483024, 0.00254406576752917297, 0.00194183577598436758, 0.00146901435994297911, 0.00110112611345193839, 0.000817541013324694931, 0.000601039879911474226, 0.000437394956159116878, 0.000314972091860212003, 0.000224359652050085491, 0.000158027884007011919, 0.000110021128466666972, 7.56839965862014778e-05, 5.14214974476588021e-05, 3.44921247593431977e-05, 2.28321181090361466e-05, 1.49085140318706084e-05, 9.59819412837847108e-06, 6.08991003209490393e-06, 3.8061983264644899e-06, 2.34216672085280968e-06, 1.41830671554939175e-06, 8.44737563848598635e-07, 4.94582887027541985e-07, 2.84499236591598063e-07, 1.60693945790762249e-07, 8.90713951402423871e-08, 4.84209501980723697e-08, 2.57995682295358924e-08, 1.34646455223020388e-08, 6.87846109558990011e-09, 3.43718567446500905e-09, 1.67888976821619068e-09, 8.00997844797296654e-10, 3.729950184305279e-10, 1.69394577894116469e-10, 7.49673975738182245e-11, 3.23044643332523658e-11, 1.35425129123362744e-11, 5.51823694681748858e-12, 2.18359220992336091e-12, 8.38312896050266709e-13, 3.11949772868480812e-13, 1.12402089599228615e-13, 3.91767945060164679e-14, 1.31943422319679894e-14, 4.289196222067908e-15, 1.34432228753952215e-15, 4.05755770226285762e-16, 1.17798121272483481e-16, 3.28538616288470066e-17, 8.79131655891989009e-18, 2.25407483043688194e-18, 5.53017691284033759e-19, 1.29645271406893694e-19, 2.89996455643157199e-20, 6.18014324933998845e-21, 1.25286764322732104e-21, 2.41225054683610101e-22, 4.40390669993986809e-23, 7.61057780758206258e-24, 1.24280516521231649e-24, 1.91431069022397607e-25, 2.77612510258505832e-26, 3.78312407281377971e-27, 4.83491015481884767e-28, 5.78317869722905296e-29, 6.46057570344172199e-30, 6.72603738958794054e-31, 6.51115345113745165e-32, 5.84740907454810199e-33, 4.86004605514227334e-34, 3.72923952984360242e-35, 2.63512306168036669e-36, 1.71019264014906972e-37, 1.01666853095521272e-38, 5.52069094434276257e-40, 2.73047551166050082e-41, 1.22638096665251285e-42, 4.98683929835361257e-44, 1.8300654157711633e-45, 6.04135032250826404e-47, 1.78800030852571268e-48, 4.72782066352906336e-50, 1.1129101718049772e-51, 2.32360072879360546e-53, 4.28657921354384008e-55, 6.95987352255375155e-57, 9.90539981286746442e-59, 1.23056903223701726e-60, 1.32870554636824381e-62, 1.24138446090017621e-64, 9.9894889830989163e-67, 6.89097928902098062e-69, 4.05504128376793915e-71, 2.02532547805183379e-73, 8.54119386081712901e-76, 3.02505849584780752e-78, 8.94815749837378473e-81, 2.19803659571925209e-83, 4.45733908425182132e-86, 7.41673167121007253e-89, 1.00627894464704291e-91, 1.10606170248612031e-94, 9.78345817231037531e-98, 6.91611604032706014e-101, 3.87970491925780374e-104, 1.71440443580946886e-107, 5.92265513981439625e-111, 1.58713616826240749e-114, 3.2726893534998181e-118, 5.14962203948078777e-122, 6.13053461759876059e-126, 5.47303084654380852e-130, 3.63074753096835834e-134, 1.77300075376963467e-138, 6.31164645321273548e-143, 1.62158369391922019e-147, 2.97579351328298596e-152, 3.85917057654421516e-157, 3.49805556185897821e-162, 2.19110324175719591e-167, 9.37362347961089205e-173, 2.70585229333265743e-178, 5.20510049827160481e-184, 6.58698972266196046e-190, 5.41133533489527735e-196, 2.84659058487511908e-202, 9.45372790667779433e-209, 1.95343097467687228e-215, 2.47381948587608999e-222, 1.89044188887636326e-229, 8.57867513484860174e-237, 2.27380804498007095e-244, 3.46059771526558578e-252, 2.97141917521293704e-260, 1.41351747260411324e-268, }, + { 1.57060771653827522, 1.56909969535166913, 1.56608823891746137, 1.56158249349181062, 1.55559611463166042, 1.54814719123555733, 1.53925814531188183, 1.52895560835458072, 1.51727027540505468, 1.50423673806367721, 1.48989329788329712, 1.47428176172807973, 1.45744722081254867, 1.43943781524640698, 1.42030448599969118, 1.40010071626944465, 1.37888226427313752, 1.35670688951560547, 1.33363407457575614, 1.30972474443743974, 1.28504098534672723, 1.2596457651166706, 1.23360265672194671, 1.20697556693130823, 1.17982847161733374, 1.15222515926254743, 1.12422898405060326, 1.09590262979297221, 1.06730788579750387, 1.03850543563739233, 1.00955465962942982, 0.980513451680855025, 0.951438051016352709, 0.922382889152455146, 0.893400452347195998, 0.864541159619668999, 0.835853256308267131, 0.807382723018763038, 0.779173199704797981, 0.751265924524356859, 0.723699687026830293, 0.696510795146546885, 0.669733055410290998, 0.643397765708252856, 0.6175337199299089, 0.592167223728206949, 0.567322120646738718, 0.543019827824842867, 0.519279380484246331, 0.496117484397316214, 0.473548575540614005, 0.451584886147544914, 0.430236516389788978, 0.409511510938193634, 0.389415939679212028, 0.369953981892113872, 0.351128013224425247, 0.332938694837747795, 0.315385064132678135, 0.298464626499444984, 0.282173447579596105, 0.266506245563135161, 0.251456483084510398, 0.237016458319418989, 0.223177394922184588, 0.209929530480207537, 0.197262203197437199, 0.185163936552775515, 0.173622521711631303, 0.162625097499384324, 0.15215822777419972, 0.142207976063401831, 0.132759977352445526, 0.123799506938412961, 0.115311546280937337, 0.107280845802556434, 0.0996919846077885777, 0.0925294271057784639, 0.0857775765352681898, 0.0794208254030081551, 0.0734436028576387748, 0.0678304190306579665, 0.0625659063844551083, 0.057634858114654727, 0.0530222636602871787, 0.0487133413807014315, 0.0446935684627655335, 0.0409487081258673025, 0.0374648341956289728, 0.0342283531201756966, 0.0312260235053317411, 0.0284449732473342374, 0.0258727143436176445, 0.0234971554639885273, 0.0213066123661260705, 0.0192898162408456015, 0.0174359200739774613, 0.0157345031130597965, 0.0141755735283304602, 0.0127495693587311627, 0.0114473578347997563, 0.0102602331714107689, 0.00917991292431090168, 0.00819853300526119991, 0.00730864145131324803, 0.00650319104428257946, 0.00577553087680654914, 0.00511939696145378187, 0.00452890197915628912, 0.00399852426273353105, 0.00352309611044298632, 0.00309779152330082066, 0.00271811345835022642, 0.00237988068810043825, 0.00207921435400866615, 0.00181252429912886427, 0.00157649526191055605, 0.00136807300960970396, 0.00118445048589027722, 0.00102305404297454109, 0.000881529824172970023, 0.000757730357827359211, 0.000649701418674290374, 0.000555669207425785582, 0.000474027894018167196, 0.000403327564549540929, 0.000342262606462976881, 0.000289660561088771743, 0.000244471467286891624, 0.000205757714679988186, 0.000172684419885929228, 0.000144510334290945865, 0.000120579287290569961, 0.000100312164601124202, 8.31994172400364807e-05, 6.8794093113496377e-05, 5.67053798539328775e-05, 4.65926446304946187e-05, 3.81599541202457603e-05, 3.11510556774483529e-05, 2.534479896885011e-05, 2.05509759449342446e-05, 1.66065559765083359e-05, 1.33722922845323726e-05, 1.07296754068523407e-05, 8.57820935370790825e-06, 6.83298627742185068e-06, 5.42253589182403319e-06, 4.28692649399982268e-06, 3.37609523480551097e-06, 2.64838622540434106e-06, 2.06927612573646709e-06, 1.61026800945076506e-06, 1.24793551211774519e-06, 9.63100521176592526e-07, 7.40128934909086142e-07, 5.66330284020507752e-07, 4.31448255871653806e-07, 3.27230373305175589e-07, 2.47066245112497007e-07, 1.85684913700251324e-07, 1.3890286996035953e-07, 1.03415280407456071e-07, 7.66238739748175847e-08, 5.64957638716706215e-08, 4.14482335585053839e-08, 3.02551964648994672e-08, 2.19716489170893499e-08, 1.58729780909682326e-08, 1.14064655548504821e-08, 8.15274648285765377e-09, 5.79534957309660641e-09, 4.0967579139685198e-09, 2.87970134644711047e-09, 2.01262102188671729e-09, 1.3984414312565442e-09, 9.65948518580993005e-10, 6.63208634701620998e-10, 4.5257576104153822e-10, 3.06927020787233287e-10, 2.06842035390292175e-10, 1.38502875258341451e-10, 9.21405642265188841e-11, 6.08933870643806705e-11, 3.99733895199302696e-11, 2.60619605028052933e-11, 1.68745193439150252e-11, 1.08491618343371201e-11, 6.92552801526813823e-12, 4.3888651899779304e-12, 2.76085876713982836e-12, 1.72376440360427176e-12, 1.06807504365414595e-12, 6.56694434965737702e-13, 4.00598537995324327e-13, 2.42429660454424091e-13, 1.45524991577718379e-13, 8.66381272543578617e-14, 5.11497490112370359e-14, 2.99421775950314841e-14, 1.73768169460742936e-14, 9.99642400989942931e-15, 5.69962666605779177e-15, 3.22043251327094293e-15, 1.80295896389489942e-15, 9.9999573441511328e-16, 5.49397839735005513e-16, 2.98942088568360808e-16, 1.6107654243893339e-16, 8.59320974827080203e-17, 4.53824682671384867e-17, 2.37225316709140862e-17, 1.22716716699576843e-17, 6.28122904855397546e-18, 3.18061471372875766e-18, 1.59304925747919683e-18, 7.89085515934558414e-19, 3.86473310301407342e-19, 1.87127732997090861e-19, 8.95573945523139025e-20, 4.23574285194563761e-20, 1.97943620153417501e-20, 9.1380785584698727e-21, 4.16664115847730492e-21, 1.87607505526684708e-21, 8.33990194865253314e-22, 3.65957523624367309e-22, 1.58478521833259782e-22, 6.77157569443439638e-23, 2.85428170793711408e-23, 1.18658385809475687e-23, 4.86406993570804503e-24, 1.96564341924698522e-24, 7.82916562469586207e-25, 3.07278922881727027e-25, 1.18810761472137628e-25, 4.52461974876349341e-26, 1.69671018684788546e-26, 6.26364100322911832e-27, 2.27579079285739671e-27, 8.13607771590443142e-28, 2.86130654929539103e-28, 9.89618419694378756e-29, 3.36520089316413987e-29, 1.12480705460763553e-29, 3.69446043271393344e-30, 1.19209330134653648e-30, 3.77775787601831979e-31, 1.17543637867784723e-31, 3.58987907782846159e-32, 1.07584268621427998e-32, 3.16283512594659586e-33, 9.11867418907406595e-34, 2.57739316844162499e-34, 7.1398295043464041e-35, 1.93782892101998192e-35, 5.15137910137900834e-36, 1.34081832632372396e-36, 3.41594078513204744e-37, 8.51526274133751428e-38, 2.07627148236909967e-38, 4.95013783834481588e-39, 1.15356967695693221e-39, 2.62668296485366097e-40, 5.8418474765546355e-41, 1.26855835228178392e-41, 2.68859122451013341e-42, 5.5593886486694507e-43, 1.12111057861687088e-43, 2.20403043717381214e-44, 4.22240917613642503e-45, 7.87952006236087725e-46, 1.4317140234575382e-46, 2.53190480341727998e-47, 4.35599819582008424e-48, 7.28767439600814101e-49, 1.18511349577795095e-49, 1.87243345837735946e-50, 2.872969414982913e-51, 4.27891206602476651e-52, 6.1831517263855102e-53, 8.66470653206476218e-54, 1.17694237323367861e-54, 1.54881873834810793e-55, 1.97366460880734193e-56, 2.43418383962132076e-57, 2.90413694228353275e-58, 3.34994299201193299e-59, 3.73408060580539564e-60, 4.01995891804574233e-61, 4.1774687856674289e-62, 4.18809723670882773e-63, 4.0484306973548958e-64, 3.77114883236106507e-65, 3.38317388825833663e-66, 2.92133483455321543e-67, 2.4265171108768021e-68, 1.93760346159320028e-69, 1.48647054250017705e-70, 1.09492322559900645e-71, 7.7387134447881401e-73, 5.24480082054261184e-74, 3.40625629278303564e-75, 2.11846924392585922e-76, 1.2608614434809477e-77, 7.17649031262087557e-79, 3.90346976562660287e-80, 2.02755734043105449e-81, 1.0049948164305939e-82, 4.75009864715140751e-84, 2.13926360994608328e-85, 9.17314929286727873e-87, 3.74222173296279272e-88, 1.4512980036440355e-89, 5.34630175749911307e-91, 1.8692545071988721e-92, 6.19789589312738535e-94, 1.94723396955242345e-95, 5.79190528725131719e-97, 1.62959562674195777e-98, 4.33324326423632619e-100, 1.08801494300863546e-101, 2.57722826273521138e-103, 5.75398380064511214e-105, 1.20969900172483152e-106, 2.39258726643450458e-108, 4.44756592826448755e-110, 7.76277384222654792e-112, 1.27092673030838632e-113, 1.9498242131608832e-115, 2.80025255319740608e-117, 3.76074748562275474e-119, 4.7181060260584104e-121, 5.5234683214250331e-123, 6.02744769044586333e-125, 6.1242336828836774e-127, 5.78733363277456218e-129, 5.08063271088400746e-131, 4.13871801736087986e-133, 3.12471881752233827e-135, 2.18390311640240775e-137, 1.41125398621265234e-139, 8.42151329455492477e-142, 4.63493394973768902e-144, 2.34969854645219935e-146, 1.09580671068190257e-148, 4.69502753712715875e-151, 1.84563108198977552e-153, 6.64760587741882562e-156, 2.19079138839584829e-158, 6.59697046136299986e-161, 1.81250242223442328e-163, 4.53707818939648398e-166, 1.03323888357107399e-168, 2.13749544976958983e-171, 4.0108149042055623e-174, 6.81578124552971753e-177, 1.04731276526762e-179, 1.45286859403218762e-182, 1.81662828371734628e-185, 2.04402028828248565e-188, 2.06615138595524586e-191, 1.87311279320577987e-194, 1.52035876371838628e-197, 1.10294124238752463e-200, 7.1386269709902758e-204, 4.11483850807611072e-207, 2.10850283455308121e-210, 9.58680472859715381e-214, 3.86041689304663802e-217, 1.37411989131828493e-220, 4.3152058575378643e-224, 1.19318553486394228e-227, 2.89916952664044891e-231, 6.17752210069930949e-235, 1.15194579122953133e-238, 1.87592143430152533e-242, 2.66216877009057987e-246, 3.28513888332404399e-250, 3.51733028987600599e-254, 3.26018945745222711e-258, 2.61009614898002005e-262, 1.80074547979629024e-266, 1.06810199062668946e-270, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 9; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0L, -0.048632035927253054272944637095360333L, -2.2522807538407135100363691311150714e-05L, -4.2941610558782407776948098746194498e-14L, -1.1676488975098609327433648963732896e-37L, -1.1479529916293899121630752460973831e-101L, -1.2256538136584864685624805213855318e-275L, -1.5540928823936461440049038613030612e-748L, -5.3329091650553293055512604419528931e-2034L, -2.9720916290005160834428657415764727e-5528L, }, + { -0.32572850775156417391957990936794786L, -0.0024851435427756131672825807611796319L, -1.1124335118015331984966677262985097e-08L, -5.3784915913936887745567608333252923e-23L, -7.9430213192221161033965793076252082e-62L, -2.3871228185819266205711383850686192e-167L, -3.5505659459518255844385870776118831e-454L, -7.5205359182648710139026226942624688e-1234L, -3.1913442054759083418654684997091651e-3353L, }, + { 0.37720973816403417379147863762593439L, -0.14043094131010336482533980273793048L, -0.012959439492623108312614281385864999L, -0.00031173597164679094947882131119246211L, -7.9526288528733553445705754617783867e-07L, -4.7143551823222575055542137870412504e-11L, -5.4152228238072308459654515228487702e-18L, -2.0403003943524943294070815498839042e-29L, -3.0596901353644500298194434206758382e-48L, -2.8621984192587511612196829791231642e-79L, -2.0070330691533226369447382138318798e-130L, -9.24799327395281672235465186719e-215L, -8.3199831454007319575241484332973316e-354L, -4.7101915049286172051527740304785445e-583L, -5.1172326001331791544221573365516138e-961L, -3.565091902092693101170960484903703e-1584L, -1.380788494593788864141714339603113e-2611L, -1.676187209363792948538214808034106e-4305L, }, + { 0.19435700332493543161464358543736564L, -0.46085329461203223095024473969116941L, -0.21939256101679970074520301166037226L, -0.085120736735425389092624476255089179L, -0.026033131804322551436697210776387341L, -0.0059444933685978567073105981025861939L, -0.00093480354421415357524054329032500553L, -9.0615304856000161419338663865283889e-05L, -4.6839587794715699213295541472938628e-06L, -1.0721838758161809434047961979486614e-07L, -8.572949078216773291904741005771376e-10L, -1.7678346928387203697450793420511691e-12L, -6.374878495044439647822814562601604e-16L, -2.4429372790852173177460412747369906e-20L, -5.2515464730195748562913138330508827e-26L, -2.7894671622894177442056826817468893e-33L, -1.2781108980938044979748713346336601e-42L, -1.3082723368531808046381743164626179e-54L, -5.2799781226102543764849911449215675e-70L, -9.0619104054181014912823874637681869e-90L, -3.7903152788024647936360099425967319e-115L, -9.8301769964870442146689481371228979e-148L, -1.4178035546472368325653350149379565e-189L, -2.6738184762632894703182151426789471e-243L, -2.7784573988900744903717061581976306e-312L, -7.3734573357629727800590803405661863e-401L, -1.3609194136463888140125728088459369e-514L, -1.2497483783949474937966696885440387e-660L, -3.8167291133270025322500901161738939e-848L, -6.4205995373383705446145927875493146e-1089L, -4.4417348039463271683501804024826735e-1398L, -4.7673068229426388972968294463896211e-1795L, -9.1130922352573668488349663479480507e-2305L, -2.9379714111577752802646622386752463e-2959L, -1.2139403773313257256483385510112958e-3799L, -1.0232729473573403414331717146692674e-4878L, }, + { 0.097923885287832333262426257841800739L, 0.28787993274271591456404741264058453L, 0.46125354393958570440308960547891476L, -0.38972634249936105511770480385767707L, -0.26898196520743848851375682587352696L, -0.17668299449359762993747017866341472L, -0.11010859721573980192313081408407809L, -0.064839142478015316771395646494440585L, -0.035887835776452708068531865802344445L, -0.018545173322664829973291436321723213L, -0.0088730075583011977688563205451530858L, -0.0038913345624914574643783628537015109L, -0.0015457912323022624891555460019043471L, -0.00054856556472539415808492760717674295L, -0.00017117792712505834023311917084994073L, -4.6128994372039252659199558313379019e-05L, -1.0517985181496388528104100992279397e-05L, -1.9828594045679206280184825675885662e-06L, -3.0110584738877965497930108986179822e-07L, -3.5760919084657714373617064589353927e-08L, -3.2128009016957604999656591474001583e-09L, -2.1026713776411488104386696975012214e-10L, -9.606066478508465003238769873504248e-12L, -2.9190266410175139338365873758536822e-13L, -5.5861166388382275217411050967087276e-15L, -6.328207134683168236714250292398626e-17L, -3.9564613394676478284814817479958896e-19L, -1.2609758447165484726150111345292941e-21L, -1.8724921745276082830417983528796313e-24L, -1.1700302939131190810173673171853244e-27L, -2.7409861783512409524809986743233587e-31L, -2.1122827214476119769953891899502657e-35L, -4.6172239482595017143038368975612786e-40L, -2.4203621976262400766076976463254527e-45L, -2.5155618638019452025824211444543239e-51L, -4.1786390697021940369390798235100086e-58L, -8.6898180082116723025562943397702972e-66L, -1.7154357765002478902943183846995354e-74L, -2.3493032412195338067008854292230121e-84L, -1.5645432388942512177369950120860268e-95L, -3.3873402047868364753040883051129579e-108L, -1.5108166471007846474189907630676839e-122L, -8.2780000956704166841985762886452778e-139L, -3.1016029819580818393688194490134506e-157L, -4.0917346928724404440872286063293528e-178L, -8.9581681449485486979882444847795217e-202L, -1.3878968774299744972242822597861929e-228L, -5.7925742129350389434060147129950123e-259L, -2.1800405760909812340138469200688552e-293L, -2.1406911761156887130351179719470661e-332L, -1.3453872213865718752685710282193859e-376L, -1.101014385623064504263959341239785e-426L, -1.9309068614975016262992988189610055e-483L, -9.3925603630660026565835909833509362e-548L, -1.2492852059051478595312298290165577e-620L, -3.2901922810889194483613206478029049e-703L, -8.7594800494412338094846019359419219e-797L, -8.0988360915906760478163297865939266e-903L, -5.7031344694656922604093410430637095e-1023L, -4.0339055664976041957619784717611254e-1159L, -2.1239178549857743261952555619757156e-1313L, -3.2107478383582521299381622502244136e-1488L, -2.5644945785388919263865858785287637e-1686L, -8.6102745649577746230102198336971101e-1911L, -3.7383203767208973356368595261534058e-2165L, -2.1998398074691126029946216118342674e-2453L, -5.4286931050493856204731826640809476e-2780L, -4.3621004458123770532320189625677295e-3150L, -1.8497978727098997950183603712476515e-3569L, -1.1369676358500293654883467577244006e-4044L, -3.7214839695831726545775627850809865e-4583L, -2.4391504445900085306499460471723674e-5193L, }, + { 0.049055967305077886314518733812558024L, 0.14641798429058794052721556654753264L, 0.24156631953888365837930785879296225L, 0.33314226457763809243847911788190042L, 0.41995211127844715849198982824847239L, -0.49898661062069089848349381875489034L, -0.42441550936484834004641698479390102L, -0.35682324101479529871858133934192696L, -0.2964499948528579843445043147096805L, -0.24330609136627005059281117751078325L, -0.19720125865675873423611581820317215L, -0.15778075364924313618002648351129378L, -0.12456460236959132162770016658853563L, -0.096986718486426129363622040287916613L, -0.074431365931387333547858011705581591L, -0.056265213947242843145098876381950312L, -0.041863977289786309881823549732911528L, -0.030633267103082664829845578114893065L, -0.022023764813335027020322387941507847L, -0.015541168832569169131789346286900099L, -0.010751568909866103993013400883081643L, -0.0072830028031727146206149733302275483L, -0.004823973844672645743610027178935428L, -0.0031196818718081262793524354157388492L, -0.0019666636845662459778601079868649985L, -0.0012064657011941007112693927041613496L, -0.00071888807820804459144864726303695018L, -0.00041524964848241268314681568037451433L, -0.00023202840043916493872468513410105539L, -0.00012513495121965351530204004794322354L, -6.4980074917576313794386569166441844e-05L, -3.2406932056540235696910972894671255e-05L, -1.5480097729175578034178680349142798e-05L, -7.0621233371143522557906813506099499e-06L, -3.0675508096424942465066236512329746e-06L, -1.2645281340904582699398919033969316e-06L, -4.9299428056311116061802876221616736e-07L, -1.8110628723299136916197821516601534e-07L, -6.2445921626224975560761130514661379e-08L, -2.0125496798245795667718397386179161e-08L, -6.0358657983522763759573155859882131e-09L, -1.6766380517421942876239492441262369e-09L, -4.292122273863880635543266425012844e-10L, -1.0072227674373084849456997974551022e-10L, -2.154466258904202365369932629331438e-11L, -4.1753931241965133013258464583874422e-12L, -7.2847372642877340424635554069698771e-13L, -1.1363869854392191510522700311409067e-13L, -1.5735535097926530184856977764147682e-14L, -1.9192189097107621395219494827869742e-15L, -2.0449595408467355635051956217352212e-16L, -1.8869583067293409682109390382712203e-17L, -1.4938716488357228966449278404247075e-18L, -1.0046938100037576480510308414445084e-19L, -5.6799291780731967001285171683592406e-21L, -2.6691039526135151405184691859723367e-22L, -1.0301781381894114683480515283399996e-23L, -3.2244848763912462050246763811724513e-25L, -8.074782900421688680511360232922118e-27L, -1.5946546019932855470728505192034342e-28L, -2.4457239752752825879158721953606166e-30L, -2.8659197719078655681373680421610036e-32L, -2.5216825251828994098262358831122367e-34L, -1.6355144403100727446739341400788963e-36L, -7.6666590990678357226674242484094458e-39L, -2.5435771288137693474957657676429463e-41L, -5.8409472280716482316816237196206469e-44L, -9.0658695647939702552111019446179921e-47L, -9.2735698160588525904827667013324314e-50L, -6.0857148042052277604035466987369298e-53L, -2.4898089736722146606232085397625384e-56L, -6.1598620863170544290033299759018975e-60L, -8.9214127072226711903218542175348322e-64L, -7.3072243260040451389778049479673039e-68L, -3.2625608625513858480451119539754283e-72L, -7.635785144983622496088267971984613e-77L, -8.9855174690288197015625761302053014e-82L, -5.0858718515487289997949540667405475e-87L, -1.3207396001984761034417395177214725e-92L, -1.4964864935610521348123903353455889e-98L, -7.0129233669310880373145304240642606e-105L, -1.2839990161964174973579406866396101e-111L, -8.6445683841052002170413994851536565e-119L, -2.0063694896831555279614790770285332e-126L, -1.4987740796184447811135706015205434e-134L, -3.3493762149589610757447357005516387e-143L, -2.0715294381434481475176795645059666e-152L, -3.2638832593319965098529982282696874e-162L, -1.199473759889723458030222815758102e-172L, -9.3602085584027101517846387151893588e-184L, -1.4035094428007866386369967794759254e-195L, -3.6356107639491247696753307742986431e-208L, -1.452743995741226464980668915527686e-221L, -7.9377235820922308566742845525117486e-236L, -5.2163536229754499795136126103956784e-251L, -3.5964743752577816321270751238997225e-267L, -2.2494401025357803105700529744520824e-284L, -1.0932895122313467863909046216907507e-302L, -3.5018653663752920075194010313564247e-322L, -6.2028644584939181030730328594330175e-343L, -5.0411076779076593359744388314869213e-365L, -1.5409305985666377552321629186300452e-388L, -1.4337691700836957601785568351756479e-413L, -3.2419333785971000532922906392702739e-440L, -1.4016483469785082716612467122698103e-468L, -8.9774004157156246399741480681783078e-499L, -6.491677776744900396848653659323143e-531L, -3.968873851900238121124736680679859e-565L, -1.5079636812339879861399394077308116e-601L, -2.5657520984549883455506649942306167e-640L, -1.3792637739621433541997914448762973e-681L, -1.6159468091505698350217369718439518e-725L, -2.7790201117578232055517503438743301e-772L, -4.6058286485158911464074200874638533e-822L, -4.7006358553201903008219637676007764e-875L, -1.8338935012250262258997114428219912e-931L, -1.6464242001502528395088533240159331e-991L, -1.9816419848867601423745192888068803e-1055L, -1.7991094041844603532543957306249989e-1123L, -6.6797992361969494675858665124683032e-1196L, -5.2859098848402526633383865829249954e-1273L, -4.4550261847470794285196049926646754e-1355L, -1.9109438945105886059290808709178883e-1442L, -1.9007367698294334902014013473010713e-1535L, -1.8987324425640464476346787762173242e-1634L, -7.8167618149826855518169886771423511e-1740L, -5.1382521738908379784587542986497343e-1852L, -1.9655086052442019324819644975934904e-1971L, -1.4940998787039296124957637312415828e-2098L, -7.1913235695994009755126799768473976e-2234L, -6.4864369300175247147155547975053653e-2378L, -2.999946728125704672445599927700136e-2531L, -1.7904880802749365558709955426180586e-2694L, -3.1752504880744458148875772810912828e-2868L, -3.5042626554286023022035386575033303e-3053L, -4.5572536942770532680494362978923935e-3250L, -1.1878504044248058672204846884752448e-3459L, -9.4149599587707022465535580134518114e-3683L, -3.0486081328912260971936320312995529e-3920L, -4.7600871041282300101380551251356845e-4173L, -3.6856282214670996203899028095741989e-4442L, -1.2567068832608339131427238307321809e-4728L, -1.43352474798599180975125045215869e-5033L, -3.5192846690056568230804624618996538e-5358L, }, + { 0.024539763574649160378815204133417875L, 0.073525122985671294475493956399705179L, 0.12222912220155764235135543647484308L, 0.17046797238201051810697458795462942L, 0.21806347346971200463019772812275949L, 0.26484507658344795046121266511868619L, 0.31065178055284596083122357022827612L, 0.35533382516507453329875421158518394L, 0.39875415046723775644258197210456498L, 0.44078959903390086626728024419415105L, 0.48133184611690504421849248706653226L, -0.47971194930876984042437695635737165L, -0.44241877173922176919985653200857201L, -0.40684964640804684120174768961798095L, -0.37304979194895712050380997331064448L, -0.34104900825664987561685714614383599L, -0.3108622749383323282394733757479914L, -0.28249053251267587278787801637860204L, -0.25592161645265260087450443652530469L, -0.23113131323175341540544311864007538L, -0.20808450762385788552523390287482686L, -0.18673639149702614832471241636026165L, -0.16703370608058912436398702772140703L, -0.14891599201215126738569202826103709L, -0.13231682422435401330546108424048627L, -0.11716501175533104486690697891318309L, -0.10338574571992397421289522925754423L, -0.090901681836979564888397733057112044L, -0.07963394696804719765304016834176825L, -0.069503062002846593688614128282605538L, -0.06042977606672524461492007773726152L, -0.052335809384846902663067556129352578L, -0.045144504194977314593201232656013596L, -0.038781384848883592468460207166535186L, -0.033174629687644147159978329404393879L, -0.02825545843451269107668693235164557L, -0.02395843974342326066584697335177699L, -0.020221724199384237353497637367719603L, -0.016987208518898894423060324544850119L, -0.014200636974716564032303584519259449L, -0.011811646199257357569283265398947793L, -0.0097737595324722530639024866802767264L, -0.0080443369973223843798692318964963564L, -0.0065844868307359609987086057921138135L, -0.0053589442874888032779151584247851277L, -0.0043359231830468303521751643564073944L, -0.0034869453597462268271205586183706831L, -0.0027866529565312977632015610760207467L, -0.0022126080410934691734971443584643208L, -0.0017450838280037065615903399860968624L, -0.001366851359322522377124006197840537L, -0.0010629651664878262735108241097275379L, -0.00082055106511408284244272347987383953L, -0.00062859885906231310357940554216565142L, -0.00047776234878279577588863291489417448L, -0.00036016865439963480978268344017946398L, -0.00026923848019151736959880088820900265L, -0.00019951856886161369803218944988361524L, -0.00014652722688858828517464005147727694L, -0.00010661345240743574350860189665463426L, -7.6829870710671305672093252530903342e-05L, -5.4819385541306910394346187661030795e-05L, -3.8715192143333868407124859677345036e-05L, -2.7053574767763435703448594138071512e-05L, -1.8698729879273208281214887386151327e-05L, -1.2778717999371889596874911057724209e-05L, -8.631551655126555923485540179705975e-06L, -5.7603723833652179866412085097651011e-06L, -3.796652833823246921587494391038503e-06L, -2.4703761948320696741670218229372071e-06L, -1.5861890352645758023485712079757291e-06L, -1.0045893100303765084297472484854592e-06L, -6.27292664630529591934671730489378e-07L, -3.8601144975725102288841415591950667e-07L, -2.339766675668795211736366707138927e-07L, -1.396287854005922888135986291920763e-07L, -8.199520528943774856188619843122174e-08L, -4.7357335538151973999955685632054965e-08L, -2.6886764056376916830145130602254872e-08L, -1.4996923688266632451823595335560501e-08L, -8.2135439009280190432084662337190249e-09L, -4.4143663841612464008735244035118061e-09L, -2.3267632621004612298287053849704746e-09L, -1.2020164996011407668894632352766295e-09L, -6.0822312416778615105389374826677738e-10L, -3.0124563074832322562803735802769698e-10L, -1.4594388450012857143914599919653952e-10L, -6.9111604985231078666967248228438538e-11L, -3.1966783264445369722850429235278972e-11L, -1.4431209924042652494507345459464675e-11L, -6.3536761284911814276716019591237312e-12L, -2.7259505188725197201090431322689677e-12L, -1.1387345722407849659711071645809649e-12L, -4.6277346217693134290561172417433117e-13L, -1.8279902248431104840099026765769527e-13L, -7.0120467384905686087185698802558123e-14L, -2.6096053661379546374618820988626935e-14L, -9.4133613352888555760685465264560536e-15L, -3.2879256949364934203905795056053052e-15L, -1.1108629401821898431250973198964316e-15L, -3.6266022642032122019717830419062828e-16L, -1.1427876525052669863279877707280153e-16L, -3.4719022692494936795924113147604942e-17L, -1.0157819068305124587449297554375856e-17L, -2.8585328245081481739274807557448345e-18L, -7.7278347873892552568443785071813692e-19L, -2.0044239922175172204979314952837677e-19L, -4.9815683764699114931038226437577286e-20L, -1.184668492422340236764487382599448e-20L, -2.6919849036103905707012031384082434e-21L, -5.8366674419339414129894129738889481e-22L, -1.2056615886548723513354371860285751e-22L, -2.3691093508078067650593562318134397e-23L, -4.4213394617280017751359368167258193e-24L, -7.8238350041086858182189611432466241e-25L, -1.3105331441254781548552012055519121e-25L, -2.0743450130735150739962743364500278e-26L, -3.0969683255507495828369632528319965e-27L, -4.3532005281967559757740065310127852e-28L, -5.7499556680703922900693138751854555e-29L, -7.1227159266381727412068631384345687e-30L, -8.2578354203558045768004451321024521e-31L, -8.9415410066249555437647937669966689e-32L, -9.022796650030866974265443296162775e-33L, -8.4660301195315971752688615420135191e-34L, -7.3692728065645298168617836618124666e-35L, -5.9366323560088749776278557840220755e-36L, -4.4152778386946959545381237143455402e-37L, -3.0239601358635314916964716581634168e-38L, -1.9022037916577048792943667867798758e-39L, -1.0960433286034577882548963198643229e-40L, -5.7686955980040694827320797355280285e-42L, -2.7653993817377102211887943260200603e-43L, -1.2038709528562574051108458784307785e-44L, -4.7447623253354987177832150988795395e-46L, -1.6876791281053309141043851984778909e-47L, -5.3999669982997284808706183365024646e-49L, -1.549024049448082614346506969629423e-50L, -3.9699472552561349765465127201129129e-52L, -9.0576749265239358552559531050991564e-54L, -1.8329504334836931380757353284221911e-55L, -3.2774223323973643896776906795254206e-57L, -5.1576871530839363640889147624270212e-59L, -7.1147152214081979999932108600174644e-61L, -8.5668890171210249323533230713364891e-63L, -8.9655585542113618588233770236885955e-65L, -8.1186937969054743805236701211415782e-67L, -6.3321938859077339155825561128906228e-69L, -4.233726342460328087225876085667347e-71L, -2.4147260464376790196845134616759282e-73L, -1.1689555910948214525778546914101199e-75L, -4.7780668985526446079787318493898922e-78L, -1.6402035716952158990309656043758773e-80L, -4.7024891487642105081472609988004035e-83L, -1.1195904670077980724005196979590736e-85L, -2.2005433507330024992345876236265894e-88L, -3.5489240240632636451154177125584074e-91L, -4.666940936883651858001572120481125e-94L, -4.9719066745930336256015501390182822e-97L, -4.2625120032373619347908954864791867e-100L, -2.9205525410269401160683450458899041e-103L, -1.5879283520520673524672134768919763e-106L, -6.8010328774211569659959576053742516e-110L, -2.2772324163917691950189307132002393e-113L, -5.914722281629598175795438531560773e-117L, -1.1820998217768840832984056598978546e-120L, -1.8028262273951398891886168129927287e-124L, -2.0802041335110124193794970445396975e-128L, -1.7999670156396935596364355347029528e-132L, -1.1573419660682545435402292296632314e-136L, -5.4777666541440989994081254549149894e-141L, -1.8900190812332372959031760309750191e-145L, -4.7064318355746675546808068910291556e-150L, -8.3711291364376416570212981885601003e-155L, -1.0522139008817658534084763162543628e-159L, -9.2441193400981258043604322474285494e-165L, -5.6121650181326378940737135740792016e-170L, -2.3270398424370294077224375501608811e-175L, -6.510721186743015604234587537579044e-181L, -1.2138997008699255952666017192674735e-186L, -1.488912999352695867344311698561554e-192L, -1.1855378186700107100267028475666946e-198L, -6.0445584657932328676234962000989188e-205L, -1.9456793188673556729031520231103262e-211L, -3.8966805747095113950686230057410173e-218L, -4.7829220009546143710431038737748715e-225L, -3.5425595917324118172041028901087466e-232L, -1.5581260191174140607938473801301532e-239L, -4.0028071638967508676664829682660027e-247L, -5.9046000382762171283315920864186447e-255L, -4.9139618035200235196744932808885781e-263L, -2.2656744698055742315406349324984012e-271L, -5.679971707464259613069663431618014e-280L, -7.5941261723746109223402306020806232e-289L, -5.3079378188778939332566204780962363e-298L, -1.8999778173084169834715816327210827e-307L, -3.4097331110687592869362387676073128e-317L, -3.0013940393884085654083505783337316e-327L, -1.2668812065800974411227932737003665e-337L, -2.5051097865973858424963978994105679e-348L, -2.2653835286828392416879577941979414e-359L, -9.1389245527311981300218270087623242e-371L, -1.6030930250662823526442537954011133e-382L, -1.1908341901916029371925944757292412e-394L, -3.6452473980708905026093050166205199e-407L, -4.470581799337985564576477205041097e-420L, -2.1337946766915608745979583351759322e-433L, -3.8466502387371814478842876774875617e-447L, -2.539400648443551278595315008859673e-461L, -5.9463310120354055195604938583173969e-476L, -4.7791154462039743101535253283672216e-491L, -1.2743368238366444127980835826074082e-506L, -1.0885513756896925921766278125740167e-522L, -2.8730852174104725878401965901098976e-539L, -2.2573125874160702024258126565183851e-556L, -5.0801120877688108677556596022448958e-574L, -3.147442313458971094095441973453258e-592L, -5.1530284704707320518750575728196905e-611L, -2.1371769888513739266688394459294633e-630L, -2.1496221573881902238982422615825289e-650L, -5.0129928677987666360823382488243001e-671L, -2.5875873756026443959521949570534425e-692L, -2.8181620714067187431385929758736621e-714L, -6.1639625895204988083360964770898867e-737L, -2.5730385846926571409465774477581834e-760L, -1.9448744127295675669050254780849454e-784L, -2.5213762798933993822025230917884045e-809L, -5.3012546029922448380589857164083814e-835L, -1.7062280322013794538523703018620566e-861L, -7.920258584822147757302618208276618e-889L, -4.9864409544476492068060565707730923e-917L, -3.9962146024411971515483669014007722e-946L, -3.8185388383865818601310492618971832e-976L, -4.0664680142829823697989791072662443e-1007L, -4.5015287529024162764736783373823692e-1039L, -4.8207630344098447587536323292213823e-1072L, -4.6375061995611002272610193821937293e-1106L, -3.7123073076807703361397549566488692e-1141L, -2.2851629967300820983086928617773692e-1177L, -9.9710151392993821636927693831761909e-1215L, -2.8354564442635450405718863241322006e-1253L, -4.8186151533506508630367161348238245e-1293L, -4.4750346397724178706383092717200537e-1334L, -2.07096024490079588158927973820168e-1376L, -4.342127308884323517312819302082545e-1420L, -3.7387854726872903857603805318252205e-1465L, -1.1946574634186879393921342144260135e-1511L, -1.2759441657028066718211573051988164e-1559L, -4.0892575258067523665855842405306752e-1609L, -3.5183875354871145031995454351438789e-1660L, -7.2453069573873944421690184084196628e-1713L, -3.1719634253495420624848681187846285e-1767L, -2.6125752080330097261369292566212969e-1823L, -3.568653966381994484787922096951618e-1881L, -7.0977732480251336872758023077199559e-1941L, -1.7972768141068333989152413556564914e-2002L, -5.0445828237798979207114411387487754e-2066L, -1.3604595412453945762407996412329254e-2131L, -3.0419951659449528528023254177983519e-2199L, -4.8436592014037520285667566761754706e-2269L, -4.6942170473823597199914323005808658e-2341L, -2.3550263329098316285032485977513203e-2415L, -5.1749636831144475403049010950928176e-2492L, -4.1920868885180451051347682697190622e-2571L, -1.0479018787402586343779450171950524e-2652L, -6.7279428066803227116834111695132562e-2737L, -9.1809880505079118230638356660916729e-2824L, -2.1903121606778754894644610552460375e-2913L, -7.4679789664508998469723121247024705e-3006L, -2.9557873617341136266023224346917197e-3101L, -1.0958275239557229340575496309183988e-3199L, -3.0498491351714004349547292302889343e-3301L, -5.0710549490564658785365657190857463e-3406L, -3.9798833012314432652288251577412562e-3514L, -1.1561503564308970430488476029765637e-3625L, -9.6738350948812768619787679276120515e-3741L, -1.7998403785619766408556530850576782e-3859L, -5.7011595100947685691764189814097789e-3982L, -2.3342553026008523985584602356036335e-4108L, -9.2972354921660563358009254715497299e-4239L, -2.6867404349734172649970964993288437e-4373L, -4.1626263982921541967696302677355217e-4512L, -2.5305298537002028475606439113724333e-4655L, -4.374081747920579431517607591486263e-4803L, -1.5419945401212975573693263841002279e-4955L, -7.8687813783350283818994253864974705e-5113L, -4.0807753246747505208452672626580765e-5275L, -1.4931173692359951169542729406105663e-5442L, }, + { 0.01227135511808220203174030407830294L, 0.036802280950025085014502801868003454L, 0.061297889413659975774096037893250044L, 0.085734754877651055755695461536205953L, 0.11008962993262801258027823870142222L, 0.13433951528767223660361301319755489L, 0.15846172828929950397368299153321965L, 0.18243396969028915021484585689969531L, 0.20623438831102876939480559034293115L, 0.229841643254360753698787981399908L, 0.25323496335600023568199079816688852L, 0.27639420357617861412235821455333865L, 0.29929989806396047268181013419640459L, 0.32193330965336916623041220093195644L, 0.34427647557970491862490100675820811L, 0.36631224923490408185795345459447966L, 0.38802433781211774758659161520378721L, 0.40939733572152948912988463410721733L, 0.43041675369143706432580814661825066L, 0.45106904350045199476872844990592136L, 0.47134161831799846568675411549444037L, 0.49122286866081148740164998519670023L, -0.48929782599744185793989666371765164L, -0.47023008989822544160728474574480754L, -0.45158254786020764535461909038883739L, -0.43336282621498114195428483532083889L, -0.41557755767733605834276062792428588L, -0.39823238999036654097849262723755211L, -0.38133199816727193874162067315553426L, -0.36488010013557816387677409414947586L, -0.34887947557569577047526159126703565L, -0.33333198773426231868095335844342399L, -0.31823860798357268745316074354464261L, -0.3035994428915407927086292160567468L, -0.28941376356199421334543326775454705L, -0.27568003700259251963348266210052998L, -0.26239595927717475510166267033301246L, -0.24955849020075956493410868722363431L, -0.2371638893386076311859247952179354L, -0.22520775307556463019220672947952605L, -0.21368505252818039398938452749375662L, -0.20259017207968775297648115336201576L, -0.19191694832666146249702413953519866L, -0.1816587092359021720484117453151821L, -0.17180831332064290072992681330484534L, -0.16235818865639997533663276272992352L, -0.15330037156853630364404549106194642L, -0.14462654483572846910471674072111206L, -0.13632807526589476511715224673350004L, -0.12839605051362228117619033241835825L, -0.12082131502061062975401342241486234L, -0.11359450497302129819348705755904515L, -0.10670608218178901767108607508338614L, -0.10014636680382986857859380586600253L, -0.093905568833595799431451407446515619L, -0.087973818305513180839892673963966241L, -0.082341194158450660178436474882477694L, -0.076997751723445596499983664621487996L, -0.07193354880544487378738311657933671L, -0.067138670338759945862672351268719341L, -0.06260325160428086186052507865402345L, -0.058317500004230664509200379313199518L, -0.054271715397367759935086056389293555L, -0.050456309004063640355911746580908904L, -0.046861820896606197349996098751978814L, -0.043478936095419069610563231210812888L, -0.040298499296663390818673202062521126L, -0.037311528260921730030179369385366989L, -0.03450922589637952691206152682222172L, -0.031882991073143683811495499895307175L, -0.029424428208099579660135740086865642L, -0.0271253556620361184294276412754116L, -0.024977812992693650455170906326981392L, -0.022974067108942042492683430416652371L, -0.021106617372505970898624990276714523L, -0.019368199694551294992954740677403882L, -0.017751789675058934941049112986218163L, -0.016250604833268754660069071624504775L, -0.014858105977601971243228436688712421L, -0.013567997763391553658409398729735747L, -0.01237422848648931564729341766812544L, -0.011270989160397638106454864191015908L, -0.010252711924012903699062738821083185L, -0.0093140678263849278340314349076327353L, -0.008449964034108265248268117472003357L, -0.0076555405060818245590132017863229384L, -0.0069261661794155687412632471018391501L, -0.0062574347092383891891208397242483686L, -0.0056451598040791099606160787309638234L, -0.005085370197361128404963242365624777L, -0.0045743042943771933124154458548517366L, -0.0041084045328997985361611689079751989L, -0.003684311494339074782205923019899892L, -0.0032988578010873948724575222465114151L, -0.0029490618343908704733333873759063219L, -0.0026321213057645656305833925217639785L, -0.0023454067136221407000743728815804873L, -0.0020864547154229734242597171162514598L, -0.0018529614442515743960802739125590691L, -0.0016427757973362357767337812404644128L, -0.0014538927225872833069713654109330111L, -0.0012844465277911570122332123844688455L, -0.0011327042356361946956708854910717802L, -0.00099705900627114148706364731704457709L, -0.00087602364761017102176873850865987398L, -0.00076822423210114801927833212686428566L, -0.00067239383717004607961542674246453911L, -0.00058736642504742093080174568452091253L, -0.00051207087617669287572188257954358842L, -0.00044552518890326020005629570593666048L, -0.00038683085665314188976467566548793199L, -0.00033516743233532263998791108562179822L, -0.00028978728824896558062724060959821788L, -0.00025001057835114127416442774611755005L, -0.00021522040834883412191823299277438955L, -0.00018485821772693895358504217864611182L, -0.00015841937651793126628162990110989201L, -0.00013544899836493134204129687787204532L, -0.00011553797023379563893736144870607114L, -9.8319197997130553498037999641991487e-05L, -8.3464066048770978005196778706600799e-05L, -7.0679108115811218906095134416154613e-05L, -5.9702885520625386671791420435362921e-05L, -5.0303068310699595343932915440924077e-05L, -4.2273713922018120404243909635658711e-05L, -3.5432737373923361833214162324345645e-05L, -2.9619566410724316247858190357851524e-05L, -2.4692974507962358657498919760422057e-05L, -2.0529084248443619898457582669713841e-05L, -1.7019533243403755023062694063359981e-05L, -1.4069794525207501119432380528847431e-05L, -1.1597643166806136977541673876760615e-05L, -9.5317607861225334492481477207976067e-06L, -7.8104695663539218978433615931904191e-06L, -6.3805874611085194148542316667027636e-06L, -5.1963963511236276943307284768443108e-06L, -4.2187150715072772351343816215627715e-06L, -3.4140694292103354602072245113222152e-06L, -2.7539515738216143655929212361430556e-06L, -2.2141613647700348500196752438228238e-06L, -1.7742226886238416354636940930406071e-06L, -1.4168680155127991206906010386776301e-06L, -1.1275848380651233667302406751686147e-06L, -8.9421800420026716637883889021333717e-07L, -7.0662233151961419975116851767251182e-07L, -5.5636027112312322628504802544396849e-07L, -4.3643976809083996211611047940700884e-07L, -3.410878406808352344192770488162828e-07L, -2.6555576704383762368205974553664254e-07L, -2.0595212394180990975114609016580268e-07L, -1.5910026405413012262681483592072574e-07L, -1.2241714489336877307229490096356811e-07L, -9.3810731511298667657736474465916103e-08L, -7.1593485856820748829676007409030264e-08L, -5.440972704881531639917700413368612e-08L, -4.1174898509745034636641901499637178e-08L, -3.1025009758847405806336107058366646e-08L, -2.3274732865051716886351304700372955e-08L, -1.7382826537542006005418736935360821e-08L, -1.2923735225028943169773355461941788e-08L, -9.5643672141012475959697164491130902e-09L, -7.0451955080630225653421587634231792e-09L, -5.1649492757248395049197216720378741e-09L, -3.7682729974336732148768443187202036e-09L, -2.7358262541647042643058722243498035e-09L, -1.9763805681294590078061949445779507e-09L, -1.4205419635481505647172465852581089e-09L, -1.0157900987858722132374807163656952e-09L, -7.2257800679698977337008871109952299e-10L, -5.1128169466802636753557604076122797e-10L, -3.5982705512040164549431243047583567e-10L, -2.5185362244554210229589301236053854e-10L, -1.7530147750309255605734608915901604e-10L, -1.2132981051324705363357105718720941e-10L, -8.3493950752320668610647319362559637e-11L, -5.7122660267481958430713410881095016e-11L, -3.8849686002793765883588257767026493e-11L, -2.6263427379949721354783426839588953e-11L, -1.7646499776378976222245772521934802e-11L, -1.1783298320120630850539029584309311e-11L, -7.818680628325362638575521404267539e-12L, -5.1548364042751350429076854858018077e-12L, -3.3765014608000294669628289654725219e-12L, -2.1970744699592342642466439966825033e-12L, -1.4200473669518126870628306394495551e-12L, -9.1158007933577728676134065579326132e-13L, -5.8113062505586808310528553401168741e-13L, -3.6786791102075633999543555381361719e-13L, -2.312068903576444768213986586668492e-13L, -1.4426172485922308843621431499934686e-13L, -8.9349666651298939216456676750565829e-14L, -5.4925677721256790529564920614679325e-14L, -3.350788309515877062958811342787956e-14L, -2.0284076402444039895928235924589244e-14L, -1.2182795128979644452912696549518128e-14L, -7.2588537362052341752692102123089101e-15L, -4.2900627866036669128285279549303027e-15L, -2.514652539480771341683046756355483e-15L, -1.4616871128475335847732485959402402e-15L, -8.4243309583746983103209365972381765e-16L, -4.8135175904015314514321104340303263e-16L, -2.7263179430684054979795995181696999e-16L, -1.5304422973965932233677561227408377e-16L, -8.5137857250384433997363815737881969e-17L, -4.6927950389611427068741326969599031e-17L, -2.5625975950320089549856176296445119e-17L, -1.3861334667950396744809652330676689e-17L, -7.4257501921384642292801069180083189e-18L, -3.9393094024445601833019849790813999e-18L, -2.0690791459774228199242128751668536e-18L, -1.0758286216493138282150652273565844e-18L, -5.5366710173011999504598745894506669e-19L, -2.819834003785898432921699582824987e-19L, -1.4210063750313593796726974809925319e-19L, -7.0842438781417380233044623416891119e-20L, -3.4933505573095044526616590274445578e-20L, -1.7035977510820099431072120902417317e-20L, -8.2147060442121877800848286483420634e-21L, -3.9159734384156989690338293870539541e-21L, -1.8451498156271871363001830659526856e-21L, -8.591874580623540129167786895666899e-22L, -3.9530069577065764915635262899095704e-22L, -1.7966697995134261385398916631645912e-22L, -8.0654088208389219862969348472697735e-23L, -3.5753372122620560623243551587275021e-23L, -1.5647821323387363967354776667279086e-23L, -6.760041764217369644940988147273804e-24L, -2.8821363233025547133119762203866565e-24L, -1.2124362329062417813651773042222047e-24L, -5.0314218307880599929168429579030218e-25L, -2.0592863122450067780181162680466505e-25L, -8.310787797639985481399920298561774e-26L, -3.3065180676145941342573597126851257e-26L, -1.2965973462467399413826706323859068e-26L, -5.010091032398552312889055575499255e-27L, -1.9071793847355632162575945250968826e-27L, -7.1505673339810973649967867585100117e-28L, -2.6399060373682682300772738413986419e-28L, -9.5946645421591590272737060192787035e-29L, -3.4320780991310649618469641664780934e-29L, -1.2079850663067081309863651387341263e-29L, -4.1824647214881752797125541962674838e-30L, -1.4241537066844817617919365428875337e-30L, -4.7678333816988133611599026436806048e-31L, -1.5689491781958062283731284050971648e-31L, -5.0734388548496443499288192319785528e-32L, -1.6116919160939245706339600215608967e-32L, -5.0283566942543780691617432163678683e-33L, -1.540320437147141644686176099192533e-33L, -4.6313924434817901733319954389626016e-34L, -1.3664702250574194828136706303116849e-34L, -3.9550085269989845845237677023544696e-35L, -1.1225918253644008151328041096174431e-35L, -3.1238487433616834059785879847016762e-36L, -8.5195402472064902632510499781952803e-37L, -2.2764734813775829740707091909282255e-37L, -5.9578473858349842310952826931317941e-38L, -1.5267023004586063974485430859996629e-38L, -3.8292452373883691255032248372279562e-39L, -9.3976484123312742513645018653353223e-40L, -2.2559187023391247540357057603608445e-40L, -5.2951057740070273455910884012728247e-41L, -1.21484005139195805370253212205352e-41L, -2.7233329057563859457781652894773382e-42L, -5.9629474724550016648059026687365969e-43L, -1.2747904563208401684090170257821763e-43L, -2.6599324647740072572781740009475107e-44L, -5.4148975705500338800900730270033864e-45L, -1.0750506783792922201321365237207054e-45L, -2.0807277332937164031945232093695697e-46L, -3.9244163140436388041993251545689042e-47L, -7.2099378100469390278450504220931707e-48L, -1.2897482330918123669983337886382095e-48L, -2.2454989700172052890162893888242529e-49L, -3.8033817751932373827258462682395899e-50L, -6.2645207667921988981079909974995822e-51L, -1.0029410834924645721226614397473029e-51L, -1.5600495091009386993988441513950677e-52L, -2.3565650292912781888129806450540921e-53L, -3.4553986153009958542696149938952582e-54L, -4.9157636744396300209125008789737936e-55L, -6.781896900608377888472479708032872e-56L, -9.0691940202443643747199815355477207e-57L, -1.1749792443564338073595948464279018e-57L, -1.4740730312062593807916913990480482e-58L, -1.78984329859422798255692388149323e-59L, -2.1022998433631042036525885470222986e-60L, -2.3874311701754330999376394091254256e-61L, -2.6199497113269397601815392049767616e-62L, -2.7768131253969855575381129113408787e-63L, -2.8408870962885800781023815369817483e-64L, -2.8039688883465382638228147703461371e-65L, -2.6684481602260540322238895901981613e-66L, -2.447154080870857351995438102206883e-67L, -2.1613619398610954911634747438934054e-68L, -1.8373843424142226299889606750473108e-69L, -1.5025103938453805607949990395131202e-70L, -1.181175530500916159109188924367755e-71L, -8.9211577919430036730810594588108188e-73L, -6.4693987201487320046787049136480794e-74L, -4.5015731884566473782551022645592059e-75L, -3.0035842209914330912805318957189823e-76L, -1.9204515997414609573256145075523711e-77L, -1.1758810849678264495241195391760596e-78L, -6.8900721571551738196701537405845152e-80L, -3.8608563387442272849431335779050044e-81L, -2.067461647504548936055359104346581e-82L, -1.0572431033554667452601572946421337e-83L, -5.1591788391388680011549213529878416e-85L, -2.4006807351389258318746737135895233e-86L, -1.0644152130176148388326772258538689e-87L, -4.4934529232365451766727877769969084e-89L, -1.8047048722799212873442491872423271e-90L, -6.8904595506732549720140200562795596e-92L, -2.4989637101487869067392480430274382e-93L, -8.6018088469863275574189994840620463e-95L, -2.8078924862967821005632597982452309e-96L, -8.6849867519796128933390271698765342e-98L, -2.5432396109247561096829294407826966e-99L, -7.0446668978619724438762397385539258e-101L, -1.8442018255867670937882313596001159e-102L, -4.5587416725253559276425131397074849e-104L, -1.0631088555204592085750091746032982e-105L, -2.3367281748964035585738800969158434e-107L, -4.8365042631130861220456426369022544e-109L, -9.4175235620877562064839942442771856e-111L, -1.7234789461694177262894389768372263e-112L, -2.961523379734186944047236046386456e-114L, -4.7734609518585313301965336240248189e-116L, -7.2097952822898640408181240050284012e-118L, -1.0193874335777637006841936637337494e-119L, -1.3478166999163432272267137132118888e-121L, -1.664711300732456447679638084338044e-123L, -1.9186583950476330921591900813216499e-125L, -2.0612648015288569084831497840721453e-127L, -2.0618953788663489533345425995316527e-129L, -1.9182619555236359873955912398757981e-131L, -1.6579128778519222560290325566834437e-133L, -1.3296099070094495947742421798539638e-135L, -9.8828871549374803987116212190790475e-138L, -6.8001851936680182899829217843093739e-140L, -4.326204276337993340016401440114041e-142L, -2.541595528522972170757701141043585e-144L, -1.3771279659495821106478129347836407e-146L, -6.8731739624384578591538313057486772e-149L, -3.1556844841718302469140036866580175e-151L, -1.3311046015007009547835866736304136e-153L, -5.1514958005010918440961548583793399e-156L, -1.8267037628056442215789990487980127e-158L, -5.9267728539858017097499689403281403e-161L, -1.7570179057820636782453206639159588e-163L, -4.7525273644644354076088841580861234e-166L, -1.1712151180634311771192081451244071e-168L, -2.6258838722203054808989693856617573e-171L, -5.348036158420190530754215189932846e-174L, -9.8795260619978679822138888646044246e-177L, -1.6528501557776328068085680725354548e-179L, -2.5003947565086958266446692572037419e-182L, -3.414859619193216220277979880289186e-185L, -4.203653605459133226010277835528306e-188L, -4.656508257021667283525304276478024e-191L, -4.6339530996535525354074849617025537e-194L, -4.1358781926049696182200878642464924e-197L, -3.3049447294950072208241398344574307e-200L, -2.3603956208589999494122184847510332e-203L, -1.504047014068835401149660217771386e-206L, -8.5352021958508046391358762569456352e-210L, -4.3057568200632214990724928361534485e-213L, -1.9273628185121124753795720186090423e-216L, -7.6407868488415044113016735817166107e-220L, -2.677582009683177696032426651320389e-223L, -8.2781625043007349263821040953856809e-227L, -2.2534850368391124035175853226989187e-230L, -5.3905685902076735531578346280529237e-234L, -1.1308097276815650308355193143392165e-237L, -2.0759721813705410476824570327172646e-241L, -3.3282687604583975257076029809432931e-245L, -4.6500067135453696640703738061616968e-249L, -5.6491873692239596907540663618927003e-253L, -5.9546966626331923325761672881695778e-257L, -5.4337990425534927929347405657826422e-261L, -4.2828363537638634149994842306436067e-265L, -2.9089854251520548595336724777976923e-269L, -1.6986979835072953491948167874994245e-273L, -8.5078874736023215648629448861985246e-278L, -3.6459301611001785382074525089193986e-282L, -1.3335508003947114825747939690317958e-286L, -4.1528110309781799510004618371028852e-291L, -1.0982617987267680462918374327390562e-295L, -2.4602717457871291167756856167595572e-300L, -4.656274386497415739809125734407304e-305L, -7.4253896458167870494540985632704167e-310L, -9.9507057756639922437150285707977622e-315L, -1.1175135227544318386694717687968224e-319L, -1.048835867763772555877163638261832e-324L, -8.2033390786966798682011027925866189e-330L, -5.3315735131149564162074506318716251e-335L, -2.8710141330746883154448723258150022e-340L, -1.2771564172267081609509990200434409e-345L, -4.679237231988855089392537021634395e-351L, -1.4076706654157792032739797667966913e-356L, -3.4663625720057878756572289263095777e-362L, -6.965054539543846678373236132189486e-368L, -1.1383132196432715526434302555043402e-373L, -1.5082487448329479128870155332131625e-379L, -1.614816076667686258793882820784337e-385L, -1.3923692408287144362457422616397937e-391L, -9.6357705989726650954351553689911432e-398L, -5.3335362887861762022108923833857644e-404L, -2.3529529322735497728866304144280939e-410L, -8.2438250199447939690869259289572704e-417L, -2.2855238208173770201725378922268636e-423L, -4.9955499211081324148253281714818585e-430L, -8.5762081046608095383619080676476731e-437L, -1.1520466338982341020319294100361546e-443L, -1.2062291598612346324429863879453543e-450L, -9.8055160740422284599044523336543234e-458L, -6.1639765190753631642664330172075405e-465L, -2.9843045493133686661298629930164973e-472L, -1.10823285826398300175507717773449e-479L, -3.1434790244922162638267628745063788e-487L, -6.7817090417200778282332735946819014e-495L, -1.1080137352329998556662834370761201e-502L, -1.3649835831781010441492893639688094e-510L, -1.2622778335796144231373603506854352e-518L, -8.7230079476014413312144088584965706e-527L, -4.4840352485865235615809427931860355e-535L, -1.7066304212439665043951442710341263e-543L, -4.7865441809026242359826342326024693e-552L, -9.8452970343625269250999633839131245e-561L, -1.4778790578536059527306608667934244e-569L, -1.6110092952268207636105891878784886e-578L, -1.2688728710128977236628155987138424e-587L, -7.1841678295696924944920506687608424e-597L, -2.9088109305034413675847131931270509e-606L, -8.3780318645305679545954425238306175e-616L, -1.7073663715760515568257862032253151e-625L, -2.4485200806811154999909042531599294e-635L, -2.4573647256627145606915141874939106e-645L, -1.7162616532700922219515556951255632e-655L, -8.2940336462928562559347382857731944e-666L, -2.7573883713227551117703313812478972e-676L, -6.2693384642795198624500212806556514e-687L, -9.6903310752055252797176389760001952e-698L, -1.0120668627816313397657974563178381e-708L, -7.0982696439175036135044214112413552e-720L, -3.3223490979680344536621296663739436e-731L, -1.0311489910731877825037981367801772e-742L, -2.1084888364587342412345374253683016e-754L, -2.8218960738946335538305090801367889e-766L, -2.4554534404272344111007341068959851e-778L, -1.3797451463824018308120568764941013e-790L, -4.9722352119016468411483808073270903e-803L, -1.141174632389420312821039197546226e-815L, -1.6562061873208393415939125326414615e-828L, -1.5090517973695404620062521847072836e-841L, -8.5691467995207824570732116071300356e-855L, -3.0100992462861676532185696320551197e-868L, -6.4915591914227985933992989098330185e-882L, -8.5291480289311605733387922175211764e-896L, -6.7742561345607759008586516480118676e-910L, -3.2268177845742615217916640601654205e-924L, -9.1442367835386354685297667090946292e-939L, -1.5290755306231257347546172504187466e-953L, -1.4962742317658249855750971462991461e-968L, -8.4962983613273098681909435342233043e-984L, -2.7756354317962233287713988508361331e-999L, -5.1716412864088598574901876510481632e-1015L, -5.4473756239469544256829106354679121e-1031L, -3.2146847397534380657713310981627524e-1047L, -1.0532205872897567235295617558264118e-1063L, -1.8980407364210960924624682689327296e-1080L, -1.8638413013078585989318566769757098e-1097L, -9.878184707808045512821781472334627e-1115L, -2.7982877400590951555125003865089596e-1132L, -4.1953712551999192397935862947005203e-1150L, -3.2957901195530958784930344030449164e-1168L, -1.3428874261296622720955452657433921e-1186L, -2.8087996369552811844908096236163199e-1205L, -2.9843000347844479031722692316121269e-1224L, -1.5935747451543053300901499796204061e-1243L, -4.2306328294965009362324717933882302e-1263L, -5.5228314338471652594276889712636454e-1283L, -3.5058000799426290470482678197659356e-1303L, -1.0699175488609417213076569958022624e-1323L, -1.5518242259547372491845055361631511e-1344L, -1.0572462818562698193769229028835047e-1365L, -3.3433625974012960853422590535670218e-1387L, -4.8485886276278601232637821173583126e-1409L, -3.1852238059952872764052353398865978e-1431L, -9.361416530125180143871854771737577e-1454L, -1.2153997660730855590852157017720519e-1476L, -6.8815302334269492601957883930533625e-1500L, -1.6771176516091137975239852271122166e-1523L, -1.7361595430709725552633953103091938e-1547L, -7.5319512846392125534714956610857413e-1572L, -1.3507317243577349648175397566286196e-1596L, -9.8749002116827156793758713498543268e-1622L, -2.9017600444094134408965714990369305e-1647L, -3.3784846386968340746897973924953046e-1673L, -1.5359688750531830898643386942465616e-1699L, -2.6866527047176469998545109651176216e-1726L, -1.7810521996687791658708980830532171e-1753L, -4.4069918722394069695147388355206565e-1781L, -4.0074519225536368666632735822098734e-1809L, -1.3182831725717259025871898011803224e-1837L, -1.5438654487729921345949019930471491e-1866L, -6.332964675016807525269001303450335e-1896L, -8.9500787015064447527716544282145449e-1926L, -4.2852989232796780762796817666627905e-1956L, -6.8338809894056785809735926537843468e-1987L, -3.5675222855473848333391077011021476e-2018L, -5.9902029406713556414824109568504936e-2050L, -3.1778560977483191067544886656870642e-2082L, -5.2307612099795388778239926501377221e-2115L, -2.622585004749696786707859063948337e-2148L, -3.9309566721122472026471743065924237e-2182L, -1.7282752365752259330631889016659569e-2216L, -2.1861776117108222661355073061235227e-2251L, -7.8018157093958177389763723299669248e-2287L, -7.6999746209936272927151686536635957e-2323L, -2.0595655884579572710261610678442846e-2359L, -1.4626001721502482969651469854201664e-2396L, -2.7006580242811967764786623573354003e-2434L, -1.2693899148553691566069699600055988e-2472L, -1.4864297410986916900605959894904808e-2511L, -4.2424104158612592858897827763816223e-2551L, -2.886325476737890820535159860850169e-2591L, -4.5765223979102481270954678544866293e-2632L, -1.6528081850614599523381524655646053e-2673L, -1.328274798653407243855327660531847e-2715L, -2.3198223770931618563520410588946674e-2758L, -8.5957488899967850735558558018957728e-2802L, -6.5943404261286890309954636455911131e-2846L, -1.0217558991001370161903847475864815e-2890L, -3.1179630912672502182141115573865598e-2936L, -1.8265451376704665882357813599889357e-2982L, -2.0014192526716340395460104532447404e-3029L, -3.9951106676925283777648320420658919e-3077L, -1.4143501265341338386948746898388465e-3125L, -8.6415836958539035920266027922282148e-3175L, -8.8638553988044639042147624946934825e-3225L, -1.4840219096599721556289490714622718e-3275L, -3.9413909056885523526277851486916637e-3327L, -1.6130887141803206541250840542937335e-3379L, -9.8781642524919349085295532219577414e-3433L, -8.7843931949057976239401506792380659e-3487L, -1.1004454490075535460405971636548993e-3541L, -1.8829655853829584691138469084815955e-3597L, -4.2649913833758498152779971325727165e-3654L, -1.2387002826718376930423594688980877e-3711L, -4.4662108799989251681924501424182082e-3770L, -1.9344990293606773314152567555369947e-3829L, -9.7355570095915342874542008807254313e-3890L, -5.5029370896508671666190160013096548e-3951L, -3.3753310533018114196752016778611603e-4013L, -2.1693889909489136218749502032440802e-4076L, -1.4100342946015435859763977543837031e-4140L, -8.9396827455669883373190732493946026e-4206L, -5.3296285690324414372171445344916662e-4272L, -2.8786292587718554179132949540534825e-4339L, -1.3563301511005327997304553445712977e-4407L, -5.3648093624713363852431573541370394e-4477L, -1.713199655224600838900218899825865e-4547L, -4.245367036181261378573090733274636e-4619L, -7.8414039345064814928186445860311876e-4692L, -1.036301574835369426138520680597679e-4765L, -9.4005882200264089643362665220611737e-4841L, -5.6115028230432295314938587541868893e-4917L, -2.1117808872654504815205210716165957e-4994L, -4.7969059512296546218382678391152525e-5073L, -6.2923913054777813860480394257938674e-5153L, -4.557320132561115296699430714437428e-5234L, -1.7411358133348974154538037089867482e-5316L, -3.3501410753353566412413655174778596e-5400L, -3.097148592957890545441753638107994e-5485L, }, + }; + m_weights = { + { 1.5707963267948966192313216916397514L, 0.23002239451478868500041247042232167L, 0.00026620051375271690865701015937223316L, 1.3581784274539090834221967874745002e-12L, 1.001741678406625296380989561316704e-35L, 2.6763080920617460968679410949198166e-99L, 7.7670706886334062872146243844453043e-273L, 2.6770629459428179490864940513366914e-745L, 2.497123188557279400555877663164169e-2030L, 3.7829658019347837822103381908509695e-5524L, }, + { 0.96597657941230114801208692453802948L, 0.018343166989927842087331266912053799L, 2.1431204556943039357697233307232118e-07L, 2.8003151019775889582580016992170153e-21L, 1.123270534548691878982747435678734e-59L, 9.1753268750017841272445320853712195e-165L, 3.7096469071314047287189555701359196e-451L, 2.1358827779704788581082183250272886e-1230L, 2.4637500105830058174530832607403982e-3349L, }, + { 1.3896147592472563228608191295320513L, 0.53107827542805397476113231761531408L, 0.0763857435708323041883405748316428L, 0.0029025177479013135935932948904580215L, 1.198370136317072004690126421734261e-05L, 1.1631165814255782765597155262382926e-09L, 2.197079236297979917409204112478354e-16L, 1.3635103307637615413724747655081585e-27L, 3.3700568540419264989934173928550566e-46L, 5.1969783800898552138641449339116869e-77L, 6.0080341705713501485949327691027087e-128L, 4.564204056355599097208981999351872e-212L, 6.769934297924075481071769868728861e-351L, 6.3189772257105317991231885214248323e-580L, 1.1318535773666956837787222565063026e-957L, 1.300088515992481474129980450433913e-1580L, 8.3018817290920015915795630666821309e-2608L, 1.6615718540023971313123206033705184e-4301L, }, + { 1.5232837186347052131949627901588453L, 1.193463025849156963909371648222972L, 0.73743784836154784136450085848526681L, 0.36046141846934367416541940530511192L, 0.13742210773316772341110281600075763L, 0.039175005493600779071814125724013544L, 0.0077426010260642407123309111640668157L, 0.00094994680428346871690539180358829065L, 6.2482559240744082890784437584871091e-05L, 1.8263320593710659699109280974494727e-06L, 1.8687282268736410131523743935312467e-08L, 4.9378538776631926963708240981686386e-11L, 2.2834926702613953995564216678996858e-14L, 1.1227531428181551500942554523402945e-18L, 3.0976539701173543715458514327631078e-24L, 2.1121233435372255913526811977623162e-31L, 1.2424147570616052367007700396344415e-40L, 1.6327707331799493237812947626932747e-52L, 8.460688731096213796022276271481337e-68L, 1.8644492079588650273068038890475311e-87L, 1.0013128468666430206628687242136761e-112L, 3.3344435411868990213060767519646709e-145L, 6.1751576225487765303410376146008819e-187L, 1.4953240022257075856966174469213765e-240L, 1.995167671391421283850079422966012e-309L, 6.7986022131150125295165555843516628e-398L, 1.6112168443011532782661941324936245e-511L, 1.8998420056198456993096891152100817e-657L, 7.4500584401117916806764514072363403e-845L, 1.6092274599867451896713421807328385e-1085L, 1.4294469100875426784155324297970964e-1394L, 1.9699812322172327797426511042200449e-1791L, 4.8353547995000100603312087832016511e-2301L, 2.0016297694765957880783422493672502e-2955L, 1.0619575437766938720176582011701185e-3795L, 1.1494098249640889641399434474174788e-4874L, }, + { 1.5587733555333301450624222553039117L, 1.4660144267169657810275411936658895L, 1.2974757504249779979885383085284353L, 1.0816349854900704074448532749336471L, 0.8501728564566200689527310980522113L, 0.63040513516474369106015058023920241L, 0.44083323627385823706771270610993222L, 0.29024067931245418500061231479966878L, 0.17932441211072829296345978397121765L, 0.10343215422333290062482385052951418L, 0.055289683742240583845301977440481557L, 0.027133510013712003218708018921405436L, 0.012083543599157953493134951286413131L, 0.0048162981439284630172757660071387715L, 0.0016908739981426396472155417510249034L, 0.00051339382406790336016588906448858883L, 0.00013205234125609974878680402074340758L, 2.8110164327940134748736157546988307e-05L, 4.8237182032615502124025440343943169e-06L, 6.4777566035929719907733987417697432e-07L, 6.5835185127183396672340995882066949e-08L, 4.8760060974240625868904606426809347e-09L, 2.5216347918530148571826656491854398e-10L, 8.6759314149796046501956077624778843e-12L, 1.8802071730750649809476255843771975e-13L, 2.4124230384308786393899307730550295e-15L, 1.7084532772405701711664118263431986e-17L, 6.1682568490762382593952567143955272e-20L, 1.0376797238528706160610863270915827e-22L, 7.3459841032226935608549262812034877e-26L, 1.9497833624335174811763249596143101e-29L, 1.7024387761257547218675324410867209e-33L, 4.2164863709484278882204462399998679e-38L, 2.5044277116275284317811847533784782e-43L, 2.9493601457461933137195159567099426e-49L, 5.5513323569653710605229337238942258e-56L, 1.3081165120210821643686110907899211e-63L, 2.9260824463823975328629659452367614e-72L, 4.5407734669997824148941045053504133e-82L, 3.4265635692086987660673772586083229e-93L, 8.4064359488831769989074631453464805e-106L, 4.2486192688198694407012327873632857e-120L, 2.6378208263504521457685936139412266e-136L, 1.1199291455841279757620547508811484e-154L, 1.6741593786710889281267003484320699e-175L, 4.1533060810194922183660114746657927e-199L, 7.291512660905660427014583724901483e-226L, 3.4484028358868219730957875473275039e-256L, 1.470608613733186341839899819856118e-290L, 1.6363373245553192894384271318647291e-329L, 1.1653396430451048019810427186628332e-373L, 1.0806491346819681711718251969578419e-423L, 2.1475318157612117601623532784345252e-480L, 1.1837197513952188698387978224315556e-544L, 1.7840752052025753295716828917620433e-617L, 5.3242634124221408997248254448704286e-700L, 1.6062136117391783778620623735552911e-793L, 1.6828070526919983211589685788034629e-899L, 1.3428023135061849684751687999574317e-1019L, 1.0762445467071890806353267455766392e-1155L, 6.4211043768224511497561388149947945e-1310L, 1.0999298719684690155223457966483755e-1484L, 9.9551400313164741067089535072684105e-1683L, 3.7874715825152699680401002242066869e-1907L, 1.8633554093895907210742600678288691e-2161L, 1.2425018321859109200647073828888711e-2449L, 3.4744660691878314268031415759661457e-2776L, 3.1635539874917104171786237474568114e-3146L, 1.520164792309349080207015729831993e-3565L, 1.0587692108054511977730210493803509e-4040L, 3.9269571376984945676082618447700578e-4579L, 2.9165229925801338811576465571535852e-5189L, }, + { 1.56778143130722185718457839560813L, 1.5438811161769592204120195652304554L, 1.4972262225410362896175121106253706L, 1.4300083548722996676294145121698845L, 1.3452788847662516614631881421588284L, 1.2467012074518577048171373166756783L, 1.1382722433763053733718328301717509L, 1.0240449331118114482594022454942541L, 0.90787937915489531693097972059732257L, 0.79324270082051671787385259862995589L, 0.68306851634426375464118893187202369L, 0.5796781030877876470811045242977012L, 0.48475809121475539286590775419868886L, 0.39938474152571713514696619655275183L, 0.32408253961152890401776015000060852L, 0.25890463951405351600251387258910213L, 0.20352399885860174518647884913232324L, 0.15732620348436615026738563376259734L, 0.11949741128869592427594275905822144L, 0.089103139240941462840959442033942474L, 0.065155533432536205042255277931864103L, 0.046668208054846613643791300289316396L, 0.032698732726609031112522702100248949L, 0.022379471063648476483258477281403216L, 0.014937835096050129695520628452448085L, 0.0097072237393916892692355786307589937L, 0.0061300376320830301252445771940873246L, 0.0037542509774318343022967144602791306L, 0.0022250827064786427021584620411703896L, 0.0012733279447082382026740903535577353L, 0.00070185951568424227080474304718567332L, 0.00037166693621677760301295760218968355L, 0.00018856442976700318571529922115575474L, 9.1390817490710122732277133049597672e-05L, 4.2183183841757600604161049520839395e-05L, 1.8481813599879217116302847163026167e-05L, 7.6595758525203162561568606199506296e-06L, 2.991661587813878709443954037223499e-06L, 1.0968835125901264731967931401061751e-06L, 3.7595411862360630091183817668146341e-07L, 1.1992442782902770218679992206070689e-07L, 3.5434777171421953042822362946016499e-08L, 9.6498888961089633609206181967630592e-09L, 2.4091773256475940778596088439332178e-09L, 5.482835779709497755012456926288581e-10L, 1.1306055347494680535789879497045831e-10L, 2.0989335404511469108589724179284344e-11L, 3.4841937670261059685298917826974968e-12L, 5.1341275245014207474276938761808301e-13L, 6.6639922833087653243643099189129361e-14L, 7.5567217757805651894455261838657557e-15L, 7.4209932309922167588538662071098972e-16L, 6.2528048446104553564782731960667282e-17L, 4.4757595066690969713939566842636666e-18L, 2.6931206614869695057714525810417824e-19L, 1.3469941569542286092134858963015562e-20L, 5.5335834994155711455633228489644644e-22L, 1.843546974718149378096179376158747e-23L, 4.9139368712649040083308200957748574e-25L, 1.0329391306928575387668383646132905e-26L, 1.686277003849260652771901316947161e-28L, 2.1033057490018089523843332100004934e-30L, 1.9699209796232343253581550830906289e-32L, 1.3599894616303795697940905597197162e-34L, 6.7859788375592479085540582968820347e-37L, 2.3965063699443217406067231991536888e-39L, 5.8579569483084210846386345961131375e-42L, 9.6783927755717095571366983570964434e-45L, 1.0538361132564208838364959652125833e-47L, 7.3615858309787649210787574154381217e-51L, 3.2059785352833866133968160706885294e-54L, 8.4430892661864256082234111135836121e-58L, 1.301669487442817299199572925297743e-61L, 1.1348985048372046635260385887339235e-65L, 5.393881369511580841024486229556929e-70L, 1.3438019476233711028911671531262384e-74L, 1.6833095936633240263022508251714738e-79L, 1.0142059074468158538185578436642225e-84L, 2.8036136193449874498478125381332892e-90L, 3.3815387893836694650191340608232241e-96L, 1.6868699597973134851614068554314712e-102L, 3.2876716054636550397600067563177134e-109L, 2.3561803975866304919776634857937977e-116L, 5.8212714268864182676007475006940935e-124L, 4.6289769416942015466154791282940135e-132L, 1.1011712417530966759846558629187253e-140L, 7.2497708296024463973360079596584377e-150L, 1.2159344493950079010263214501254854e-159L, 4.7567332287785056252666937863445785e-170L, 3.9513561319289952903145090015894379e-181L, 6.3069398037899023031641976078084843e-193L, 1.7390958115772548420234336819215406e-205L, 7.3973824490445198187310257149181993e-219L, 4.3025693007354699025906405899973485e-233L, 3.0098295695832487716215316168466764e-248L, 2.2089957315907529731668895943677893e-264L, 1.4707383302537016829517267662493224e-281L, 7.6092047493292429607812922938663979e-300L, 2.5944582029845183791860228756757574e-319L, 4.8919577835343219860639698905291437e-340L, 4.2321357135722486316129327838961609e-362L, 1.377082367391413218915156512362392e-385L, 1.363952742750262175587655506596678e-410L, 3.282973957767873844612670506024268e-437L, 1.510934727927437884800902577518545e-465L, 1.0301501430760404101952742972682365e-495L, 7.9295801879971179076172461167077394e-528L, 5.1606434722064335409175586840009083e-562L, 2.0872322362104964031726231732635154e-598L, 3.7804014749166388131317806793058942e-637L, 2.1632858420984952938030309932161571e-678L, 2.697969237867160734724398915290777e-722L, 4.939067732330739558253971083984646e-769L, 8.7137367268607555569549275663836614e-819L, 9.4666568790742115790866970449104673e-872L, 3.9314930560193364712728646099681646e-928L, 3.7572363915786555422592370375561427e-988L, 4.8138810542737654527596947066774263e-1052L, 4.6523364803809138193102091214841167e-1120L, 1.8387400682879078406702806989874382e-1192L, 1.5488882086634896755007358131079033e-1269L, 1.3896133256118102918631384214217437e-1351L, 6.3450498372554790778619758345952674e-1439L, 6.718192925085413277150654870462718e-1532L, 7.1439377408604826875747242429241183e-1631L, 3.1307195483169831435149812630603435e-1736L, 2.1906656484419255825224621505729532e-1848L, 8.9202911849845695393803303860897414e-1968L, 7.2181700833126514821590990431204877e-2095L, 3.69827933239331943547271842529346e-2230L, 3.5509166675222604652849078491152928e-2374L, 1.7482004370958645792029686167921119e-2527L, 1.1106891190500999916896792610406226e-2690L, 2.0967298422181990469075373625054175e-2864L, 2.4632275747625679891658308849723178e-3049L, 3.4100009144092401643961247399658256e-3246L, 9.461422635018898458311235983749575e-3456L, 7.9828243452163492698389979442314978e-3679L, 2.751586075619233132202409409236628e-3916L, 4.573406478327970954594749406297331e-4169L, 3.7694660070555500868572517438534528e-4438L, 1.3681877706178551350653622286560967e-4724L, 1.6613468385141710911219854343435161e-5029L, 4.3416310672295866779590889330326041e-5354L, }, + { 1.5700420292795931467492986437735064L, 1.564021403773232099877114326609257L, 1.5520531698454121192208571607383634L, 1.5342817381543034316353772145375646L, 1.5109197230741697127061791873634288L, 1.4822432978855380699918515557505545L, 1.4485862549613225916106262684975582L, 1.410332971446259012949044799400295L, 1.3679105116808964880788896668731933L, 1.3217801174437728578945834791848425L, 1.2724283455378627082346213018713573L, 1.2203581095793582207386389532998567L, 1.1660798699324345766327658650910729L, 1.1101031939653403795568765186098518L, 1.0529288799552666555511877000344537L, 0.99504180404613271513656897365437693L, 0.93690461274566793365666309492163748L, 0.87895234555278212039056482196455926L, 0.82158803526696470334184690990337618L, 0.76517929890895613670160403610671453L, 0.7100559012054689838533558330696999L, 0.65650824613162753075637187406975179L, 0.60478673057840362157663695141011708L, 0.55510187800363350959266471517172014L, 0.50762515883190809969744129508607212L, 0.46249039805536776129564056825534108L, 0.41979566844501548065589545493380249L, 0.37960556938665160999227127370288764L, 0.34195379592301683230370363663700268L, 0.30684590941791694932077002517250017L, 0.27426222968906810637090960121437003L, 0.24416077786983990867520612813967892L, 0.21648020911729617038131524528780352L, 0.19114268413342749532225095746508781L, 0.16805663794826916233031413596643794L, 0.14711941325785693247796311096185123L, 0.12821973363120098675278273881295278L, 0.11123999898874453034874054225116091L, 0.096058391865189467849178662072631058L, 0.08255078811070173765353752357300814L, 0.070592469906866999351840896875301286L, 0.060059642358636300319399035772689021L, 0.050830757572570471070050742610585547L, 0.042787652157725676034469840927028069L, 0.035816505604196436523119991586426561L, 0.029808628117310126968601751537697736L, 0.024661087314753282510573737140694345L, 0.020277183817500123925718353350832364L, 0.016566786254247575375293749008565117L, 0.013446536605285730674148393318910799L, 0.010839937168255907210869762269731544L, 0.0086773307495391815853559138369297225L, 0.0068957859690660035329120415695881464L, 0.0054388997976239984331249261778682035L, 0.0042565295990178580164922070775372331L, 0.0033044669940348302363413922293941345L, 0.0025440657675291729677737674183717872L, 0.0019418357759843675814337234877431187L, 0.0014690143599429791058440789865212569L, 0.0011011261134519383861925290686638441L, 0.00081754101332469493114796258629778861L, 0.00060103987991147422573401527665731798L, 0.00043739495615911687786086941160964625L, 0.00031497209186021200273816328980956318L, 0.00022435965205008549104107147410537586L, 0.00015802788400701191949230617575051454L, 0.00011002112846666697224455022994264118L, 7.5683996586201477788165374446595019e-05L, 5.1421497447658802091816641948792101e-05L, 3.4492124759343197699875355951697823e-05L, 2.2832118109036146591351441225788429e-05L, 1.4908514031870608449073273504082825e-05L, 9.5981941283784710776464665022285646e-06L, 6.089910032094903925589071885768365e-06L, 3.806198326464489904501471179191111e-06L, 2.3421667208528096842717147966610279e-06L, 1.4183067155493917523149875336299115e-06L, 8.4473756384859863469243774523267053e-07L, 4.9458288702754198508296104158884319e-07L, 2.8449923659159806339254761906866073e-07L, 1.6069394579076224910854372243815059e-07L, 8.907139514024238712375244371846641e-08L, 4.8420950198072369668651027805560416e-08L, 2.5799568229535892380414249079124995e-08L, 1.3464645522302038795727293982948898e-08L, 6.878461095589900111136392082034183e-09L, 3.4371856744650090511359612982214485e-09L, 1.6788897682161906806903450478834801e-09L, 8.0099784479729665355704238927483163e-10L, 3.7299501843052790038025133658401989e-10L, 1.6939457789411646875651299532593942e-10L, 7.4967397573818224522463983518852213e-11L, 3.2304464333252365759775564205312505e-11L, 1.3542512912336274431500361753892705e-11L, 5.5182369468174885820640573102698266e-12L, 2.1835922099233609052099969606827855e-12L, 8.3831289605026670935474089966848491e-13L, 3.1194977286848081234778051650691241e-13L, 1.1240208959922861475529576279412917e-13L, 3.9176794506016467939451671035436525e-14L, 1.3194342231967989407842390664342776e-14L, 4.2891962220679080018159948630799523e-15L, 1.3443222875395221462210806176730482e-15L, 4.0575577022628576213784976604019497e-16L, 1.1779812127248348143079542926522782e-16L, 3.2853861628847006575461912014493979e-17L, 8.791316558919890092526902998792709e-18L, 2.2540748304368819446158103388678448e-18L, 5.5301769128403375894905317866280607e-19L, 1.2964527140689369428189650628176523e-19L, 2.8999645564315719864785175397007916e-20L, 6.1801432493399884472690523294170016e-21L, 1.2528676432273210433625630071013181e-21L, 2.4122505468361010054762467348044815e-22L, 4.4039066999398680900169681674054685e-23L, 7.6105778075820625755732634136772293e-24L, 1.2428051652123164945236765528871363e-24L, 1.9143106902239760676488034727771211e-25L, 2.7761251025850583169467065718383927e-26L, 3.7831240728137797052283562714381636e-27L, 4.8349101548188476652448113863661033e-28L, 5.7831786972290529603663947121744896e-29L, 6.4605757034417219896312763235825947e-30L, 6.7260373895879405356485977108634093e-31L, 6.5111534511374516546657070065569591e-32L, 5.8474090745481019884619654259625198e-33L, 4.8600460551422733352577609809902488e-34L, 3.7292395298436024198774848925631642e-35L, 2.6351230616803666949611566230315689e-36L, 1.7101926401490697241365293331985362e-37L, 1.0166685309552127228580017693019009e-38L, 5.5206909443427625675929025278647327e-40L, 2.7304755116605008208950089540576932e-41L, 1.226380966652512847885874020657185e-42L, 4.9868392983536125725869145787511357e-44L, 1.8300654157711633015675688730645846e-45L, 6.0413503225082640435207520715838788e-47L, 1.7880003085257126775048837670283103e-48L, 4.7278206635290633557485891499143011e-50L, 1.1129101718049771950203375840916927e-51L, 2.3236007287936054634490409808175661e-53L, 4.2865792135438400818864832679645293e-55L, 6.9598735225537515535247172084789902e-57L, 9.905399812867464416784441328019894e-59L, 1.2305690322370172647654483736261024e-60L, 1.3287055463682438112745418077294776e-62L, 1.2413844609001762091919818631042531e-64L, 9.9894889830989163005162036230629025e-67L, 6.8909792890209806239542239718708282e-69L, 4.0550412837679391530484571616360602e-71L, 2.025325478051833791855348665597344e-73L, 8.541193860817129005635611395334028e-76L, 3.0250584958478075188394058484674014e-78L, 8.9481574983737847286009199268691343e-81L, 2.1980365957192520850759686078382165e-83L, 4.457339084251821318983583351230449e-86L, 7.4167316712100725345384814229429518e-89L, 1.0062789446470429122974386215670469e-91L, 1.1060617024861203148604052551620709e-94L, 9.7834581723103753096719332058265664e-98L, 6.9161160403270601376643047091198938e-101L, 3.8797049192578037362892459079447827e-104L, 1.7144044358094688607777762897347039e-107L, 5.9226551398143962456841752185003654e-111L, 1.5871361682624074916136417159312335e-114L, 3.2726893534998181040216294108876001e-118L, 5.1496220394807877679493913965250783e-122L, 6.1305346175987605932476180523733874e-126L, 5.473030846543808520009167994615492e-130L, 3.6307475309683583384111588486160093e-134L, 1.7730007537696346688915570033698743e-138L, 6.3116464532127354831381913256985002e-143L, 1.621583693919220194566929433171311e-147L, 2.9757935132829859613289387859126523e-152L, 3.8591705765442151638142119206858087e-157L, 3.4980555618589782147605871793646301e-162L, 2.1911032417571959066795311563828556e-167L, 9.3736234796108920474724971094564098e-173L, 2.7058522933326574274299142121455261e-178L, 5.2051004982716048091082896972654894e-184L, 6.5869897226619604622569213699928695e-190L, 5.4113353348952773541650437440862393e-196L, 2.8465905848751190783736476660662487e-202L, 9.4537279066777943316631814110533656e-209L, 1.9534309746768722817386272635097574e-215L, 2.4738194858760899904808482337660157e-222L, 1.8904418888763632604075097028006049e-229L, 8.5786751348486017374921228218675884e-237L, 2.273808044980070953576133599904938e-244L, 3.4605977152655857787870383972443829e-252L, 2.9714191752129370394435745626764138e-260L, 1.4135174726041132417612082341294276e-268L, 3.6561278873359158194812461400887331e-277L, 5.0434133108713706852575809257966216e-286L, 3.6370069739853174907232860458211075e-295L, 1.3431929449017207014618114298104235e-304L, 2.4870346219017639693976883745872467e-314L, 2.2586869384020337841470045671934569e-324L, 9.8364979621195023902799369645695391e-335L, 2.0067948188168259586571751290590148e-345L, 1.8723608312818058521936506625581294e-356L, 7.7931764302539272294837164978121943e-368L, 1.4104242105367751421756306559719189e-379L, 1.0809707526373134180302026203191734e-391L, 3.413982422671325929147843223533059e-404L, 4.3198627266120931546631293969877099e-417L, 2.1273069601360357294162339387648629e-430L, 3.9566885872209056027370422510981332e-444L, 2.6949582298096968115536767242364878e-458L, 6.5109076931010576854739908270299986e-473L, 5.3989788614177770156022874990436434e-488L, 1.4853198669149487016912694923346188e-503L, 1.3090503251521584428930352496581121e-519L, 3.5647376837004158357511297570921346e-536L, 2.8896313028497521005627356654844694e-553L, 6.7095854399465738026181868874992309e-571L, 4.2889584337257558657454644184109877e-589L, 7.2448311439514538923291336946008664e-608L, 3.1001155749336353171177254469615123e-627L, 3.2171491615676533889663223546563542e-647L, 7.7406570695117283869992601856060778e-668L, 4.1223744692343859730646543586548491e-689L, 4.6322294010052851367822679106298139e-711L, 1.045335659900684312871171221243375e-733L, 4.5020856241223108492475174506019875e-757L, 3.5109989183708310084991820318792658e-781L, 4.6962204836998229475507359520919518e-806L, 1.0187348472076847046857363810773889e-831L, 3.3829163365599114939619605636207329e-858L, 1.6201873291670617651278341356078551e-885L, 1.052417929633641351707580294560769e-913L, 8.7019793416937745490332209560882093e-943L, 8.5790292111351760552267505428090183e-973L, 9.4260553303166607465714226577573373e-1004L, 1.0765751303003708312349678449534298e-1035L, 1.1895201137046793178631747385045816e-1068L, 1.180625613342395519601533530260917e-1102L, 9.7508687447891759767569844552344533e-1138L, 6.1928172812184124261845708258990883e-1174L, 2.7879318459600816091819660853849943e-1211L, 8.1797014327573742781475939847205791e-1250L, 1.4341956738449380463933781088853353e-1289L, 1.3742136648085548142182437043687567e-1330L, 6.5614725919712462874880606553304539e-1373L, 1.4193967474068871671305637677852339e-1416L, 1.260966346895598155305400631354573e-1461L, 4.1570767913697591845636153183534885e-1508L, 4.5808704947181685782204593123998747e-1556L, 1.5147204987797220696721543058866571e-1605L, 1.3446319068528240765599796700835479e-1656L, 2.8568551875090842255902159455984979e-1709L, 1.290420656637587734011142529706619e-1763L, 1.0965883695419688652509296670806449e-1819L, 1.5454358117029190110066857968185965e-1877L, 3.1713220921953507873149502965607843e-1937L, 8.2852363729842743064713740610323336e-1999L, 2.399312892921620764854020931161764e-2062L, 6.6760404808499701150348715300290141e-2128L, 1.5401518790175723653421594673899941e-2195L, 2.5301735371980282112359832727046555e-2265L, 2.5299480120770166824316075523796362e-2337L, 1.3095313462113548374850512340351666e-2411L, 2.9689243920149770430661749727744362e-2488L, 2.4813830291085919140036931759581715e-2567L, 6.3996445311970094107659804037592786e-2649L, 4.239251909781851582408879081262827e-2733L, 5.96853928335010438943934366176163e-2820L, 1.4691168838129215779634944240558196e-2909L, 5.1680311504236953911307750231831853e-3002L, 2.1104104354704386557845763111476113e-3097L, 8.0724923764466854235161222774323272e-3196L, 2.3180110258875131728741090820512076e-3297L, 3.9765565093255272984730390679523982e-3402L, 3.2199629992549034490326426922965119e-3510L, 9.6508721511747631002418659479792544e-3622L, 8.3314890242471693358884470423786766e-3737L, 1.5992989019877436694379940011582504e-3855L, 5.2267357291195312826488098055916878e-3978L, 2.2079407038664800796624257814276463e-4104L, 9.0732856778373185742790691459304111e-4235L, 2.7052547418764871675136904567273848e-4369L, 4.3243575109951310431228833829026739e-4508L, 2.7122975060794559909023695709869724e-4651L, 4.8370932158845122662637153824534517e-4799L, 1.7593494088080091822518592461420403e-4951L, 9.2629313370158738463326647490577837e-5109L, 4.9562745065321184922933588793911493e-5271L, 1.8710195150434747289751408668152425e-5438L, }, + { 1.5706077165382752220570950499753154L, 1.5690996953516691278086267057102919L, 1.5660882389174613671811758395264413L, 1.5615824934918106190924913174771039L, 1.555596114631660422166342990902623L, 1.5481471912355573327293783013569808L, 1.5392581453118818324345492520631963L, 1.5289556083545807159292699900112433L, 1.517270275405054680346497720954261L, 1.5042367380636772129345718219774013L, 1.4898932978832971219484878984168431L, 1.4742817617280797281467109946343097L, 1.4574472208125486663314082491076236L, 1.4394378152464069775161779990628486L, 1.4203044859996911837480782185431865L, 1.4001007162694446513758901419788661L, 1.3788822642731375176779450629832807L, 1.3567068895156054674526777181888561L, 1.333634074575756135382992612713127L, 1.3097247444374397383128243464895219L, 1.2850409853467272312421857577496357L, 1.2596457651166706020800416735545885L, 1.2336026567219467107844443624642869L, 1.2069755669313082254213358903568052L, 1.1798284716173337422807600081541025L, 1.1522251592625474295137962600991148L, 1.1242289840506032580653098282178496L, 1.0959026297929722120123658782081807L, 1.0673078857975038741099002717210955L, 1.0385054356373923292061824367921921L, 1.0095546596294298182250582016592233L, 0.98051345168085502517972727278507908L, 0.95143805101635270871239123838108163L, 0.92238288915245514551412028761663168L, 0.8934004523471959982711625120192134L, 0.86454115961966899850156197132807295L, 0.83585325630826713062996261999715574L, 0.80738272301876303826323728461609798L, 0.77917319970479798076341140529382576L, 0.75126592452435685914062625329355162L, 0.72369968702683029319553573992504406L, 0.69651079514654688482101628454709857L, 0.66973305541029099783625527361406845L, 0.6433977657082528556344204308635143L, 0.61753371992990889983731720244260268L, 0.59216722372820694935702418127019L, 0.5673221206467387178357679693601802L, 0.54301982782484286720274321665461387L, 0.51927938048424633084628868358974812L, 0.49611748439731621394870318175376878L, 0.47354857554061400457926695177211335L, 0.45158488614754491438064885165412276L, 0.43023651638978897817371690879635701L, 0.4095115109381936343721381503891959L, 0.38941593967921202782661222737925564L, 0.36995398189211387219291724401952693L, 0.35112801322442524717390619924264052L, 0.33293869483774779538113623624821976L, 0.31538506413267813525698287867505706L, 0.29846462649944498394951741316395666L, 0.28217344757959610491269401677566302L, 0.26650624556313516141887797351312194L, 0.25145648308451039819955104711453138L, 0.23701645831941898915989673276556716L, 0.22317739492218458776987874976238264L, 0.20992953048020753663062039840873861L, 0.19726220319743719884124330734112999L, 0.18516393655277551537189585427079996L, 0.17362252171163130317128688392273587L, 0.16262509749938432420455409981591821L, 0.15215822777419972032806536862862315L, 0.14220797606340183123695433555896409L, 0.13275997735244552637840297048350341L, 0.12379950693841296100725547935434371L, 0.11531154628093733739002418825877215L, 0.10728084580255643428531503966925542L, 0.099691984607788577667458210957830992L, 0.092529427105778463900867988199890184L, 0.085777576535268189772833000772228023L, 0.079420825403008155143300459369002492L, 0.073443602857638774779152196546779989L, 0.067830419030657966460701735648315918L, 0.062565906384455108312883097272720571L, 0.057634858114654726990360882355019006L, 0.053022263660287178654865336510427632L, 0.048713341380701431454862729860209054L, 0.044693568462765533522590231699541224L, 0.040948708125867302497552393088112476L, 0.037464834195628972796376547170838841L, 0.034228353120175696600101652094083332L, 0.031226023505331741095045556858942863L, 0.028444973247334237420578959776412296L, 0.025872714343617644485216127636544335L, 0.023497155463988527331246316453605283L, 0.021306612366126070465592025046447108L, 0.019289816240845601467614148418736892L, 0.017435920073977461259931130790681214L, 0.015734503113059796501938486945359929L, 0.014175573528330460201833138862417195L, 0.012749569358731162695972946581614495L, 0.011447357834799756252759767428888751L, 0.010260233171410768904966921400699131L, 0.0091799129243109016820036013086815458L, 0.0081985330052611999146716526049152539L, 0.0073086414513132480272928751787482011L, 0.0065031910442825794569735904252798084L, 0.0057755308768065491405505517951108403L, 0.0051193969614537818669843222017295048L, 0.0045289019791562891246666236654351803L, 0.0039985242627335310486699760330762132L, 0.0035230961104429863210055440392477764L, 0.003097791523300820656719025216576771L, 0.0027181134583502264180047688832185696L, 0.00237988068810043824649673132220802L, 0.0020792143540086661490040088456472881L, 0.0018125242991288642651054139496748517L, 0.0015764952619105560466714983901735372L, 0.001368073009609703955236179563862531L, 0.0011844504858902772190681005760231091L, 0.0010230540429745410945605352201833147L, 0.00088152982417297002262517617153839107L, 0.00075773035782735921074324212296621353L, 0.00064970141867429037384583446669345298L, 0.00055566920742578558188343231541026958L, 0.00047402789401816719609357067930453704L, 0.00040332756454954092910822407611191225L, 0.0003422626064629768809457896368129693L, 0.00028966056108877174342801893880690422L, 0.00024447146728689162442142144970348683L, 0.00020575771467998818628501233394779612L, 0.00017268441988592922811041420156552324L, 0.00014451033429094586468260075495740334L, 0.00012057928729056996115421473619828627L, 0.0001003121646011242017105871905771618L, 8.3199417240036480655327139421155229e-05L, 6.8794093113496376994935071214960655e-05L, 5.6705379853932877470011678973870605e-05L, 4.6592644630494618702241456703037532e-05L, 3.8159954120245760316298139014562893e-05L, 3.1151055677448352880855786865941099e-05L, 2.5344798968850110019503595997329621e-05L, 2.0550975944934244592401576964828471e-05L, 1.6606555976508335934243673648199596e-05L, 1.3372292284532372637222480551805329e-05L, 1.0729675406852340659025097863229453e-05L, 8.5782093537079082475098159798479489e-06L, 6.8329862774218506793384467861049682e-06L, 5.4225358918240331874795406776236123e-06L, 4.2869264939998226801201888531480146e-06L, 3.3760952348055109687047948553034167e-06L, 2.648386225404341059332347382668934e-06L, 2.0692761257364670911197722058327534e-06L, 1.6102680094507650586919500255804135e-06L, 1.2479355121177451927952866165256362e-06L, 9.6310052117659252623275411195037422e-07L, 7.4012893490908614244527654085271701e-07L, 5.6633028402050775174949474283673891e-07L, 4.3144825587165380566889409128276242e-07L, 3.2723037330517558940458575985214918e-07L, 2.4706624511249700700814105972385083e-07L, 1.8568491370025132363780817403060483e-07L, 1.3890286996035952957423247999266266e-07L, 1.0341528040745607124994759911720107e-07L, 7.6623873974817584699067130031657306e-08L, 5.6495763871670621475281493521314709e-08L, 4.1448233558505383939707940899336768e-08L, 3.0255196464899467188973440250947218e-08L, 2.1971648917089349870913690980235634e-08L, 1.5872978090968232625950436800137184e-08L, 1.1406465554850482080861078708713322e-08L, 8.1527464828576537674941124925699748e-09L, 5.7953495730966064129686023678242569e-09L, 4.0967579139685198004841429173893772e-09L, 2.8797013464471104655049488102491186e-09L, 2.0126210218867172874496187582569718e-09L, 1.3984414312565442025515753185221259e-09L, 9.6594851858099300536090988590771494e-10L, 6.6320863470162099803938291638680053e-10L, 4.5257576104153821951813027371570715e-10L, 3.0692702078723328679138233160912672e-10L, 2.0684203539029217544821684017571545e-10L, 1.3850287525834145108955800004991698e-10L, 9.214056422651888408320635035510389e-11L, 6.0893387064380670508776147108848386e-11L, 3.9973389519930269589286591598258413e-11L, 2.6061960502805293348144397281679947e-11L, 1.6874519343915025228826792012273533e-11L, 1.0849161834337120075418713193749676e-11L, 6.925528015268138234276418201069421e-12L, 4.3888651899779304012906781620222308e-12L, 2.7608587671398283608193689290767215e-12L, 1.7237644036042717645352410466671951e-12L, 1.0680750436541459501472279340038532e-12L, 6.5669443496573770247087892915106603e-13L, 4.0059853799532432743143892523313549e-13L, 2.4242966045442409054601213028173084e-13L, 1.455249915777183791487150796402817e-13L, 8.6638127254357861703205617203908732e-14L, 5.1149749011237035858347608326433163e-14L, 2.994217759503148409824465166785657e-14L, 1.7376816946074293584520159998670905e-14L, 9.9964240098994293054396937904035808e-15L, 5.6996266660577917745539527915605509e-15L, 3.2204325132709429326443049307963174e-15L, 1.8029589638948994224704223595333813e-15L, 9.9999573441511328003764710559432247e-16L, 5.4939783973500551313304111867037353e-16L, 2.9894208856836080833460170608635085e-16L, 1.610765424389333897595412933702905e-16L, 8.5932097482708020320234894915603507e-17L, 4.5382468267138486711718165281416612e-17L, 2.3722531670914086186505578503296188e-17L, 1.2271671669957684251768746309727359e-17L, 6.2812290485539754593993025086049784e-18L, 3.1806147137287576603303714266387884e-18L, 1.5930492574791968327078642420897427e-18L, 7.8908551593455841363543904697547233e-19L, 3.8647331030140734169770289169399394e-19L, 1.8712773299709086118483416095592492e-19L, 8.9557394552313902528032623648079256e-20L, 4.2357428519456376102962467454513856e-20L, 1.979436201534175012643985224780424e-20L, 9.1380785584698727034273276491713887e-21L, 4.1666411584773049229385926804715087e-21L, 1.8760750552668470771305003442308049e-21L, 8.3399019486525331443195597764274931e-22L, 3.6595752362436730932932611770341911e-22L, 1.5847852183325978194205652538004105e-22L, 6.7715756944343963844212791596730701e-23L, 2.8542817079371140817224171432389793e-23L, 1.1865838580947568695752893868758282e-23L, 4.8640699357080450262013571667032291e-24L, 1.9656434192469852200073765210097077e-24L, 7.8291656246958620676899939812206199e-25L, 3.0727892288172702707668669968129923e-25L, 1.1881076147213762784564203492918474e-25L, 4.5246197487634934114352468991264689e-26L, 1.6967101868478854591740026523544294e-26L, 6.2636410032291183199621894495108545e-27L, 2.275790792857396714851032797332432e-27L, 8.1360777159044314206100175821194793e-28L, 2.8613065492953910272350038532776635e-28L, 9.8961841969437875600155257339935786e-29L, 3.3652008931641398734060087635568974e-29L, 1.124807054607635533524732113721643e-29L, 3.6944604327139334398530256817969063e-30L, 1.1920933013465364813127655880555969e-30L, 3.7777578760183197857216889284069537e-31L, 1.1754363786778472289935929233399097e-31L, 3.5898790778284615893833448994196406e-32L, 1.0758426862142799782307176268359752e-32L, 3.1628351259465958616106447958915727e-33L, 9.1186741890740659476367230179943904e-34L, 2.5773931684416249884030668079887807e-34L, 7.1398295043464040965283248909128753e-35L, 1.9378289210199819221125431141075043e-35L, 5.1513791013790083352767878745680313e-36L, 1.3408183263237239554032545670003467e-36L, 3.4159407851320474430217223083201431e-37L, 8.5152627413375142768339982799164144e-38L, 2.076271482369099670696465965718329e-38L, 4.9501378383448158752628326041586328e-39L, 1.1535696769569322062307767078682896e-39L, 2.6266829648536609656499385130095636e-40L, 5.8418474765546354958505600321922284e-41L, 1.2685583522817839163209325300191513e-41L, 2.6885912245101334092484585567288326e-42L, 5.5593886486694506967808090446058169e-43L, 1.1211105786168708837628837423551506e-43L, 2.204030437173812137094585242452846e-44L, 4.2224091761364250309210368326791673e-45L, 7.879520062360877249284818876749499e-46L, 1.4317140234575381985434267597963095e-46L, 2.5319048034172799761988113239574673e-47L, 4.3559981958200842427093791079007571e-48L, 7.2876743960081410061189361036751606e-49L, 1.1851134957779509548750104934682377e-49L, 1.872433458377359457763352131002218e-50L, 2.8729694149829129971079440142039839e-51L, 4.2789120660247665069210975132651194e-52L, 6.1831517263855101991333477522333856e-53L, 8.664706532064762178060555848235158e-54L, 1.1769423732336786099340369561810161e-54L, 1.5488187383481079319128553087281025e-55L, 1.9736646088073419346394015708589866e-56L, 2.4341838396213207647077873905717686e-57L, 2.9041369422835327495394798923780893e-58L, 3.3499429920119329938613749830054234e-59L, 3.7340806058053956442103094318030179e-60L, 4.0199589180457423324670244391460705e-61L, 4.1774687856674289017944418799754548e-62L, 4.1880972367088277279311490203747192e-63L, 4.0484306973548957998328137903090132e-64L, 3.77114883236106507191241601008861e-65L, 3.3831738882583366253452262404438761e-66L, 2.9213348345532154319786866459214566e-67L, 2.4265171108768020980951563482987534e-68L, 1.9376034615932002776264780070086131e-69L, 1.4864705425001770514685771802938584e-70L, 1.0949232255990064493457806009226565e-71L, 7.7387134447881401018887497774386554e-73L, 5.2448008205426118383234631723504239e-74L, 3.4062562927830356374440099107130253e-75L, 2.1184692439258592242177714552745419e-76L, 1.2608614434809477030102983673195673e-77L, 7.1764903126208755695723110547276813e-79L, 3.9034697656266028736188479360578122e-80L, 2.0275573404310544862715347770507338e-81L, 1.004994816430593904290660376649901e-82L, 4.7500986471514075093717143999280406e-84L, 2.1392636099460832836078416112710222e-85L, 9.173149292867278730161085643245862e-87L, 3.7422217329627927169047643424111024e-88L, 1.4512980036440354977046772500061822e-89L, 5.3463017574991130746397399989936882e-91L, 1.8692545071988721039716330965097833e-92L, 6.1978958931273853497246435906829052e-94L, 1.9472339695524234456610961876127122e-95L, 5.7919052872513171909291273369047611e-97L, 1.6295956267419577729908767823766263e-98L, 4.3332432642363261903550403983227406e-100L, 1.0880149430086354606207846327564807e-101L, 2.5772282627352113781815039093907765e-103L, 5.7539838006451121430858484531452556e-105L, 1.2096990017248315153784188752260699e-106L, 2.3925872664345045807315831521649824e-108L, 4.4475659282644875495932738704595289e-110L, 7.7627738422265479186699876924736519e-112L, 1.2709267303083863208341290697181042e-113L, 1.9498242131608832039698501560236386e-115L, 2.8002525531974060834525812862103801e-117L, 3.7607474856227547424556497710309557e-119L, 4.7181060260584103957700726731938295e-121L, 5.5234683214250331048701341097289187e-123L, 6.0274476904458633271417170323324512e-125L, 6.1242336828836773956273877493935834e-127L, 5.7873336327745621779130244175524495e-129L, 5.080632710884007461562439620052701e-131L, 4.1387180173608798644427799558698992e-133L, 3.1247188175223382722031520705749413e-135L, 2.1839031164024077549981710942515192e-137L, 1.4112539862126523413412548851519319e-139L, 8.4215132945549247707528420294855683e-142L, 4.6349339497376890248654482771898709e-144L, 2.3496985464521993504910835710336684e-146L, 1.095806710681902573252914390685236e-148L, 4.6950275371271587533706139425003387e-151L, 1.8456310819897755187059215917442304e-153L, 6.6476058774188256202611396416535206e-156L, 2.1907913883958482863705726011811944e-158L, 6.5969704613629998580324088255164448e-161L, 1.8125024222344232769814833021310009e-163L, 4.5370781893964839845073953864812105e-166L, 1.0332388835710739936372904447767308e-168L, 2.1374954497695898284726118552680548e-171L, 4.0108149042055622979938927508096981e-174L, 6.8157812455297175262972900652817266e-177L, 1.0473127652676199964496156413213892e-179L, 1.4528685940321876156376494017441343e-182L, 1.8166282837173462776489744689123018e-185L, 2.0440202882824856548036164467448088e-188L, 2.0661513859552458565266153108297534e-191L, 1.8731127932057798663856916994067048e-194L, 1.5203587637183862829799380406495058e-197L, 1.1029412423875246289335781867943994e-200L, 7.138626970990275795307217364262657e-204L, 4.1148385080761107172311325770404465e-207L, 2.1085028345530812052701929614749437e-210L, 9.586804728597153811540457301738394e-214L, 3.8604168930466380230648935566836905e-217L, 1.3741198913182849308419643845423577e-220L, 4.3152058575378643032664917818412533e-224L, 1.19318553486394227968739928824324e-227L, 2.8991695266404489121362655770787829e-231L, 6.1775221006993094876500875992969792e-235L, 1.1519457912295313262297054573241955e-238L, 1.8759214343015253296548435854195451e-242L, 2.6621687700905798726983482845704724e-246L, 3.2851388833240439850794784627378447e-250L, 3.5173302898760059862233242135090423e-254L, 3.260189457452227113017033626415114e-258L, 2.6100961489800200467379180863184362e-262L, 1.8007454797962902444457099319194981e-266L, 1.0681019906266894643271137718146545e-270L, 5.4338051160125203325306044546291973e-275L, 2.3652466547636417935201205492175566e-279L, 8.7874613708003418754944028581674092e-284L, 2.7795968403545195493312606588081939e-288L, 7.4667445765219841782970695464816343e-293L, 1.6990035121087781757668989612218036e-297L, 3.2661456244114182842789617411036552e-302L, 5.2905644824269341726292739407836284e-307L, 7.2014912174357894815487914007866659e-312L, 8.2149916381513794689686855840667286e-317L, 7.8315488217791735530193073164613925e-322L, 6.221807701348355377240172152359918e-327L, 4.1074011155154758472047101692258134e-332L, 2.2466366589127674529456245569217313e-337L, 1.0151434061771573997492847262735324e-342L, 3.7778453114026807637246195807729534e-348L, 1.1543990703305213109241662519678786e-353L, 2.8874514917596574178755044320075352e-359L, 5.8931980361396154630354121875276487e-365L, 9.7830460697139640980628824283457061e-371L, 1.3166522887017193888073217487220663e-376L, 1.4318812372702150835656599374620546e-382L, 1.2540768871672304974301195995718396e-388L, 8.8153996483879828169726259431129063e-395L, 4.9562889772003524717252843516553902e-401L, 2.2209583723340796264599763080008776e-407L, 7.903905845967360394872219425003336e-414L, 2.2257919152191142215565812315993462e-420L, 4.9416038684875140142672214621735078e-427L, 8.6171916788075114925145119819509171e-434L, 1.1757806822258262957023704296248014e-440L, 1.2504660464052680899003468814266606e-447L, 1.0325197258632347378121850864959173e-454L, 6.5928728293837187402797552969580767e-462L, 3.2422215378060561710679179733872247e-469L, 1.222971654709343975246423698805888e-476L, 3.523560719191273512100160441884497e-484L, 7.7214021325433144875052949047234787e-492L, 1.2814096433117550022825846412075423e-499L, 1.6034524983169066795932277083952198e-507L, 1.506154257333325578480885384144555e-515L, 1.0572229793982283970011093126796893e-523L, 5.5202045762026741431740525809554222e-532L, 2.1340837910128019442948018148493991e-540L, 6.0796683172016911238300290124661526e-549L, 1.2702010542787853060770224333562558e-557L, 1.9367268433132755704840764854736682e-566L, 2.1444373126935426310796432391730652e-575L, 1.7156127051237753338771752429597998e-584L, 9.866507362005302302229219896627392e-594L, 4.0577781777778825723169578502780851e-603L, 1.1871364801794013747840938511563031e-612L, 2.4573736732127578624297116105185871e-622L, 3.5795957466771145363085369419550411e-632L, 3.6491000343716609306595204093204503e-642L, 2.5887224173643746039322073618863653e-652L, 1.2707309714711704379079743917253552e-662L, 4.2911292837382087644451178350840055e-673L, 9.9101724991114880676267115929463864e-684L, 1.5559081312551687762049592042215559e-694L, 1.6505944447381619620675148844917786e-705L, 1.1758976044388560589646808736426135e-716L, 5.5904673599123524828590221558073227e-728L, 1.762422841281411916279811438897522e-739L, 3.660545736359787919552147533680784e-751L, 4.9762407942794836638678732794521407e-763L, 4.3982297935392846258826361101417004e-775L, 2.5103306493196863847807186768995234e-787L, 9.1890276778950746130428977933070467e-800L, 2.1421794336828190981917187030902949e-812L, 3.1579407773552118084939940851249037e-825L, 2.9226685587591509131252404660323457e-838L, 1.6857720383594173922437511994184956e-851L, 6.0148932059792413237874599630717323e-865L, 1.3175950977896871810836083428540193e-878L, 1.7584274071402706626129462062711265e-892L, 1.4186205574627811155197950438077455e-906L, 6.863804756553040536363703712029114e-921L, 1.9757126782016829801994589969078639e-935L, 3.3557616466388148224311943077895109e-950L, 3.3354866661158784873247273739595471e-965L, 1.9238163515428741014100444007200552e-980L, 6.3838419214869081664291315367530963e-996L, 1.208186393746817780221157077221556e-1011L, 1.2926433460770675227136395965601267e-1027L, 7.7484641126890628613399212918871834e-1044L, 2.578590762872741885363873428172601e-1060L, 4.720135411440959292309368252688105e-1077L, 4.7080786123051904219070581932647786e-1094L, 2.5345319096404707885383043943244978e-1111L, 7.2928761242789730396354678181188802e-1129L, 1.1106128952895418090598971812669904e-1146L, 8.8621216538366976598099979452808551e-1165L, 3.6677828388640988980975786646419682e-1183L, 7.7923888084439739305704880307980387e-1202L, 8.4096550976573708334084140027496576e-1221L, 4.5613561814429013831962003215267279e-1240L, 1.2300215778004431684442502009102409e-1259L, 1.6310040159866857782581696492106591e-1279L, 1.0516379174444742948762886500817157e-1299L, 3.2599823473651125257811218258666689e-1320L, 4.8027868480449172060158102541122388e-1341L, 3.3236309884819155458562664594667437e-1362L, 1.0675935976034168796912624171598076e-1383L, 1.5726195400977448490722891999643084e-1405L, 1.0493832555753684651126599489805473e-1427L, 3.1327201084154872489458088843708842e-1450L, 4.1312837255709912970140480142041816e-1473L, 2.3759469769680296617336666937339053e-1496L, 5.8816760470052203616229940275916193e-1520L, 6.1846204357986408200352274197037853e-1544L, 2.7253154006156158167192213817170292e-1568L, 4.964370850871644112480158952518382e-1593L, 3.6864952720610418491857518517405997e-1618L, 1.1003435724966953469136035841615193e-1643L, 1.3012915572536198178305157209959287e-1669L, 6.0092590718277568469858434192698668e-1696L, 1.0676671777328477051443719591612721e-1722L, 7.1893041788265042697820383343649581e-1750L, 1.8069174401475778125395048319028868e-1777L, 1.6689765331128672749329764129278041e-1805L, 5.5766895369980043818737558535999006e-1834L, 6.6338104205654511592967377535571654e-1863L, 2.7640539994999072399732281044814252e-1892L, 3.9678218215367472586686997493459426e-1922L, 1.9297110274588854079208153981267479e-1952L, 3.125823255660491143824024380405163e-1983L, 1.6574847870654916983076674690989236e-2014L, 2.8268986732520512350429266473306993e-2046L, 1.5233117185863507338781156113800939e-2078L, 2.546861334196453858326476740489303e-2111L, 1.2970473455790653045919178951673388e-2144L, 1.9747419969447016216735762205746422e-2178L, 8.8188278044353709778558661887540083e-2213L, 1.1331026308914886857015956789021835e-2247L, 4.1073843396377054383734821718609159e-2283L, 4.1176061068991316842526396776090883e-2319L, 1.1187086154165438557157295454514512e-2355L, 8.0696152044407520449588862080186105e-2393L, 1.5135007846133660639825213215103939e-2430L, 7.2259333243684066847653432848351411e-2469L, 8.5946687461833096509693248289938412e-2508L, 2.4916284852956646502671815296350685e-2547L, 1.7218755528601187283427831366854425e-2587L, 2.7731789802471774097405514299103397e-2628L, 1.0173036737175759305843452255817661e-2669L, 8.3042791798168477802920353914502218e-2712L, 1.473175854535708068279125062330391e-2754L, 5.5445898944436653916624336507572418e-2798L, 4.320588676830861227044616106347197e-2842L, 6.7999319106199079525777026656783353e-2887L, 2.1077263780365503485840282493709679e-2932L, 1.2541789874677469018547003272238725e-2978L, 1.3958959110384407791740617210399902e-3025L, 2.8302814609077924874798718558506843e-3073L, 1.0177558252358910503169620579616733e-3121L, 6.316345161489586703263200702377878e-3171L, 6.5808353794152592529153513818570413e-3221L, 1.1191402820754794725611968922105955e-3271L, 3.0191144446114914489317417615052391e-3323L, 1.2550879768384736567252096901362895e-3375L, 7.8068891083719869927416696059040226e-3429L, 7.0517902304991510532607166162881123e-3483L, 8.9730892510839231589218006993975962e-3538L, 1.5595586152851619317721078977043233e-3593L, 3.5880900047081973177436521469002167e-3650L, 1.0585155878906962124317498469363852e-3707L, 3.8766455756851727310799307162918377e-3766L, 1.7055766393620807246392140051588691e-3825L, 8.7186526945824113614692955827617228e-3886L, 5.0057478847913665022916271652366648e-3947L, 3.118721903551705673676508466953291e-4009L, 2.0360271187838855169643637345546437e-4072L, 1.344193072571113944443469925533764e-4136L, 8.6564521926545774914724471102499854e-4202L, 5.2420435234912004640647252129478902e-4268L, 2.8759098307799421718470860096954611e-4335L, 1.3763877452472741048491095385711433e-4403L, 5.5298776937738818735087266649244396e-4473L, 1.7937216962986389293716315095996859e-4543L, 4.5149004338871753808860898565339903e-4615L, 8.4705695199542943533046216376760939e-4688L, 1.1370794062105632021349671352107651e-4761L, 1.0477206804639390072354388690482908e-4836L, 6.3526587059143165049479765478742544e-4913L, 2.4283486680552345908529800038916585e-4990L, 5.6028531999416699789095738832933157e-5069L, 7.4653403674710397422097751397913229e-5149L, 5.4919841992020489039553213694177019e-5230L, 2.1312688707736268785590779947753119e-5312L, 4.1653791598980828217930742787672032e-5396L, 3.9114639992058990826656399856975019e-5481L, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +#ifdef BOOST_HAS_FLOAT128 + +template +void tanh_sinh_detail::init(const Real& min_complement, const std::integral_constant&) +{ + m_inital_row_length = 9; + m_abscissas.reserve(m_max_refinements + 1); + m_weights.reserve(m_max_refinements + 1); + m_first_complements.reserve(m_max_refinements + 1); + m_abscissas = { + { 0.0Q, -0.048632035927253054272944637095360333Q, -2.2522807538407135100363691311150714e-05Q, -4.2941610558782407776948098746194498e-14Q, -1.1676488975098609327433648963732896e-37Q, -1.1479529916293899121630752460973831e-101Q, -1.2256538136584864685624805213855318e-275Q, -1.5540928823936461440049038613030612e-748Q, -5.3329091650553293055512604419528931e-2034Q, -2.9720916290005160834428657415764727e-5528Q, }, + { -0.32572850775156417391957990936794786Q, -0.0024851435427756131672825807611796319Q, -1.1124335118015331984966677262985097e-08Q, -5.3784915913936887745567608333252923e-23Q, -7.9430213192221161033965793076252082e-62Q, -2.3871228185819266205711383850686192e-167Q, -3.5505659459518255844385870776118831e-454Q, -7.5205359182648710139026226942624688e-1234Q, -3.1913442054759083418654684997091651e-3353Q, }, + { 0.37720973816403417379147863762593439Q, -0.14043094131010336482533980273793048Q, -0.012959439492623108312614281385864999Q, -0.00031173597164679094947882131119246211Q, -7.9526288528733553445705754617783867e-07Q, -4.7143551823222575055542137870412504e-11Q, -5.4152228238072308459654515228487702e-18Q, -2.0403003943524943294070815498839042e-29Q, -3.0596901353644500298194434206758382e-48Q, -2.8621984192587511612196829791231642e-79Q, -2.0070330691533226369447382138318798e-130Q, -9.24799327395281672235465186719e-215Q, -8.3199831454007319575241484332973316e-354Q, -4.7101915049286172051527740304785445e-583Q, -5.1172326001331791544221573365516138e-961Q, -3.565091902092693101170960484903703e-1584Q, -1.380788494593788864141714339603113e-2611Q, -1.676187209363792948538214808034106e-4305Q, }, + { 0.19435700332493543161464358543736564Q, -0.46085329461203223095024473969116941Q, -0.21939256101679970074520301166037226Q, -0.085120736735425389092624476255089179Q, -0.026033131804322551436697210776387341Q, -0.0059444933685978567073105981025861939Q, -0.00093480354421415357524054329032500553Q, -9.0615304856000161419338663865283889e-05Q, -4.6839587794715699213295541472938628e-06Q, -1.0721838758161809434047961979486614e-07Q, -8.572949078216773291904741005771376e-10Q, -1.7678346928387203697450793420511691e-12Q, -6.374878495044439647822814562601604e-16Q, -2.4429372790852173177460412747369906e-20Q, -5.2515464730195748562913138330508827e-26Q, -2.7894671622894177442056826817468893e-33Q, -1.2781108980938044979748713346336601e-42Q, -1.3082723368531808046381743164626179e-54Q, -5.2799781226102543764849911449215675e-70Q, -9.0619104054181014912823874637681869e-90Q, -3.7903152788024647936360099425967319e-115Q, -9.8301769964870442146689481371228979e-148Q, -1.4178035546472368325653350149379565e-189Q, -2.6738184762632894703182151426789471e-243Q, -2.7784573988900744903717061581976306e-312Q, -7.3734573357629727800590803405661863e-401Q, -1.3609194136463888140125728088459369e-514Q, -1.2497483783949474937966696885440387e-660Q, -3.8167291133270025322500901161738939e-848Q, -6.4205995373383705446145927875493146e-1089Q, -4.4417348039463271683501804024826735e-1398Q, -4.7673068229426388972968294463896211e-1795Q, -9.1130922352573668488349663479480507e-2305Q, -2.9379714111577752802646622386752463e-2959Q, -1.2139403773313257256483385510112958e-3799Q, -1.0232729473573403414331717146692674e-4878Q, }, + { 0.097923885287832333262426257841800739Q, 0.28787993274271591456404741264058453Q, 0.46125354393958570440308960547891476Q, -0.38972634249936105511770480385767707Q, -0.26898196520743848851375682587352696Q, -0.17668299449359762993747017866341472Q, -0.11010859721573980192313081408407809Q, -0.064839142478015316771395646494440585Q, -0.035887835776452708068531865802344445Q, -0.018545173322664829973291436321723213Q, -0.0088730075583011977688563205451530858Q, -0.0038913345624914574643783628537015109Q, -0.0015457912323022624891555460019043471Q, -0.00054856556472539415808492760717674295Q, -0.00017117792712505834023311917084994073Q, -4.6128994372039252659199558313379019e-05Q, -1.0517985181496388528104100992279397e-05Q, -1.9828594045679206280184825675885662e-06Q, -3.0110584738877965497930108986179822e-07Q, -3.5760919084657714373617064589353927e-08Q, -3.2128009016957604999656591474001583e-09Q, -2.1026713776411488104386696975012214e-10Q, -9.606066478508465003238769873504248e-12Q, -2.9190266410175139338365873758536822e-13Q, -5.5861166388382275217411050967087276e-15Q, -6.328207134683168236714250292398626e-17Q, -3.9564613394676478284814817479958896e-19Q, -1.2609758447165484726150111345292941e-21Q, -1.8724921745276082830417983528796313e-24Q, -1.1700302939131190810173673171853244e-27Q, -2.7409861783512409524809986743233587e-31Q, -2.1122827214476119769953891899502657e-35Q, -4.6172239482595017143038368975612786e-40Q, -2.4203621976262400766076976463254527e-45Q, -2.5155618638019452025824211444543239e-51Q, -4.1786390697021940369390798235100086e-58Q, -8.6898180082116723025562943397702972e-66Q, -1.7154357765002478902943183846995354e-74Q, -2.3493032412195338067008854292230121e-84Q, -1.5645432388942512177369950120860268e-95Q, -3.3873402047868364753040883051129579e-108Q, -1.5108166471007846474189907630676839e-122Q, -8.2780000956704166841985762886452778e-139Q, -3.1016029819580818393688194490134506e-157Q, -4.0917346928724404440872286063293528e-178Q, -8.9581681449485486979882444847795217e-202Q, -1.3878968774299744972242822597861929e-228Q, -5.7925742129350389434060147129950123e-259Q, -2.1800405760909812340138469200688552e-293Q, -2.1406911761156887130351179719470661e-332Q, -1.3453872213865718752685710282193859e-376Q, -1.101014385623064504263959341239785e-426Q, -1.9309068614975016262992988189610055e-483Q, -9.3925603630660026565835909833509362e-548Q, -1.2492852059051478595312298290165577e-620Q, -3.2901922810889194483613206478029049e-703Q, -8.7594800494412338094846019359419219e-797Q, -8.0988360915906760478163297865939266e-903Q, -5.7031344694656922604093410430637095e-1023Q, -4.0339055664976041957619784717611254e-1159Q, -2.1239178549857743261952555619757156e-1313Q, -3.2107478383582521299381622502244136e-1488Q, -2.5644945785388919263865858785287637e-1686Q, -8.6102745649577746230102198336971101e-1911Q, -3.7383203767208973356368595261534058e-2165Q, -2.1998398074691126029946216118342674e-2453Q, -5.4286931050493856204731826640809476e-2780Q, -4.3621004458123770532320189625677295e-3150Q, -1.8497978727098997950183603712476515e-3569Q, -1.1369676358500293654883467577244006e-4044Q, -3.7214839695831726545775627850809865e-4583Q, -2.4391504445900085306499460471723674e-5193Q, }, + { 0.049055967305077886314518733812558024Q, 0.14641798429058794052721556654753264Q, 0.24156631953888365837930785879296225Q, 0.33314226457763809243847911788190042Q, 0.41995211127844715849198982824847239Q, -0.49898661062069089848349381875489034Q, -0.42441550936484834004641698479390102Q, -0.35682324101479529871858133934192696Q, -0.2964499948528579843445043147096805Q, -0.24330609136627005059281117751078325Q, -0.19720125865675873423611581820317215Q, -0.15778075364924313618002648351129378Q, -0.12456460236959132162770016658853563Q, -0.096986718486426129363622040287916613Q, -0.074431365931387333547858011705581591Q, -0.056265213947242843145098876381950312Q, -0.041863977289786309881823549732911528Q, -0.030633267103082664829845578114893065Q, -0.022023764813335027020322387941507847Q, -0.015541168832569169131789346286900099Q, -0.010751568909866103993013400883081643Q, -0.0072830028031727146206149733302275483Q, -0.004823973844672645743610027178935428Q, -0.0031196818718081262793524354157388492Q, -0.0019666636845662459778601079868649985Q, -0.0012064657011941007112693927041613496Q, -0.00071888807820804459144864726303695018Q, -0.00041524964848241268314681568037451433Q, -0.00023202840043916493872468513410105539Q, -0.00012513495121965351530204004794322354Q, -6.4980074917576313794386569166441844e-05Q, -3.2406932056540235696910972894671255e-05Q, -1.5480097729175578034178680349142798e-05Q, -7.0621233371143522557906813506099499e-06Q, -3.0675508096424942465066236512329746e-06Q, -1.2645281340904582699398919033969316e-06Q, -4.9299428056311116061802876221616736e-07Q, -1.8110628723299136916197821516601534e-07Q, -6.2445921626224975560761130514661379e-08Q, -2.0125496798245795667718397386179161e-08Q, -6.0358657983522763759573155859882131e-09Q, -1.6766380517421942876239492441262369e-09Q, -4.292122273863880635543266425012844e-10Q, -1.0072227674373084849456997974551022e-10Q, -2.154466258904202365369932629331438e-11Q, -4.1753931241965133013258464583874422e-12Q, -7.2847372642877340424635554069698771e-13Q, -1.1363869854392191510522700311409067e-13Q, -1.5735535097926530184856977764147682e-14Q, -1.9192189097107621395219494827869742e-15Q, -2.0449595408467355635051956217352212e-16Q, -1.8869583067293409682109390382712203e-17Q, -1.4938716488357228966449278404247075e-18Q, -1.0046938100037576480510308414445084e-19Q, -5.6799291780731967001285171683592406e-21Q, -2.6691039526135151405184691859723367e-22Q, -1.0301781381894114683480515283399996e-23Q, -3.2244848763912462050246763811724513e-25Q, -8.074782900421688680511360232922118e-27Q, -1.5946546019932855470728505192034342e-28Q, -2.4457239752752825879158721953606166e-30Q, -2.8659197719078655681373680421610036e-32Q, -2.5216825251828994098262358831122367e-34Q, -1.6355144403100727446739341400788963e-36Q, -7.6666590990678357226674242484094458e-39Q, -2.5435771288137693474957657676429463e-41Q, -5.8409472280716482316816237196206469e-44Q, -9.0658695647939702552111019446179921e-47Q, -9.2735698160588525904827667013324314e-50Q, -6.0857148042052277604035466987369298e-53Q, -2.4898089736722146606232085397625384e-56Q, -6.1598620863170544290033299759018975e-60Q, -8.9214127072226711903218542175348322e-64Q, -7.3072243260040451389778049479673039e-68Q, -3.2625608625513858480451119539754283e-72Q, -7.635785144983622496088267971984613e-77Q, -8.9855174690288197015625761302053014e-82Q, -5.0858718515487289997949540667405475e-87Q, -1.3207396001984761034417395177214725e-92Q, -1.4964864935610521348123903353455889e-98Q, -7.0129233669310880373145304240642606e-105Q, -1.2839990161964174973579406866396101e-111Q, -8.6445683841052002170413994851536565e-119Q, -2.0063694896831555279614790770285332e-126Q, -1.4987740796184447811135706015205434e-134Q, -3.3493762149589610757447357005516387e-143Q, -2.0715294381434481475176795645059666e-152Q, -3.2638832593319965098529982282696874e-162Q, -1.199473759889723458030222815758102e-172Q, -9.3602085584027101517846387151893588e-184Q, -1.4035094428007866386369967794759254e-195Q, -3.6356107639491247696753307742986431e-208Q, -1.452743995741226464980668915527686e-221Q, -7.9377235820922308566742845525117486e-236Q, -5.2163536229754499795136126103956784e-251Q, -3.5964743752577816321270751238997225e-267Q, -2.2494401025357803105700529744520824e-284Q, -1.0932895122313467863909046216907507e-302Q, -3.5018653663752920075194010313564247e-322Q, -6.2028644584939181030730328594330175e-343Q, -5.0411076779076593359744388314869213e-365Q, -1.5409305985666377552321629186300452e-388Q, -1.4337691700836957601785568351756479e-413Q, -3.2419333785971000532922906392702739e-440Q, -1.4016483469785082716612467122698103e-468Q, -8.9774004157156246399741480681783078e-499Q, -6.491677776744900396848653659323143e-531Q, -3.968873851900238121124736680679859e-565Q, -1.5079636812339879861399394077308116e-601Q, -2.5657520984549883455506649942306167e-640Q, -1.3792637739621433541997914448762973e-681Q, -1.6159468091505698350217369718439518e-725Q, -2.7790201117578232055517503438743301e-772Q, -4.6058286485158911464074200874638533e-822Q, -4.7006358553201903008219637676007764e-875Q, -1.8338935012250262258997114428219912e-931Q, -1.6464242001502528395088533240159331e-991Q, -1.9816419848867601423745192888068803e-1055Q, -1.7991094041844603532543957306249989e-1123Q, -6.6797992361969494675858665124683032e-1196Q, -5.2859098848402526633383865829249954e-1273Q, -4.4550261847470794285196049926646754e-1355Q, -1.9109438945105886059290808709178883e-1442Q, -1.9007367698294334902014013473010713e-1535Q, -1.8987324425640464476346787762173242e-1634Q, -7.8167618149826855518169886771423511e-1740Q, -5.1382521738908379784587542986497343e-1852Q, -1.9655086052442019324819644975934904e-1971Q, -1.4940998787039296124957637312415828e-2098Q, -7.1913235695994009755126799768473976e-2234Q, -6.4864369300175247147155547975053653e-2378Q, -2.999946728125704672445599927700136e-2531Q, -1.7904880802749365558709955426180586e-2694Q, -3.1752504880744458148875772810912828e-2868Q, -3.5042626554286023022035386575033303e-3053Q, -4.5572536942770532680494362978923935e-3250Q, -1.1878504044248058672204846884752448e-3459Q, -9.4149599587707022465535580134518114e-3683Q, -3.0486081328912260971936320312995529e-3920Q, -4.7600871041282300101380551251356845e-4173Q, -3.6856282214670996203899028095741989e-4442Q, -1.2567068832608339131427238307321809e-4728Q, -1.43352474798599180975125045215869e-5033Q, -3.5192846690056568230804624618996538e-5358Q, }, + { 0.024539763574649160378815204133417875Q, 0.073525122985671294475493956399705179Q, 0.12222912220155764235135543647484308Q, 0.17046797238201051810697458795462942Q, 0.21806347346971200463019772812275949Q, 0.26484507658344795046121266511868619Q, 0.31065178055284596083122357022827612Q, 0.35533382516507453329875421158518394Q, 0.39875415046723775644258197210456498Q, 0.44078959903390086626728024419415105Q, 0.48133184611690504421849248706653226Q, -0.47971194930876984042437695635737165Q, -0.44241877173922176919985653200857201Q, -0.40684964640804684120174768961798095Q, -0.37304979194895712050380997331064448Q, -0.34104900825664987561685714614383599Q, -0.3108622749383323282394733757479914Q, -0.28249053251267587278787801637860204Q, -0.25592161645265260087450443652530469Q, -0.23113131323175341540544311864007538Q, -0.20808450762385788552523390287482686Q, -0.18673639149702614832471241636026165Q, -0.16703370608058912436398702772140703Q, -0.14891599201215126738569202826103709Q, -0.13231682422435401330546108424048627Q, -0.11716501175533104486690697891318309Q, -0.10338574571992397421289522925754423Q, -0.090901681836979564888397733057112044Q, -0.07963394696804719765304016834176825Q, -0.069503062002846593688614128282605538Q, -0.06042977606672524461492007773726152Q, -0.052335809384846902663067556129352578Q, -0.045144504194977314593201232656013596Q, -0.038781384848883592468460207166535186Q, -0.033174629687644147159978329404393879Q, -0.02825545843451269107668693235164557Q, -0.02395843974342326066584697335177699Q, -0.020221724199384237353497637367719603Q, -0.016987208518898894423060324544850119Q, -0.014200636974716564032303584519259449Q, -0.011811646199257357569283265398947793Q, -0.0097737595324722530639024866802767264Q, -0.0080443369973223843798692318964963564Q, -0.0065844868307359609987086057921138135Q, -0.0053589442874888032779151584247851277Q, -0.0043359231830468303521751643564073944Q, -0.0034869453597462268271205586183706831Q, -0.0027866529565312977632015610760207467Q, -0.0022126080410934691734971443584643208Q, -0.0017450838280037065615903399860968624Q, -0.001366851359322522377124006197840537Q, -0.0010629651664878262735108241097275379Q, -0.00082055106511408284244272347987383953Q, -0.00062859885906231310357940554216565142Q, -0.00047776234878279577588863291489417448Q, -0.00036016865439963480978268344017946398Q, -0.00026923848019151736959880088820900265Q, -0.00019951856886161369803218944988361524Q, -0.00014652722688858828517464005147727694Q, -0.00010661345240743574350860189665463426Q, -7.6829870710671305672093252530903342e-05Q, -5.4819385541306910394346187661030795e-05Q, -3.8715192143333868407124859677345036e-05Q, -2.7053574767763435703448594138071512e-05Q, -1.8698729879273208281214887386151327e-05Q, -1.2778717999371889596874911057724209e-05Q, -8.631551655126555923485540179705975e-06Q, -5.7603723833652179866412085097651011e-06Q, -3.796652833823246921587494391038503e-06Q, -2.4703761948320696741670218229372071e-06Q, -1.5861890352645758023485712079757291e-06Q, -1.0045893100303765084297472484854592e-06Q, -6.27292664630529591934671730489378e-07Q, -3.8601144975725102288841415591950667e-07Q, -2.339766675668795211736366707138927e-07Q, -1.396287854005922888135986291920763e-07Q, -8.199520528943774856188619843122174e-08Q, -4.7357335538151973999955685632054965e-08Q, -2.6886764056376916830145130602254872e-08Q, -1.4996923688266632451823595335560501e-08Q, -8.2135439009280190432084662337190249e-09Q, -4.4143663841612464008735244035118061e-09Q, -2.3267632621004612298287053849704746e-09Q, -1.2020164996011407668894632352766295e-09Q, -6.0822312416778615105389374826677738e-10Q, -3.0124563074832322562803735802769698e-10Q, -1.4594388450012857143914599919653952e-10Q, -6.9111604985231078666967248228438538e-11Q, -3.1966783264445369722850429235278972e-11Q, -1.4431209924042652494507345459464675e-11Q, -6.3536761284911814276716019591237312e-12Q, -2.7259505188725197201090431322689677e-12Q, -1.1387345722407849659711071645809649e-12Q, -4.6277346217693134290561172417433117e-13Q, -1.8279902248431104840099026765769527e-13Q, -7.0120467384905686087185698802558123e-14Q, -2.6096053661379546374618820988626935e-14Q, -9.4133613352888555760685465264560536e-15Q, -3.2879256949364934203905795056053052e-15Q, -1.1108629401821898431250973198964316e-15Q, -3.6266022642032122019717830419062828e-16Q, -1.1427876525052669863279877707280153e-16Q, -3.4719022692494936795924113147604942e-17Q, -1.0157819068305124587449297554375856e-17Q, -2.8585328245081481739274807557448345e-18Q, -7.7278347873892552568443785071813692e-19Q, -2.0044239922175172204979314952837677e-19Q, -4.9815683764699114931038226437577286e-20Q, -1.184668492422340236764487382599448e-20Q, -2.6919849036103905707012031384082434e-21Q, -5.8366674419339414129894129738889481e-22Q, -1.2056615886548723513354371860285751e-22Q, -2.3691093508078067650593562318134397e-23Q, -4.4213394617280017751359368167258193e-24Q, -7.8238350041086858182189611432466241e-25Q, -1.3105331441254781548552012055519121e-25Q, -2.0743450130735150739962743364500278e-26Q, -3.0969683255507495828369632528319965e-27Q, -4.3532005281967559757740065310127852e-28Q, -5.7499556680703922900693138751854555e-29Q, -7.1227159266381727412068631384345687e-30Q, -8.2578354203558045768004451321024521e-31Q, -8.9415410066249555437647937669966689e-32Q, -9.022796650030866974265443296162775e-33Q, -8.4660301195315971752688615420135191e-34Q, -7.3692728065645298168617836618124666e-35Q, -5.9366323560088749776278557840220755e-36Q, -4.4152778386946959545381237143455402e-37Q, -3.0239601358635314916964716581634168e-38Q, -1.9022037916577048792943667867798758e-39Q, -1.0960433286034577882548963198643229e-40Q, -5.7686955980040694827320797355280285e-42Q, -2.7653993817377102211887943260200603e-43Q, -1.2038709528562574051108458784307785e-44Q, -4.7447623253354987177832150988795395e-46Q, -1.6876791281053309141043851984778909e-47Q, -5.3999669982997284808706183365024646e-49Q, -1.549024049448082614346506969629423e-50Q, -3.9699472552561349765465127201129129e-52Q, -9.0576749265239358552559531050991564e-54Q, -1.8329504334836931380757353284221911e-55Q, -3.2774223323973643896776906795254206e-57Q, -5.1576871530839363640889147624270212e-59Q, -7.1147152214081979999932108600174644e-61Q, -8.5668890171210249323533230713364891e-63Q, -8.9655585542113618588233770236885955e-65Q, -8.1186937969054743805236701211415782e-67Q, -6.3321938859077339155825561128906228e-69Q, -4.233726342460328087225876085667347e-71Q, -2.4147260464376790196845134616759282e-73Q, -1.1689555910948214525778546914101199e-75Q, -4.7780668985526446079787318493898922e-78Q, -1.6402035716952158990309656043758773e-80Q, -4.7024891487642105081472609988004035e-83Q, -1.1195904670077980724005196979590736e-85Q, -2.2005433507330024992345876236265894e-88Q, -3.5489240240632636451154177125584074e-91Q, -4.666940936883651858001572120481125e-94Q, -4.9719066745930336256015501390182822e-97Q, -4.2625120032373619347908954864791867e-100Q, -2.9205525410269401160683450458899041e-103Q, -1.5879283520520673524672134768919763e-106Q, -6.8010328774211569659959576053742516e-110Q, -2.2772324163917691950189307132002393e-113Q, -5.914722281629598175795438531560773e-117Q, -1.1820998217768840832984056598978546e-120Q, -1.8028262273951398891886168129927287e-124Q, -2.0802041335110124193794970445396975e-128Q, -1.7999670156396935596364355347029528e-132Q, -1.1573419660682545435402292296632314e-136Q, -5.4777666541440989994081254549149894e-141Q, -1.8900190812332372959031760309750191e-145Q, -4.7064318355746675546808068910291556e-150Q, -8.3711291364376416570212981885601003e-155Q, -1.0522139008817658534084763162543628e-159Q, -9.2441193400981258043604322474285494e-165Q, -5.6121650181326378940737135740792016e-170Q, -2.3270398424370294077224375501608811e-175Q, -6.510721186743015604234587537579044e-181Q, -1.2138997008699255952666017192674735e-186Q, -1.488912999352695867344311698561554e-192Q, -1.1855378186700107100267028475666946e-198Q, -6.0445584657932328676234962000989188e-205Q, -1.9456793188673556729031520231103262e-211Q, -3.8966805747095113950686230057410173e-218Q, -4.7829220009546143710431038737748715e-225Q, -3.5425595917324118172041028901087466e-232Q, -1.5581260191174140607938473801301532e-239Q, -4.0028071638967508676664829682660027e-247Q, -5.9046000382762171283315920864186447e-255Q, -4.9139618035200235196744932808885781e-263Q, -2.2656744698055742315406349324984012e-271Q, -5.679971707464259613069663431618014e-280Q, -7.5941261723746109223402306020806232e-289Q, -5.3079378188778939332566204780962363e-298Q, -1.8999778173084169834715816327210827e-307Q, -3.4097331110687592869362387676073128e-317Q, -3.0013940393884085654083505783337316e-327Q, -1.2668812065800974411227932737003665e-337Q, -2.5051097865973858424963978994105679e-348Q, -2.2653835286828392416879577941979414e-359Q, -9.1389245527311981300218270087623242e-371Q, -1.6030930250662823526442537954011133e-382Q, -1.1908341901916029371925944757292412e-394Q, -3.6452473980708905026093050166205199e-407Q, -4.470581799337985564576477205041097e-420Q, -2.1337946766915608745979583351759322e-433Q, -3.8466502387371814478842876774875617e-447Q, -2.539400648443551278595315008859673e-461Q, -5.9463310120354055195604938583173969e-476Q, -4.7791154462039743101535253283672216e-491Q, -1.2743368238366444127980835826074082e-506Q, -1.0885513756896925921766278125740167e-522Q, -2.8730852174104725878401965901098976e-539Q, -2.2573125874160702024258126565183851e-556Q, -5.0801120877688108677556596022448958e-574Q, -3.147442313458971094095441973453258e-592Q, -5.1530284704707320518750575728196905e-611Q, -2.1371769888513739266688394459294633e-630Q, -2.1496221573881902238982422615825289e-650Q, -5.0129928677987666360823382488243001e-671Q, -2.5875873756026443959521949570534425e-692Q, -2.8181620714067187431385929758736621e-714Q, -6.1639625895204988083360964770898867e-737Q, -2.5730385846926571409465774477581834e-760Q, -1.9448744127295675669050254780849454e-784Q, -2.5213762798933993822025230917884045e-809Q, -5.3012546029922448380589857164083814e-835Q, -1.7062280322013794538523703018620566e-861Q, -7.920258584822147757302618208276618e-889Q, -4.9864409544476492068060565707730923e-917Q, -3.9962146024411971515483669014007722e-946Q, -3.8185388383865818601310492618971832e-976Q, -4.0664680142829823697989791072662443e-1007Q, -4.5015287529024162764736783373823692e-1039Q, -4.8207630344098447587536323292213823e-1072Q, -4.6375061995611002272610193821937293e-1106Q, -3.7123073076807703361397549566488692e-1141Q, -2.2851629967300820983086928617773692e-1177Q, -9.9710151392993821636927693831761909e-1215Q, -2.8354564442635450405718863241322006e-1253Q, -4.8186151533506508630367161348238245e-1293Q, -4.4750346397724178706383092717200537e-1334Q, -2.07096024490079588158927973820168e-1376Q, -4.342127308884323517312819302082545e-1420Q, -3.7387854726872903857603805318252205e-1465Q, -1.1946574634186879393921342144260135e-1511Q, -1.2759441657028066718211573051988164e-1559Q, -4.0892575258067523665855842405306752e-1609Q, -3.5183875354871145031995454351438789e-1660Q, -7.2453069573873944421690184084196628e-1713Q, -3.1719634253495420624848681187846285e-1767Q, -2.6125752080330097261369292566212969e-1823Q, -3.568653966381994484787922096951618e-1881Q, -7.0977732480251336872758023077199559e-1941Q, -1.7972768141068333989152413556564914e-2002Q, -5.0445828237798979207114411387487754e-2066Q, -1.3604595412453945762407996412329254e-2131Q, -3.0419951659449528528023254177983519e-2199Q, -4.8436592014037520285667566761754706e-2269Q, -4.6942170473823597199914323005808658e-2341Q, -2.3550263329098316285032485977513203e-2415Q, -5.1749636831144475403049010950928176e-2492Q, -4.1920868885180451051347682697190622e-2571Q, -1.0479018787402586343779450171950524e-2652Q, -6.7279428066803227116834111695132562e-2737Q, -9.1809880505079118230638356660916729e-2824Q, -2.1903121606778754894644610552460375e-2913Q, -7.4679789664508998469723121247024705e-3006Q, -2.9557873617341136266023224346917197e-3101Q, -1.0958275239557229340575496309183988e-3199Q, -3.0498491351714004349547292302889343e-3301Q, -5.0710549490564658785365657190857463e-3406Q, -3.9798833012314432652288251577412562e-3514Q, -1.1561503564308970430488476029765637e-3625Q, -9.6738350948812768619787679276120515e-3741Q, -1.7998403785619766408556530850576782e-3859Q, -5.7011595100947685691764189814097789e-3982Q, -2.3342553026008523985584602356036335e-4108Q, -9.2972354921660563358009254715497299e-4239Q, -2.6867404349734172649970964993288437e-4373Q, -4.1626263982921541967696302677355217e-4512Q, -2.5305298537002028475606439113724333e-4655Q, -4.374081747920579431517607591486263e-4803Q, -1.5419945401212975573693263841002279e-4955Q, -7.8687813783350283818994253864974705e-5113Q, -4.0807753246747505208452672626580765e-5275Q, -1.4931173692359951169542729406105663e-5442Q, }, + { 0.01227135511808220203174030407830294Q, 0.036802280950025085014502801868003454Q, 0.061297889413659975774096037893250044Q, 0.085734754877651055755695461536205953Q, 0.11008962993262801258027823870142222Q, 0.13433951528767223660361301319755489Q, 0.15846172828929950397368299153321965Q, 0.18243396969028915021484585689969531Q, 0.20623438831102876939480559034293115Q, 0.229841643254360753698787981399908Q, 0.25323496335600023568199079816688852Q, 0.27639420357617861412235821455333865Q, 0.29929989806396047268181013419640459Q, 0.32193330965336916623041220093195644Q, 0.34427647557970491862490100675820811Q, 0.36631224923490408185795345459447966Q, 0.38802433781211774758659161520378721Q, 0.40939733572152948912988463410721733Q, 0.43041675369143706432580814661825066Q, 0.45106904350045199476872844990592136Q, 0.47134161831799846568675411549444037Q, 0.49122286866081148740164998519670023Q, -0.48929782599744185793989666371765164Q, -0.47023008989822544160728474574480754Q, -0.45158254786020764535461909038883739Q, -0.43336282621498114195428483532083889Q, -0.41557755767733605834276062792428588Q, -0.39823238999036654097849262723755211Q, -0.38133199816727193874162067315553426Q, -0.36488010013557816387677409414947586Q, -0.34887947557569577047526159126703565Q, -0.33333198773426231868095335844342399Q, -0.31823860798357268745316074354464261Q, -0.3035994428915407927086292160567468Q, -0.28941376356199421334543326775454705Q, -0.27568003700259251963348266210052998Q, -0.26239595927717475510166267033301246Q, -0.24955849020075956493410868722363431Q, -0.2371638893386076311859247952179354Q, -0.22520775307556463019220672947952605Q, -0.21368505252818039398938452749375662Q, -0.20259017207968775297648115336201576Q, -0.19191694832666146249702413953519866Q, -0.1816587092359021720484117453151821Q, -0.17180831332064290072992681330484534Q, -0.16235818865639997533663276272992352Q, -0.15330037156853630364404549106194642Q, -0.14462654483572846910471674072111206Q, -0.13632807526589476511715224673350004Q, -0.12839605051362228117619033241835825Q, -0.12082131502061062975401342241486234Q, -0.11359450497302129819348705755904515Q, -0.10670608218178901767108607508338614Q, -0.10014636680382986857859380586600253Q, -0.093905568833595799431451407446515619Q, -0.087973818305513180839892673963966241Q, -0.082341194158450660178436474882477694Q, -0.076997751723445596499983664621487996Q, -0.07193354880544487378738311657933671Q, -0.067138670338759945862672351268719341Q, -0.06260325160428086186052507865402345Q, -0.058317500004230664509200379313199518Q, -0.054271715397367759935086056389293555Q, -0.050456309004063640355911746580908904Q, -0.046861820896606197349996098751978814Q, -0.043478936095419069610563231210812888Q, -0.040298499296663390818673202062521126Q, -0.037311528260921730030179369385366989Q, -0.03450922589637952691206152682222172Q, -0.031882991073143683811495499895307175Q, -0.029424428208099579660135740086865642Q, -0.0271253556620361184294276412754116Q, -0.024977812992693650455170906326981392Q, -0.022974067108942042492683430416652371Q, -0.021106617372505970898624990276714523Q, -0.019368199694551294992954740677403882Q, -0.017751789675058934941049112986218163Q, -0.016250604833268754660069071624504775Q, -0.014858105977601971243228436688712421Q, -0.013567997763391553658409398729735747Q, -0.01237422848648931564729341766812544Q, -0.011270989160397638106454864191015908Q, -0.010252711924012903699062738821083185Q, -0.0093140678263849278340314349076327353Q, -0.008449964034108265248268117472003357Q, -0.0076555405060818245590132017863229384Q, -0.0069261661794155687412632471018391501Q, -0.0062574347092383891891208397242483686Q, -0.0056451598040791099606160787309638234Q, -0.005085370197361128404963242365624777Q, -0.0045743042943771933124154458548517366Q, -0.0041084045328997985361611689079751989Q, -0.003684311494339074782205923019899892Q, -0.0032988578010873948724575222465114151Q, -0.0029490618343908704733333873759063219Q, -0.0026321213057645656305833925217639785Q, -0.0023454067136221407000743728815804873Q, -0.0020864547154229734242597171162514598Q, -0.0018529614442515743960802739125590691Q, -0.0016427757973362357767337812404644128Q, -0.0014538927225872833069713654109330111Q, -0.0012844465277911570122332123844688455Q, -0.0011327042356361946956708854910717802Q, -0.00099705900627114148706364731704457709Q, -0.00087602364761017102176873850865987398Q, -0.00076822423210114801927833212686428566Q, -0.00067239383717004607961542674246453911Q, -0.00058736642504742093080174568452091253Q, -0.00051207087617669287572188257954358842Q, -0.00044552518890326020005629570593666048Q, -0.00038683085665314188976467566548793199Q, -0.00033516743233532263998791108562179822Q, -0.00028978728824896558062724060959821788Q, -0.00025001057835114127416442774611755005Q, -0.00021522040834883412191823299277438955Q, -0.00018485821772693895358504217864611182Q, -0.00015841937651793126628162990110989201Q, -0.00013544899836493134204129687787204532Q, -0.00011553797023379563893736144870607114Q, -9.8319197997130553498037999641991487e-05Q, -8.3464066048770978005196778706600799e-05Q, -7.0679108115811218906095134416154613e-05Q, -5.9702885520625386671791420435362921e-05Q, -5.0303068310699595343932915440924077e-05Q, -4.2273713922018120404243909635658711e-05Q, -3.5432737373923361833214162324345645e-05Q, -2.9619566410724316247858190357851524e-05Q, -2.4692974507962358657498919760422057e-05Q, -2.0529084248443619898457582669713841e-05Q, -1.7019533243403755023062694063359981e-05Q, -1.4069794525207501119432380528847431e-05Q, -1.1597643166806136977541673876760615e-05Q, -9.5317607861225334492481477207976067e-06Q, -7.8104695663539218978433615931904191e-06Q, -6.3805874611085194148542316667027636e-06Q, -5.1963963511236276943307284768443108e-06Q, -4.2187150715072772351343816215627715e-06Q, -3.4140694292103354602072245113222152e-06Q, -2.7539515738216143655929212361430556e-06Q, -2.2141613647700348500196752438228238e-06Q, -1.7742226886238416354636940930406071e-06Q, -1.4168680155127991206906010386776301e-06Q, -1.1275848380651233667302406751686147e-06Q, -8.9421800420026716637883889021333717e-07Q, -7.0662233151961419975116851767251182e-07Q, -5.5636027112312322628504802544396849e-07Q, -4.3643976809083996211611047940700884e-07Q, -3.410878406808352344192770488162828e-07Q, -2.6555576704383762368205974553664254e-07Q, -2.0595212394180990975114609016580268e-07Q, -1.5910026405413012262681483592072574e-07Q, -1.2241714489336877307229490096356811e-07Q, -9.3810731511298667657736474465916103e-08Q, -7.1593485856820748829676007409030264e-08Q, -5.440972704881531639917700413368612e-08Q, -4.1174898509745034636641901499637178e-08Q, -3.1025009758847405806336107058366646e-08Q, -2.3274732865051716886351304700372955e-08Q, -1.7382826537542006005418736935360821e-08Q, -1.2923735225028943169773355461941788e-08Q, -9.5643672141012475959697164491130902e-09Q, -7.0451955080630225653421587634231792e-09Q, -5.1649492757248395049197216720378741e-09Q, -3.7682729974336732148768443187202036e-09Q, -2.7358262541647042643058722243498035e-09Q, -1.9763805681294590078061949445779507e-09Q, -1.4205419635481505647172465852581089e-09Q, -1.0157900987858722132374807163656952e-09Q, -7.2257800679698977337008871109952299e-10Q, -5.1128169466802636753557604076122797e-10Q, -3.5982705512040164549431243047583567e-10Q, -2.5185362244554210229589301236053854e-10Q, -1.7530147750309255605734608915901604e-10Q, -1.2132981051324705363357105718720941e-10Q, -8.3493950752320668610647319362559637e-11Q, -5.7122660267481958430713410881095016e-11Q, -3.8849686002793765883588257767026493e-11Q, -2.6263427379949721354783426839588953e-11Q, -1.7646499776378976222245772521934802e-11Q, -1.1783298320120630850539029584309311e-11Q, -7.818680628325362638575521404267539e-12Q, -5.1548364042751350429076854858018077e-12Q, -3.3765014608000294669628289654725219e-12Q, -2.1970744699592342642466439966825033e-12Q, -1.4200473669518126870628306394495551e-12Q, -9.1158007933577728676134065579326132e-13Q, -5.8113062505586808310528553401168741e-13Q, -3.6786791102075633999543555381361719e-13Q, -2.312068903576444768213986586668492e-13Q, -1.4426172485922308843621431499934686e-13Q, -8.9349666651298939216456676750565829e-14Q, -5.4925677721256790529564920614679325e-14Q, -3.350788309515877062958811342787956e-14Q, -2.0284076402444039895928235924589244e-14Q, -1.2182795128979644452912696549518128e-14Q, -7.2588537362052341752692102123089101e-15Q, -4.2900627866036669128285279549303027e-15Q, -2.514652539480771341683046756355483e-15Q, -1.4616871128475335847732485959402402e-15Q, -8.4243309583746983103209365972381765e-16Q, -4.8135175904015314514321104340303263e-16Q, -2.7263179430684054979795995181696999e-16Q, -1.5304422973965932233677561227408377e-16Q, -8.5137857250384433997363815737881969e-17Q, -4.6927950389611427068741326969599031e-17Q, -2.5625975950320089549856176296445119e-17Q, -1.3861334667950396744809652330676689e-17Q, -7.4257501921384642292801069180083189e-18Q, -3.9393094024445601833019849790813999e-18Q, -2.0690791459774228199242128751668536e-18Q, -1.0758286216493138282150652273565844e-18Q, -5.5366710173011999504598745894506669e-19Q, -2.819834003785898432921699582824987e-19Q, -1.4210063750313593796726974809925319e-19Q, -7.0842438781417380233044623416891119e-20Q, -3.4933505573095044526616590274445578e-20Q, -1.7035977510820099431072120902417317e-20Q, -8.2147060442121877800848286483420634e-21Q, -3.9159734384156989690338293870539541e-21Q, -1.8451498156271871363001830659526856e-21Q, -8.591874580623540129167786895666899e-22Q, -3.9530069577065764915635262899095704e-22Q, -1.7966697995134261385398916631645912e-22Q, -8.0654088208389219862969348472697735e-23Q, -3.5753372122620560623243551587275021e-23Q, -1.5647821323387363967354776667279086e-23Q, -6.760041764217369644940988147273804e-24Q, -2.8821363233025547133119762203866565e-24Q, -1.2124362329062417813651773042222047e-24Q, -5.0314218307880599929168429579030218e-25Q, -2.0592863122450067780181162680466505e-25Q, -8.310787797639985481399920298561774e-26Q, -3.3065180676145941342573597126851257e-26Q, -1.2965973462467399413826706323859068e-26Q, -5.010091032398552312889055575499255e-27Q, -1.9071793847355632162575945250968826e-27Q, -7.1505673339810973649967867585100117e-28Q, -2.6399060373682682300772738413986419e-28Q, -9.5946645421591590272737060192787035e-29Q, -3.4320780991310649618469641664780934e-29Q, -1.2079850663067081309863651387341263e-29Q, -4.1824647214881752797125541962674838e-30Q, -1.4241537066844817617919365428875337e-30Q, -4.7678333816988133611599026436806048e-31Q, -1.5689491781958062283731284050971648e-31Q, -5.0734388548496443499288192319785528e-32Q, -1.6116919160939245706339600215608967e-32Q, -5.0283566942543780691617432163678683e-33Q, -1.540320437147141644686176099192533e-33Q, -4.6313924434817901733319954389626016e-34Q, -1.3664702250574194828136706303116849e-34Q, -3.9550085269989845845237677023544696e-35Q, -1.1225918253644008151328041096174431e-35Q, -3.1238487433616834059785879847016762e-36Q, -8.5195402472064902632510499781952803e-37Q, -2.2764734813775829740707091909282255e-37Q, -5.9578473858349842310952826931317941e-38Q, -1.5267023004586063974485430859996629e-38Q, -3.8292452373883691255032248372279562e-39Q, -9.3976484123312742513645018653353223e-40Q, -2.2559187023391247540357057603608445e-40Q, -5.2951057740070273455910884012728247e-41Q, -1.21484005139195805370253212205352e-41Q, -2.7233329057563859457781652894773382e-42Q, -5.9629474724550016648059026687365969e-43Q, -1.2747904563208401684090170257821763e-43Q, -2.6599324647740072572781740009475107e-44Q, -5.4148975705500338800900730270033864e-45Q, -1.0750506783792922201321365237207054e-45Q, -2.0807277332937164031945232093695697e-46Q, -3.9244163140436388041993251545689042e-47Q, -7.2099378100469390278450504220931707e-48Q, -1.2897482330918123669983337886382095e-48Q, -2.2454989700172052890162893888242529e-49Q, -3.8033817751932373827258462682395899e-50Q, -6.2645207667921988981079909974995822e-51Q, -1.0029410834924645721226614397473029e-51Q, -1.5600495091009386993988441513950677e-52Q, -2.3565650292912781888129806450540921e-53Q, -3.4553986153009958542696149938952582e-54Q, -4.9157636744396300209125008789737936e-55Q, -6.781896900608377888472479708032872e-56Q, -9.0691940202443643747199815355477207e-57Q, -1.1749792443564338073595948464279018e-57Q, -1.4740730312062593807916913990480482e-58Q, -1.78984329859422798255692388149323e-59Q, -2.1022998433631042036525885470222986e-60Q, -2.3874311701754330999376394091254256e-61Q, -2.6199497113269397601815392049767616e-62Q, -2.7768131253969855575381129113408787e-63Q, -2.8408870962885800781023815369817483e-64Q, -2.8039688883465382638228147703461371e-65Q, -2.6684481602260540322238895901981613e-66Q, -2.447154080870857351995438102206883e-67Q, -2.1613619398610954911634747438934054e-68Q, -1.8373843424142226299889606750473108e-69Q, -1.5025103938453805607949990395131202e-70Q, -1.181175530500916159109188924367755e-71Q, -8.9211577919430036730810594588108188e-73Q, -6.4693987201487320046787049136480794e-74Q, -4.5015731884566473782551022645592059e-75Q, -3.0035842209914330912805318957189823e-76Q, -1.9204515997414609573256145075523711e-77Q, -1.1758810849678264495241195391760596e-78Q, -6.8900721571551738196701537405845152e-80Q, -3.8608563387442272849431335779050044e-81Q, -2.067461647504548936055359104346581e-82Q, -1.0572431033554667452601572946421337e-83Q, -5.1591788391388680011549213529878416e-85Q, -2.4006807351389258318746737135895233e-86Q, -1.0644152130176148388326772258538689e-87Q, -4.4934529232365451766727877769969084e-89Q, -1.8047048722799212873442491872423271e-90Q, -6.8904595506732549720140200562795596e-92Q, -2.4989637101487869067392480430274382e-93Q, -8.6018088469863275574189994840620463e-95Q, -2.8078924862967821005632597982452309e-96Q, -8.6849867519796128933390271698765342e-98Q, -2.5432396109247561096829294407826966e-99Q, -7.0446668978619724438762397385539258e-101Q, -1.8442018255867670937882313596001159e-102Q, -4.5587416725253559276425131397074849e-104Q, -1.0631088555204592085750091746032982e-105Q, -2.3367281748964035585738800969158434e-107Q, -4.8365042631130861220456426369022544e-109Q, -9.4175235620877562064839942442771856e-111Q, -1.7234789461694177262894389768372263e-112Q, -2.961523379734186944047236046386456e-114Q, -4.7734609518585313301965336240248189e-116Q, -7.2097952822898640408181240050284012e-118Q, -1.0193874335777637006841936637337494e-119Q, -1.3478166999163432272267137132118888e-121Q, -1.664711300732456447679638084338044e-123Q, -1.9186583950476330921591900813216499e-125Q, -2.0612648015288569084831497840721453e-127Q, -2.0618953788663489533345425995316527e-129Q, -1.9182619555236359873955912398757981e-131Q, -1.6579128778519222560290325566834437e-133Q, -1.3296099070094495947742421798539638e-135Q, -9.8828871549374803987116212190790475e-138Q, -6.8001851936680182899829217843093739e-140Q, -4.326204276337993340016401440114041e-142Q, -2.541595528522972170757701141043585e-144Q, -1.3771279659495821106478129347836407e-146Q, -6.8731739624384578591538313057486772e-149Q, -3.1556844841718302469140036866580175e-151Q, -1.3311046015007009547835866736304136e-153Q, -5.1514958005010918440961548583793399e-156Q, -1.8267037628056442215789990487980127e-158Q, -5.9267728539858017097499689403281403e-161Q, -1.7570179057820636782453206639159588e-163Q, -4.7525273644644354076088841580861234e-166Q, -1.1712151180634311771192081451244071e-168Q, -2.6258838722203054808989693856617573e-171Q, -5.348036158420190530754215189932846e-174Q, -9.8795260619978679822138888646044246e-177Q, -1.6528501557776328068085680725354548e-179Q, -2.5003947565086958266446692572037419e-182Q, -3.414859619193216220277979880289186e-185Q, -4.203653605459133226010277835528306e-188Q, -4.656508257021667283525304276478024e-191Q, -4.6339530996535525354074849617025537e-194Q, -4.1358781926049696182200878642464924e-197Q, -3.3049447294950072208241398344574307e-200Q, -2.3603956208589999494122184847510332e-203Q, -1.504047014068835401149660217771386e-206Q, -8.5352021958508046391358762569456352e-210Q, -4.3057568200632214990724928361534485e-213Q, -1.9273628185121124753795720186090423e-216Q, -7.6407868488415044113016735817166107e-220Q, -2.677582009683177696032426651320389e-223Q, -8.2781625043007349263821040953856809e-227Q, -2.2534850368391124035175853226989187e-230Q, -5.3905685902076735531578346280529237e-234Q, -1.1308097276815650308355193143392165e-237Q, -2.0759721813705410476824570327172646e-241Q, -3.3282687604583975257076029809432931e-245Q, -4.6500067135453696640703738061616968e-249Q, -5.6491873692239596907540663618927003e-253Q, -5.9546966626331923325761672881695778e-257Q, -5.4337990425534927929347405657826422e-261Q, -4.2828363537638634149994842306436067e-265Q, -2.9089854251520548595336724777976923e-269Q, -1.6986979835072953491948167874994245e-273Q, -8.5078874736023215648629448861985246e-278Q, -3.6459301611001785382074525089193986e-282Q, -1.3335508003947114825747939690317958e-286Q, -4.1528110309781799510004618371028852e-291Q, -1.0982617987267680462918374327390562e-295Q, -2.4602717457871291167756856167595572e-300Q, -4.656274386497415739809125734407304e-305Q, -7.4253896458167870494540985632704167e-310Q, -9.9507057756639922437150285707977622e-315Q, -1.1175135227544318386694717687968224e-319Q, -1.048835867763772555877163638261832e-324Q, -8.2033390786966798682011027925866189e-330Q, -5.3315735131149564162074506318716251e-335Q, -2.8710141330746883154448723258150022e-340Q, -1.2771564172267081609509990200434409e-345Q, -4.679237231988855089392537021634395e-351Q, -1.4076706654157792032739797667966913e-356Q, -3.4663625720057878756572289263095777e-362Q, -6.965054539543846678373236132189486e-368Q, -1.1383132196432715526434302555043402e-373Q, -1.5082487448329479128870155332131625e-379Q, -1.614816076667686258793882820784337e-385Q, -1.3923692408287144362457422616397937e-391Q, -9.6357705989726650954351553689911432e-398Q, -5.3335362887861762022108923833857644e-404Q, -2.3529529322735497728866304144280939e-410Q, -8.2438250199447939690869259289572704e-417Q, -2.2855238208173770201725378922268636e-423Q, -4.9955499211081324148253281714818585e-430Q, -8.5762081046608095383619080676476731e-437Q, -1.1520466338982341020319294100361546e-443Q, -1.2062291598612346324429863879453543e-450Q, -9.8055160740422284599044523336543234e-458Q, -6.1639765190753631642664330172075405e-465Q, -2.9843045493133686661298629930164973e-472Q, -1.10823285826398300175507717773449e-479Q, -3.1434790244922162638267628745063788e-487Q, -6.7817090417200778282332735946819014e-495Q, -1.1080137352329998556662834370761201e-502Q, -1.3649835831781010441492893639688094e-510Q, -1.2622778335796144231373603506854352e-518Q, -8.7230079476014413312144088584965706e-527Q, -4.4840352485865235615809427931860355e-535Q, -1.7066304212439665043951442710341263e-543Q, -4.7865441809026242359826342326024693e-552Q, -9.8452970343625269250999633839131245e-561Q, -1.4778790578536059527306608667934244e-569Q, -1.6110092952268207636105891878784886e-578Q, -1.2688728710128977236628155987138424e-587Q, -7.1841678295696924944920506687608424e-597Q, -2.9088109305034413675847131931270509e-606Q, -8.3780318645305679545954425238306175e-616Q, -1.7073663715760515568257862032253151e-625Q, -2.4485200806811154999909042531599294e-635Q, -2.4573647256627145606915141874939106e-645Q, -1.7162616532700922219515556951255632e-655Q, -8.2940336462928562559347382857731944e-666Q, -2.7573883713227551117703313812478972e-676Q, -6.2693384642795198624500212806556514e-687Q, -9.6903310752055252797176389760001952e-698Q, -1.0120668627816313397657974563178381e-708Q, -7.0982696439175036135044214112413552e-720Q, -3.3223490979680344536621296663739436e-731Q, -1.0311489910731877825037981367801772e-742Q, -2.1084888364587342412345374253683016e-754Q, -2.8218960738946335538305090801367889e-766Q, -2.4554534404272344111007341068959851e-778Q, -1.3797451463824018308120568764941013e-790Q, -4.9722352119016468411483808073270903e-803Q, -1.141174632389420312821039197546226e-815Q, -1.6562061873208393415939125326414615e-828Q, -1.5090517973695404620062521847072836e-841Q, -8.5691467995207824570732116071300356e-855Q, -3.0100992462861676532185696320551197e-868Q, -6.4915591914227985933992989098330185e-882Q, -8.5291480289311605733387922175211764e-896Q, -6.7742561345607759008586516480118676e-910Q, -3.2268177845742615217916640601654205e-924Q, -9.1442367835386354685297667090946292e-939Q, -1.5290755306231257347546172504187466e-953Q, -1.4962742317658249855750971462991461e-968Q, -8.4962983613273098681909435342233043e-984Q, -2.7756354317962233287713988508361331e-999Q, -5.1716412864088598574901876510481632e-1015Q, -5.4473756239469544256829106354679121e-1031Q, -3.2146847397534380657713310981627524e-1047Q, -1.0532205872897567235295617558264118e-1063Q, -1.8980407364210960924624682689327296e-1080Q, -1.8638413013078585989318566769757098e-1097Q, -9.878184707808045512821781472334627e-1115Q, -2.7982877400590951555125003865089596e-1132Q, -4.1953712551999192397935862947005203e-1150Q, -3.2957901195530958784930344030449164e-1168Q, -1.3428874261296622720955452657433921e-1186Q, -2.8087996369552811844908096236163199e-1205Q, -2.9843000347844479031722692316121269e-1224Q, -1.5935747451543053300901499796204061e-1243Q, -4.2306328294965009362324717933882302e-1263Q, -5.5228314338471652594276889712636454e-1283Q, -3.5058000799426290470482678197659356e-1303Q, -1.0699175488609417213076569958022624e-1323Q, -1.5518242259547372491845055361631511e-1344Q, -1.0572462818562698193769229028835047e-1365Q, -3.3433625974012960853422590535670218e-1387Q, -4.8485886276278601232637821173583126e-1409Q, -3.1852238059952872764052353398865978e-1431Q, -9.361416530125180143871854771737577e-1454Q, -1.2153997660730855590852157017720519e-1476Q, -6.8815302334269492601957883930533625e-1500Q, -1.6771176516091137975239852271122166e-1523Q, -1.7361595430709725552633953103091938e-1547Q, -7.5319512846392125534714956610857413e-1572Q, -1.3507317243577349648175397566286196e-1596Q, -9.8749002116827156793758713498543268e-1622Q, -2.9017600444094134408965714990369305e-1647Q, -3.3784846386968340746897973924953046e-1673Q, -1.5359688750531830898643386942465616e-1699Q, -2.6866527047176469998545109651176216e-1726Q, -1.7810521996687791658708980830532171e-1753Q, -4.4069918722394069695147388355206565e-1781Q, -4.0074519225536368666632735822098734e-1809Q, -1.3182831725717259025871898011803224e-1837Q, -1.5438654487729921345949019930471491e-1866Q, -6.332964675016807525269001303450335e-1896Q, -8.9500787015064447527716544282145449e-1926Q, -4.2852989232796780762796817666627905e-1956Q, -6.8338809894056785809735926537843468e-1987Q, -3.5675222855473848333391077011021476e-2018Q, -5.9902029406713556414824109568504936e-2050Q, -3.1778560977483191067544886656870642e-2082Q, -5.2307612099795388778239926501377221e-2115Q, -2.622585004749696786707859063948337e-2148Q, -3.9309566721122472026471743065924237e-2182Q, -1.7282752365752259330631889016659569e-2216Q, -2.1861776117108222661355073061235227e-2251Q, -7.8018157093958177389763723299669248e-2287Q, -7.6999746209936272927151686536635957e-2323Q, -2.0595655884579572710261610678442846e-2359Q, -1.4626001721502482969651469854201664e-2396Q, -2.7006580242811967764786623573354003e-2434Q, -1.2693899148553691566069699600055988e-2472Q, -1.4864297410986916900605959894904808e-2511Q, -4.2424104158612592858897827763816223e-2551Q, -2.886325476737890820535159860850169e-2591Q, -4.5765223979102481270954678544866293e-2632Q, -1.6528081850614599523381524655646053e-2673Q, -1.328274798653407243855327660531847e-2715Q, -2.3198223770931618563520410588946674e-2758Q, -8.5957488899967850735558558018957728e-2802Q, -6.5943404261286890309954636455911131e-2846Q, -1.0217558991001370161903847475864815e-2890Q, -3.1179630912672502182141115573865598e-2936Q, -1.8265451376704665882357813599889357e-2982Q, -2.0014192526716340395460104532447404e-3029Q, -3.9951106676925283777648320420658919e-3077Q, -1.4143501265341338386948746898388465e-3125Q, -8.6415836958539035920266027922282148e-3175Q, -8.8638553988044639042147624946934825e-3225Q, -1.4840219096599721556289490714622718e-3275Q, -3.9413909056885523526277851486916637e-3327Q, -1.6130887141803206541250840542937335e-3379Q, -9.8781642524919349085295532219577414e-3433Q, -8.7843931949057976239401506792380659e-3487Q, -1.1004454490075535460405971636548993e-3541Q, -1.8829655853829584691138469084815955e-3597Q, -4.2649913833758498152779971325727165e-3654Q, -1.2387002826718376930423594688980877e-3711Q, -4.4662108799989251681924501424182082e-3770Q, -1.9344990293606773314152567555369947e-3829Q, -9.7355570095915342874542008807254313e-3890Q, -5.5029370896508671666190160013096548e-3951Q, -3.3753310533018114196752016778611603e-4013Q, -2.1693889909489136218749502032440802e-4076Q, -1.4100342946015435859763977543837031e-4140Q, -8.9396827455669883373190732493946026e-4206Q, -5.3296285690324414372171445344916662e-4272Q, -2.8786292587718554179132949540534825e-4339Q, -1.3563301511005327997304553445712977e-4407Q, -5.3648093624713363852431573541370394e-4477Q, -1.713199655224600838900218899825865e-4547Q, -4.245367036181261378573090733274636e-4619Q, -7.8414039345064814928186445860311876e-4692Q, -1.036301574835369426138520680597679e-4765Q, -9.4005882200264089643362665220611737e-4841Q, -5.6115028230432295314938587541868893e-4917Q, -2.1117808872654504815205210716165957e-4994Q, -4.7969059512296546218382678391152525e-5073Q, -6.2923913054777813860480394257938674e-5153Q, -4.557320132561115296699430714437428e-5234Q, -1.7411358133348974154538037089867482e-5316Q, -3.3501410753353566412413655174778596e-5400Q, -3.097148592957890545441753638107994e-5485Q, }, + }; + m_weights = { + { 1.5707963267948966192313216916397514Q, 0.23002239451478868500041247042232167Q, 0.00026620051375271690865701015937223316Q, 1.3581784274539090834221967874745002e-12Q, 1.001741678406625296380989561316704e-35Q, 2.6763080920617460968679410949198166e-99Q, 7.7670706886334062872146243844453043e-273Q, 2.6770629459428179490864940513366914e-745Q, 2.497123188557279400555877663164169e-2030Q, 3.7829658019347837822103381908509695e-5524Q, }, + { 0.96597657941230114801208692453802948Q, 0.018343166989927842087331266912053799Q, 2.1431204556943039357697233307232118e-07Q, 2.8003151019775889582580016992170153e-21Q, 1.123270534548691878982747435678734e-59Q, 9.1753268750017841272445320853712195e-165Q, 3.7096469071314047287189555701359196e-451Q, 2.1358827779704788581082183250272886e-1230Q, 2.4637500105830058174530832607403982e-3349Q, }, + { 1.3896147592472563228608191295320513Q, 0.53107827542805397476113231761531408Q, 0.0763857435708323041883405748316428Q, 0.0029025177479013135935932948904580215Q, 1.198370136317072004690126421734261e-05Q, 1.1631165814255782765597155262382926e-09Q, 2.197079236297979917409204112478354e-16Q, 1.3635103307637615413724747655081585e-27Q, 3.3700568540419264989934173928550566e-46Q, 5.1969783800898552138641449339116869e-77Q, 6.0080341705713501485949327691027087e-128Q, 4.564204056355599097208981999351872e-212Q, 6.769934297924075481071769868728861e-351Q, 6.3189772257105317991231885214248323e-580Q, 1.1318535773666956837787222565063026e-957Q, 1.300088515992481474129980450433913e-1580Q, 8.3018817290920015915795630666821309e-2608Q, 1.6615718540023971313123206033705184e-4301Q, }, + { 1.5232837186347052131949627901588453Q, 1.193463025849156963909371648222972Q, 0.73743784836154784136450085848526681Q, 0.36046141846934367416541940530511192Q, 0.13742210773316772341110281600075763Q, 0.039175005493600779071814125724013544Q, 0.0077426010260642407123309111640668157Q, 0.00094994680428346871690539180358829065Q, 6.2482559240744082890784437584871091e-05Q, 1.8263320593710659699109280974494727e-06Q, 1.8687282268736410131523743935312467e-08Q, 4.9378538776631926963708240981686386e-11Q, 2.2834926702613953995564216678996858e-14Q, 1.1227531428181551500942554523402945e-18Q, 3.0976539701173543715458514327631078e-24Q, 2.1121233435372255913526811977623162e-31Q, 1.2424147570616052367007700396344415e-40Q, 1.6327707331799493237812947626932747e-52Q, 8.460688731096213796022276271481337e-68Q, 1.8644492079588650273068038890475311e-87Q, 1.0013128468666430206628687242136761e-112Q, 3.3344435411868990213060767519646709e-145Q, 6.1751576225487765303410376146008819e-187Q, 1.4953240022257075856966174469213765e-240Q, 1.995167671391421283850079422966012e-309Q, 6.7986022131150125295165555843516628e-398Q, 1.6112168443011532782661941324936245e-511Q, 1.8998420056198456993096891152100817e-657Q, 7.4500584401117916806764514072363403e-845Q, 1.6092274599867451896713421807328385e-1085Q, 1.4294469100875426784155324297970964e-1394Q, 1.9699812322172327797426511042200449e-1791Q, 4.8353547995000100603312087832016511e-2301Q, 2.0016297694765957880783422493672502e-2955Q, 1.0619575437766938720176582011701185e-3795Q, 1.1494098249640889641399434474174788e-4874Q, }, + { 1.5587733555333301450624222553039117Q, 1.4660144267169657810275411936658895Q, 1.2974757504249779979885383085284353Q, 1.0816349854900704074448532749336471Q, 0.8501728564566200689527310980522113Q, 0.63040513516474369106015058023920241Q, 0.44083323627385823706771270610993222Q, 0.29024067931245418500061231479966878Q, 0.17932441211072829296345978397121765Q, 0.10343215422333290062482385052951418Q, 0.055289683742240583845301977440481557Q, 0.027133510013712003218708018921405436Q, 0.012083543599157953493134951286413131Q, 0.0048162981439284630172757660071387715Q, 0.0016908739981426396472155417510249034Q, 0.00051339382406790336016588906448858883Q, 0.00013205234125609974878680402074340758Q, 2.8110164327940134748736157546988307e-05Q, 4.8237182032615502124025440343943169e-06Q, 6.4777566035929719907733987417697432e-07Q, 6.5835185127183396672340995882066949e-08Q, 4.8760060974240625868904606426809347e-09Q, 2.5216347918530148571826656491854398e-10Q, 8.6759314149796046501956077624778843e-12Q, 1.8802071730750649809476255843771975e-13Q, 2.4124230384308786393899307730550295e-15Q, 1.7084532772405701711664118263431986e-17Q, 6.1682568490762382593952567143955272e-20Q, 1.0376797238528706160610863270915827e-22Q, 7.3459841032226935608549262812034877e-26Q, 1.9497833624335174811763249596143101e-29Q, 1.7024387761257547218675324410867209e-33Q, 4.2164863709484278882204462399998679e-38Q, 2.5044277116275284317811847533784782e-43Q, 2.9493601457461933137195159567099426e-49Q, 5.5513323569653710605229337238942258e-56Q, 1.3081165120210821643686110907899211e-63Q, 2.9260824463823975328629659452367614e-72Q, 4.5407734669997824148941045053504133e-82Q, 3.4265635692086987660673772586083229e-93Q, 8.4064359488831769989074631453464805e-106Q, 4.2486192688198694407012327873632857e-120Q, 2.6378208263504521457685936139412266e-136Q, 1.1199291455841279757620547508811484e-154Q, 1.6741593786710889281267003484320699e-175Q, 4.1533060810194922183660114746657927e-199Q, 7.291512660905660427014583724901483e-226Q, 3.4484028358868219730957875473275039e-256Q, 1.470608613733186341839899819856118e-290Q, 1.6363373245553192894384271318647291e-329Q, 1.1653396430451048019810427186628332e-373Q, 1.0806491346819681711718251969578419e-423Q, 2.1475318157612117601623532784345252e-480Q, 1.1837197513952188698387978224315556e-544Q, 1.7840752052025753295716828917620433e-617Q, 5.3242634124221408997248254448704286e-700Q, 1.6062136117391783778620623735552911e-793Q, 1.6828070526919983211589685788034629e-899Q, 1.3428023135061849684751687999574317e-1019Q, 1.0762445467071890806353267455766392e-1155Q, 6.4211043768224511497561388149947945e-1310Q, 1.0999298719684690155223457966483755e-1484Q, 9.9551400313164741067089535072684105e-1683Q, 3.7874715825152699680401002242066869e-1907Q, 1.8633554093895907210742600678288691e-2161Q, 1.2425018321859109200647073828888711e-2449Q, 3.4744660691878314268031415759661457e-2776Q, 3.1635539874917104171786237474568114e-3146Q, 1.520164792309349080207015729831993e-3565Q, 1.0587692108054511977730210493803509e-4040Q, 3.9269571376984945676082618447700578e-4579Q, 2.9165229925801338811576465571535852e-5189Q, }, + { 1.56778143130722185718457839560813Q, 1.5438811161769592204120195652304554Q, 1.4972262225410362896175121106253706Q, 1.4300083548722996676294145121698845Q, 1.3452788847662516614631881421588284Q, 1.2467012074518577048171373166756783Q, 1.1382722433763053733718328301717509Q, 1.0240449331118114482594022454942541Q, 0.90787937915489531693097972059732257Q, 0.79324270082051671787385259862995589Q, 0.68306851634426375464118893187202369Q, 0.5796781030877876470811045242977012Q, 0.48475809121475539286590775419868886Q, 0.39938474152571713514696619655275183Q, 0.32408253961152890401776015000060852Q, 0.25890463951405351600251387258910213Q, 0.20352399885860174518647884913232324Q, 0.15732620348436615026738563376259734Q, 0.11949741128869592427594275905822144Q, 0.089103139240941462840959442033942474Q, 0.065155533432536205042255277931864103Q, 0.046668208054846613643791300289316396Q, 0.032698732726609031112522702100248949Q, 0.022379471063648476483258477281403216Q, 0.014937835096050129695520628452448085Q, 0.0097072237393916892692355786307589937Q, 0.0061300376320830301252445771940873246Q, 0.0037542509774318343022967144602791306Q, 0.0022250827064786427021584620411703896Q, 0.0012733279447082382026740903535577353Q, 0.00070185951568424227080474304718567332Q, 0.00037166693621677760301295760218968355Q, 0.00018856442976700318571529922115575474Q, 9.1390817490710122732277133049597672e-05Q, 4.2183183841757600604161049520839395e-05Q, 1.8481813599879217116302847163026167e-05Q, 7.6595758525203162561568606199506296e-06Q, 2.991661587813878709443954037223499e-06Q, 1.0968835125901264731967931401061751e-06Q, 3.7595411862360630091183817668146341e-07Q, 1.1992442782902770218679992206070689e-07Q, 3.5434777171421953042822362946016499e-08Q, 9.6498888961089633609206181967630592e-09Q, 2.4091773256475940778596088439332178e-09Q, 5.482835779709497755012456926288581e-10Q, 1.1306055347494680535789879497045831e-10Q, 2.0989335404511469108589724179284344e-11Q, 3.4841937670261059685298917826974968e-12Q, 5.1341275245014207474276938761808301e-13Q, 6.6639922833087653243643099189129361e-14Q, 7.5567217757805651894455261838657557e-15Q, 7.4209932309922167588538662071098972e-16Q, 6.2528048446104553564782731960667282e-17Q, 4.4757595066690969713939566842636666e-18Q, 2.6931206614869695057714525810417824e-19Q, 1.3469941569542286092134858963015562e-20Q, 5.5335834994155711455633228489644644e-22Q, 1.843546974718149378096179376158747e-23Q, 4.9139368712649040083308200957748574e-25Q, 1.0329391306928575387668383646132905e-26Q, 1.686277003849260652771901316947161e-28Q, 2.1033057490018089523843332100004934e-30Q, 1.9699209796232343253581550830906289e-32Q, 1.3599894616303795697940905597197162e-34Q, 6.7859788375592479085540582968820347e-37Q, 2.3965063699443217406067231991536888e-39Q, 5.8579569483084210846386345961131375e-42Q, 9.6783927755717095571366983570964434e-45Q, 1.0538361132564208838364959652125833e-47Q, 7.3615858309787649210787574154381217e-51Q, 3.2059785352833866133968160706885294e-54Q, 8.4430892661864256082234111135836121e-58Q, 1.301669487442817299199572925297743e-61Q, 1.1348985048372046635260385887339235e-65Q, 5.393881369511580841024486229556929e-70Q, 1.3438019476233711028911671531262384e-74Q, 1.6833095936633240263022508251714738e-79Q, 1.0142059074468158538185578436642225e-84Q, 2.8036136193449874498478125381332892e-90Q, 3.3815387893836694650191340608232241e-96Q, 1.6868699597973134851614068554314712e-102Q, 3.2876716054636550397600067563177134e-109Q, 2.3561803975866304919776634857937977e-116Q, 5.8212714268864182676007475006940935e-124Q, 4.6289769416942015466154791282940135e-132Q, 1.1011712417530966759846558629187253e-140Q, 7.2497708296024463973360079596584377e-150Q, 1.2159344493950079010263214501254854e-159Q, 4.7567332287785056252666937863445785e-170Q, 3.9513561319289952903145090015894379e-181Q, 6.3069398037899023031641976078084843e-193Q, 1.7390958115772548420234336819215406e-205Q, 7.3973824490445198187310257149181993e-219Q, 4.3025693007354699025906405899973485e-233Q, 3.0098295695832487716215316168466764e-248Q, 2.2089957315907529731668895943677893e-264Q, 1.4707383302537016829517267662493224e-281Q, 7.6092047493292429607812922938663979e-300Q, 2.5944582029845183791860228756757574e-319Q, 4.8919577835343219860639698905291437e-340Q, 4.2321357135722486316129327838961609e-362Q, 1.377082367391413218915156512362392e-385Q, 1.363952742750262175587655506596678e-410Q, 3.282973957767873844612670506024268e-437Q, 1.510934727927437884800902577518545e-465Q, 1.0301501430760404101952742972682365e-495Q, 7.9295801879971179076172461167077394e-528Q, 5.1606434722064335409175586840009083e-562Q, 2.0872322362104964031726231732635154e-598Q, 3.7804014749166388131317806793058942e-637Q, 2.1632858420984952938030309932161571e-678Q, 2.697969237867160734724398915290777e-722Q, 4.939067732330739558253971083984646e-769Q, 8.7137367268607555569549275663836614e-819Q, 9.4666568790742115790866970449104673e-872Q, 3.9314930560193364712728646099681646e-928Q, 3.7572363915786555422592370375561427e-988Q, 4.8138810542737654527596947066774263e-1052Q, 4.6523364803809138193102091214841167e-1120Q, 1.8387400682879078406702806989874382e-1192Q, 1.5488882086634896755007358131079033e-1269Q, 1.3896133256118102918631384214217437e-1351Q, 6.3450498372554790778619758345952674e-1439Q, 6.718192925085413277150654870462718e-1532Q, 7.1439377408604826875747242429241183e-1631Q, 3.1307195483169831435149812630603435e-1736Q, 2.1906656484419255825224621505729532e-1848Q, 8.9202911849845695393803303860897414e-1968Q, 7.2181700833126514821590990431204877e-2095Q, 3.69827933239331943547271842529346e-2230Q, 3.5509166675222604652849078491152928e-2374Q, 1.7482004370958645792029686167921119e-2527Q, 1.1106891190500999916896792610406226e-2690Q, 2.0967298422181990469075373625054175e-2864Q, 2.4632275747625679891658308849723178e-3049Q, 3.4100009144092401643961247399658256e-3246Q, 9.461422635018898458311235983749575e-3456Q, 7.9828243452163492698389979442314978e-3679Q, 2.751586075619233132202409409236628e-3916Q, 4.573406478327970954594749406297331e-4169Q, 3.7694660070555500868572517438534528e-4438Q, 1.3681877706178551350653622286560967e-4724Q, 1.6613468385141710911219854343435161e-5029Q, 4.3416310672295866779590889330326041e-5354Q, }, + { 1.5700420292795931467492986437735064Q, 1.564021403773232099877114326609257Q, 1.5520531698454121192208571607383634Q, 1.5342817381543034316353772145375646Q, 1.5109197230741697127061791873634288Q, 1.4822432978855380699918515557505545Q, 1.4485862549613225916106262684975582Q, 1.410332971446259012949044799400295Q, 1.3679105116808964880788896668731933Q, 1.3217801174437728578945834791848425Q, 1.2724283455378627082346213018713573Q, 1.2203581095793582207386389532998567Q, 1.1660798699324345766327658650910729Q, 1.1101031939653403795568765186098518Q, 1.0529288799552666555511877000344537Q, 0.99504180404613271513656897365437693Q, 0.93690461274566793365666309492163748Q, 0.87895234555278212039056482196455926Q, 0.82158803526696470334184690990337618Q, 0.76517929890895613670160403610671453Q, 0.7100559012054689838533558330696999Q, 0.65650824613162753075637187406975179Q, 0.60478673057840362157663695141011708Q, 0.55510187800363350959266471517172014Q, 0.50762515883190809969744129508607212Q, 0.46249039805536776129564056825534108Q, 0.41979566844501548065589545493380249Q, 0.37960556938665160999227127370288764Q, 0.34195379592301683230370363663700268Q, 0.30684590941791694932077002517250017Q, 0.27426222968906810637090960121437003Q, 0.24416077786983990867520612813967892Q, 0.21648020911729617038131524528780352Q, 0.19114268413342749532225095746508781Q, 0.16805663794826916233031413596643794Q, 0.14711941325785693247796311096185123Q, 0.12821973363120098675278273881295278Q, 0.11123999898874453034874054225116091Q, 0.096058391865189467849178662072631058Q, 0.08255078811070173765353752357300814Q, 0.070592469906866999351840896875301286Q, 0.060059642358636300319399035772689021Q, 0.050830757572570471070050742610585547Q, 0.042787652157725676034469840927028069Q, 0.035816505604196436523119991586426561Q, 0.029808628117310126968601751537697736Q, 0.024661087314753282510573737140694345Q, 0.020277183817500123925718353350832364Q, 0.016566786254247575375293749008565117Q, 0.013446536605285730674148393318910799Q, 0.010839937168255907210869762269731544Q, 0.0086773307495391815853559138369297225Q, 0.0068957859690660035329120415695881464Q, 0.0054388997976239984331249261778682035Q, 0.0042565295990178580164922070775372331Q, 0.0033044669940348302363413922293941345Q, 0.0025440657675291729677737674183717872Q, 0.0019418357759843675814337234877431187Q, 0.0014690143599429791058440789865212569Q, 0.0011011261134519383861925290686638441Q, 0.00081754101332469493114796258629778861Q, 0.00060103987991147422573401527665731798Q, 0.00043739495615911687786086941160964625Q, 0.00031497209186021200273816328980956318Q, 0.00022435965205008549104107147410537586Q, 0.00015802788400701191949230617575051454Q, 0.00011002112846666697224455022994264118Q, 7.5683996586201477788165374446595019e-05Q, 5.1421497447658802091816641948792101e-05Q, 3.4492124759343197699875355951697823e-05Q, 2.2832118109036146591351441225788429e-05Q, 1.4908514031870608449073273504082825e-05Q, 9.5981941283784710776464665022285646e-06Q, 6.089910032094903925589071885768365e-06Q, 3.806198326464489904501471179191111e-06Q, 2.3421667208528096842717147966610279e-06Q, 1.4183067155493917523149875336299115e-06Q, 8.4473756384859863469243774523267053e-07Q, 4.9458288702754198508296104158884319e-07Q, 2.8449923659159806339254761906866073e-07Q, 1.6069394579076224910854372243815059e-07Q, 8.907139514024238712375244371846641e-08Q, 4.8420950198072369668651027805560416e-08Q, 2.5799568229535892380414249079124995e-08Q, 1.3464645522302038795727293982948898e-08Q, 6.878461095589900111136392082034183e-09Q, 3.4371856744650090511359612982214485e-09Q, 1.6788897682161906806903450478834801e-09Q, 8.0099784479729665355704238927483163e-10Q, 3.7299501843052790038025133658401989e-10Q, 1.6939457789411646875651299532593942e-10Q, 7.4967397573818224522463983518852213e-11Q, 3.2304464333252365759775564205312505e-11Q, 1.3542512912336274431500361753892705e-11Q, 5.5182369468174885820640573102698266e-12Q, 2.1835922099233609052099969606827855e-12Q, 8.3831289605026670935474089966848491e-13Q, 3.1194977286848081234778051650691241e-13Q, 1.1240208959922861475529576279412917e-13Q, 3.9176794506016467939451671035436525e-14Q, 1.3194342231967989407842390664342776e-14Q, 4.2891962220679080018159948630799523e-15Q, 1.3443222875395221462210806176730482e-15Q, 4.0575577022628576213784976604019497e-16Q, 1.1779812127248348143079542926522782e-16Q, 3.2853861628847006575461912014493979e-17Q, 8.791316558919890092526902998792709e-18Q, 2.2540748304368819446158103388678448e-18Q, 5.5301769128403375894905317866280607e-19Q, 1.2964527140689369428189650628176523e-19Q, 2.8999645564315719864785175397007916e-20Q, 6.1801432493399884472690523294170016e-21Q, 1.2528676432273210433625630071013181e-21Q, 2.4122505468361010054762467348044815e-22Q, 4.4039066999398680900169681674054685e-23Q, 7.6105778075820625755732634136772293e-24Q, 1.2428051652123164945236765528871363e-24Q, 1.9143106902239760676488034727771211e-25Q, 2.7761251025850583169467065718383927e-26Q, 3.7831240728137797052283562714381636e-27Q, 4.8349101548188476652448113863661033e-28Q, 5.7831786972290529603663947121744896e-29Q, 6.4605757034417219896312763235825947e-30Q, 6.7260373895879405356485977108634093e-31Q, 6.5111534511374516546657070065569591e-32Q, 5.8474090745481019884619654259625198e-33Q, 4.8600460551422733352577609809902488e-34Q, 3.7292395298436024198774848925631642e-35Q, 2.6351230616803666949611566230315689e-36Q, 1.7101926401490697241365293331985362e-37Q, 1.0166685309552127228580017693019009e-38Q, 5.5206909443427625675929025278647327e-40Q, 2.7304755116605008208950089540576932e-41Q, 1.226380966652512847885874020657185e-42Q, 4.9868392983536125725869145787511357e-44Q, 1.8300654157711633015675688730645846e-45Q, 6.0413503225082640435207520715838788e-47Q, 1.7880003085257126775048837670283103e-48Q, 4.7278206635290633557485891499143011e-50Q, 1.1129101718049771950203375840916927e-51Q, 2.3236007287936054634490409808175661e-53Q, 4.2865792135438400818864832679645293e-55Q, 6.9598735225537515535247172084789902e-57Q, 9.905399812867464416784441328019894e-59Q, 1.2305690322370172647654483736261024e-60Q, 1.3287055463682438112745418077294776e-62Q, 1.2413844609001762091919818631042531e-64Q, 9.9894889830989163005162036230629025e-67Q, 6.8909792890209806239542239718708282e-69Q, 4.0550412837679391530484571616360602e-71Q, 2.025325478051833791855348665597344e-73Q, 8.541193860817129005635611395334028e-76Q, 3.0250584958478075188394058484674014e-78Q, 8.9481574983737847286009199268691343e-81Q, 2.1980365957192520850759686078382165e-83Q, 4.457339084251821318983583351230449e-86Q, 7.4167316712100725345384814229429518e-89Q, 1.0062789446470429122974386215670469e-91Q, 1.1060617024861203148604052551620709e-94Q, 9.7834581723103753096719332058265664e-98Q, 6.9161160403270601376643047091198938e-101Q, 3.8797049192578037362892459079447827e-104Q, 1.7144044358094688607777762897347039e-107Q, 5.9226551398143962456841752185003654e-111Q, 1.5871361682624074916136417159312335e-114Q, 3.2726893534998181040216294108876001e-118Q, 5.1496220394807877679493913965250783e-122Q, 6.1305346175987605932476180523733874e-126Q, 5.473030846543808520009167994615492e-130Q, 3.6307475309683583384111588486160093e-134Q, 1.7730007537696346688915570033698743e-138Q, 6.3116464532127354831381913256985002e-143Q, 1.621583693919220194566929433171311e-147Q, 2.9757935132829859613289387859126523e-152Q, 3.8591705765442151638142119206858087e-157Q, 3.4980555618589782147605871793646301e-162Q, 2.1911032417571959066795311563828556e-167Q, 9.3736234796108920474724971094564098e-173Q, 2.7058522933326574274299142121455261e-178Q, 5.2051004982716048091082896972654894e-184Q, 6.5869897226619604622569213699928695e-190Q, 5.4113353348952773541650437440862393e-196Q, 2.8465905848751190783736476660662487e-202Q, 9.4537279066777943316631814110533656e-209Q, 1.9534309746768722817386272635097574e-215Q, 2.4738194858760899904808482337660157e-222Q, 1.8904418888763632604075097028006049e-229Q, 8.5786751348486017374921228218675884e-237Q, 2.273808044980070953576133599904938e-244Q, 3.4605977152655857787870383972443829e-252Q, 2.9714191752129370394435745626764138e-260Q, 1.4135174726041132417612082341294276e-268Q, 3.6561278873359158194812461400887331e-277Q, 5.0434133108713706852575809257966216e-286Q, 3.6370069739853174907232860458211075e-295Q, 1.3431929449017207014618114298104235e-304Q, 2.4870346219017639693976883745872467e-314Q, 2.2586869384020337841470045671934569e-324Q, 9.8364979621195023902799369645695391e-335Q, 2.0067948188168259586571751290590148e-345Q, 1.8723608312818058521936506625581294e-356Q, 7.7931764302539272294837164978121943e-368Q, 1.4104242105367751421756306559719189e-379Q, 1.0809707526373134180302026203191734e-391Q, 3.413982422671325929147843223533059e-404Q, 4.3198627266120931546631293969877099e-417Q, 2.1273069601360357294162339387648629e-430Q, 3.9566885872209056027370422510981332e-444Q, 2.6949582298096968115536767242364878e-458Q, 6.5109076931010576854739908270299986e-473Q, 5.3989788614177770156022874990436434e-488Q, 1.4853198669149487016912694923346188e-503Q, 1.3090503251521584428930352496581121e-519Q, 3.5647376837004158357511297570921346e-536Q, 2.8896313028497521005627356654844694e-553Q, 6.7095854399465738026181868874992309e-571Q, 4.2889584337257558657454644184109877e-589Q, 7.2448311439514538923291336946008664e-608Q, 3.1001155749336353171177254469615123e-627Q, 3.2171491615676533889663223546563542e-647Q, 7.7406570695117283869992601856060778e-668Q, 4.1223744692343859730646543586548491e-689Q, 4.6322294010052851367822679106298139e-711Q, 1.045335659900684312871171221243375e-733Q, 4.5020856241223108492475174506019875e-757Q, 3.5109989183708310084991820318792658e-781Q, 4.6962204836998229475507359520919518e-806Q, 1.0187348472076847046857363810773889e-831Q, 3.3829163365599114939619605636207329e-858Q, 1.6201873291670617651278341356078551e-885Q, 1.052417929633641351707580294560769e-913Q, 8.7019793416937745490332209560882093e-943Q, 8.5790292111351760552267505428090183e-973Q, 9.4260553303166607465714226577573373e-1004Q, 1.0765751303003708312349678449534298e-1035Q, 1.1895201137046793178631747385045816e-1068Q, 1.180625613342395519601533530260917e-1102Q, 9.7508687447891759767569844552344533e-1138Q, 6.1928172812184124261845708258990883e-1174Q, 2.7879318459600816091819660853849943e-1211Q, 8.1797014327573742781475939847205791e-1250Q, 1.4341956738449380463933781088853353e-1289Q, 1.3742136648085548142182437043687567e-1330Q, 6.5614725919712462874880606553304539e-1373Q, 1.4193967474068871671305637677852339e-1416Q, 1.260966346895598155305400631354573e-1461Q, 4.1570767913697591845636153183534885e-1508Q, 4.5808704947181685782204593123998747e-1556Q, 1.5147204987797220696721543058866571e-1605Q, 1.3446319068528240765599796700835479e-1656Q, 2.8568551875090842255902159455984979e-1709Q, 1.290420656637587734011142529706619e-1763Q, 1.0965883695419688652509296670806449e-1819Q, 1.5454358117029190110066857968185965e-1877Q, 3.1713220921953507873149502965607843e-1937Q, 8.2852363729842743064713740610323336e-1999Q, 2.399312892921620764854020931161764e-2062Q, 6.6760404808499701150348715300290141e-2128Q, 1.5401518790175723653421594673899941e-2195Q, 2.5301735371980282112359832727046555e-2265Q, 2.5299480120770166824316075523796362e-2337Q, 1.3095313462113548374850512340351666e-2411Q, 2.9689243920149770430661749727744362e-2488Q, 2.4813830291085919140036931759581715e-2567Q, 6.3996445311970094107659804037592786e-2649Q, 4.239251909781851582408879081262827e-2733Q, 5.96853928335010438943934366176163e-2820Q, 1.4691168838129215779634944240558196e-2909Q, 5.1680311504236953911307750231831853e-3002Q, 2.1104104354704386557845763111476113e-3097Q, 8.0724923764466854235161222774323272e-3196Q, 2.3180110258875131728741090820512076e-3297Q, 3.9765565093255272984730390679523982e-3402Q, 3.2199629992549034490326426922965119e-3510Q, 9.6508721511747631002418659479792544e-3622Q, 8.3314890242471693358884470423786766e-3737Q, 1.5992989019877436694379940011582504e-3855Q, 5.2267357291195312826488098055916878e-3978Q, 2.2079407038664800796624257814276463e-4104Q, 9.0732856778373185742790691459304111e-4235Q, 2.7052547418764871675136904567273848e-4369Q, 4.3243575109951310431228833829026739e-4508Q, 2.7122975060794559909023695709869724e-4651Q, 4.8370932158845122662637153824534517e-4799Q, 1.7593494088080091822518592461420403e-4951Q, 9.2629313370158738463326647490577837e-5109Q, 4.9562745065321184922933588793911493e-5271Q, 1.8710195150434747289751408668152425e-5438Q, }, + { 1.5706077165382752220570950499753154Q, 1.5690996953516691278086267057102919Q, 1.5660882389174613671811758395264413Q, 1.5615824934918106190924913174771039Q, 1.555596114631660422166342990902623Q, 1.5481471912355573327293783013569808Q, 1.5392581453118818324345492520631963Q, 1.5289556083545807159292699900112433Q, 1.517270275405054680346497720954261Q, 1.5042367380636772129345718219774013Q, 1.4898932978832971219484878984168431Q, 1.4742817617280797281467109946343097Q, 1.4574472208125486663314082491076236Q, 1.4394378152464069775161779990628486Q, 1.4203044859996911837480782185431865Q, 1.4001007162694446513758901419788661Q, 1.3788822642731375176779450629832807Q, 1.3567068895156054674526777181888561Q, 1.333634074575756135382992612713127Q, 1.3097247444374397383128243464895219Q, 1.2850409853467272312421857577496357Q, 1.2596457651166706020800416735545885Q, 1.2336026567219467107844443624642869Q, 1.2069755669313082254213358903568052Q, 1.1798284716173337422807600081541025Q, 1.1522251592625474295137962600991148Q, 1.1242289840506032580653098282178496Q, 1.0959026297929722120123658782081807Q, 1.0673078857975038741099002717210955Q, 1.0385054356373923292061824367921921Q, 1.0095546596294298182250582016592233Q, 0.98051345168085502517972727278507908Q, 0.95143805101635270871239123838108163Q, 0.92238288915245514551412028761663168Q, 0.8934004523471959982711625120192134Q, 0.86454115961966899850156197132807295Q, 0.83585325630826713062996261999715574Q, 0.80738272301876303826323728461609798Q, 0.77917319970479798076341140529382576Q, 0.75126592452435685914062625329355162Q, 0.72369968702683029319553573992504406Q, 0.69651079514654688482101628454709857Q, 0.66973305541029099783625527361406845Q, 0.6433977657082528556344204308635143Q, 0.61753371992990889983731720244260268Q, 0.59216722372820694935702418127019Q, 0.5673221206467387178357679693601802Q, 0.54301982782484286720274321665461387Q, 0.51927938048424633084628868358974812Q, 0.49611748439731621394870318175376878Q, 0.47354857554061400457926695177211335Q, 0.45158488614754491438064885165412276Q, 0.43023651638978897817371690879635701Q, 0.4095115109381936343721381503891959Q, 0.38941593967921202782661222737925564Q, 0.36995398189211387219291724401952693Q, 0.35112801322442524717390619924264052Q, 0.33293869483774779538113623624821976Q, 0.31538506413267813525698287867505706Q, 0.29846462649944498394951741316395666Q, 0.28217344757959610491269401677566302Q, 0.26650624556313516141887797351312194Q, 0.25145648308451039819955104711453138Q, 0.23701645831941898915989673276556716Q, 0.22317739492218458776987874976238264Q, 0.20992953048020753663062039840873861Q, 0.19726220319743719884124330734112999Q, 0.18516393655277551537189585427079996Q, 0.17362252171163130317128688392273587Q, 0.16262509749938432420455409981591821Q, 0.15215822777419972032806536862862315Q, 0.14220797606340183123695433555896409Q, 0.13275997735244552637840297048350341Q, 0.12379950693841296100725547935434371Q, 0.11531154628093733739002418825877215Q, 0.10728084580255643428531503966925542Q, 0.099691984607788577667458210957830992Q, 0.092529427105778463900867988199890184Q, 0.085777576535268189772833000772228023Q, 0.079420825403008155143300459369002492Q, 0.073443602857638774779152196546779989Q, 0.067830419030657966460701735648315918Q, 0.062565906384455108312883097272720571Q, 0.057634858114654726990360882355019006Q, 0.053022263660287178654865336510427632Q, 0.048713341380701431454862729860209054Q, 0.044693568462765533522590231699541224Q, 0.040948708125867302497552393088112476Q, 0.037464834195628972796376547170838841Q, 0.034228353120175696600101652094083332Q, 0.031226023505331741095045556858942863Q, 0.028444973247334237420578959776412296Q, 0.025872714343617644485216127636544335Q, 0.023497155463988527331246316453605283Q, 0.021306612366126070465592025046447108Q, 0.019289816240845601467614148418736892Q, 0.017435920073977461259931130790681214Q, 0.015734503113059796501938486945359929Q, 0.014175573528330460201833138862417195Q, 0.012749569358731162695972946581614495Q, 0.011447357834799756252759767428888751Q, 0.010260233171410768904966921400699131Q, 0.0091799129243109016820036013086815458Q, 0.0081985330052611999146716526049152539Q, 0.0073086414513132480272928751787482011Q, 0.0065031910442825794569735904252798084Q, 0.0057755308768065491405505517951108403Q, 0.0051193969614537818669843222017295048Q, 0.0045289019791562891246666236654351803Q, 0.0039985242627335310486699760330762132Q, 0.0035230961104429863210055440392477764Q, 0.003097791523300820656719025216576771Q, 0.0027181134583502264180047688832185696Q, 0.00237988068810043824649673132220802Q, 0.0020792143540086661490040088456472881Q, 0.0018125242991288642651054139496748517Q, 0.0015764952619105560466714983901735372Q, 0.001368073009609703955236179563862531Q, 0.0011844504858902772190681005760231091Q, 0.0010230540429745410945605352201833147Q, 0.00088152982417297002262517617153839107Q, 0.00075773035782735921074324212296621353Q, 0.00064970141867429037384583446669345298Q, 0.00055566920742578558188343231541026958Q, 0.00047402789401816719609357067930453704Q, 0.00040332756454954092910822407611191225Q, 0.0003422626064629768809457896368129693Q, 0.00028966056108877174342801893880690422Q, 0.00024447146728689162442142144970348683Q, 0.00020575771467998818628501233394779612Q, 0.00017268441988592922811041420156552324Q, 0.00014451033429094586468260075495740334Q, 0.00012057928729056996115421473619828627Q, 0.0001003121646011242017105871905771618Q, 8.3199417240036480655327139421155229e-05Q, 6.8794093113496376994935071214960655e-05Q, 5.6705379853932877470011678973870605e-05Q, 4.6592644630494618702241456703037532e-05Q, 3.8159954120245760316298139014562893e-05Q, 3.1151055677448352880855786865941099e-05Q, 2.5344798968850110019503595997329621e-05Q, 2.0550975944934244592401576964828471e-05Q, 1.6606555976508335934243673648199596e-05Q, 1.3372292284532372637222480551805329e-05Q, 1.0729675406852340659025097863229453e-05Q, 8.5782093537079082475098159798479489e-06Q, 6.8329862774218506793384467861049682e-06Q, 5.4225358918240331874795406776236123e-06Q, 4.2869264939998226801201888531480146e-06Q, 3.3760952348055109687047948553034167e-06Q, 2.648386225404341059332347382668934e-06Q, 2.0692761257364670911197722058327534e-06Q, 1.6102680094507650586919500255804135e-06Q, 1.2479355121177451927952866165256362e-06Q, 9.6310052117659252623275411195037422e-07Q, 7.4012893490908614244527654085271701e-07Q, 5.6633028402050775174949474283673891e-07Q, 4.3144825587165380566889409128276242e-07Q, 3.2723037330517558940458575985214918e-07Q, 2.4706624511249700700814105972385083e-07Q, 1.8568491370025132363780817403060483e-07Q, 1.3890286996035952957423247999266266e-07Q, 1.0341528040745607124994759911720107e-07Q, 7.6623873974817584699067130031657306e-08Q, 5.6495763871670621475281493521314709e-08Q, 4.1448233558505383939707940899336768e-08Q, 3.0255196464899467188973440250947218e-08Q, 2.1971648917089349870913690980235634e-08Q, 1.5872978090968232625950436800137184e-08Q, 1.1406465554850482080861078708713322e-08Q, 8.1527464828576537674941124925699748e-09Q, 5.7953495730966064129686023678242569e-09Q, 4.0967579139685198004841429173893772e-09Q, 2.8797013464471104655049488102491186e-09Q, 2.0126210218867172874496187582569718e-09Q, 1.3984414312565442025515753185221259e-09Q, 9.6594851858099300536090988590771494e-10Q, 6.6320863470162099803938291638680053e-10Q, 4.5257576104153821951813027371570715e-10Q, 3.0692702078723328679138233160912672e-10Q, 2.0684203539029217544821684017571545e-10Q, 1.3850287525834145108955800004991698e-10Q, 9.214056422651888408320635035510389e-11Q, 6.0893387064380670508776147108848386e-11Q, 3.9973389519930269589286591598258413e-11Q, 2.6061960502805293348144397281679947e-11Q, 1.6874519343915025228826792012273533e-11Q, 1.0849161834337120075418713193749676e-11Q, 6.925528015268138234276418201069421e-12Q, 4.3888651899779304012906781620222308e-12Q, 2.7608587671398283608193689290767215e-12Q, 1.7237644036042717645352410466671951e-12Q, 1.0680750436541459501472279340038532e-12Q, 6.5669443496573770247087892915106603e-13Q, 4.0059853799532432743143892523313549e-13Q, 2.4242966045442409054601213028173084e-13Q, 1.455249915777183791487150796402817e-13Q, 8.6638127254357861703205617203908732e-14Q, 5.1149749011237035858347608326433163e-14Q, 2.994217759503148409824465166785657e-14Q, 1.7376816946074293584520159998670905e-14Q, 9.9964240098994293054396937904035808e-15Q, 5.6996266660577917745539527915605509e-15Q, 3.2204325132709429326443049307963174e-15Q, 1.8029589638948994224704223595333813e-15Q, 9.9999573441511328003764710559432247e-16Q, 5.4939783973500551313304111867037353e-16Q, 2.9894208856836080833460170608635085e-16Q, 1.610765424389333897595412933702905e-16Q, 8.5932097482708020320234894915603507e-17Q, 4.5382468267138486711718165281416612e-17Q, 2.3722531670914086186505578503296188e-17Q, 1.2271671669957684251768746309727359e-17Q, 6.2812290485539754593993025086049784e-18Q, 3.1806147137287576603303714266387884e-18Q, 1.5930492574791968327078642420897427e-18Q, 7.8908551593455841363543904697547233e-19Q, 3.8647331030140734169770289169399394e-19Q, 1.8712773299709086118483416095592492e-19Q, 8.9557394552313902528032623648079256e-20Q, 4.2357428519456376102962467454513856e-20Q, 1.979436201534175012643985224780424e-20Q, 9.1380785584698727034273276491713887e-21Q, 4.1666411584773049229385926804715087e-21Q, 1.8760750552668470771305003442308049e-21Q, 8.3399019486525331443195597764274931e-22Q, 3.6595752362436730932932611770341911e-22Q, 1.5847852183325978194205652538004105e-22Q, 6.7715756944343963844212791596730701e-23Q, 2.8542817079371140817224171432389793e-23Q, 1.1865838580947568695752893868758282e-23Q, 4.8640699357080450262013571667032291e-24Q, 1.9656434192469852200073765210097077e-24Q, 7.8291656246958620676899939812206199e-25Q, 3.0727892288172702707668669968129923e-25Q, 1.1881076147213762784564203492918474e-25Q, 4.5246197487634934114352468991264689e-26Q, 1.6967101868478854591740026523544294e-26Q, 6.2636410032291183199621894495108545e-27Q, 2.275790792857396714851032797332432e-27Q, 8.1360777159044314206100175821194793e-28Q, 2.8613065492953910272350038532776635e-28Q, 9.8961841969437875600155257339935786e-29Q, 3.3652008931641398734060087635568974e-29Q, 1.124807054607635533524732113721643e-29Q, 3.6944604327139334398530256817969063e-30Q, 1.1920933013465364813127655880555969e-30Q, 3.7777578760183197857216889284069537e-31Q, 1.1754363786778472289935929233399097e-31Q, 3.5898790778284615893833448994196406e-32Q, 1.0758426862142799782307176268359752e-32Q, 3.1628351259465958616106447958915727e-33Q, 9.1186741890740659476367230179943904e-34Q, 2.5773931684416249884030668079887807e-34Q, 7.1398295043464040965283248909128753e-35Q, 1.9378289210199819221125431141075043e-35Q, 5.1513791013790083352767878745680313e-36Q, 1.3408183263237239554032545670003467e-36Q, 3.4159407851320474430217223083201431e-37Q, 8.5152627413375142768339982799164144e-38Q, 2.076271482369099670696465965718329e-38Q, 4.9501378383448158752628326041586328e-39Q, 1.1535696769569322062307767078682896e-39Q, 2.6266829648536609656499385130095636e-40Q, 5.8418474765546354958505600321922284e-41Q, 1.2685583522817839163209325300191513e-41Q, 2.6885912245101334092484585567288326e-42Q, 5.5593886486694506967808090446058169e-43Q, 1.1211105786168708837628837423551506e-43Q, 2.204030437173812137094585242452846e-44Q, 4.2224091761364250309210368326791673e-45Q, 7.879520062360877249284818876749499e-46Q, 1.4317140234575381985434267597963095e-46Q, 2.5319048034172799761988113239574673e-47Q, 4.3559981958200842427093791079007571e-48Q, 7.2876743960081410061189361036751606e-49Q, 1.1851134957779509548750104934682377e-49Q, 1.872433458377359457763352131002218e-50Q, 2.8729694149829129971079440142039839e-51Q, 4.2789120660247665069210975132651194e-52Q, 6.1831517263855101991333477522333856e-53Q, 8.664706532064762178060555848235158e-54Q, 1.1769423732336786099340369561810161e-54Q, 1.5488187383481079319128553087281025e-55Q, 1.9736646088073419346394015708589866e-56Q, 2.4341838396213207647077873905717686e-57Q, 2.9041369422835327495394798923780893e-58Q, 3.3499429920119329938613749830054234e-59Q, 3.7340806058053956442103094318030179e-60Q, 4.0199589180457423324670244391460705e-61Q, 4.1774687856674289017944418799754548e-62Q, 4.1880972367088277279311490203747192e-63Q, 4.0484306973548957998328137903090132e-64Q, 3.77114883236106507191241601008861e-65Q, 3.3831738882583366253452262404438761e-66Q, 2.9213348345532154319786866459214566e-67Q, 2.4265171108768020980951563482987534e-68Q, 1.9376034615932002776264780070086131e-69Q, 1.4864705425001770514685771802938584e-70Q, 1.0949232255990064493457806009226565e-71Q, 7.7387134447881401018887497774386554e-73Q, 5.2448008205426118383234631723504239e-74Q, 3.4062562927830356374440099107130253e-75Q, 2.1184692439258592242177714552745419e-76Q, 1.2608614434809477030102983673195673e-77Q, 7.1764903126208755695723110547276813e-79Q, 3.9034697656266028736188479360578122e-80Q, 2.0275573404310544862715347770507338e-81Q, 1.004994816430593904290660376649901e-82Q, 4.7500986471514075093717143999280406e-84Q, 2.1392636099460832836078416112710222e-85Q, 9.173149292867278730161085643245862e-87Q, 3.7422217329627927169047643424111024e-88Q, 1.4512980036440354977046772500061822e-89Q, 5.3463017574991130746397399989936882e-91Q, 1.8692545071988721039716330965097833e-92Q, 6.1978958931273853497246435906829052e-94Q, 1.9472339695524234456610961876127122e-95Q, 5.7919052872513171909291273369047611e-97Q, 1.6295956267419577729908767823766263e-98Q, 4.3332432642363261903550403983227406e-100Q, 1.0880149430086354606207846327564807e-101Q, 2.5772282627352113781815039093907765e-103Q, 5.7539838006451121430858484531452556e-105Q, 1.2096990017248315153784188752260699e-106Q, 2.3925872664345045807315831521649824e-108Q, 4.4475659282644875495932738704595289e-110Q, 7.7627738422265479186699876924736519e-112Q, 1.2709267303083863208341290697181042e-113Q, 1.9498242131608832039698501560236386e-115Q, 2.8002525531974060834525812862103801e-117Q, 3.7607474856227547424556497710309557e-119Q, 4.7181060260584103957700726731938295e-121Q, 5.5234683214250331048701341097289187e-123Q, 6.0274476904458633271417170323324512e-125Q, 6.1242336828836773956273877493935834e-127Q, 5.7873336327745621779130244175524495e-129Q, 5.080632710884007461562439620052701e-131Q, 4.1387180173608798644427799558698992e-133Q, 3.1247188175223382722031520705749413e-135Q, 2.1839031164024077549981710942515192e-137Q, 1.4112539862126523413412548851519319e-139Q, 8.4215132945549247707528420294855683e-142Q, 4.6349339497376890248654482771898709e-144Q, 2.3496985464521993504910835710336684e-146Q, 1.095806710681902573252914390685236e-148Q, 4.6950275371271587533706139425003387e-151Q, 1.8456310819897755187059215917442304e-153Q, 6.6476058774188256202611396416535206e-156Q, 2.1907913883958482863705726011811944e-158Q, 6.5969704613629998580324088255164448e-161Q, 1.8125024222344232769814833021310009e-163Q, 4.5370781893964839845073953864812105e-166Q, 1.0332388835710739936372904447767308e-168Q, 2.1374954497695898284726118552680548e-171Q, 4.0108149042055622979938927508096981e-174Q, 6.8157812455297175262972900652817266e-177Q, 1.0473127652676199964496156413213892e-179Q, 1.4528685940321876156376494017441343e-182Q, 1.8166282837173462776489744689123018e-185Q, 2.0440202882824856548036164467448088e-188Q, 2.0661513859552458565266153108297534e-191Q, 1.8731127932057798663856916994067048e-194Q, 1.5203587637183862829799380406495058e-197Q, 1.1029412423875246289335781867943994e-200Q, 7.138626970990275795307217364262657e-204Q, 4.1148385080761107172311325770404465e-207Q, 2.1085028345530812052701929614749437e-210Q, 9.586804728597153811540457301738394e-214Q, 3.8604168930466380230648935566836905e-217Q, 1.3741198913182849308419643845423577e-220Q, 4.3152058575378643032664917818412533e-224Q, 1.19318553486394227968739928824324e-227Q, 2.8991695266404489121362655770787829e-231Q, 6.1775221006993094876500875992969792e-235Q, 1.1519457912295313262297054573241955e-238Q, 1.8759214343015253296548435854195451e-242Q, 2.6621687700905798726983482845704724e-246Q, 3.2851388833240439850794784627378447e-250Q, 3.5173302898760059862233242135090423e-254Q, 3.260189457452227113017033626415114e-258Q, 2.6100961489800200467379180863184362e-262Q, 1.8007454797962902444457099319194981e-266Q, 1.0681019906266894643271137718146545e-270Q, 5.4338051160125203325306044546291973e-275Q, 2.3652466547636417935201205492175566e-279Q, 8.7874613708003418754944028581674092e-284Q, 2.7795968403545195493312606588081939e-288Q, 7.4667445765219841782970695464816343e-293Q, 1.6990035121087781757668989612218036e-297Q, 3.2661456244114182842789617411036552e-302Q, 5.2905644824269341726292739407836284e-307Q, 7.2014912174357894815487914007866659e-312Q, 8.2149916381513794689686855840667286e-317Q, 7.8315488217791735530193073164613925e-322Q, 6.221807701348355377240172152359918e-327Q, 4.1074011155154758472047101692258134e-332Q, 2.2466366589127674529456245569217313e-337Q, 1.0151434061771573997492847262735324e-342Q, 3.7778453114026807637246195807729534e-348Q, 1.1543990703305213109241662519678786e-353Q, 2.8874514917596574178755044320075352e-359Q, 5.8931980361396154630354121875276487e-365Q, 9.7830460697139640980628824283457061e-371Q, 1.3166522887017193888073217487220663e-376Q, 1.4318812372702150835656599374620546e-382Q, 1.2540768871672304974301195995718396e-388Q, 8.8153996483879828169726259431129063e-395Q, 4.9562889772003524717252843516553902e-401Q, 2.2209583723340796264599763080008776e-407Q, 7.903905845967360394872219425003336e-414Q, 2.2257919152191142215565812315993462e-420Q, 4.9416038684875140142672214621735078e-427Q, 8.6171916788075114925145119819509171e-434Q, 1.1757806822258262957023704296248014e-440Q, 1.2504660464052680899003468814266606e-447Q, 1.0325197258632347378121850864959173e-454Q, 6.5928728293837187402797552969580767e-462Q, 3.2422215378060561710679179733872247e-469Q, 1.222971654709343975246423698805888e-476Q, 3.523560719191273512100160441884497e-484Q, 7.7214021325433144875052949047234787e-492Q, 1.2814096433117550022825846412075423e-499Q, 1.6034524983169066795932277083952198e-507Q, 1.506154257333325578480885384144555e-515Q, 1.0572229793982283970011093126796893e-523Q, 5.5202045762026741431740525809554222e-532Q, 2.1340837910128019442948018148493991e-540Q, 6.0796683172016911238300290124661526e-549Q, 1.2702010542787853060770224333562558e-557Q, 1.9367268433132755704840764854736682e-566Q, 2.1444373126935426310796432391730652e-575Q, 1.7156127051237753338771752429597998e-584Q, 9.866507362005302302229219896627392e-594Q, 4.0577781777778825723169578502780851e-603Q, 1.1871364801794013747840938511563031e-612Q, 2.4573736732127578624297116105185871e-622Q, 3.5795957466771145363085369419550411e-632Q, 3.6491000343716609306595204093204503e-642Q, 2.5887224173643746039322073618863653e-652Q, 1.2707309714711704379079743917253552e-662Q, 4.2911292837382087644451178350840055e-673Q, 9.9101724991114880676267115929463864e-684Q, 1.5559081312551687762049592042215559e-694Q, 1.6505944447381619620675148844917786e-705Q, 1.1758976044388560589646808736426135e-716Q, 5.5904673599123524828590221558073227e-728Q, 1.762422841281411916279811438897522e-739Q, 3.660545736359787919552147533680784e-751Q, 4.9762407942794836638678732794521407e-763Q, 4.3982297935392846258826361101417004e-775Q, 2.5103306493196863847807186768995234e-787Q, 9.1890276778950746130428977933070467e-800Q, 2.1421794336828190981917187030902949e-812Q, 3.1579407773552118084939940851249037e-825Q, 2.9226685587591509131252404660323457e-838Q, 1.6857720383594173922437511994184956e-851Q, 6.0148932059792413237874599630717323e-865Q, 1.3175950977896871810836083428540193e-878Q, 1.7584274071402706626129462062711265e-892Q, 1.4186205574627811155197950438077455e-906Q, 6.863804756553040536363703712029114e-921Q, 1.9757126782016829801994589969078639e-935Q, 3.3557616466388148224311943077895109e-950Q, 3.3354866661158784873247273739595471e-965Q, 1.9238163515428741014100444007200552e-980Q, 6.3838419214869081664291315367530963e-996Q, 1.208186393746817780221157077221556e-1011Q, 1.2926433460770675227136395965601267e-1027Q, 7.7484641126890628613399212918871834e-1044Q, 2.578590762872741885363873428172601e-1060Q, 4.720135411440959292309368252688105e-1077Q, 4.7080786123051904219070581932647786e-1094Q, 2.5345319096404707885383043943244978e-1111Q, 7.2928761242789730396354678181188802e-1129Q, 1.1106128952895418090598971812669904e-1146Q, 8.8621216538366976598099979452808551e-1165Q, 3.6677828388640988980975786646419682e-1183Q, 7.7923888084439739305704880307980387e-1202Q, 8.4096550976573708334084140027496576e-1221Q, 4.5613561814429013831962003215267279e-1240Q, 1.2300215778004431684442502009102409e-1259Q, 1.6310040159866857782581696492106591e-1279Q, 1.0516379174444742948762886500817157e-1299Q, 3.2599823473651125257811218258666689e-1320Q, 4.8027868480449172060158102541122388e-1341Q, 3.3236309884819155458562664594667437e-1362Q, 1.0675935976034168796912624171598076e-1383Q, 1.5726195400977448490722891999643084e-1405Q, 1.0493832555753684651126599489805473e-1427Q, 3.1327201084154872489458088843708842e-1450Q, 4.1312837255709912970140480142041816e-1473Q, 2.3759469769680296617336666937339053e-1496Q, 5.8816760470052203616229940275916193e-1520Q, 6.1846204357986408200352274197037853e-1544Q, 2.7253154006156158167192213817170292e-1568Q, 4.964370850871644112480158952518382e-1593Q, 3.6864952720610418491857518517405997e-1618Q, 1.1003435724966953469136035841615193e-1643Q, 1.3012915572536198178305157209959287e-1669Q, 6.0092590718277568469858434192698668e-1696Q, 1.0676671777328477051443719591612721e-1722Q, 7.1893041788265042697820383343649581e-1750Q, 1.8069174401475778125395048319028868e-1777Q, 1.6689765331128672749329764129278041e-1805Q, 5.5766895369980043818737558535999006e-1834Q, 6.6338104205654511592967377535571654e-1863Q, 2.7640539994999072399732281044814252e-1892Q, 3.9678218215367472586686997493459426e-1922Q, 1.9297110274588854079208153981267479e-1952Q, 3.125823255660491143824024380405163e-1983Q, 1.6574847870654916983076674690989236e-2014Q, 2.8268986732520512350429266473306993e-2046Q, 1.5233117185863507338781156113800939e-2078Q, 2.546861334196453858326476740489303e-2111Q, 1.2970473455790653045919178951673388e-2144Q, 1.9747419969447016216735762205746422e-2178Q, 8.8188278044353709778558661887540083e-2213Q, 1.1331026308914886857015956789021835e-2247Q, 4.1073843396377054383734821718609159e-2283Q, 4.1176061068991316842526396776090883e-2319Q, 1.1187086154165438557157295454514512e-2355Q, 8.0696152044407520449588862080186105e-2393Q, 1.5135007846133660639825213215103939e-2430Q, 7.2259333243684066847653432848351411e-2469Q, 8.5946687461833096509693248289938412e-2508Q, 2.4916284852956646502671815296350685e-2547Q, 1.7218755528601187283427831366854425e-2587Q, 2.7731789802471774097405514299103397e-2628Q, 1.0173036737175759305843452255817661e-2669Q, 8.3042791798168477802920353914502218e-2712Q, 1.473175854535708068279125062330391e-2754Q, 5.5445898944436653916624336507572418e-2798Q, 4.320588676830861227044616106347197e-2842Q, 6.7999319106199079525777026656783353e-2887Q, 2.1077263780365503485840282493709679e-2932Q, 1.2541789874677469018547003272238725e-2978Q, 1.3958959110384407791740617210399902e-3025Q, 2.8302814609077924874798718558506843e-3073Q, 1.0177558252358910503169620579616733e-3121Q, 6.316345161489586703263200702377878e-3171Q, 6.5808353794152592529153513818570413e-3221Q, 1.1191402820754794725611968922105955e-3271Q, 3.0191144446114914489317417615052391e-3323Q, 1.2550879768384736567252096901362895e-3375Q, 7.8068891083719869927416696059040226e-3429Q, 7.0517902304991510532607166162881123e-3483Q, 8.9730892510839231589218006993975962e-3538Q, 1.5595586152851619317721078977043233e-3593Q, 3.5880900047081973177436521469002167e-3650Q, 1.0585155878906962124317498469363852e-3707Q, 3.8766455756851727310799307162918377e-3766Q, 1.7055766393620807246392140051588691e-3825Q, 8.7186526945824113614692955827617228e-3886Q, 5.0057478847913665022916271652366648e-3947Q, 3.118721903551705673676508466953291e-4009Q, 2.0360271187838855169643637345546437e-4072Q, 1.344193072571113944443469925533764e-4136Q, 8.6564521926545774914724471102499854e-4202Q, 5.2420435234912004640647252129478902e-4268Q, 2.8759098307799421718470860096954611e-4335Q, 1.3763877452472741048491095385711433e-4403Q, 5.5298776937738818735087266649244396e-4473Q, 1.7937216962986389293716315095996859e-4543Q, 4.5149004338871753808860898565339903e-4615Q, 8.4705695199542943533046216376760939e-4688Q, 1.1370794062105632021349671352107651e-4761Q, 1.0477206804639390072354388690482908e-4836Q, 6.3526587059143165049479765478742544e-4913Q, 2.4283486680552345908529800038916585e-4990Q, 5.6028531999416699789095738832933157e-5069Q, 7.4653403674710397422097751397913229e-5149Q, 5.4919841992020489039553213694177019e-5230Q, 2.1312688707736268785590779947753119e-5312Q, 4.1653791598980828217930742787672032e-5396Q, 3.9114639992058990826656399856975019e-5481Q, }, + }; + m_first_complements = { + 1, 0, 1, 1, 3, 5, 11, 22, + }; +#if !defined(BOOST_MATH_NO_ATOMIC_INT) && defined(BOOST_HAS_THREADS) + m_committed_refinements = static_cast(m_abscissas.size() - 1); +#else + m_committed_refinements = m_abscissas.size() - 1; +#endif + + if (m_max_refinements >= m_abscissas.size()) + { + m_abscissas.resize(m_max_refinements + 1); + m_weights.resize(m_max_refinements + 1); + m_first_complements.resize(m_max_refinements + 1); + } + else + { + m_max_refinements = m_abscissas.size() - 1; + } + m_t_max = static_cast(m_inital_row_length); + m_t_crossover = t_from_abscissa_complement(Real(0.5)); + + prune_to_min_complement(min_complement); +} + +#endif // BOOST_HAS_FLOAT128 + +template +void tanh_sinh_detail::prune_to_min_complement(const Real& m) +{ + // + // If our tables were constructed from pre-computed data, then they will have more values stored than we can ever use, + // and although the table size at this stage won't be too large, if we calculate down to m_max_levels then they will + // grow by a huge amount - doubling in size at each step - so lets prune them down, removing values which will never + // be used: + // + if (m > tools::min_value() * 4) + { + for (unsigned row = 0; (row < m_abscissas.size()) && m_abscissas[row].size(); ++row) + { + typename std::vector::iterator pos = std::lower_bound(m_abscissas[row].begin(), m_abscissas[row].end(), m, [](const Real& a, const Real& b) { using std::fabs; return fabs(a) > fabs(b); }); + if (pos != m_abscissas[row].end()) + { + m_abscissas[row].erase(pos, m_abscissas[row].end()); + m_weights[row].erase(m_weights[row].begin() + m_abscissas[row].size(), m_weights[row].end()); + } + } + } +} + +}}}} // namespaces + +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/exp_sinh.hpp b/libcxx/src/third-party/boost/math/quadrature/exp_sinh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/exp_sinh.hpp @@ -0,0 +1,102 @@ +// Copyright Nick Thompson, 2017 +// 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) + +/* + * This class performs exp-sinh quadrature on half infinite intervals. + * + * References: + * + * 1) Tanaka, Ken'ichiro, et al. "Function classes for double exponential integration formulas." Numerische Mathematik 111.4 (2009): 631-655. + */ + +#ifndef BOOST_MATH_QUADRATURE_EXP_SINH_HPP +#define BOOST_MATH_QUADRATURE_EXP_SINH_HPP + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class exp_sinh +{ +public: + exp_sinh(size_t max_refinements = 9) + : m_imp(std::make_shared>(max_refinements)) {} + + template + auto integrate(const F& f, Real a, Real b, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr)->decltype(std::declval()(std::declval())) const; + template + auto integrate(const F& f, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr)->decltype(std::declval()(std::declval())) const; + +private: + std::shared_ptr> m_imp; +}; + +template +template +auto exp_sinh::integrate(const F& f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels)->decltype(std::declval()(std::declval())) const +{ + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + using std::abs; + using boost::math::constants::half; + using boost::math::quadrature::detail::exp_sinh_detail; + + static const char* function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + + // Neither limit may be a NaN: + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + { + return static_cast(policies::raise_domain_error(function, "NaN supplied as one limit of integration - sorry I don't know what to do", a, Policy())); + } + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= boost::math::tools::max_value())) + { + // If a = 0, don't use an additional level of indirection: + if (a == static_cast(0)) + { + return m_imp->integrate(f, error, L1, function, tolerance, levels); + } + const auto u = [&](Real t)->K { return f(t + a); }; + return m_imp->integrate(u, error, L1, function, tolerance, levels); + } + + if ((boost::math::isfinite)(b) && a <= -boost::math::tools::max_value()) + { + const auto u = [&](Real t)->K { return f(b-t);}; + return m_imp->integrate(u, error, L1, function, tolerance, levels); + } + + // Infinite limits: + if ((a <= -boost::math::tools::max_value()) && (b >= boost::math::tools::max_value())) + { + return static_cast(policies::raise_domain_error(function, "Use sinh_sinh quadrature for integration over the whole real line; exp_sinh is for half infinite integrals.", a, Policy())); + } + // If we get to here then both ends must necessarily be finite: + return static_cast(policies::raise_domain_error(function, "Use tanh_sinh quadrature for integration over finite domains; exp_sinh is for half infinite integrals.", a, Policy())); +} + +template +template +auto exp_sinh::integrate(const F& f, Real tolerance, Real* error, Real* L1, std::size_t* levels)->decltype(std::declval()(std::declval())) const +{ + static const char* function = "boost::math::quadrature::exp_sinh<%1%>::integrate"; + using std::abs; + if (abs(tolerance) > 1) { + std::string msg = std::string(__FILE__) + ":" + std::to_string(__LINE__) + ":" + std::string(function) + ": The tolerance provided is unusually large; did you confuse it with a domain bound?"; + throw std::domain_error(msg); + } + return m_imp->integrate(f, error, L1, function, tolerance, levels); +} + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/gauss.hpp b/libcxx/src/third-party/boost/math/quadrature/gauss.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/gauss.hpp @@ -0,0 +1,1300 @@ +// Copyright John Maddock 2015. +// 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_QUADRATURE_GAUSS_HPP +#define BOOST_MATH_QUADRATURE_GAUSS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +namespace boost { namespace math{ namespace quadrature{ namespace detail{ + +template +struct gauss_constant_category +{ + static const unsigned value = + (std::numeric_limits::is_specialized == 0) ? 999 : + (std::numeric_limits::radix == 2) ? + ( + (std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_convertible::value ? 0 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_convertible::value ? 1 : + (std::numeric_limits::digits <= std::numeric_limits::digits) && std::is_convertible::value ? 2 : +#ifdef BOOST_HAS_FLOAT128 + (std::numeric_limits::digits <= 113) && std::is_constructible<__float128, T>::value ? 3 : +#endif + (std::numeric_limits::digits10 <= 110) ? 4 : 999 + ) : (std::numeric_limits::digits10 <= 110) ? 4 : 999; +}; + +#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND + +template +class gauss_detail +{ + static std::vector calculate_weights() + { + std::vector result(abscissa().size(), 0); + for (unsigned i = 0; i < abscissa().size(); ++i) + { + Real x = abscissa()[i]; + Real p = boost::math::legendre_p_prime(N, x); + result[i] = 2 / ((1 - x * x) * p * p); + } + return result; + } +public: + static const std::vector& abscissa() + { + static std::vector data = boost::math::legendre_p_zeros(N); + return data; + } + static const std::vector& weights() + { + static std::vector data = calculate_weights(); + return data; + } +}; + +#else + +template +class gauss_detail; + +#endif + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 4.058451514e-01f, + 7.415311856e-01f, + 9.491079123e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 4.179591837e-01f, + 3.818300505e-01f, + 2.797053915e-01f, + 1.294849662e-01f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 4.05845151377397167e-01, + 7.41531185599394440e-01, + 9.49107912342758525e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 4.17959183673469388e-01, + 3.81830050505118945e-01, + 2.79705391489276668e-01, + 1.29484966168869693e-01, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 4.05845151377397166906606412076961463e-01L, + 7.41531185599394439863864773280788407e-01L, + 9.49107912342758524526189684047851262e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 4.17959183673469387755102040816326531e-01L, + 3.81830050505118944950369775488975134e-01L, + 2.79705391489276667901467771423779582e-01L, + 1.29484966168869693270611432679082018e-01L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 4.05845151377397166906606412076961463e-01Q, + 7.41531185599394439863864773280788407e-01Q, + 9.49107912342758524526189684047851262e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 4.17959183673469387755102040816326531e-01Q, + 3.81830050505118944950369775488975134e-01Q, + 2.79705391489276667901467771423779582e-01Q, + 1.29484966168869693270611432679082018e-01Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1795918367346938775510204081632653061224489795918367346938775510204081632653061224489795918367346938775510204081633e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8183005050511894495036977548897513387836508353386273475108345103070554643412970834868465934404480145031467176458536e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7970539148927666790146777142377958248692506522659876453701403269361881043056267681324094290119761876632337521337205e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2948496616886969327061143267908201832858740225994666397720863872465523497204230871562541816292084508948440200163443e-01), + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 1.488743390e-01f, + 4.333953941e-01f, + 6.794095683e-01f, + 8.650633667e-01f, + 9.739065285e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.955242247e-01f, + 2.692667193e-01f, + 2.190863625e-01f, + 1.494513492e-01f, + 6.667134431e-02f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 1.48874338981631211e-01, + 4.33395394129247191e-01, + 6.79409568299024406e-01, + 8.65063366688984511e-01, + 9.73906528517171720e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.95524224714752870e-01, + 2.69266719309996355e-01, + 2.19086362515982044e-01, + 1.49451349150580593e-01, + 6.66713443086881376e-02, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 1.48874338981631210884826001129719985e-01L, + 4.33395394129247190799265943165784162e-01L, + 6.79409568299024406234327365114873576e-01L, + 8.65063366688984510732096688423493049e-01L, + 9.73906528517171720077964012084452053e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.95524224714752870173892994651338329e-01L, + 2.69266719309996355091226921569469353e-01L, + 2.19086362515982043995534934228163192e-01L, + 1.49451349150580593145776339657697332e-01L, + 6.66713443086881375935688098933317929e-02L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 1.48874338981631210884826001129719985e-01Q, + 4.33395394129247190799265943165784162e-01Q, + 6.79409568299024406234327365114873576e-01Q, + 8.65063366688984510732096688423493049e-01Q, + 9.73906528517171720077964012084452053e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 2.95524224714752870173892994651338329e-01Q, + 2.69266719309996355091226921569469353e-01Q, + 2.19086362515982043995534934228163192e-01Q, + 1.49451349150580593145776339657697332e-01Q, + 6.66713443086881375935688098933317929e-02Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9552422471475287017389299465133832942104671702685360135430802975599593821715232927035659579375421672271716440125256e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6926671930999635509122692156946935285975993846088379580056327624215343231917927676422663670925276075559581145036870e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1908636251598204399553493422816319245877187052267708988095654363519991065295128124268399317720219278659121687281289e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4945134915058059314577633965769733240255663966942736783547726875323865472663001094594726463473195191400575256104544e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6671344308688137593568809893331792857864834320158145128694881613412064084087101776785509685058877821090054714520419e-02), + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 2.011940940e-01f, + 3.941513471e-01f, + 5.709721726e-01f, + 7.244177314e-01f, + 8.482065834e-01f, + 9.372733924e-01f, + 9.879925180e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.025782419e-01f, + 1.984314853e-01f, + 1.861610000e-01f, + 1.662692058e-01f, + 1.395706779e-01f, + 1.071592205e-01f, + 7.036604749e-02f, + 3.075324200e-02f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 2.01194093997434522e-01, + 3.94151347077563370e-01, + 5.70972172608538848e-01, + 7.24417731360170047e-01, + 8.48206583410427216e-01, + 9.37273392400705904e-01, + 9.87992518020485428e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.02578241925561273e-01, + 1.98431485327111576e-01, + 1.86161000015562211e-01, + 1.66269205816993934e-01, + 1.39570677926154314e-01, + 1.07159220467171935e-01, + 7.03660474881081247e-02, + 3.07532419961172684e-02, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 2.01194093997434522300628303394596208e-01L, + 3.94151347077563369897207370981045468e-01L, + 5.70972172608538847537226737253910641e-01L, + 7.24417731360170047416186054613938010e-01L, + 8.48206583410427216200648320774216851e-01L, + 9.37273392400705904307758947710209471e-01L, + 9.87992518020485428489565718586612581e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.02578241925561272880620199967519315e-01L, + 1.98431485327111576456118326443839325e-01L, + 1.86161000015562211026800561866422825e-01L, + 1.66269205816993933553200860481208811e-01L, + 1.39570677926154314447804794511028323e-01L, + 1.07159220467171935011869546685869303e-01L, + 7.03660474881081247092674164506673385e-02L, + 3.07532419961172683546283935772044177e-02L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 2.01194093997434522300628303394596208e-01Q, + 3.94151347077563369897207370981045468e-01Q, + 5.70972172608538847537226737253910641e-01Q, + 7.24417731360170047416186054613938010e-01Q, + 8.48206583410427216200648320774216851e-01Q, + 9.37273392400705904307758947710209471e-01Q, + 9.87992518020485428489565718586612581e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 2.02578241925561272880620199967519315e-01Q, + 1.98431485327111576456118326443839325e-01Q, + 1.86161000015562211026800561866422825e-01Q, + 1.66269205816993933553200860481208811e-01Q, + 1.39570677926154314447804794511028323e-01Q, + 1.07159220467171935011869546685869303e-01Q, + 7.03660474881081247092674164506673385e-02Q, + 3.07532419961172683546283935772044177e-02Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0257824192556127288062019996751931483866215800947735679670411605143539875474607409339344071278803213535148267082999e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9843148532711157645611832644383932481869255995754199348473792792912479753343426813331499916481782320766020854889310e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8616100001556221102680056186642282450622601227792840281549572731001325550269916061894976888609932360539977709001384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6626920581699393355320086048120881113090018009841290732186519056355356321227851771070517429241553621484461540657185e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3957067792615431444780479451102832252085027531551124320239112863108844454190781168076825736357133363814908889327664e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0715922046717193501186954668586930341554371575810198068702238912187799485231579972568585713760862404439808767837506e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.0366047488108124709267416450667338466708032754330719825907292914387055512874237044840452066693939219355489858595041e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0753241996117268354628393577204417721748144833434074264228285504237189467117168039038770732399404002516991188859473e-02), + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 7.652652113e-02f, + 2.277858511e-01f, + 3.737060887e-01f, + 5.108670020e-01f, + 6.360536807e-01f, + 7.463319065e-01f, + 8.391169718e-01f, + 9.122344283e-01f, + 9.639719273e-01f, + 9.931285992e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.527533871e-01f, + 1.491729865e-01f, + 1.420961093e-01f, + 1.316886384e-01f, + 1.181945320e-01f, + 1.019301198e-01f, + 8.327674158e-02f, + 6.267204833e-02f, + 4.060142980e-02f, + 1.761400714e-02f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 7.65265211334973338e-02, + 2.27785851141645078e-01, + 3.73706088715419561e-01, + 5.10867001950827098e-01, + 6.36053680726515025e-01, + 7.46331906460150793e-01, + 8.39116971822218823e-01, + 9.12234428251325906e-01, + 9.63971927277913791e-01, + 9.93128599185094925e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.52753387130725851e-01, + 1.49172986472603747e-01, + 1.42096109318382051e-01, + 1.31688638449176627e-01, + 1.18194531961518417e-01, + 1.01930119817240435e-01, + 8.32767415767047487e-02, + 6.26720483341090636e-02, + 4.06014298003869413e-02, + 1.76140071391521183e-02, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 7.65265211334973337546404093988382110e-02L, + 2.27785851141645078080496195368574625e-01L, + 3.73706088715419560672548177024927237e-01L, + 5.10867001950827098004364050955250998e-01L, + 6.36053680726515025452836696226285937e-01L, + 7.46331906460150792614305070355641590e-01L, + 8.39116971822218823394529061701520685e-01L, + 9.12234428251325905867752441203298113e-01L, + 9.63971927277913791267666131197277222e-01L, + 9.93128599185094924786122388471320278e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.52753387130725850698084331955097593e-01L, + 1.49172986472603746787828737001969437e-01L, + 1.42096109318382051329298325067164933e-01L, + 1.31688638449176626898494499748163135e-01L, + 1.18194531961518417312377377711382287e-01L, + 1.01930119817240435036750135480349876e-01L, + 8.32767415767047487247581432220462061e-02L, + 6.26720483341090635695065351870416064e-02L, + 4.06014298003869413310399522749321099e-02L, + 1.76140071391521183118619623518528164e-02L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 7.65265211334973337546404093988382110e-02Q, + 2.27785851141645078080496195368574625e-01Q, + 3.73706088715419560672548177024927237e-01Q, + 5.10867001950827098004364050955250998e-01Q, + 6.36053680726515025452836696226285937e-01Q, + 7.46331906460150792614305070355641590e-01Q, + 8.39116971822218823394529061701520685e-01Q, + 9.12234428251325905867752441203298113e-01Q, + 9.63971927277913791267666131197277222e-01Q, + 9.93128599185094924786122388471320278e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 1.52753387130725850698084331955097593e-01Q, + 1.49172986472603746787828737001969437e-01Q, + 1.42096109318382051329298325067164933e-01Q, + 1.31688638449176626898494499748163135e-01Q, + 1.18194531961518417312377377711382287e-01Q, + 1.01930119817240435036750135480349876e-01Q, + 8.32767415767047487247581432220462061e-02Q, + 6.26720483341090635695065351870416064e-02Q, + 4.06014298003869413310399522749321099e-02Q, + 1.76140071391521183118619623518528164e-02Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5275338713072585069808433195509759349194864511237859727470104981759745316273778153557248783650390593544001842813788e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4917298647260374678782873700196943669267990408136831649621121780984442259558678069396132603521048105170913854567338e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4209610931838205132929832506716493303451541339202030333736708298382808749793436761694922428320058260133068573666201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3168863844917662689849449974816313491611051114698352699643649370885435642948093314355797518397262924510598005463625e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1819453196151841731237737771138228700504121954896877544688995202017474835051151630572868782581901744606267543092317e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0193011981724043503675013548034987616669165602339255626197161619685232202539434647534931576947985821375859035525483e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3276741576704748724758143222046206100177828583163290744882060785693082894079419471375190843790839349096116111932764e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2672048334109063569506535187041606351601076578436364099584345437974811033665678644563766056832203512603253399592073e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0601429800386941331039952274932109879090639989951536817606854561832296750987328295538920623044384976189825709675075e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.7614007139152118311861962351852816362143105543336732524349326677348419259621847817403105542146097668703716227512570e-02), + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 1.228646926e-01f, + 2.438668837e-01f, + 3.611723058e-01f, + 4.730027314e-01f, + 5.776629302e-01f, + 6.735663685e-01f, + 7.592592630e-01f, + 8.334426288e-01f, + 8.949919979e-01f, + 9.429745712e-01f, + 9.766639215e-01f, + 9.955569698e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.231760537e-01f, + 1.222424430e-01f, + 1.194557635e-01f, + 1.148582591e-01f, + 1.085196245e-01f, + 1.005359491e-01f, + 9.102826198e-02f, + 8.014070034e-02f, + 6.803833381e-02f, + 5.490469598e-02f, + 4.093915670e-02f, + 2.635498662e-02f, + 1.139379850e-02f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 1.22864692610710396e-01, + 2.43866883720988432e-01, + 3.61172305809387838e-01, + 4.73002731445714961e-01, + 5.77662930241222968e-01, + 6.73566368473468364e-01, + 7.59259263037357631e-01, + 8.33442628760834001e-01, + 8.94991997878275369e-01, + 9.42974571228974339e-01, + 9.76663921459517511e-01, + 9.95556969790498098e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.23176053726715451e-01, + 1.22242442990310042e-01, + 1.19455763535784772e-01, + 1.14858259145711648e-01, + 1.08519624474263653e-01, + 1.00535949067050644e-01, + 9.10282619829636498e-02, + 8.01407003350010180e-02, + 6.80383338123569172e-02, + 5.49046959758351919e-02, + 4.09391567013063127e-02, + 2.63549866150321373e-02, + 1.13937985010262879e-02, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 1.22864692610710396387359818808036806e-01L, + 2.43866883720988432045190362797451586e-01L, + 3.61172305809387837735821730127640667e-01L, + 4.73002731445714960522182115009192041e-01L, + 5.77662930241222967723689841612654067e-01L, + 6.73566368473468364485120633247622176e-01L, + 7.59259263037357630577282865204360976e-01L, + 8.33442628760834001421021108693569569e-01L, + 8.94991997878275368851042006782804954e-01L, + 9.42974571228974339414011169658470532e-01L, + 9.76663921459517511498315386479594068e-01L, + 9.95556969790498097908784946893901617e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.23176053726715451203902873079050142e-01L, + 1.22242442990310041688959518945851506e-01L, + 1.19455763535784772228178126512901047e-01L, + 1.14858259145711648339325545869555809e-01L, + 1.08519624474263653116093957050116619e-01L, + 1.00535949067050644202206890392685827e-01L, + 9.10282619829636498114972207028916534e-02L, + 8.01407003350010180132349596691113023e-02L, + 6.80383338123569172071871856567079686e-02L, + 5.49046959758351919259368915404733242e-02L, + 4.09391567013063126556234877116459537e-02L, + 2.63549866150321372619018152952991449e-02L, + 1.13937985010262879479029641132347736e-02L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 1.22864692610710396387359818808036806e-01Q, + 2.43866883720988432045190362797451586e-01Q, + 3.61172305809387837735821730127640667e-01Q, + 4.73002731445714960522182115009192041e-01Q, + 5.77662930241222967723689841612654067e-01Q, + 6.73566368473468364485120633247622176e-01Q, + 7.59259263037357630577282865204360976e-01Q, + 8.33442628760834001421021108693569569e-01Q, + 8.94991997878275368851042006782804954e-01Q, + 9.42974571228974339414011169658470532e-01Q, + 9.76663921459517511498315386479594068e-01Q, + 9.95556969790498097908784946893901617e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 1.23176053726715451203902873079050142e-01Q, + 1.22242442990310041688959518945851506e-01Q, + 1.19455763535784772228178126512901047e-01Q, + 1.14858259145711648339325545869555809e-01Q, + 1.08519624474263653116093957050116619e-01Q, + 1.00535949067050644202206890392685827e-01Q, + 9.10282619829636498114972207028916534e-02Q, + 8.01407003350010180132349596691113023e-02Q, + 6.80383338123569172071871856567079686e-02Q, + 5.49046959758351919259368915404733242e-02Q, + 4.09391567013063126556234877116459537e-02Q, + 2.63549866150321372619018152952991449e-02Q, + 1.13937985010262879479029641132347736e-02Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2317605372671545120390287307905014243823362751815166539135219731691200794926142128460112517504958377310054583945994e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2224244299031004168895951894585150583505924756305904090758008223203896721918010243033540891078906637115620156845304e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1945576353578477222817812651290104739017670141372642551958788133518409022018773502442869720975271321374348568426235e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1485825914571164833932554586955580864093619166818014959151499003148279667112542256534429898558156273250513652351744e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0851962447426365311609395705011661934007758798672201615649430734883929279360844269339768350029654172135832773427565e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0053594906705064420220689039268582698846609452814190706986904199941294815904602968195565620373258211755226681206658e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1028261982963649811497220702891653380992558959334310970483768967017384678410526902484398142953718885872521590850372e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0140700335001018013234959669111302290225732853675893716201462973612828934801289559457377714225318048243957479325813e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8038333812356917207187185656707968554709494354636562615071226410003654051711473106651522969481873733098761760660898e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4904695975835191925936891540473324160109985553111349048508498244593774678436511895711924079433444763756746828817613e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0939156701306312655623487711645953660845783364104346504698414899297432880215512770478971055110424130123527015425511e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6354986615032137261901815295299144935963281703322468755366165783870934008879499371529821528172928890350362464605104e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1393798501026287947902964113234773603320526292909696448948061116189891729766743355923677112945033505688431618009664e-02), + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 5.147184256e-02f, + 1.538699136e-01f, + 2.546369262e-01f, + 3.527047255e-01f, + 4.470337695e-01f, + 5.366241481e-01f, + 6.205261830e-01f, + 6.978504948e-01f, + 7.677774321e-01f, + 8.295657624e-01f, + 8.825605358e-01f, + 9.262000474e-01f, + 9.600218650e-01f, + 9.836681233e-01f, + 9.968934841e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.028526529e-01f, + 1.017623897e-01f, + 9.959342059e-02f, + 9.636873717e-02f, + 9.212252224e-02f, + 8.689978720e-02f, + 8.075589523e-02f, + 7.375597474e-02f, + 6.597422988e-02f, + 5.749315622e-02f, + 4.840267283e-02f, + 3.879919257e-02f, + 2.878470788e-02f, + 1.846646831e-02f, + 7.968192496e-03f, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 5.14718425553176958e-02, + 1.53869913608583547e-01, + 2.54636926167889846e-01, + 3.52704725530878113e-01, + 4.47033769538089177e-01, + 5.36624148142019899e-01, + 6.20526182989242861e-01, + 6.97850494793315797e-01, + 7.67777432104826195e-01, + 8.29565762382768397e-01, + 8.82560535792052682e-01, + 9.26200047429274326e-01, + 9.60021864968307512e-01, + 9.83668123279747210e-01, + 9.96893484074649540e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.02852652893558840e-01, + 1.01762389748405505e-01, + 9.95934205867952671e-02, + 9.63687371746442596e-02, + 9.21225222377861287e-02, + 8.68997872010829798e-02, + 8.07558952294202154e-02, + 7.37559747377052063e-02, + 6.59742298821804951e-02, + 5.74931562176190665e-02, + 4.84026728305940529e-02, + 3.87991925696270496e-02, + 2.87847078833233693e-02, + 1.84664683110909591e-02, + 7.96819249616660562e-03, + }; + return data; + } +}; + +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 5.14718425553176958330252131667225737e-02L, + 1.53869913608583546963794672743255920e-01L, + 2.54636926167889846439805129817805108e-01L, + 3.52704725530878113471037207089373861e-01L, + 4.47033769538089176780609900322854000e-01L, + 5.36624148142019899264169793311072794e-01L, + 6.20526182989242861140477556431189299e-01L, + 6.97850494793315796932292388026640068e-01L, + 7.67777432104826194917977340974503132e-01L, + 8.29565762382768397442898119732501916e-01L, + 8.82560535792052681543116462530225590e-01L, + 9.26200047429274325879324277080474004e-01L, + 9.60021864968307512216871025581797663e-01L, + 9.83668123279747209970032581605662802e-01L, + 9.96893484074649540271630050918695283e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.02852652893558840341285636705415044e-01L, + 1.01762389748405504596428952168554045e-01L, + 9.95934205867952670627802821035694765e-02L, + 9.63687371746442596394686263518098651e-02L, + 9.21225222377861287176327070876187672e-02L, + 8.68997872010829798023875307151257026e-02L, + 8.07558952294202153546949384605297309e-02L, + 7.37559747377052062682438500221907342e-02L, + 6.59742298821804951281285151159623612e-02L, + 5.74931562176190664817216894020561288e-02L, + 4.84026728305940529029381404228075178e-02L, + 3.87991925696270495968019364463476920e-02L, + 2.87847078833233693497191796112920436e-02L, + 1.84664683110909591423021319120472691e-02L, + 7.96819249616660561546588347467362245e-03L, + }; + return data; + } +}; +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 5.14718425553176958330252131667225737e-02Q, + 1.53869913608583546963794672743255920e-01Q, + 2.54636926167889846439805129817805108e-01Q, + 3.52704725530878113471037207089373861e-01Q, + 4.47033769538089176780609900322854000e-01Q, + 5.36624148142019899264169793311072794e-01Q, + 6.20526182989242861140477556431189299e-01Q, + 6.97850494793315796932292388026640068e-01Q, + 7.67777432104826194917977340974503132e-01Q, + 8.29565762382768397442898119732501916e-01Q, + 8.82560535792052681543116462530225590e-01Q, + 9.26200047429274325879324277080474004e-01Q, + 9.60021864968307512216871025581797663e-01Q, + 9.83668123279747209970032581605662802e-01Q, + 9.96893484074649540271630050918695283e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 1.02852652893558840341285636705415044e-01Q, + 1.01762389748405504596428952168554045e-01Q, + 9.95934205867952670627802821035694765e-02Q, + 9.63687371746442596394686263518098651e-02Q, + 9.21225222377861287176327070876187672e-02Q, + 8.68997872010829798023875307151257026e-02Q, + 8.07558952294202153546949384605297309e-02Q, + 7.37559747377052062682438500221907342e-02Q, + 6.59742298821804951281285151159623612e-02Q, + 5.74931562176190664817216894020561288e-02Q, + 4.84026728305940529029381404228075178e-02Q, + 3.87991925696270495968019364463476920e-02Q, + 2.87847078833233693497191796112920436e-02Q, + 1.84664683110909591423021319120472691e-02Q, + 7.96819249616660561546588347467362245e-03Q, + }; + return data; + } +}; +#endif +template +class gauss_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0285265289355884034128563670541504386837555706492822258631898667601623865660942939262884632188870916503815852709086e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0176238974840550459642895216855404463270628948712684086426094541964251360531767494547599781978391198881693385887696e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9593420586795267062780282103569476529869263666704277221365146183946660389908809018092299289324184705373523229592037e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6368737174644259639468626351809865096406461430160245912994275732837534742003123724951247818104195363343093583583429e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2122522237786128717632707087618767196913234418234107527675047001973047070094168298464052916811907158954949394100501e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6899787201082979802387530715125702576753328743545344012222129882153582254261494247955033509639105330215477601953921e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.0755895229420215354694938460529730875892803708439299890258593706051180567026345604212402769217808080749416147400962e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3755974737705206268243850022190734153770526037049438941269182374599399314635211710401352716638183270192254236882630e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5974229882180495128128515115962361237442953656660378967031516042143672466094179365819913911598737439478205808271237e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7493156217619066481721689402056128797120670721763134548715799003232147409954376925211999650950125355559974348279846e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8402672830594052902938140422807517815271809197372736345191936791805425677102152797767439563562263454374645955072007e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8799192569627049596801936446347692033200976766395352107732789705946970952769793919055026279035105656340228558382274e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8784707883323369349719179611292043639588894546287496474180122608145988940013933101730206711484171554940392262251283e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8466468311090959142302131912047269096206533968181403371298365514585599521307973654080519029675417955638095832046164e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9681924961666056154658834746736224504806965871517212294851633569200384329013332941536616922861735209846506562158817e-03), + }; + return data; + } +}; + +} + +template > +class gauss : public detail::gauss_detail::value> +{ + typedef detail::gauss_detail::value> base; +public: + + template + static auto integrate(F f, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + // In many math texts, K represents the field of real or complex numbers. + // Too bad we can't put blackboard bold into C++ source! + typedef decltype(f(Real(0))) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + using std::abs; + unsigned non_zero_start = 1; + K result = Real(0); + if (N & 1) { + result = f(Real(0)) * base::weights()[0]; + } + else { + result = 0; + non_zero_start = 0; + } + Real L1 = abs(result); + for (unsigned i = non_zero_start; i < base::abscissa().size(); ++i) + { + K fp = f(base::abscissa()[i]); + K fm = f(-base::abscissa()[i]); + result += (fp + fm) * base::weights()[i]; + L1 += (abs(fp) + abs(fm)) * base::weights()[i]; + } + if (pL1) + *pL1 = L1; + return result; + } + template + static auto integrate(F f, Real a, Real b, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(a)) K; + static const char* function = "boost::math::quadrature::gauss<%1%>::integrate(f, %1%, %1%)"; + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + // Infinite limits: + Real min_inf = -tools::max_value(); + if ((a <= min_inf) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real t_sq = t*t; + Real inv = 1 / (1 - t_sq); + K res = f(t*inv)*(1 + t_sq)*inv*inv; + return res; + }; + return integrate(u, pL1); + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z + a - 1; + K res = f(arg)*z*z; + return res; + }; + K Q = Real(2) * integrate(u, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z - 1; + K res = f(b - arg) * z * z; + return res; + }; + K Q = Real(2) * integrate(v, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a == b) + { + return K(0); + } + if (b < a) + { + return -integrate(f, b, a, pL1); + } + Real avg = (a + b)*constants::half(); + Real scale = (b - a)*constants::half(); + + auto u = [&](Real z)->K + { + return f(avg + scale*z); + }; + K Q = scale*integrate(u, pL1); + + if (pL1) + { + *pL1 *= scale; + } + return Q; + } + } + return static_cast(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy())); + } +}; + +} // namespace quadrature +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_QUADRATURE_GAUSS_HPP diff --git a/libcxx/src/third-party/boost/math/quadrature/gauss_kronrod.hpp b/libcxx/src/third-party/boost/math/quadrature/gauss_kronrod.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/gauss_kronrod.hpp @@ -0,0 +1,1958 @@ +// Copyright John Maddock 2017. +// Copyright Nick Thompson 2017. +// 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_QUADRATURE_GAUSS_KRONROD_HPP +#define BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable: 4127) +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math{ namespace quadrature{ namespace detail{ + +#ifndef BOOST_MATH_GAUSS_NO_COMPUTE_ON_DEMAND + +template +class gauss_kronrod_detail +{ + static legendre_stieltjes const& get_legendre_stieltjes() + { + static const legendre_stieltjes data((N - 1) / 2 + 1); + return data; + } + static std::vector calculate_abscissa() + { + static std::vector result = boost::math::legendre_p_zeros((N - 1) / 2); + const legendre_stieltjes E = get_legendre_stieltjes(); + std::vector ls_zeros = E.zeros(); + result.insert(result.end(), ls_zeros.begin(), ls_zeros.end()); + std::sort(result.begin(), result.end()); + return result; + } + static std::vector calculate_weights() + { + std::vector result(abscissa().size(), 0); + unsigned gauss_order = (N - 1) / 2; + unsigned gauss_start = gauss_order & 1 ? 0 : 1; + const legendre_stieltjes& E = get_legendre_stieltjes(); + + for (unsigned i = gauss_start; i < abscissa().size(); i += 2) + { + Real x = abscissa()[i]; + Real p = boost::math::legendre_p_prime(gauss_order, x); + Real gauss_weight = 2 / ((1 - x * x) * p * p); + result[i] = gauss_weight + static_cast(2) / (static_cast(gauss_order + 1) * legendre_p_prime(gauss_order, x) * E(x)); + } + for (unsigned i = gauss_start ? 0 : 1; i < abscissa().size(); i += 2) + { + Real x = abscissa()[i]; + result[i] = static_cast(2) / (static_cast(gauss_order + 1) * legendre_p(gauss_order, x) * E.prime(x)); + } + return result; + } +public: + static const std::vector& abscissa() + { + static std::vector data = calculate_abscissa(); + return data; + } + static const std::vector& weights() + { + static std::vector data = calculate_weights(); + return data; + } +}; + +#else + +template +class gauss_kronrod_detail; + +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 2.077849550e-01f, + 4.058451514e-01f, + 5.860872355e-01f, + 7.415311856e-01f, + 8.648644234e-01f, + 9.491079123e-01f, + 9.914553711e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.094821411e-01f, + 2.044329401e-01f, + 1.903505781e-01f, + 1.690047266e-01f, + 1.406532597e-01f, + 1.047900103e-01f, + 6.309209263e-02f, + 2.293532201e-02f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 2.07784955007898468e-01, + 4.05845151377397167e-01, + 5.86087235467691130e-01, + 7.41531185599394440e-01, + 8.64864423359769073e-01, + 9.49107912342758525e-01, + 9.91455371120812639e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.09482141084727828e-01, + 2.04432940075298892e-01, + 1.90350578064785410e-01, + 1.69004726639267903e-01, + 1.40653259715525919e-01, + 1.04790010322250184e-01, + 6.30920926299785533e-02, + 2.29353220105292250e-02, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 2.07784955007898467600689403773244913e-01L, + 4.05845151377397166906606412076961463e-01L, + 5.86087235467691130294144838258729598e-01L, + 7.41531185599394439863864773280788407e-01L, + 8.64864423359769072789712788640926201e-01L, + 9.49107912342758524526189684047851262e-01L, + 9.91455371120812639206854697526328517e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 2.09482141084727828012999174891714264e-01L, + 2.04432940075298892414161999234649085e-01L, + 1.90350578064785409913256402421013683e-01L, + 1.69004726639267902826583426598550284e-01L, + 1.40653259715525918745189590510237920e-01L, + 1.04790010322250183839876322541518017e-01L, + 6.30920926299785532907006631892042867e-02L, + 2.29353220105292249637320080589695920e-02L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 2.07784955007898467600689403773244913e-01Q, + 4.05845151377397166906606412076961463e-01Q, + 5.86087235467691130294144838258729598e-01Q, + 7.41531185599394439863864773280788407e-01Q, + 8.64864423359769072789712788640926201e-01Q, + 9.49107912342758524526189684047851262e-01Q, + 9.91455371120812639206854697526328517e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 2.09482141084727828012999174891714264e-01Q, + 2.04432940075298892414161999234649085e-01Q, + 1.90350578064785409913256402421013683e-01Q, + 1.69004726639267902826583426598550284e-01Q, + 1.40653259715525918745189590510237920e-01Q, + 1.04790010322250183839876322541518017e-01Q, + 6.30920926299785532907006631892042867e-02Q, + 2.29353220105292249637320080589695920e-02Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0778495500789846760068940377324491347978440714517064971384573461986693844943520226910343227183698530560857645062738e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0584515137739716690660641207696146334738201409937012638704325179466381322612565532831268972774658776528675866604802e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8608723546769113029414483825872959843678075060436095130499289319880373607444407464511674498935942098956811555121368e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4153118559939443986386477328078840707414764714139026011995535196742987467218051379282683236686324705969251809311201e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6486442335976907278971278864092620121097230707408814860145771276706770813259572103585847859604590541475281326027862e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4910791234275852452618968404785126240077093767061778354876910391306333035484014080573077002792572414430073966699522e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9145537112081263920685469752632851664204433837033470129108741357244173934653407235924503509626841760744349505339308e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0948214108472782801299917489171426369776208022370431671299800656137515132325648616816908211675949102392971459688215e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0443294007529889241416199923464908471651760418071835742447095312045467698546598879348374292009347554167803659293064e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9035057806478540991325640242101368282607807545535835588544088036744058072410212679605964605106377593834568683551139e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6900472663926790282658342659855028410624490030294424149734006755695680921619029112936702403855359908156070095656537e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4065325971552591874518959051023792039988975724799857556174546893312708093090950408097379122415555910759700350860143e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0479001032225018383987632254151801744375665421383061189339065133963746321576289524167571627509311333949422518201492e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3092092629978553290700663189204286665071157211550707113605545146983997477964874928199170264504441995865872491871943e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2935322010529224963732008058969591993560811275746992267507430254711815787976075946156368168156289483493617134063245e-02), + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 1.488743390e-01f, + 2.943928627e-01f, + 4.333953941e-01f, + 5.627571347e-01f, + 6.794095683e-01f, + 7.808177266e-01f, + 8.650633667e-01f, + 9.301574914e-01f, + 9.739065285e-01f, + 9.956571630e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.494455540e-01f, + 1.477391049e-01f, + 1.427759386e-01f, + 1.347092173e-01f, + 1.234919763e-01f, + 1.093871588e-01f, + 9.312545458e-02f, + 7.503967481e-02f, + 5.475589657e-02f, + 3.255816231e-02f, + 1.169463887e-02f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 1.48874338981631211e-01, + 2.94392862701460198e-01, + 4.33395394129247191e-01, + 5.62757134668604683e-01, + 6.79409568299024406e-01, + 7.80817726586416897e-01, + 8.65063366688984511e-01, + 9.30157491355708226e-01, + 9.73906528517171720e-01, + 9.95657163025808081e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.49445554002916906e-01, + 1.47739104901338491e-01, + 1.42775938577060081e-01, + 1.34709217311473326e-01, + 1.23491976262065851e-01, + 1.09387158802297642e-01, + 9.31254545836976055e-02, + 7.50396748109199528e-02, + 5.47558965743519960e-02, + 3.25581623079647275e-02, + 1.16946388673718743e-02, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 1.48874338981631210884826001129719985e-01L, + 2.94392862701460198131126603103865566e-01L, + 4.33395394129247190799265943165784162e-01L, + 5.62757134668604683339000099272694141e-01L, + 6.79409568299024406234327365114873576e-01L, + 7.80817726586416897063717578345042377e-01L, + 8.65063366688984510732096688423493049e-01L, + 9.30157491355708226001207180059508346e-01L, + 9.73906528517171720077964012084452053e-01L, + 9.95657163025808080735527280689002848e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.49445554002916905664936468389821204e-01L, + 1.47739104901338491374841515972068046e-01L, + 1.42775938577060080797094273138717061e-01L, + 1.34709217311473325928054001771706833e-01L, + 1.23491976262065851077958109831074160e-01L, + 1.09387158802297641899210590325804960e-01L, + 9.31254545836976055350654650833663444e-02L, + 7.50396748109199527670431409161900094e-02L, + 5.47558965743519960313813002445801764e-02L, + 3.25581623079647274788189724593897606e-02L, + 1.16946388673718742780643960621920484e-02L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 1.48874338981631210884826001129719985e-01Q, + 2.94392862701460198131126603103865566e-01Q, + 4.33395394129247190799265943165784162e-01Q, + 5.62757134668604683339000099272694141e-01Q, + 6.79409568299024406234327365114873576e-01Q, + 7.80817726586416897063717578345042377e-01Q, + 8.65063366688984510732096688423493049e-01Q, + 9.30157491355708226001207180059508346e-01Q, + 9.73906528517171720077964012084452053e-01Q, + 9.95657163025808080735527280689002848e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 1.49445554002916905664936468389821204e-01Q, + 1.47739104901338491374841515972068046e-01Q, + 1.42775938577060080797094273138717061e-01Q, + 1.34709217311473325928054001771706833e-01Q, + 1.23491976262065851077958109831074160e-01Q, + 1.09387158802297641899210590325804960e-01Q, + 9.31254545836976055350654650833663444e-02Q, + 7.50396748109199527670431409161900094e-02Q, + 5.47558965743519960313813002445801764e-02Q, + 3.25581623079647274788189724593897606e-02Q, + 1.16946388673718742780643960621920484e-02Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4887433898163121088482600112971998461756485942069169570798925351590361735566852137117762979946369123003116080525534e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9439286270146019813112660310386556616268662515695791864888229172724611166332737888445523178268237359119185139299872e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3339539412924719079926594316578416220007183765624649650270151314376698907770350122510275795011772122368293504099894e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.6275713466860468333900009927269414084301388194196695886034621458779266353216327549712087854169992422106448211158815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7940956829902440623432736511487357576929471183480946766481718895255857539507492461507857357048037949983390204739932e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.8081772658641689706371757834504237716340752029815717974694859999505607982761420654526977234238996241110129779403362e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6506336668898451073209668842349304852754301496533045252195973184537475513805556135679072894604577069440463108641177e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3015749135570822600120718005950834622516790998193924230349406866828415983091673055011194572851007884702013619684320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7390652851717172007796401208445205342826994669238211923121206669659520323463615962572356495626855625823304251877421e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9565716302580808073552728068900284792126058721947892436337916111757023046774867357152325996912076724298149077812671e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4944555400291690566493646838982120374523631668747280383560851873698964478511841925721030705689540264726493367634340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4773910490133849137484151597206804552373162548520660451819195439885993016735696405732703959182882254268727823258502e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4277593857706008079709427313871706088597905653190555560741004743970770449909340027811131706283756428281146832304737e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3470921731147332592805400177170683276099191300855971406636668491320291400121282036676953159488271772384389604997640e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2349197626206585107795810983107415951230034952864832764467994120974054238975454689681538622363738230836484113389878e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0938715880229764189921059032580496027181329983434522007819675829826550372891432168683899432674553842507906611591517e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3125454583697605535065465083366344390018828880760031970085038760177735672200775237414123061615827474831165614953012e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5039674810919952767043140916190009395219382000910088173697048048430404342858495178813808730646554086856929327903059e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4755896574351996031381300244580176373721114058333557524432615804784098927818975325116301569003298086458722055550981e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2558162307964727478818972459389760617388939845662609571537504232714121820165498692381607605384626494546068817765276e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1694638867371874278064396062192048396217332481931888927598147525622222058064992651806736704969967250888097490233242e-02), + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 1.011420669e-01f, + 2.011940940e-01f, + 2.991800072e-01f, + 3.941513471e-01f, + 4.850818636e-01f, + 5.709721726e-01f, + 6.509967413e-01f, + 7.244177314e-01f, + 7.904185014e-01f, + 8.482065834e-01f, + 8.972645323e-01f, + 9.372733924e-01f, + 9.677390757e-01f, + 9.879925180e-01f, + 9.980022987e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.013300070e-01f, + 1.007698455e-01f, + 9.917359872e-02f, + 9.664272698e-02f, + 9.312659817e-02f, + 8.856444306e-02f, + 8.308050282e-02f, + 7.684968076e-02f, + 6.985412132e-02f, + 6.200956780e-02f, + 5.348152469e-02f, + 4.458975132e-02f, + 3.534636079e-02f, + 2.546084733e-02f, + 1.500794733e-02f, + 5.377479873e-03f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 1.01142066918717499e-01, + 2.01194093997434522e-01, + 2.99180007153168812e-01, + 3.94151347077563370e-01, + 4.85081863640239681e-01, + 5.70972172608538848e-01, + 6.50996741297416971e-01, + 7.24417731360170047e-01, + 7.90418501442465933e-01, + 8.48206583410427216e-01, + 8.97264532344081901e-01, + 9.37273392400705904e-01, + 9.67739075679139134e-01, + 9.87992518020485428e-01, + 9.98002298693397060e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.01330007014791549e-01, + 1.00769845523875595e-01, + 9.91735987217919593e-02, + 9.66427269836236785e-02, + 9.31265981708253212e-02, + 8.85644430562117706e-02, + 8.30805028231330210e-02, + 7.68496807577203789e-02, + 6.98541213187282587e-02, + 6.20095678006706403e-02, + 5.34815246909280873e-02, + 4.45897513247648766e-02, + 3.53463607913758462e-02, + 2.54608473267153202e-02, + 1.50079473293161225e-02, + 5.37747987292334899e-03, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 1.01142066918717499027074231447392339e-01L, + 2.01194093997434522300628303394596208e-01L, + 2.99180007153168812166780024266388963e-01L, + 3.94151347077563369897207370981045468e-01L, + 4.85081863640239680693655740232350613e-01L, + 5.70972172608538847537226737253910641e-01L, + 6.50996741297416970533735895313274693e-01L, + 7.24417731360170047416186054613938010e-01L, + 7.90418501442465932967649294817947347e-01L, + 8.48206583410427216200648320774216851e-01L, + 8.97264532344081900882509656454495883e-01L, + 9.37273392400705904307758947710209471e-01L, + 9.67739075679139134257347978784337225e-01L, + 9.87992518020485428489565718586612581e-01L, + 9.98002298693397060285172840152271209e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 1.01330007014791549017374792767492547e-01L, + 1.00769845523875595044946662617569722e-01L, + 9.91735987217919593323931734846031311e-02L, + 9.66427269836236785051799076275893351e-02L, + 9.31265981708253212254868727473457186e-02L, + 8.85644430562117706472754436937743032e-02L, + 8.30805028231330210382892472861037896e-02L, + 7.68496807577203788944327774826590067e-02L, + 6.98541213187282587095200770991474758e-02L, + 6.20095678006706402851392309608029322e-02L, + 5.34815246909280872653431472394302968e-02L, + 4.45897513247648766082272993732796902e-02L, + 3.53463607913758462220379484783600481e-02L, + 2.54608473267153201868740010196533594e-02L, + 1.50079473293161225383747630758072681e-02L, + 5.37747987292334898779205143012764982e-03L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 1.01142066918717499027074231447392339e-01Q, + 2.01194093997434522300628303394596208e-01Q, + 2.99180007153168812166780024266388963e-01Q, + 3.94151347077563369897207370981045468e-01Q, + 4.85081863640239680693655740232350613e-01Q, + 5.70972172608538847537226737253910641e-01Q, + 6.50996741297416970533735895313274693e-01Q, + 7.24417731360170047416186054613938010e-01Q, + 7.90418501442465932967649294817947347e-01Q, + 8.48206583410427216200648320774216851e-01Q, + 8.97264532344081900882509656454495883e-01Q, + 9.37273392400705904307758947710209471e-01Q, + 9.67739075679139134257347978784337225e-01Q, + 9.87992518020485428489565718586612581e-01Q, + 9.98002298693397060285172840152271209e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 1.01330007014791549017374792767492547e-01Q, + 1.00769845523875595044946662617569722e-01Q, + 9.91735987217919593323931734846031311e-02Q, + 9.66427269836236785051799076275893351e-02Q, + 9.31265981708253212254868727473457186e-02Q, + 8.85644430562117706472754436937743032e-02Q, + 8.30805028231330210382892472861037896e-02Q, + 7.68496807577203788944327774826590067e-02Q, + 6.98541213187282587095200770991474758e-02Q, + 6.20095678006706402851392309608029322e-02Q, + 5.34815246909280872653431472394302968e-02Q, + 4.45897513247648766082272993732796902e-02Q, + 3.53463607913758462220379484783600481e-02Q, + 2.54608473267153201868740010196533594e-02Q, + 1.50079473293161225383747630758072681e-02Q, + 5.37747987292334898779205143012764982e-03Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0114206691871749902707423144739233878745105740164180495800189504151097862454083050931321451540380998341273193681967e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0119409399743452230062830339459620781283645446263767961594972460994823900302018760183625806752105908967902257386509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.9918000715316881216678002426638896266160338274382080184125545738918081102513884467602322020157243563662094470221235e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.9415134707756336989720737098104546836275277615869825503116534395160895778696141797549711416165976202589352169635648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8508186364023968069365574023235061286633893089407312129367943604080239955167155974371848690848595275551258416303565e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7097217260853884753722673725391064123838639628274960485326541705419537986975857948341462856982614477912646497026257e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5099674129741697053373589531327469254694822609259966708966160576093305841043840794460394747228060367236079289132544e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.2441773136017004741618605461393800963089929458410256355142342070412378167792521899610109760313432626923598549381925e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9041850144246593296764929481794734686214051995697617332365280643308302974631807059994738664225445530963711137343440e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.4820658341042721620064832077421685136625617473699263409572755876067507517414548519760771975082148085090373835713340e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9726453234408190088250965645449588283177871149442786763972687601078537721473771221195399661919716123038835639691946e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3727339240070590430775894771020947124399627351530445790136307635020297379704552795054758617426808659746824044603157e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6773907567913913425734797878433722528335733730013163797468062226335804249452174804319385048203118506304424717089291e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8799251802048542848956571858661258114697281712376148999999751558738843736901942471272205036831914497667516843990079e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9800229869339706028517284015227120907340644231555723034839427970683348682837134566648979907760125278631896777136104e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0133000701479154901737479276749254677092627259659629246734858372174107615774696665932418050683956749891773195816338e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0076984552387559504494666261756972191634838013536373069278929029488122760822761077475060185965408326901925180106227e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9173598721791959332393173484603131059567260816713281734860095693651563064308745717056680128223790739026832596087552e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6642726983623678505179907627589335136656568630495198973407668882934392359962841826511402504664592185391687490319950e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.3126598170825321225486872747345718561927881321317330560285879189052002874531855060114908990458716740695847509343865e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8564443056211770647275443693774303212266732690655967817996052574877144544749814260718837576325109922207832119243346e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3080502823133021038289247286103789601554188253368717607281604875233630643885056057630789228337088859687986285569521e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6849680757720378894432777482659006722109101167947000584089097112470821092034084418224731527690291913686588446455555e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9854121318728258709520077099147475786045435140671549698798093177992675624987998849748628778570667518643649536771245e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2009567800670640285139230960802932190400004210329723569147829395618376206272317333030584268303808639229575334680414e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3481524690928087265343147239430296771554760947116739813222888752727413616259625439714812475198987513183153639571249e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4589751324764876608227299373279690223256649667921096570980823211805450700059906366455036418897149593261561551176267e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5346360791375846222037948478360048122630678992420820868148023340902501837247680978434662724296810081131106317333086e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5460847326715320186874001019653359397271745046864640508377984982400903447009185267605205778819712848080691366407461e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5007947329316122538374763075807268094639436437387634979291759700896494746154334398961710227490402528151677469993935e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3774798729233489877920514301276498183080402431284197876486169536848635554354599213793172596490038991436925569025913e-03), + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 7.652652113e-02f, + 1.526054652e-01f, + 2.277858511e-01f, + 3.016278681e-01f, + 3.737060887e-01f, + 4.435931752e-01f, + 5.108670020e-01f, + 5.751404468e-01f, + 6.360536807e-01f, + 6.932376563e-01f, + 7.463319065e-01f, + 7.950414288e-01f, + 8.391169718e-01f, + 8.782768113e-01f, + 9.122344283e-01f, + 9.408226338e-01f, + 9.639719273e-01f, + 9.815078775e-01f, + 9.931285992e-01f, + 9.988590316e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 7.660071192e-02f, + 7.637786767e-02f, + 7.570449768e-02f, + 7.458287540e-02f, + 7.303069033e-02f, + 7.105442355e-02f, + 6.864867293e-02f, + 6.583459713e-02f, + 6.265323755e-02f, + 5.911140088e-02f, + 5.519510535e-02f, + 5.094457392e-02f, + 4.643482187e-02f, + 4.166887333e-02f, + 3.660016976e-02f, + 3.128730678e-02f, + 2.588213360e-02f, + 2.038837346e-02f, + 1.462616926e-02f, + 8.600269856e-03f, + 3.073583719e-03f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 7.65265211334973338e-02, + 1.52605465240922676e-01, + 2.27785851141645078e-01, + 3.01627868114913004e-01, + 3.73706088715419561e-01, + 4.43593175238725103e-01, + 5.10867001950827098e-01, + 5.75140446819710315e-01, + 6.36053680726515025e-01, + 6.93237656334751385e-01, + 7.46331906460150793e-01, + 7.95041428837551198e-01, + 8.39116971822218823e-01, + 8.78276811252281976e-01, + 9.12234428251325906e-01, + 9.40822633831754754e-01, + 9.63971927277913791e-01, + 9.81507877450250259e-01, + 9.93128599185094925e-01, + 9.98859031588277664e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 7.66007119179996564e-02, + 7.63778676720807367e-02, + 7.57044976845566747e-02, + 7.45828754004991890e-02, + 7.30306903327866675e-02, + 7.10544235534440683e-02, + 6.86486729285216193e-02, + 6.58345971336184221e-02, + 6.26532375547811680e-02, + 5.91114008806395724e-02, + 5.51951053482859947e-02, + 5.09445739237286919e-02, + 4.64348218674976747e-02, + 4.16688733279736863e-02, + 3.66001697582007980e-02, + 3.12873067770327990e-02, + 2.58821336049511588e-02, + 2.03883734612665236e-02, + 1.46261692569712530e-02, + 8.60026985564294220e-03, + 3.07358371852053150e-03, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 7.65265211334973337546404093988382110e-02L, + 1.52605465240922675505220241022677528e-01L, + 2.27785851141645078080496195368574625e-01L, + 3.01627868114913004320555356858592261e-01L, + 3.73706088715419560672548177024927237e-01L, + 4.43593175238725103199992213492640108e-01L, + 5.10867001950827098004364050955250998e-01L, + 5.75140446819710315342946036586425133e-01L, + 6.36053680726515025452836696226285937e-01L, + 6.93237656334751384805490711845931533e-01L, + 7.46331906460150792614305070355641590e-01L, + 7.95041428837551198350638833272787943e-01L, + 8.39116971822218823394529061701520685e-01L, + 8.78276811252281976077442995113078467e-01L, + 9.12234428251325905867752441203298113e-01L, + 9.40822633831754753519982722212443380e-01L, + 9.63971927277913791267666131197277222e-01L, + 9.81507877450250259193342994720216945e-01L, + 9.93128599185094924786122388471320278e-01L, + 9.98859031588277663838315576545863010e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 7.66007119179996564450499015301017408e-02L, + 7.63778676720807367055028350380610018e-02L, + 7.57044976845566746595427753766165583e-02L, + 7.45828754004991889865814183624875286e-02L, + 7.30306903327866674951894176589131128e-02L, + 7.10544235534440683057903617232101674e-02L, + 6.86486729285216193456234118853678017e-02L, + 6.58345971336184221115635569693979431e-02L, + 6.26532375547811680258701221742549806e-02L, + 5.91114008806395723749672206485942171e-02L, + 5.51951053482859947448323724197773292e-02L, + 5.09445739237286919327076700503449487e-02L, + 4.64348218674976747202318809261075168e-02L, + 4.16688733279736862637883059368947380e-02L, + 3.66001697582007980305572407072110085e-02L, + 3.12873067770327989585431193238007379e-02L, + 2.58821336049511588345050670961531430e-02L, + 2.03883734612665235980102314327547051e-02L, + 1.46261692569712529837879603088683562e-02L, + 8.60026985564294219866178795010234725e-03L, + 3.07358371852053150121829324603098749e-03L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 7.65265211334973337546404093988382110e-02Q, + 1.52605465240922675505220241022677528e-01Q, + 2.27785851141645078080496195368574625e-01Q, + 3.01627868114913004320555356858592261e-01Q, + 3.73706088715419560672548177024927237e-01Q, + 4.43593175238725103199992213492640108e-01Q, + 5.10867001950827098004364050955250998e-01Q, + 5.75140446819710315342946036586425133e-01Q, + 6.36053680726515025452836696226285937e-01Q, + 6.93237656334751384805490711845931533e-01Q, + 7.46331906460150792614305070355641590e-01Q, + 7.95041428837551198350638833272787943e-01Q, + 8.39116971822218823394529061701520685e-01Q, + 8.78276811252281976077442995113078467e-01Q, + 9.12234428251325905867752441203298113e-01Q, + 9.40822633831754753519982722212443380e-01Q, + 9.63971927277913791267666131197277222e-01Q, + 9.81507877450250259193342994720216945e-01Q, + 9.93128599185094924786122388471320278e-01Q, + 9.98859031588277663838315576545863010e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 7.66007119179996564450499015301017408e-02Q, + 7.63778676720807367055028350380610018e-02Q, + 7.57044976845566746595427753766165583e-02Q, + 7.45828754004991889865814183624875286e-02Q, + 7.30306903327866674951894176589131128e-02Q, + 7.10544235534440683057903617232101674e-02Q, + 6.86486729285216193456234118853678017e-02Q, + 6.58345971336184221115635569693979431e-02Q, + 6.26532375547811680258701221742549806e-02Q, + 5.91114008806395723749672206485942171e-02Q, + 5.51951053482859947448323724197773292e-02Q, + 5.09445739237286919327076700503449487e-02Q, + 4.64348218674976747202318809261075168e-02Q, + 4.16688733279736862637883059368947380e-02Q, + 3.66001697582007980305572407072110085e-02Q, + 3.12873067770327989585431193238007379e-02Q, + 2.58821336049511588345050670961531430e-02Q, + 2.03883734612665235980102314327547051e-02Q, + 1.46261692569712529837879603088683562e-02Q, + 8.60026985564294219866178795010234725e-03Q, + 3.07358371852053150121829324603098749e-03Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6526521133497333754640409398838211004796266813497500804795244384256342048336978241545114181556215606998505646364133e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5260546524092267550522024102267752791167622481841730660174156703809133685751696356987995886397049724808931527012542e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.2778585114164507808049619536857462474308893768292747231463573920717134186355582779495212519096870803177373131560430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0162786811491300432055535685859226061539650501373092456926374427956957435978384116066498234762220215751079886015902e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7370608871541956067254817702492723739574632170568271182794861351564576437305952789589568363453337894476772208852815e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4359317523872510319999221349264010784010101082300309613315028346299543059315258601993479156987847429893626854030516e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1086700195082709800436405095525099842549132920242683347234861989473497039076572814403168305086777919832943068843526e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7514044681971031534294603658642513281381264014771682537415885495717468074720062012357788489049470208285175093670561e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.3605368072651502545283669622628593674338911679936846393944662254654126258543013255870319549576130658211710937772596e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9323765633475138480549071184593153338642585141021417904687378454301191710739219011546672416325022748282227809465165e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4633190646015079261430507035564159031073067956917644413954590606853535503815506468110411362064752061238490065167656e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9504142883755119835063883327278794295938959911578029703855163894322697871710382866701777890251824617748545658564370e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3911697182221882339452906170152068532962936506563737325249272553286109399932480991922934056595764922060422035306914e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.7827681125228197607744299511307846671124526828251164853898086998248145904743220740840261624245683876748360309079747e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.1223442825132590586775244120329811304918479742369177479588221915807089120871907893644472619292138737876039175464603e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4082263383175475351998272221244338027429557377965291059536839973186796006557571220888218676776618448841584569497535e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6397192727791379126766613119727722191206032780618885606353759389204158078438305698001812525596471563131043491596423e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8150787745025025919334299472021694456725093981023759869077533318793098857465723460898060491887511355706497739384103e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9312859918509492478612238847132027822264713090165589614818413121798471762775378083944940249657220927472894034724419e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9885903158827766383831557654586300999957020432629666866666860339324411793311982967839129772854179884971700274369367e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6600711917999656445049901530101740827932500628670118055485349620314721456712029449597396569857880493210849110825276e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6377867672080736705502835038061001800801036764945996714946431116936745542061941050008345047482501253320401746334511e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5704497684556674659542775376616558263363155900414326194855223272348838596099414841886740468379707283366777797425290e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.4582875400499188986581418362487528616116493572092273080047040726969899567887364227664202642942357104526915332274625e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3030690332786667495189417658913112760626845234552742380174250771849743831660040966804802312464527721645765620253776e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1054423553444068305790361723210167412912159322210143921628270586407381879789525901086146473278095159807542174985045e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.8648672928521619345623411885367801715489704958239860400434264173923806029589970941711224257967651039544669425313433e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.5834597133618422111563556969397943147223506343381443709751749639944420314384296347503523810096842402960802728781816e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2653237554781168025870122174254980585819744698897886186553324157100424088919284503451596742588386343548162830898103e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9111400880639572374967220648594217136419365977042191748388047204015262840407696611508732839851952697839735487615776e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5195105348285994744832372419777329194753456228153116909812131213177827707884692917845453999535518818940813085110223e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0944573923728691932707670050344948664836365809262579747517140086119113476866735641054822574173198900379392130050979e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6434821867497674720231880926107516842127071007077929289994127933243222585938804392953931185146446072587020288747981e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1668873327973686263788305936894738043960843153010324860966353235271889596379726462208702081068715463576895020003842e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6600169758200798030557240707211008487453496747498001651070009441973280061489266074044986901436324295513243878212345e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.1287306777032798958543119323800737887769280362813337359554598005322423266047996771926031069705049476071896145456496e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5882133604951158834505067096153142999479118048674944526997797755374306421629440393392427198869345793286369198147609e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0388373461266523598010231432754705122838627940185929365371868214433006532030353671253640300679157504987977281782909e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4626169256971252983787960308868356163881050162249770342103474631076960029748751959380482484308382288261238476948520e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6002698556429421986617879501023472521289227667077976622450602031426535362696437838448828009554532025301579670206091e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0735837185205315012182932460309874880335046882543449198461628212114333665590378156706265241414469306987988292234740e-03), + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 6.154448301e-02f, + 1.228646926e-01f, + 1.837189394e-01f, + 2.438668837e-01f, + 3.030895389e-01f, + 3.611723058e-01f, + 4.178853822e-01f, + 4.730027314e-01f, + 5.263252843e-01f, + 5.776629302e-01f, + 6.268100990e-01f, + 6.735663685e-01f, + 7.177664068e-01f, + 7.592592630e-01f, + 7.978737980e-01f, + 8.334426288e-01f, + 8.658470653e-01f, + 8.949919979e-01f, + 9.207471153e-01f, + 9.429745712e-01f, + 9.616149864e-01f, + 9.766639215e-01f, + 9.880357945e-01f, + 9.955569698e-01f, + 9.992621050e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 6.158081807e-02f, + 6.147118987e-02f, + 6.112850972e-02f, + 6.053945538e-02f, + 5.972034032e-02f, + 5.868968002e-02f, + 5.743711636e-02f, + 5.595081122e-02f, + 5.425112989e-02f, + 5.236288581e-02f, + 5.027767908e-02f, + 4.798253714e-02f, + 4.550291305e-02f, + 4.287284502e-02f, + 4.008382550e-02f, + 3.711627148e-02f, + 3.400213027e-02f, + 3.079230017e-02f, + 2.747531759e-02f, + 2.400994561e-02f, + 2.043537115e-02f, + 1.684781771e-02f, + 1.323622920e-02f, + 9.473973386e-03f, + 5.561932135e-03f, + 1.987383892e-03f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 6.15444830056850789e-02, + 1.22864692610710396e-01, + 1.83718939421048892e-01, + 2.43866883720988432e-01, + 3.03089538931107830e-01, + 3.61172305809387838e-01, + 4.17885382193037749e-01, + 4.73002731445714961e-01, + 5.26325284334719183e-01, + 5.77662930241222968e-01, + 6.26810099010317413e-01, + 6.73566368473468364e-01, + 7.17766406813084388e-01, + 7.59259263037357631e-01, + 7.97873797998500059e-01, + 8.33442628760834001e-01, + 8.65847065293275595e-01, + 8.94991997878275369e-01, + 9.20747115281701562e-01, + 9.42974571228974339e-01, + 9.61614986425842512e-01, + 9.76663921459517511e-01, + 9.88035794534077248e-01, + 9.95556969790498098e-01, + 9.99262104992609834e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 6.15808180678329351e-02, + 6.14711898714253167e-02, + 6.11285097170530483e-02, + 6.05394553760458629e-02, + 5.97203403241740600e-02, + 5.86896800223942080e-02, + 5.74371163615678329e-02, + 5.59508112204123173e-02, + 5.42511298885454901e-02, + 5.23628858064074759e-02, + 5.02776790807156720e-02, + 4.79825371388367139e-02, + 4.55029130499217889e-02, + 4.28728450201700495e-02, + 4.00838255040323821e-02, + 3.71162714834155436e-02, + 3.40021302743293378e-02, + 3.07923001673874889e-02, + 2.74753175878517378e-02, + 2.40099456069532162e-02, + 2.04353711458828355e-02, + 1.68478177091282982e-02, + 1.32362291955716748e-02, + 9.47397338617415161e-03, + 5.56193213535671376e-03, + 1.98738389233031593e-03, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 6.15444830056850788865463923667966313e-02L, + 1.22864692610710396387359818808036806e-01L, + 1.83718939421048892015969888759528416e-01L, + 2.43866883720988432045190362797451586e-01L, + 3.03089538931107830167478909980339329e-01L, + 3.61172305809387837735821730127640667e-01L, + 4.17885382193037748851814394594572487e-01L, + 4.73002731445714960522182115009192041e-01L, + 5.26325284334719182599623778158010178e-01L, + 5.77662930241222967723689841612654067e-01L, + 6.26810099010317412788122681624517881e-01L, + 6.73566368473468364485120633247622176e-01L, + 7.17766406813084388186654079773297781e-01L, + 7.59259263037357630577282865204360976e-01L, + 7.97873797998500059410410904994306569e-01L, + 8.33442628760834001421021108693569569e-01L, + 8.65847065293275595448996969588340088e-01L, + 8.94991997878275368851042006782804954e-01L, + 9.20747115281701561746346084546330632e-01L, + 9.42974571228974339414011169658470532e-01L, + 9.61614986425842512418130033660167242e-01L, + 9.76663921459517511498315386479594068e-01L, + 9.88035794534077247637331014577406227e-01L, + 9.95556969790498097908784946893901617e-01L, + 9.99262104992609834193457486540340594e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 6.15808180678329350787598242400645532e-02L, + 6.14711898714253166615441319652641776e-02L, + 6.11285097170530483058590304162927119e-02L, + 6.05394553760458629453602675175654272e-02L, + 5.97203403241740599790992919325618538e-02L, + 5.86896800223942079619741758567877641e-02L, + 5.74371163615678328535826939395064720e-02L, + 5.59508112204123173082406863827473468e-02L, + 5.42511298885454901445433704598756068e-02L, + 5.23628858064074758643667121378727149e-02L, + 5.02776790807156719633252594334400844e-02L, + 4.79825371388367139063922557569147550e-02L, + 4.55029130499217889098705847526603930e-02L, + 4.28728450201700494768957924394951611e-02L, + 4.00838255040323820748392844670756464e-02L, + 3.71162714834155435603306253676198760e-02L, + 3.40021302743293378367487952295512032e-02L, + 3.07923001673874888911090202152285856e-02L, + 2.74753175878517378029484555178110786e-02L, + 2.40099456069532162200924891648810814e-02L, + 2.04353711458828354565682922359389737e-02L, + 1.68478177091282982315166675363363158e-02L, + 1.32362291955716748136564058469762381e-02L, + 9.47397338617415160720771052365532387e-03L, + 5.56193213535671375804023690106552207e-03L, + 1.98738389233031592650785188284340989e-03L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 6.15444830056850788865463923667966313e-02Q, + 1.22864692610710396387359818808036806e-01Q, + 1.83718939421048892015969888759528416e-01Q, + 2.43866883720988432045190362797451586e-01Q, + 3.03089538931107830167478909980339329e-01Q, + 3.61172305809387837735821730127640667e-01Q, + 4.17885382193037748851814394594572487e-01Q, + 4.73002731445714960522182115009192041e-01Q, + 5.26325284334719182599623778158010178e-01Q, + 5.77662930241222967723689841612654067e-01Q, + 6.26810099010317412788122681624517881e-01Q, + 6.73566368473468364485120633247622176e-01Q, + 7.17766406813084388186654079773297781e-01Q, + 7.59259263037357630577282865204360976e-01Q, + 7.97873797998500059410410904994306569e-01Q, + 8.33442628760834001421021108693569569e-01Q, + 8.65847065293275595448996969588340088e-01Q, + 8.94991997878275368851042006782804954e-01Q, + 9.20747115281701561746346084546330632e-01Q, + 9.42974571228974339414011169658470532e-01Q, + 9.61614986425842512418130033660167242e-01Q, + 9.76663921459517511498315386479594068e-01Q, + 9.88035794534077247637331014577406227e-01Q, + 9.95556969790498097908784946893901617e-01Q, + 9.99262104992609834193457486540340594e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 6.15808180678329350787598242400645532e-02Q, + 6.14711898714253166615441319652641776e-02Q, + 6.11285097170530483058590304162927119e-02Q, + 6.05394553760458629453602675175654272e-02Q, + 5.97203403241740599790992919325618538e-02Q, + 5.86896800223942079619741758567877641e-02Q, + 5.74371163615678328535826939395064720e-02Q, + 5.59508112204123173082406863827473468e-02Q, + 5.42511298885454901445433704598756068e-02Q, + 5.23628858064074758643667121378727149e-02Q, + 5.02776790807156719633252594334400844e-02Q, + 4.79825371388367139063922557569147550e-02Q, + 4.55029130499217889098705847526603930e-02Q, + 4.28728450201700494768957924394951611e-02Q, + 4.00838255040323820748392844670756464e-02Q, + 3.71162714834155435603306253676198760e-02Q, + 3.40021302743293378367487952295512032e-02Q, + 3.07923001673874888911090202152285856e-02Q, + 2.74753175878517378029484555178110786e-02Q, + 2.40099456069532162200924891648810814e-02Q, + 2.04353711458828354565682922359389737e-02Q, + 1.68478177091282982315166675363363158e-02Q, + 1.32362291955716748136564058469762381e-02Q, + 9.47397338617415160720771052365532387e-03Q, + 5.56193213535671375804023690106552207e-03Q, + 1.98738389233031592650785188284340989e-03Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1544483005685078886546392366796631281724348039823545274305431751687279361558658545141048781022691067898008423227288e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.2286469261071039638735981880803680553220534604978373842389353789270883496885841582643884994633105537597765980412320e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.8371893942104889201596988875952841578528447834990555215034512653236752851109815617651867160645591242103823539931527e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4386688372098843204519036279745158640563315632598447642113565325038747278585595067977636776325034060327548499765742e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0308953893110783016747890998033932920041937876655194685731578452573120372337209717349617882111662416355753711853559e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6117230580938783773582173012764066742207834704337506979457877784674538239569654860329531506093761400789294612122812e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1788538219303774885181439459457248709336998140069528034955785068796932076966599548717224205109797297615032607570119e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7300273144571496052218211500919204133181773846162729090723082769560327584128603010315684778279363544192787010704498e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2632528433471918259962377815801017803683252320191114313002425180471455022502695302371008520604638341970901082293650e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7766293024122296772368984161265406739573503929151825664548350776102301275263202227671659646579649084013116066120581e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2681009901031741278812268162451788101954628995068510806525222008437260184181183053045236423845198752346149030569920e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.7356636847346836448512063324762217588341672807274931705965696177828773684928421158196368568030932194044282149314388e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.1776640681308438818665407977329778059771167555515582423493486823991612820974965089522905953765860328116692570706602e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.5925926303735763057728286520436097638752201889833412091838973544501862882026240760763679724185230331463919586229073e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9787379799850005941041090499430656940863230009338267661706934499488650817643824077118950314443984031474353711531825e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.3344262876083400142102110869356956946096411382352078602086471546171813247709012525322973947759168107133491065937347e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.6584706529327559544899696958834008820284409402823690293965213246691432948180280120756708738064779055576005302835351e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.9499199787827536885104200678280495417455484975358390306170168295917151090119945137118600693039178162093726882638296e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2074711528170156174634608454633063157457035996277199700642836501131385042631212407808952281702820179915510491592339e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4297457122897433941401116965847053190520157060899014192745249713729532254404926130890521815127348327109666786665572e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6161498642584251241813003366016724169212642963709676666624520141292893281185666917636407790823210892689040877316178e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7666392145951751149831538647959406774537055531440674467098742731616386753588055389644670948300617866819865983054648e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8803579453407724763733101457740622707248415209160748131449972199405186821347293686245404742032360498210710718706868e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9555696979049809790878494689390161725756264940480817121080493113293348134372793448728802635294700756868258870429256e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9926210499260983419345748654034059370452496042279618586228697762904524428167719073818746102238075978747461480736921e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1580818067832935078759824240064553190436936903140808056908996403358367244202623293256774502185186717703954810463664e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1471189871425316661544131965264177586537962876885022711111683500151700796198726558483367566537422877227096643444043e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.1128509717053048305859030416292711922678552321960938357322028070390133769952032831204895569347757809858568165047769e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.0539455376045862945360267517565427162312365710457079923487043144554747810689514408013582515489930908693681447570811e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.9720340324174059979099291932561853835363045476189975483372207816149988460708299020779612375010639778624011960832019e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.8689680022394207961974175856787764139795646254828315293243700305012569486054157617049685031506591863121580010947248e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7437116361567832853582693939506471994832856823896682976509412313367495727224381199978598247737089593472710899482737e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5950811220412317308240686382747346820271035112771802428932791066115158268338607019365831655460314732208940609352540e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.4251129888545490144543370459875606826076838441263383072163293312936923476650934130242315028422047795830492882862973e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.2362885806407475864366712137872714887351550723707596350905793656046659248541276597504566497990926306481919129870507e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0277679080715671963325259433440084440587630604775975142050968279743014641141402310302584542633557037153607386127936e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7982537138836713906392255756914754983592207423271169651235865196757913880334117810235517477328110033499422471098658e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.5502913049921788909870584752660393043707768935695327316724254392794299567957035458208970599641697203261236226745020e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.2872845020170049476895792439495161101999504199883328877919242515738957655253932048951366960802592343905647433925806e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0083825504032382074839284467075646401410549266591308713115878386835777315058451955614116158949614066927183232852042e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.7116271483415543560330625367619875995997802688047764805628702762773009669395760582294525748583875707140577080663373e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4002130274329337836748795229551203225670528250050443083264193121524339063344855010257660547708022429300203676502386e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0792300167387488891109020215228585600877162393292487644544830559965388047996492709248618249084851477787538356572832e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.7475317587851737802948455517811078614796013288710603199613621069727810352835469926107822047433566792405123805901196e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4009945606953216220092489164881081392931528209659330290734972342536012282191913069778658241972047765300060007037359e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0435371145882835456568292235938973678758006097668937220074531550163622566841885855957623103354443247806459277197725e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6847817709128298231516667536336315840402654624706139411175769276842182270078960078544597372646532637619276509222462e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3236229195571674813656405846976238077578084997863654732213860488560614587634395544002156258192582265590155862296710e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4739733861741516072077105236553238716453268483726334971394029603529306140359023187904705754719643032594360138998941e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.5619321353567137580402369010655220701769295496290984052961210793810038857581724171021610100708799763006942755331129e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9873838923303159265078518828434098894299804282505973837653346298985629336820118753523093675303476883723992297810124e-03), + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.000000000e+00f, + 5.147184256e-02f, + 1.028069380e-01f, + 1.538699136e-01f, + 2.045251167e-01f, + 2.546369262e-01f, + 3.040732023e-01f, + 3.527047255e-01f, + 4.004012548e-01f, + 4.470337695e-01f, + 4.924804679e-01f, + 5.366241481e-01f, + 5.793452358e-01f, + 6.205261830e-01f, + 6.600610641e-01f, + 6.978504948e-01f, + 7.337900625e-01f, + 7.677774321e-01f, + 7.997278358e-01f, + 8.295657624e-01f, + 8.572052335e-01f, + 8.825605358e-01f, + 9.055733077e-01f, + 9.262000474e-01f, + 9.443744447e-01f, + 9.600218650e-01f, + 9.731163225e-01f, + 9.836681233e-01f, + 9.916309969e-01f, + 9.968934841e-01f, + 9.994844101e-01f, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 5.149472943e-02f, + 5.142612854e-02f, + 5.122154785e-02f, + 5.088179590e-02f, + 5.040592140e-02f, + 4.979568343e-02f, + 4.905543456e-02f, + 4.818586176e-02f, + 4.718554657e-02f, + 4.605923827e-02f, + 4.481480013e-02f, + 4.345253970e-02f, + 4.196981022e-02f, + 4.037453895e-02f, + 3.867894562e-02f, + 3.688236465e-02f, + 3.497933803e-02f, + 3.298144706e-02f, + 3.090725756e-02f, + 2.875404877e-02f, + 2.650995488e-02f, + 2.419116208e-02f, + 2.182803582e-02f, + 1.941414119e-02f, + 1.692088919e-02f, + 1.436972951e-02f, + 1.182301525e-02f, + 9.273279660e-03f, + 6.630703916e-03f, + 3.890461127e-03f, + 1.389013699e-03f, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000e+00, + 5.14718425553176958e-02, + 1.02806937966737030e-01, + 1.53869913608583547e-01, + 2.04525116682309891e-01, + 2.54636926167889846e-01, + 3.04073202273625077e-01, + 3.52704725530878113e-01, + 4.00401254830394393e-01, + 4.47033769538089177e-01, + 4.92480467861778575e-01, + 5.36624148142019899e-01, + 5.79345235826361692e-01, + 6.20526182989242861e-01, + 6.60061064126626961e-01, + 6.97850494793315797e-01, + 7.33790062453226805e-01, + 7.67777432104826195e-01, + 7.99727835821839083e-01, + 8.29565762382768397e-01, + 8.57205233546061099e-01, + 8.82560535792052682e-01, + 9.05573307699907799e-01, + 9.26200047429274326e-01, + 9.44374444748559979e-01, + 9.60021864968307512e-01, + 9.73116322501126268e-01, + 9.83668123279747210e-01, + 9.91630996870404595e-01, + 9.96893484074649540e-01, + 9.99484410050490638e-01, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 5.14947294294515676e-02, + 5.14261285374590259e-02, + 5.12215478492587722e-02, + 5.08817958987496065e-02, + 5.04059214027823468e-02, + 4.97956834270742064e-02, + 4.90554345550297789e-02, + 4.81858617570871291e-02, + 4.71855465692991539e-02, + 4.60592382710069881e-02, + 4.48148001331626632e-02, + 4.34525397013560693e-02, + 4.19698102151642461e-02, + 4.03745389515359591e-02, + 3.86789456247275930e-02, + 3.68823646518212292e-02, + 3.49793380280600241e-02, + 3.29814470574837260e-02, + 3.09072575623877625e-02, + 2.87540487650412928e-02, + 2.65099548823331016e-02, + 2.41911620780806014e-02, + 2.18280358216091923e-02, + 1.94141411939423812e-02, + 1.69208891890532726e-02, + 1.43697295070458048e-02, + 1.18230152534963417e-02, + 9.27327965951776343e-03, + 6.63070391593129217e-03, + 3.89046112709988405e-03, + 1.38901369867700762e-03, + }; + return data; + } +}; + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static constexpr std::array data = { + 0.00000000000000000000000000000000000e+00L, + 5.14718425553176958330252131667225737e-02L, + 1.02806937966737030147096751318000592e-01L, + 1.53869913608583546963794672743255920e-01L, + 2.04525116682309891438957671002024710e-01L, + 2.54636926167889846439805129817805108e-01L, + 3.04073202273625077372677107199256554e-01L, + 3.52704725530878113471037207089373861e-01L, + 4.00401254830394392535476211542660634e-01L, + 4.47033769538089176780609900322854000e-01L, + 4.92480467861778574993693061207708796e-01L, + 5.36624148142019899264169793311072794e-01L, + 5.79345235826361691756024932172540496e-01L, + 6.20526182989242861140477556431189299e-01L, + 6.60061064126626961370053668149270753e-01L, + 6.97850494793315796932292388026640068e-01L, + 7.33790062453226804726171131369527646e-01L, + 7.67777432104826194917977340974503132e-01L, + 7.99727835821839083013668942322683241e-01L, + 8.29565762382768397442898119732501916e-01L, + 8.57205233546061098958658510658943857e-01L, + 8.82560535792052681543116462530225590e-01L, + 9.05573307699907798546522558925958320e-01L, + 9.26200047429274325879324277080474004e-01L, + 9.44374444748559979415831324037439122e-01L, + 9.60021864968307512216871025581797663e-01L, + 9.73116322501126268374693868423706885e-01L, + 9.83668123279747209970032581605662802e-01L, + 9.91630996870404594858628366109485725e-01L, + 9.96893484074649540271630050918695283e-01L, + 9.99484410050490637571325895705810819e-01L, + }; + return data; + } + static std::array const & weights() + { + static constexpr std::array data = { + 5.14947294294515675583404336470993075e-02L, + 5.14261285374590259338628792157812598e-02L, + 5.12215478492587721706562826049442083e-02L, + 5.08817958987496064922974730498046919e-02L, + 5.04059214027823468408930856535850289e-02L, + 4.97956834270742063578115693799423285e-02L, + 4.90554345550297788875281653672381736e-02L, + 4.81858617570871291407794922983045926e-02L, + 4.71855465692991539452614781810994865e-02L, + 4.60592382710069881162717355593735806e-02L, + 4.48148001331626631923555516167232438e-02L, + 4.34525397013560693168317281170732581e-02L, + 4.19698102151642461471475412859697578e-02L, + 4.03745389515359591119952797524681142e-02L, + 3.86789456247275929503486515322810503e-02L, + 3.68823646518212292239110656171359677e-02L, + 3.49793380280600241374996707314678751e-02L, + 3.29814470574837260318141910168539275e-02L, + 3.09072575623877624728842529430922726e-02L, + 2.87540487650412928439787853543342111e-02L, + 2.65099548823331016106017093350754144e-02L, + 2.41911620780806013656863707252320268e-02L, + 2.18280358216091922971674857383389934e-02L, + 1.94141411939423811734089510501284559e-02L, + 1.69208891890532726275722894203220924e-02L, + 1.43697295070458048124514324435800102e-02L, + 1.18230152534963417422328988532505929e-02L, + 9.27327965951776342844114689202436042e-03L, + 6.63070391593129217331982636975016813e-03L, + 3.89046112709988405126720184451550328e-03L, + 1.38901369867700762455159122675969968e-03L, + }; + return data; + } +}; + +#ifdef BOOST_HAS_FLOAT128 +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static const std::array data = { + 0.00000000000000000000000000000000000e+00Q, + 5.14718425553176958330252131667225737e-02Q, + 1.02806937966737030147096751318000592e-01Q, + 1.53869913608583546963794672743255920e-01Q, + 2.04525116682309891438957671002024710e-01Q, + 2.54636926167889846439805129817805108e-01Q, + 3.04073202273625077372677107199256554e-01Q, + 3.52704725530878113471037207089373861e-01Q, + 4.00401254830394392535476211542660634e-01Q, + 4.47033769538089176780609900322854000e-01Q, + 4.92480467861778574993693061207708796e-01Q, + 5.36624148142019899264169793311072794e-01Q, + 5.79345235826361691756024932172540496e-01Q, + 6.20526182989242861140477556431189299e-01Q, + 6.60061064126626961370053668149270753e-01Q, + 6.97850494793315796932292388026640068e-01Q, + 7.33790062453226804726171131369527646e-01Q, + 7.67777432104826194917977340974503132e-01Q, + 7.99727835821839083013668942322683241e-01Q, + 8.29565762382768397442898119732501916e-01Q, + 8.57205233546061098958658510658943857e-01Q, + 8.82560535792052681543116462530225590e-01Q, + 9.05573307699907798546522558925958320e-01Q, + 9.26200047429274325879324277080474004e-01Q, + 9.44374444748559979415831324037439122e-01Q, + 9.60021864968307512216871025581797663e-01Q, + 9.73116322501126268374693868423706885e-01Q, + 9.83668123279747209970032581605662802e-01Q, + 9.91630996870404594858628366109485725e-01Q, + 9.96893484074649540271630050918695283e-01Q, + 9.99484410050490637571325895705810819e-01Q, + }; + return data; + } + static std::array const & weights() + { + static const std::array data = { + 5.14947294294515675583404336470993075e-02Q, + 5.14261285374590259338628792157812598e-02Q, + 5.12215478492587721706562826049442083e-02Q, + 5.08817958987496064922974730498046919e-02Q, + 5.04059214027823468408930856535850289e-02Q, + 4.97956834270742063578115693799423285e-02Q, + 4.90554345550297788875281653672381736e-02Q, + 4.81858617570871291407794922983045926e-02Q, + 4.71855465692991539452614781810994865e-02Q, + 4.60592382710069881162717355593735806e-02Q, + 4.48148001331626631923555516167232438e-02Q, + 4.34525397013560693168317281170732581e-02Q, + 4.19698102151642461471475412859697578e-02Q, + 4.03745389515359591119952797524681142e-02Q, + 3.86789456247275929503486515322810503e-02Q, + 3.68823646518212292239110656171359677e-02Q, + 3.49793380280600241374996707314678751e-02Q, + 3.29814470574837260318141910168539275e-02Q, + 3.09072575623877624728842529430922726e-02Q, + 2.87540487650412928439787853543342111e-02Q, + 2.65099548823331016106017093350754144e-02Q, + 2.41911620780806013656863707252320268e-02Q, + 2.18280358216091922971674857383389934e-02Q, + 1.94141411939423811734089510501284559e-02Q, + 1.69208891890532726275722894203220924e-02Q, + 1.43697295070458048124514324435800102e-02Q, + 1.18230152534963417422328988532505929e-02Q, + 9.27327965951776342844114689202436042e-03Q, + 6.63070391593129217331982636975016813e-03Q, + 3.89046112709988405126720184451550328e-03Q, + 1.38901369867700762455159122675969968e-03Q, + }; + return data; + } +}; +#endif + +template +class gauss_kronrod_detail +{ +public: + static std::array const & abscissa() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1471842555317695833025213166722573749141453666569564255160843987964755210427109055870090707285485841217089963590678e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.0280693796673703014709675131800059247190133296515840552101946914632788253917872738234797140786490207720254922664913e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.5386991360858354696379467274325592041855197124433846171896298291578714851081610139692310651074078557990111754952062e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.0452511668230989143895767100202470952410426459556377447604465028350321894663245495592565235317147819577892124850607e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.5463692616788984643980512981780510788278930330251842616428597508896353156907880290636628138423620257595521678255758e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0407320227362507737267710719925655353115778980946272844421536998312150442387767304001423699909778588529370119457430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.5270472553087811347103720708937386065363100802142562659418446890026941623319107866436039675211352945165817827083104e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0040125483039439253547621154266063361104593297078395983186610656429170689311759061175527015710247383961903284673474e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4703376953808917678060990032285400016240759386142440975447738172761535172858420700400688872124189834257262048739699e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9248046786177857499369306120770879564426564096318697026073340982988422546396352776837047452262025983265531109327026e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.3662414814201989926416979331107279416417800693029710545274348291201490861897837863114116009718990258091585830703557e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.7934523582636169175602493217254049590705158881215289208126016612312833567812241903809970751783808208940322061083509e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.2052618298924286114047755643118929920736469282952813259505117012433531497488911774115258445532782106478789996137481e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6006106412662696137005366814927075303835037480883390955067197339904937499734522076788020517029688190998858739703079e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.9785049479331579693229238802664006838235380065395465637972284673997672124315996069538163644008904690545069439941341e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.3379006245322680472617113136952764566938172775468549208701399518300016463613325382024664531597318795933262446521430e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.6777743210482619491797734097450313169488361723290845320649438736515857017299504505260960258623968420224697596501719e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 7.9972783582183908301366894232268324073569842937778450923647349548686662567326007229195202524185356472023967927713548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.2956576238276839744289811973250191643906869617034167880695298345365650658958163508295244350814016004371545455777732e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.5720523354606109895865851065894385682080017062359612850504551739119887225712932688031120704657195642614071367390794e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 8.8256053579205268154311646253022559005668914714648423206832605312161626269519165572921583828573210485349058106849548e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.0557330769990779854652255892595831956897536366222841356404766397803760239449631913585074426842574155323901785046522e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2620004742927432587932427708047400408647453682532906091103713367942299565110232681677288015055886244486106298320068e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.4437444474855997941583132403743912158564371496498093181748940139520917000657342753448871376849848523800667868447591e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.6002186496830751221687102558179766293035921740392339948566167242493995770706842922718944370380002378239172677454384e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.7311632250112626837469386842370688488763796428343933853755850185624118958166838288308561708261486365954975485787212e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.8366812327974720997003258160566280194031785470971136351718001015114429536479104370207597166035471368057762560137209e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9163099687040459485862836610948572485050033374616325510019923349807489603260796605556191495843575227494654783755353e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9689348407464954027163005091869528334088203811775079010809429780238769521016374081588201955806171741257405095963817e-01), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.9948441005049063757132589570581081946887394701850801923632642830748016674843587830656468823145435723317885056396548e-01), + }; + return data; + } + static std::array const & weights() + { + static std::array data = { + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1494729429451567558340433647099307532736880396464168074637323362474083844397567724480716864880173808112573901197920e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1426128537459025933862879215781259829552034862395987263855824172761589259406892072066110681184224608133314131500422e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.1221547849258772170656282604944208251146952425246327553509056805511015401279553971190412722969308620984161625812560e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0881795898749606492297473049804691853384914260919239920771942080972542646780575571132056254070929858650733836163479e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 5.0405921402782346840893085653585028902197018251622233664243959211066713308635283713447747907973700791599900911248852e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9795683427074206357811569379942328539209602813696108951047392842948482646220377655098341924089250200477846596263918e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.9055434555029778887528165367238173605887405295296569579490717901328215644590555247522873065246297467067324397612445e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.8185861757087129140779492298304592605799236108429800057373350872433793583969368428942672063270298939865425225579922e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.7185546569299153945261478181099486482884807300628457194141861551725533289490897029020276525603515502104799540544222e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.6059238271006988116271735559373580594692875571824924004732379492293604006446052672252973438978639166425766841417488e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.4814800133162663192355551616723243757431392796373009889680201194063503947907899189061064792111919040540351834527742e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.3452539701356069316831728117073258074603308631703168064888805495738640839573863333942084117196541456054957383622173e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.1969810215164246147147541285969757790088656718992374820388720323852655511200365790379948462006156953358103259681948e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 4.0374538951535959111995279752468114216126062126030255633998289613810846761059740961836828802959573901107306640876603e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8678945624727592950348651532281050250923629821553846790376130679337402056620700554139109487533759557982632153728099e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.6882364651821229223911065617135967736955164781030337670005198584196134970154169862584193360751243227989492571664973e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.4979338028060024137499670731467875097226912794818719972208457232177786702008744219498470603846784465175225933802357e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.2981447057483726031814191016853927510599291213858385714519347641452316582381008804994515341969205985818543200837577e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.0907257562387762472884252943092272635270458523807153426840486964022086189874056947717446328187131273807982629114591e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.8754048765041292843978785354334211144679160542074930035102280759132174815469834227854660515366003136772757344886331e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.6509954882333101610601709335075414366517579522748565770867438338472138903658077617652522759934474895733739329287706e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.4191162078080601365686370725232026760391377828182462432228943562944885267501070688006470962871743661192935455117297e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 2.1828035821609192297167485738338993401507296056834912773630422358720439403382559079356058602393879803560534375378340e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.9414141193942381173408951050128455851421014191431525770276066536497179079025540486072726114628763606440143557769099e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.6920889189053272627572289420322092368566703783835191139883410840546679978551861043620089451681146020853650713611444e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.4369729507045804812451432443580010195841899895001505873565899403000198662495821906144274682894222591414503342336172e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.1823015253496341742232898853250592896264406250607818326302431548265365155855182739401700032519141448997853772603766e-02), + BOOST_MATH_HUGE_CONSTANT(T, 0, 9.2732796595177634284411468920243604212700249381931076964956469143626665557434385492325784596343112153704094886248672e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 6.6307039159312921733198263697501681336283882177812585973955597357837568277731921327731815844512598157843672104469554e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 3.8904611270998840512672018445155032785151429848864649214200101281144733676455451061226273655941038347210163533085954e-03), + BOOST_MATH_HUGE_CONSTANT(T, 0, 1.3890136986770076245515912267596996810488412919632724534411055332301367130989865366956251556423820479579333920310978e-03), + }; + return data; + } +}; + +} + +template > +class gauss_kronrod : public detail::gauss_kronrod_detail::value> +{ + typedef detail::gauss_kronrod_detail::value> base; +public: + typedef Real value_type; +private: + template + static auto integrate_non_adaptive_m1_1(F f, Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(Real(0))) K; + using std::abs; + unsigned gauss_start = 2; + unsigned kronrod_start = 1; + unsigned gauss_order = (N - 1) / 2; + K kronrod_result = 0; + K gauss_result = 0; + K fp, fm; + if (gauss_order & 1) + { + fp = f(value_type(0)); + kronrod_result = fp * base::weights()[0]; + gauss_result += fp * gauss::weights()[0]; + } + else + { + fp = f(value_type(0)); + kronrod_result = fp * base::weights()[0]; + gauss_start = 1; + kronrod_start = 2; + } + Real L1 = abs(kronrod_result); + for (unsigned i = gauss_start; i < base::abscissa().size(); i += 2) + { + fp = f(base::abscissa()[i]); + fm = f(-base::abscissa()[i]); + kronrod_result += (fp + fm) * base::weights()[i]; + L1 += (abs(fp) + abs(fm)) * base::weights()[i]; + gauss_result += (fp + fm) * gauss::weights()[i / 2]; + } + for (unsigned i = kronrod_start; i < base::abscissa().size(); i += 2) + { + fp = f(base::abscissa()[i]); + fm = f(-base::abscissa()[i]); + kronrod_result += (fp + fm) * base::weights()[i]; + L1 += (abs(fp) + abs(fm)) * base::weights()[i]; + } + if (pL1) + *pL1 = L1; + if (error) + *error = (std::max)(static_cast(abs(kronrod_result - gauss_result)), static_cast(abs(kronrod_result * tools::epsilon() * Real(2)))); + return kronrod_result; + } + + template + struct recursive_info + { + F f; + Real tol; + }; + + template + static auto recursive_adaptive_integrate(const recursive_info* info, Real a, Real b, unsigned max_levels, Real abs_tol, Real* error, Real* L1)->decltype(std::declval()(std::declval())) + { + typedef decltype(info->f(Real(a))) K; + using std::abs; + Real error_local; + Real mean = (b + a) / 2; + Real scale = (b - a) / 2; + auto ff = [&](const Real& x)->K + { + return info->f(scale * x + mean); + }; + K r1 = integrate_non_adaptive_m1_1(ff, &error_local, L1); + K estimate = scale * r1; + + K tmp = estimate * info->tol; + Real abs_tol1 = abs(tmp); + if (abs_tol == 0) + abs_tol = abs_tol1; + + if (max_levels && (abs_tol1 < error_local) && (abs_tol < error_local)) + { + Real mid = (a + b) / 2; + Real L1_local; + estimate = recursive_adaptive_integrate(info, a, mid, max_levels - 1, abs_tol / 2, error, L1); + estimate += recursive_adaptive_integrate(info, mid, b, max_levels - 1, abs_tol / 2, &error_local, &L1_local); + if (error) + *error += error_local; + if (L1) + *L1 += L1_local; + return estimate; + } + if(L1) + *L1 *= scale; + if (error) + *error = error_local; + return estimate; + } + +public: + template + static auto integrate(F f, Real a, Real b, unsigned max_depth = 15, Real tol = tools::root_epsilon(), Real* error = nullptr, Real* pL1 = nullptr)->decltype(std::declval()(std::declval())) + { + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + static const char* function = "boost::math::quadrature::gauss_kronrod<%1%>::integrate(f, %1%, %1%)"; + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + // Infinite limits: + if ((a <= -tools::max_value()) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real t_sq = t*t; + Real inv = 1 / (1 - t_sq); + Real w = (1 + t_sq)*inv*inv; + Real arg = t*inv; + K res = f(arg)*w; + return res; + }; + recursive_info info = { u, tol }; + K res = recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + return res; + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z + a - 1; + K res = f(arg)*z*z; + return res; + }; + recursive_info info = { u, tol }; + K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t)->K + { + Real z = 1 / (t + 1); + Real arg = 2 * z - 1; + return f(b - arg) * z * z; + }; + recursive_info info = { v, tol }; + K Q = Real(2) * recursive_adaptive_integrate(&info, Real(-1), Real(1), max_depth, Real(0), error, pL1); + if (pL1) + { + *pL1 *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a==b) + { + return K(0); + } + recursive_info info = { f, tol }; + if (b < a) + { + return -recursive_adaptive_integrate(&info, b, a, max_depth, Real(0), error, pL1); + } + return recursive_adaptive_integrate(&info, a, b, max_depth, Real(0), error, pL1); + } + } + return static_cast(policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy())); + } +}; + +} // namespace quadrature +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_QUADRATURE_GAUSS_KRONROD_HPP diff --git a/libcxx/src/third-party/boost/math/quadrature/naive_monte_carlo.hpp b/libcxx/src/third-party/boost/math/quadrature/naive_monte_carlo.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/naive_monte_carlo.hpp @@ -0,0 +1,461 @@ +/* + * Copyright Nick Thompson, 2018 + * 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_QUADRATURE_NAIVE_MONTE_CARLO_HPP +#define BOOST_MATH_QUADRATURE_NAIVE_MONTE_CARLO_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace quadrature { + +namespace detail { + enum class limit_classification {FINITE, + LOWER_BOUND_INFINITE, + UPPER_BOUND_INFINITE, + DOUBLE_INFINITE}; +} + +template, + typename std::enable_if::value, bool>::type = true> +class naive_monte_carlo +{ +public: + naive_monte_carlo(const F& integrand, + std::vector> const & bounds, + Real error_goal, + bool singular = true, + uint64_t threads = std::thread::hardware_concurrency(), + uint64_t seed = 0) noexcept : m_num_threads{threads}, m_seed{seed}, m_volume(1) + { + using std::numeric_limits; + using std::sqrt; + uint64_t n = bounds.size(); + m_lbs.resize(n); + m_dxs.resize(n); + m_limit_types.resize(n); + + static const char* function = "boost::math::quadrature::naive_monte_carlo<%1%>"; + for (uint64_t i = 0; i < n; ++i) + { + if (bounds[i].second <= bounds[i].first) + { + boost::math::policies::raise_domain_error(function, "The upper bound is <= the lower bound.\n", bounds[i].second, Policy()); + return; + } + if (bounds[i].first == -numeric_limits::infinity()) + { + if (bounds[i].second == numeric_limits::infinity()) + { + m_limit_types[i] = detail::limit_classification::DOUBLE_INFINITE; + } + else + { + m_limit_types[i] = detail::limit_classification::LOWER_BOUND_INFINITE; + // Ok ok this is bad to use the second bound as the lower limit and then reflect. + m_lbs[i] = bounds[i].second; + m_dxs[i] = numeric_limits::quiet_NaN(); + } + } + else if (bounds[i].second == numeric_limits::infinity()) + { + m_limit_types[i] = detail::limit_classification::UPPER_BOUND_INFINITE; + if (singular) + { + // I've found that it's easier to sample on a closed set and perturb the boundary + // than to try to sample very close to the boundary. + m_lbs[i] = std::nextafter(bounds[i].first, (std::numeric_limits::max)()); + } + else + { + m_lbs[i] = bounds[i].first; + } + m_dxs[i] = numeric_limits::quiet_NaN(); + } + else + { + m_limit_types[i] = detail::limit_classification::FINITE; + if (singular) + { + if (bounds[i].first == 0) + { + m_lbs[i] = std::numeric_limits::epsilon(); + } + else + { + m_lbs[i] = std::nextafter(bounds[i].first, (std::numeric_limits::max)()); + } + + m_dxs[i] = std::nextafter(bounds[i].second, std::numeric_limits::lowest()) - m_lbs[i]; + } + else + { + m_lbs[i] = bounds[i].first; + m_dxs[i] = bounds[i].second - bounds[i].first; + } + m_volume *= m_dxs[i]; + } + } + + m_integrand = [this, &integrand](std::vector & x)->Real + { + Real coeff = m_volume; + for (uint64_t i = 0; i < x.size(); ++i) + { + // Variable transformation are listed at: + // https://en.wikipedia.org/wiki/Numerical_integration + // However, we've made some changes to these so that we can evaluate on a compact domain. + if (m_limit_types[i] == detail::limit_classification::FINITE) + { + x[i] = m_lbs[i] + x[i]*m_dxs[i]; + } + else if (m_limit_types[i] == detail::limit_classification::UPPER_BOUND_INFINITE) + { + Real t = x[i]; + Real z = 1/(1 + numeric_limits::epsilon() - t); + coeff *= (z*z)*(1 + numeric_limits::epsilon()); + x[i] = m_lbs[i] + t*z; + } + else if (m_limit_types[i] == detail::limit_classification::LOWER_BOUND_INFINITE) + { + Real t = x[i]; + Real z = 1/(t+sqrt((numeric_limits::min)())); + coeff *= (z*z); + x[i] = m_lbs[i] + (t-1)*z; + } + else + { + Real t1 = 1/(1+numeric_limits::epsilon() - x[i]); + Real t2 = 1/(x[i]+numeric_limits::epsilon()); + x[i] = (2*x[i]-1)*t1*t2/4; + coeff *= (t1*t1+t2*t2)/4; + } + } + return coeff*integrand(x); + }; + + // If we don't do a single function call in the constructor, + // we can't do a restart. + std::vector x(m_lbs.size()); + + // If the seed is zero, that tells us to choose a random seed for the user: + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + + RandomNumberGenerator gen(seed); + Real inv_denom = 1/static_cast(((gen.max)()-(gen.min)())); + + m_num_threads = (std::max)(m_num_threads, static_cast(1)); + m_thread_calls.reset(new std::atomic[threads]); + m_thread_Ss.reset(new std::atomic[threads]); + m_thread_averages.reset(new std::atomic[threads]); + + Real avg = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + for (uint64_t j = 0; j < m_lbs.size(); ++j) + { + x[j] = (gen()-(gen.min)())*inv_denom; + } + Real y = m_integrand(x); + m_thread_averages[i] = y; // relaxed store + m_thread_calls[i] = 1; + m_thread_Ss[i] = 0; + avg += y; + } + avg /= m_num_threads; + m_avg = avg; // relaxed store + + m_error_goal = error_goal; // relaxed store + m_start = std::chrono::system_clock::now(); + m_done = false; // relaxed store + m_total_calls = m_num_threads; // relaxed store + m_variance = (numeric_limits::max)(); + } + + std::future integrate() + { + // Set done to false in case we wish to restart: + m_done.store(false); // relaxed store, no worker threads yet + m_start = std::chrono::system_clock::now(); + return std::async(std::launch::async, + &naive_monte_carlo::m_integrate, this); + } + + void cancel() + { + // If seed = 0 (meaning have the routine pick the seed), this leaves the seed the same. + // If seed != 0, then the seed is changed, so a restart doesn't do the exact same thing. + m_seed = m_seed*m_seed; + m_done = true; // relaxed store, worker threads will get the message eventually + // Make sure the error goal is infinite, because otherwise we'll loop when we do the final error goal check: + m_error_goal = (std::numeric_limits::max)(); + } + + Real variance() const + { + return m_variance.load(); + } + + Real current_error_estimate() const + { + using std::sqrt; + // + // There is a bug here: m_variance and m_total_calls get updated asynchronously + // and may be out of synch when we compute the error estimate, not sure if it matters though... + // + return sqrt(m_variance.load()/m_total_calls.load()); + } + + std::chrono::duration estimated_time_to_completion() const + { + auto now = std::chrono::system_clock::now(); + std::chrono::duration elapsed_seconds = now - m_start; + Real r = this->current_error_estimate()/m_error_goal.load(); // relaxed load + if (r*r <= 1) { + return 0*elapsed_seconds; + } + return (r*r - 1)*elapsed_seconds; + } + + void update_target_error(Real new_target_error) + { + m_error_goal = new_target_error; // relaxed store + } + + Real progress() const + { + Real r = m_error_goal.load()/this->current_error_estimate(); // relaxed load + if (r*r >= 1) + { + return 1; + } + return r*r; + } + + Real current_estimate() const + { + return m_avg.load(); + } + + uint64_t calls() const + { + return m_total_calls.load(); // relaxed load + } + +private: + + Real m_integrate() + { + uint64_t seed; + // If the user tells us to pick a seed, pick a seed: + if (m_seed == 0) + { + std::random_device rd; + seed = rd(); + } + else // use the seed we are given: + { + seed = m_seed; + } + RandomNumberGenerator gen(seed); + int max_repeat_tries = 5; + do{ + + if (max_repeat_tries < 5) + { + m_done = false; + +#ifdef BOOST_NAIVE_MONTE_CARLO_DEBUG_FAILURES + std::cout << "Failed to achieve required tolerance first time through..\n"; + std::cout << " variance = " << m_variance << std::endl; + std::cout << " average = " << m_avg << std::endl; + std::cout << " total calls = " << m_total_calls << std::endl; + + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cout << " thread_calls[" << i << "] = " << m_thread_calls[i] << std::endl; + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cout << " thread_averages[" << i << "] = " << m_thread_averages[i] << std::endl; + for (std::size_t i = 0; i < m_num_threads; ++i) + std::cout << " thread_Ss[" << i << "] = " << m_thread_Ss[i] << std::endl; +#endif + } + + std::vector threads(m_num_threads); + for (uint64_t i = 0; i < threads.size(); ++i) + { + threads[i] = std::thread(&naive_monte_carlo::m_thread_monte, this, i, gen()); + } + do { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + uint64_t total_calls = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + total_calls += t_calls; + } + Real variance = 0; + Real avg = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + // Will this overflow? Not hard to remove . . . + avg += m_thread_averages[i].load(std::memory_order_relaxed)*(static_cast(t_calls) / static_cast(total_calls)); + variance += m_thread_Ss[i].load(std::memory_order_relaxed); + } + m_avg.store(avg, std::memory_order_release); + m_variance.store(variance / (total_calls - 1), std::memory_order_release); + m_total_calls = total_calls; // relaxed store, it's just for user feedback + // Allow cancellation: + if (m_done) // relaxed load + { + break; + } + } while (m_total_calls < 2048 || this->current_error_estimate() > m_error_goal.load(std::memory_order_consume)); + // Error bound met; signal the threads: + m_done = true; // relaxed store, threads will get the message in the end + std::for_each(threads.begin(), threads.end(), + std::mem_fn(&std::thread::join)); + if (m_exception) + { + std::rethrow_exception(m_exception); + } + // Incorporate their work into the final estimate: + uint64_t total_calls = 0; + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + total_calls += t_calls; + } + Real variance = 0; + Real avg = 0; + + for (uint64_t i = 0; i < m_num_threads; ++i) + { + uint64_t t_calls = m_thread_calls[i].load(std::memory_order_consume); + // Averages weighted by the number of calls the thread made: + avg += m_thread_averages[i].load(std::memory_order_relaxed)*(static_cast(t_calls) / static_cast(total_calls)); + variance += m_thread_Ss[i].load(std::memory_order_relaxed); + } + m_avg.store(avg, std::memory_order_release); + m_variance.store(variance / (total_calls - 1), std::memory_order_release); + m_total_calls = total_calls; // relaxed store, this is just user feedback + + // Sometimes, the master will observe the variance at a very "good" (or bad?) moment, + // Then the threads proceed to find the variance is much greater by the time they hear the message to stop. + // This *WOULD* make sure that the final error estimate is within the error bounds. + } + while ((--max_repeat_tries >= 0) && (this->current_error_estimate() > m_error_goal)); + + return m_avg.load(std::memory_order_consume); + } + + void m_thread_monte(uint64_t thread_index, uint64_t seed) + { + using std::numeric_limits; + try + { + std::vector x(m_lbs.size()); + RandomNumberGenerator gen(seed); + Real inv_denom = static_cast(1) / static_cast(( (gen.max)() - (gen.min)() )); + Real M1 = m_thread_averages[thread_index].load(std::memory_order_consume); + Real S = m_thread_Ss[thread_index].load(std::memory_order_consume); + // Kahan summation is required or the value of the integrand will go on a random walk during long computations. + // See the implementation discussion. + // The idea is that the unstabilized additions have error sigma(f)/sqrt(N) + epsilon*N, which diverges faster than it converges! + // Kahan summation turns this to sigma(f)/sqrt(N) + epsilon^2*N, and the random walk occurs on a timescale of 10^14 years (on current hardware) + Real compensator = 0; + uint64_t k = m_thread_calls[thread_index].load(std::memory_order_consume); + while (!m_done) // relaxed load + { + int j = 0; + // If we don't have a certain number of calls before an update, we can easily terminate prematurely + // because the variance estimate is way too low. This magic number is a reasonable compromise, as 1/sqrt(2048) = 0.02, + // so it should recover 2 digits if the integrand isn't poorly behaved, and if it is, it should discover that before premature termination. + // Of course if the user has 64 threads, then this number is probably excessive. + int magic_calls_before_update = 2048; + while (j++ < magic_calls_before_update) + { + for (uint64_t i = 0; i < m_lbs.size(); ++i) + { + x[i] = (gen() - (gen.min)())*inv_denom; + } + Real f = m_integrand(x); + using std::isfinite; + if (!isfinite(f)) + { + // The call to m_integrand transform x, so this error message states the correct node. + std::stringstream os; + os << "Your integrand was evaluated at {"; + for (uint64_t i = 0; i < x.size() -1; ++i) + { + os << x[i] << ", "; + } + os << x[x.size() -1] << "}, and returned " << f << std::endl; + static const char* function = "boost::math::quadrature::naive_monte_carlo<%1%>"; + boost::math::policies::raise_domain_error(function, os.str().c_str(), /*this is a dummy arg to make it compile*/ 7.2, Policy()); + } + ++k; + Real term = (f - M1)/k; + Real y1 = term - compensator; + Real M2 = M1 + y1; + compensator = (M2 - M1) - y1; + S += (f - M1)*(f - M2); + M1 = M2; + } + m_thread_averages[thread_index].store(M1, std::memory_order_release); + m_thread_Ss[thread_index].store(S, std::memory_order_release); + m_thread_calls[thread_index].store(k, std::memory_order_release); + } + } + catch (...) + { + // Signal the other threads that the computation is ruined: + m_done = true; // relaxed store + std::lock_guard lock(m_exception_mutex); // Scoped lock to prevent race writing to m_exception + m_exception = std::current_exception(); + } + } + + std::function &)> m_integrand; + uint64_t m_num_threads; + std::atomic m_seed; + std::atomic m_error_goal; + std::atomic m_done{}; + std::vector m_lbs; + std::vector m_dxs; + std::vector m_limit_types; + Real m_volume; + std::atomic m_total_calls{}; + // I wanted these to be vectors rather than maps, + // but you can't resize a vector of atomics. + std::unique_ptr[]> m_thread_calls; + std::atomic m_variance; + std::unique_ptr[]> m_thread_Ss; + std::atomic m_avg; + std::unique_ptr[]> m_thread_averages; + std::chrono::time_point m_start; + std::exception_ptr m_exception; + std::mutex m_exception_mutex; +}; + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/ooura_fourier_integrals.hpp b/libcxx/src/third-party/boost/math/quadrature/ooura_fourier_integrals.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/ooura_fourier_integrals.hpp @@ -0,0 +1,68 @@ +// Copyright Nick Thompson, 2019 +// 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) + +/* + * References: + * Ooura, Takuya, and Masatake Mori. "A robust double exponential formula for Fourier-type integrals." Journal of computational and applied mathematics 112.1-2 (1999): 229-241. + * http://www.kurims.kyoto-u.ac.jp/~ooura/intde.html + */ +#ifndef BOOST_MATH_QUADRATURE_OOURA_FOURIER_INTEGRALS_HPP +#define BOOST_MATH_QUADRATURE_OOURA_FOURIER_INTEGRALS_HPP +#include +#include + +namespace boost { namespace math { namespace quadrature { + +template +class ooura_fourier_sin { +public: + ooura_fourier_sin(const Real relative_error_tolerance = tools::root_epsilon(), size_t levels = sizeof(Real)) : impl_(std::make_shared>(relative_error_tolerance, levels)) + {} + + template + std::pair integrate(F const & f, Real omega) { + return impl_->integrate(f, omega); + } + + // These are just for debugging/unit tests: + std::vector> const & big_nodes() const { + return impl_->big_nodes(); + } + + std::vector> const & weights_for_big_nodes() const { + return impl_->weights_for_big_nodes(); + } + + std::vector> const & little_nodes() const { + return impl_->little_nodes(); + } + + std::vector> const & weights_for_little_nodes() const { + return impl_->weights_for_little_nodes(); + } + +private: + std::shared_ptr> impl_; +}; + + +template +class ooura_fourier_cos { +public: + ooura_fourier_cos(const Real relative_error_tolerance = tools::root_epsilon(), size_t levels = sizeof(Real)) : impl_(std::make_shared>(relative_error_tolerance, levels)) + {} + + template + std::pair integrate(F const & f, Real omega) { + return impl_->integrate(f, omega); + } +private: + std::shared_ptr> impl_; +}; + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/sinh_sinh.hpp b/libcxx/src/third-party/boost/math/quadrature/sinh_sinh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/sinh_sinh.hpp @@ -0,0 +1,43 @@ +// Copyright Nick Thompson, 2017 +// 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) + +/* + * This class performs sinh-sinh quadrature over the entire real line. + * + * References: + * + * 1) Tanaka, Ken'ichiro, et al. "Function classes for double exponential integration formulas." Numerische Mathematik 111.4 (2009): 631-655. + */ + +#ifndef BOOST_MATH_QUADRATURE_SINH_SINH_HPP +#define BOOST_MATH_QUADRATURE_SINH_SINH_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class sinh_sinh +{ +public: + sinh_sinh(size_t max_refinements = 9) + : m_imp(std::make_shared >(max_refinements)) {} + + template + auto integrate(const F f, Real tol = boost::math::tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr)->decltype(std::declval()(std::declval())) const + { + return m_imp->integrate(f, tol, error, L1, levels); + } + +private: + std::shared_ptr> m_imp; +}; + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/tanh_sinh.hpp b/libcxx/src/third-party/boost/math/quadrature/tanh_sinh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/tanh_sinh.hpp @@ -0,0 +1,289 @@ +// Copyright Nick Thompson, 2017 +// 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) + +/* + * This class performs tanh-sinh quadrature on the real line. + * Tanh-sinh quadrature is exponentially convergent for integrands in Hardy spaces, + * (see https://en.wikipedia.org/wiki/Hardy_space for a formal definition), and is optimal for a random function from that class. + * + * The tanh-sinh quadrature is one of a class of so called "double exponential quadratures"-there is a large family of them, + * but this one seems to be the most commonly used. + * + * As always, there are caveats: For instance, if the function you want to integrate is not holomorphic on the unit disk, + * then the rapid convergence will be spoiled. In this case, a more appropriate quadrature is (say) Romberg, which does not + * require the function to be holomorphic, only differentiable up to some order. + * + * In addition, if you are integrating a periodic function over a period, the trapezoidal rule is better. + * + * References: + * + * 1) Mori, Masatake. "Quadrature formulas obtained by variable transformation and the DE-rule." Journal of Computational and Applied Mathematics 12 (1985): 119-130. + * 2) Bailey, David H., Karthik Jeyabalan, and Xiaoye S. Li. "A comparison of three high-precision quadrature schemes." Experimental Mathematics 14.3 (2005): 317-329. + * 3) Press, William H., et al. "Numerical recipes third edition: the art of scientific computing." Cambridge University Press 32 (2007): 10013-2473. + * + */ + +#ifndef BOOST_MATH_QUADRATURE_TANH_SINH_HPP +#define BOOST_MATH_QUADRATURE_TANH_SINH_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template > +class tanh_sinh +{ +public: + tanh_sinh(size_t max_refinements = 15, const Real& min_complement = tools::min_value() * 4) + : m_imp(std::make_shared>(max_refinements, min_complement)) {} + + template + auto integrate(const F f, Real a, Real b, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) ->decltype(std::declval()(std::declval())) const; + template + auto integrate(const F f, Real a, Real b, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) ->decltype(std::declval()(std::declval(), std::declval())) const; + + template + auto integrate(const F f, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) ->decltype(std::declval()(std::declval())) const; + template + auto integrate(const F f, Real tolerance = tools::root_epsilon(), Real* error = nullptr, Real* L1 = nullptr, std::size_t* levels = nullptr) ->decltype(std::declval()(std::declval(), std::declval())) const; + +private: + std::shared_ptr> m_imp; +}; + +template +template +auto tanh_sinh::integrate(const F f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels) ->decltype(std::declval()(std::declval())) const +{ + BOOST_MATH_STD_USING + using boost::math::constants::half; + using boost::math::quadrature::detail::tanh_sinh_detail; + + static const char* function = "tanh_sinh<%1%>::integrate"; + + typedef decltype(std::declval()(std::declval())) result_type; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + if (!(boost::math::isnan)(a) && !(boost::math::isnan)(b)) + { + + // Infinite limits: + if ((a <= -tools::max_value()) && (b >= tools::max_value())) + { + auto u = [&](const Real& t, const Real& tc)->result_type + { + Real t_sq = t*t; + Real inv; + if (t > 0.5f) + inv = 1 / ((2 - tc) * tc); + else if(t < -0.5) + inv = 1 / ((2 + tc) * -tc); + else + inv = 1 / (1 - t_sq); + return f(t*inv)*(1 + t_sq)*inv*inv; + }; + Real limit = sqrt(tools::min_value()) * 4; + return m_imp->integrate(u, error, L1, function, limit, limit, tolerance, levels); + } + + // Right limit is infinite: + if ((boost::math::isfinite)(a) && (b >= tools::max_value())) + { + auto u = [&](const Real& t, const Real& tc)->result_type + { + Real z, arg; + if (t > -0.5f) + z = 1 / (t + 1); + else + z = -1 / tc; + if (t < 0.5) + arg = 2 * z + a - 1; + else + arg = a + tc / (2 - tc); + return f(arg)*z*z; + }; + Real left_limit = sqrt(tools::min_value()) * 4; + result_type Q = Real(2) * m_imp->integrate(u, error, L1, function, left_limit, tools::min_value(), tolerance, levels); + if (L1) + { + *L1 *= 2; + } + if (error) + { + *error *= 2; + } + + return Q; + } + + if ((boost::math::isfinite)(b) && (a <= -tools::max_value())) + { + auto v = [&](const Real& t, const Real& tc)->result_type + { + Real z; + if (t > -0.5) + z = 1 / (t + 1); + else + z = -1 / tc; + Real arg; + if (t < 0.5) + arg = 2 * z - 1; + else + arg = tc / (2 - tc); + return f(b - arg) * z * z; + }; + + Real left_limit = sqrt(tools::min_value()) * 4; + result_type Q = Real(2) * m_imp->integrate(v, error, L1, function, left_limit, tools::min_value(), tolerance, levels); + if (L1) + { + *L1 *= 2; + } + if (error) + { + *error *= 2; + } + return Q; + } + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (a == b) + { + return result_type(0); + } + if (b < a) + { + return -this->integrate(f, b, a, tolerance, error, L1, levels); + } + Real avg = (a + b)*half(); + Real diff = (b - a)*half(); + Real avg_over_diff_m1 = a / diff; + Real avg_over_diff_p1 = b / diff; + bool have_small_left = fabs(a) < 0.5f; + bool have_small_right = fabs(b) < 0.5f; + Real left_min_complement = float_next(avg_over_diff_m1) - avg_over_diff_m1; + Real min_complement_limit = (std::max)(tools::min_value(), Real(tools::min_value() / diff)); + if (left_min_complement < min_complement_limit) + left_min_complement = min_complement_limit; + Real right_min_complement = avg_over_diff_p1 - float_prior(avg_over_diff_p1); + if (right_min_complement < min_complement_limit) + right_min_complement = min_complement_limit; + // + // These asserts will fail only if rounding errors on + // type Real have accumulated so much error that it's + // broken our internal logic. Should that prove to be + // a persistent issue, we might need to add a bit of fudge + // factor to move left_min_complement and right_min_complement + // further from the end points of the range. + // + BOOST_MATH_ASSERT((left_min_complement * diff + a) > a); + BOOST_MATH_ASSERT((b - right_min_complement * diff) < b); + auto u = [&](Real z, Real zc)->result_type + { + Real position; + if (z < -0.5) + { + if(have_small_left) + return f(diff * (avg_over_diff_m1 - zc)); + position = a - diff * zc; + } + else if (z > 0.5) + { + if(have_small_right) + return f(diff * (avg_over_diff_p1 - zc)); + position = b - diff * zc; + } + else + position = avg + diff*z; + BOOST_MATH_ASSERT(position != a); + BOOST_MATH_ASSERT(position != b); + return f(position); + }; + result_type Q = diff*m_imp->integrate(u, error, L1, function, left_min_complement, right_min_complement, tolerance, levels); + + if (L1) + { + *L1 *= diff; + } + if (error) + { + *error *= diff; + } + return Q; + } + } + return policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()); +} + +template +template +auto tanh_sinh::integrate(const F f, Real a, Real b, Real tolerance, Real* error, Real* L1, std::size_t* levels) ->decltype(std::declval()(std::declval(), std::declval())) const +{ + BOOST_MATH_STD_USING + using boost::math::constants::half; + using boost::math::quadrature::detail::tanh_sinh_detail; + + static const char* function = "tanh_sinh<%1%>::integrate"; + + if ((boost::math::isfinite)(a) && (boost::math::isfinite)(b)) + { + if (b <= a) + { + return policies::raise_domain_error(function, "Arguments to integrate are in wrong order; integration over [a,b] must have b > a.", a, Policy()); + } + auto u = [&](Real z, Real zc)->Real + { + if (z < 0) + return f((a - b) * zc / 2 + a, (b - a) * zc / 2); + else + return f((a - b) * zc / 2 + b, (b - a) * zc / 2); + }; + Real diff = (b - a)*half(); + Real left_min_complement = tools::min_value() * 4; + Real right_min_complement = tools::min_value() * 4; + Real Q = diff*m_imp->integrate(u, error, L1, function, left_min_complement, right_min_complement, tolerance, levels); + + if (L1) + { + *L1 *= diff; + } + if (error) + { + *error *= diff; + } + return Q; + } + return policies::raise_domain_error(function, "The domain of integration is not sensible; please check the bounds.", a, Policy()); +} + +template +template +auto tanh_sinh::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) ->decltype(std::declval()(std::declval())) const +{ + using boost::math::quadrature::detail::tanh_sinh_detail; + static const char* function = "tanh_sinh<%1%>::integrate"; + Real min_complement = tools::epsilon(); + return m_imp->integrate([&](const Real& arg, const Real&) { return f(arg); }, error, L1, function, min_complement, min_complement, tolerance, levels); +} + +template +template +auto tanh_sinh::integrate(const F f, Real tolerance, Real* error, Real* L1, std::size_t* levels) ->decltype(std::declval()(std::declval(), std::declval())) const +{ + using boost::math::quadrature::detail::tanh_sinh_detail; + static const char* function = "tanh_sinh<%1%>::integrate"; + Real min_complement = tools::min_value() * 4; + return m_imp->integrate(f, error, L1, function, min_complement, min_complement, tolerance, levels); +} + +} +} +} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/trapezoidal.hpp b/libcxx/src/third-party/boost/math/quadrature/trapezoidal.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/trapezoidal.hpp @@ -0,0 +1,125 @@ +/* + * Copyright Nick Thompson, 2017 + * 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) + * + * Use the adaptive trapezoidal rule to estimate the integral of periodic functions over a period, + * or to integrate a function whose derivative vanishes at the endpoints. + * + * If your function does not satisfy these conditions, and instead is simply continuous and bounded + * over the whole interval, then this routine will still converge, albeit slowly. However, there + * are much more efficient methods in this case, including Romberg, Simpson, and double exponential quadrature. + */ + +#ifndef BOOST_MATH_QUADRATURE_TRAPEZOIDAL_HPP +#define BOOST_MATH_QUADRATURE_TRAPEZOIDAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace quadrature { + +template +auto trapezoidal(F f, Real a, Real b, Real tol, std::size_t max_refinements, Real* error_estimate, Real* L1, const Policy& pol)->decltype(std::declval()(std::declval())) +{ + static const char* function = "boost::math::quadrature::trapezoidal<%1%>(F, %1%, %1%, %1%)"; + using std::abs; + using boost::math::constants::half; + // In many math texts, K represents the field of real or complex numbers. + // Too bad we can't put blackboard bold into C++ source! + typedef decltype(f(a)) K; + static_assert(!std::is_integral::value, + "The return type cannot be integral, it must be either a real or complex floating point type."); + if (!(boost::math::isfinite)(a)) + { + return static_cast(boost::math::policies::raise_domain_error(function, "Left endpoint of integration must be finite for adaptive trapezoidal integration but got a = %1%.\n", a, pol)); + } + if (!(boost::math::isfinite)(b)) + { + return static_cast(boost::math::policies::raise_domain_error(function, "Right endpoint of integration must be finite for adaptive trapezoidal integration but got b = %1%.\n", b, pol)); + } + + if (a == b) + { + return static_cast(0); + } + if(a > b) + { + return -trapezoidal(f, b, a, tol, max_refinements, error_estimate, L1, pol); + } + + + K ya = f(a); + K yb = f(b); + Real h = (b - a)*half(); + K I0 = (ya + yb)*h; + Real IL0 = (abs(ya) + abs(yb))*h; + + K yh = f(a + h); + K I1; + I1 = I0*half() + yh*h; + Real IL1 = IL0*half() + abs(yh)*h; + + // The recursion is: + // I_k = 1/2 I_{k-1} + 1/2^k \sum_{j=1; j odd, j < 2^k} f(a + j(b-a)/2^k) + std::size_t k = 2; + // We want to go through at least 5 levels so we have sampled the function at least 20 times. + // Otherwise, we could terminate prematurely and miss essential features. + // This is of course possible anyway, but 20 samples seems to be a reasonable compromise. + Real error = abs(I0 - I1); + // I take k < 5, rather than k < 4, or some other smaller minimum number, + // because I hit a truly exceptional bug where the k = 2 and k =3 refinement were bitwise equal, + // but the quadrature had not yet converged. + while (k < 5 || (k < max_refinements && error > tol*IL1) ) + { + I0 = I1; + IL0 = IL1; + + I1 = I0*half(); + IL1 = IL0*half(); + std::size_t p = static_cast(1u) << k; + h *= half(); + K sum = 0; + Real absum = 0; + + for(std::size_t j = 1; j < p; j += 2) + { + K y = f(a + j*h); + sum += y; + absum += abs(y); + } + + I1 += sum*h; + IL1 += absum*h; + ++k; + error = abs(I0 - I1); + } + + if (error_estimate) + { + *error_estimate = error; + } + + if (L1) + { + *L1 = IL1; + } + + return static_cast(I1); +} + +template +auto trapezoidal(F f, Real a, Real b, Real tol = boost::math::tools::root_epsilon(), std::size_t max_refinements = 12, Real* error_estimate = nullptr, Real* L1 = nullptr)->decltype(std::declval()(std::declval())) +{ + return trapezoidal(f, a, b, tol, max_refinements, error_estimate, L1, boost::math::policies::policy<>()); +} + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/quadrature/wavelet_transforms.hpp b/libcxx/src/third-party/boost/math/quadrature/wavelet_transforms.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quadrature/wavelet_transforms.hpp @@ -0,0 +1,47 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_QUADRATURE_WAVELET_TRANSFORMS_HPP +#define BOOST_MATH_QUADRATURE_WAVELET_TRANSFORMS_HPP +#include +#include + +namespace boost::math::quadrature { + +template +class daubechies_wavelet_transform +{ +public: + daubechies_wavelet_transform(F f, int grid_refinements = -1, Real tol = 100*std::numeric_limits::epsilon(), + int max_refinements = 12) : f_{f}, psi_(grid_refinements), tol_{tol}, max_refinements_{max_refinements} + {} + + daubechies_wavelet_transform(F f, boost::math::daubechies_wavelet wavelet, Real tol = 100*std::numeric_limits::epsilon(), + int max_refinements = 12) : f_{f}, psi_{wavelet}, tol_{tol}, max_refinements_{max_refinements} + {} + + auto operator()(Real s, Real t)->decltype(std::declval()(std::declval())) const + { + using std::sqrt; + using std::abs; + using boost::math::quadrature::trapezoidal; + auto g = [&] (Real u) { + return f_(s*u+t)*psi_(u); + }; + auto [a,b] = psi_.support(); + return sqrt(abs(s))*trapezoidal(g, a, b, tol_, max_refinements_); + } + +private: + F f_; + boost::math::daubechies_wavelet psi_; + Real tol_; + int max_refinements_; +}; + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/quaternion.hpp b/libcxx/src/third-party/boost/math/quaternion.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/quaternion.hpp @@ -0,0 +1,1190 @@ +// boost quaternion.hpp header file + +// (C) Copyright Hubert Holin 2001. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_QUATERNION_HPP +#define BOOST_QUATERNION_HPP + +#include +#include +#include // for the "<<" operator + +#include +#include // for the "<<" and ">>" operators +#include // for the "<<" operator + +#include // for the Sinus cardinal +#include // for the Hyperbolic Sinus cardinal +#include + +#include + +namespace boost +{ + namespace math + { + + namespace detail { + + template + struct is_trivial_arithmetic_type_imp + { + typedef std::integral_constant() += std::declval()) + && noexcept(std::declval() -= std::declval()) + && noexcept(std::declval() *= std::declval()) + && noexcept(std::declval() /= std::declval()) + > type; + }; + + template + struct is_trivial_arithmetic_type : public is_trivial_arithmetic_type_imp::type {}; + } + +#ifndef BOOST_NO_CXX14_CONSTEXPR + namespace constexpr_detail + { + template + constexpr void swap(T& a, T& b) + { + T t(a); + a = b; + b = t; + } + } +#endif + + template + class quaternion + { + public: + + typedef T value_type; + + + // constructor for H seen as R^4 + // (also default constructor) + + constexpr explicit quaternion( T const & requested_a = T(), + T const & requested_b = T(), + T const & requested_c = T(), + T const & requested_d = T()) + : a(requested_a), + b(requested_b), + c(requested_c), + d(requested_d) + { + // nothing to do! + } + + + // constructor for H seen as C^2 + + constexpr explicit quaternion( ::std::complex const & z0, + ::std::complex const & z1 = ::std::complex()) + : a(z0.real()), + b(z0.imag()), + c(z1.real()), + d(z1.imag()) + { + // nothing to do! + } + + + // UNtemplated copy constructor + constexpr quaternion(quaternion const & a_recopier) + : a(a_recopier.R_component_1()), + b(a_recopier.R_component_2()), + c(a_recopier.R_component_3()), + d(a_recopier.R_component_4()) {} + + constexpr quaternion(quaternion && a_recopier) + : a(std::move(a_recopier.R_component_1())), + b(std::move(a_recopier.R_component_2())), + c(std::move(a_recopier.R_component_3())), + d(std::move(a_recopier.R_component_4())) {} + + // templated copy constructor + + template + constexpr explicit quaternion(quaternion const & a_recopier) + : a(static_cast(a_recopier.R_component_1())), + b(static_cast(a_recopier.R_component_2())), + c(static_cast(a_recopier.R_component_3())), + d(static_cast(a_recopier.R_component_4())) + { + // nothing to do! + } + + + // destructor + // (this is taken care of by the compiler itself) + + + // accessors + // + // Note: Like complex number, quaternions do have a meaningful notion of "real part", + // but unlike them there is no meaningful notion of "imaginary part". + // Instead there is an "unreal part" which itself is a quaternion, and usually + // nothing simpler (as opposed to the complex number case). + // However, for practicality, there are accessors for the other components + // (these are necessary for the templated copy constructor, for instance). + + constexpr T real() const + { + return(a); + } + + constexpr quaternion unreal() const + { + return(quaternion(static_cast(0), b, c, d)); + } + + constexpr T R_component_1() const + { + return(a); + } + + constexpr T R_component_2() const + { + return(b); + } + + constexpr T R_component_3() const + { + return(c); + } + + constexpr T R_component_4() const + { + return(d); + } + + constexpr ::std::complex C_component_1() const + { + return(::std::complex(a, b)); + } + + constexpr ::std::complex C_component_2() const + { + return(::std::complex(c, d)); + } + + BOOST_CXX14_CONSTEXPR void swap(quaternion& o) + { +#ifndef BOOST_NO_CXX14_CONSTEXPR + using constexpr_detail::swap; +#else + using std::swap; +#endif + swap(a, o.a); + swap(b, o.b); + swap(c, o.c); + swap(d, o.d); + } + + // assignment operators + + template + BOOST_CXX14_CONSTEXPR quaternion & operator = (quaternion const & a_affecter) + { + a = static_cast(a_affecter.R_component_1()); + b = static_cast(a_affecter.R_component_2()); + c = static_cast(a_affecter.R_component_3()); + d = static_cast(a_affecter.R_component_4()); + + return(*this); + } + + BOOST_CXX14_CONSTEXPR quaternion & operator = (quaternion const & a_affecter) + { + a = a_affecter.a; + b = a_affecter.b; + c = a_affecter.c; + d = a_affecter.d; + + return(*this); + } + + BOOST_CXX14_CONSTEXPR quaternion & operator = (quaternion && a_affecter) + { + a = std::move(a_affecter.a); + b = std::move(a_affecter.b); + c = std::move(a_affecter.c); + d = std::move(a_affecter.d); + + return(*this); + } + + BOOST_CXX14_CONSTEXPR quaternion & operator = (T const & a_affecter) + { + a = a_affecter; + + b = c = d = static_cast(0); + + return(*this); + } + + BOOST_CXX14_CONSTEXPR quaternion & operator = (::std::complex const & a_affecter) + { + a = a_affecter.real(); + b = a_affecter.imag(); + + c = d = static_cast(0); + + return(*this); + } + + // other assignment-related operators + // + // NOTE: Quaternion multiplication is *NOT* commutative; + // symbolically, "q *= rhs;" means "q = q * rhs;" + // and "q /= rhs;" means "q = q * inverse_of(rhs);" + // + // Note2: Each operator comes in 2 forms - one for the simple case where + // type T throws no exceptions, and one exception-safe version + // for the case where it might. + private: + BOOST_CXX14_CONSTEXPR quaternion & do_add(T const & rhs, const std::true_type&) + { + a += rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_add(T const & rhs, const std::false_type&) + { + quaternion result(a + rhs, b, c, d); // exception guard + swap(result); + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_add(std::complex const & rhs, const std::true_type&) + { + a += std::real(rhs); + b += std::imag(rhs); + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_add(std::complex const & rhs, const std::false_type&) + { + quaternion result(a + std::real(rhs), b + std::imag(rhs), c, d); // exception guard + swap(result); + return *this; + } + template + BOOST_CXX14_CONSTEXPR quaternion & do_add(quaternion const & rhs, const std::true_type&) + { + a += rhs.R_component_1(); + b += rhs.R_component_2(); + c += rhs.R_component_3(); + d += rhs.R_component_4(); + return *this; + } + template + BOOST_CXX14_CONSTEXPR quaternion & do_add(quaternion const & rhs, const std::false_type&) + { + quaternion result(a + rhs.R_component_1(), b + rhs.R_component_2(), c + rhs.R_component_3(), d + rhs.R_component_4()); // exception guard + swap(result); + return *this; + } + + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(T const & rhs, const std::true_type&) + { + a -= rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(T const & rhs, const std::false_type&) + { + quaternion result(a - rhs, b, c, d); // exception guard + swap(result); + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(std::complex const & rhs, const std::true_type&) + { + a -= std::real(rhs); + b -= std::imag(rhs); + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(std::complex const & rhs, const std::false_type&) + { + quaternion result(a - std::real(rhs), b - std::imag(rhs), c, d); // exception guard + swap(result); + return *this; + } + template + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(quaternion const & rhs, const std::true_type&) + { + a -= rhs.R_component_1(); + b -= rhs.R_component_2(); + c -= rhs.R_component_3(); + d -= rhs.R_component_4(); + return *this; + } + template + BOOST_CXX14_CONSTEXPR quaternion & do_subtract(quaternion const & rhs, const std::false_type&) + { + quaternion result(a - rhs.R_component_1(), b - rhs.R_component_2(), c - rhs.R_component_3(), d - rhs.R_component_4()); // exception guard + swap(result); + return *this; + } + + BOOST_CXX14_CONSTEXPR quaternion & do_multiply(T const & rhs, const std::true_type&) + { + a *= rhs; + b *= rhs; + c *= rhs; + d *= rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_multiply(T const & rhs, const std::false_type&) + { + quaternion result(a * rhs, b * rhs, c * rhs, d * rhs); // exception guard + swap(result); + return *this; + } + + BOOST_CXX14_CONSTEXPR quaternion & do_divide(T const & rhs, const std::true_type&) + { + a /= rhs; + b /= rhs; + c /= rhs; + d /= rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR quaternion & do_divide(T const & rhs, const std::false_type&) + { + quaternion result(a / rhs, b / rhs, c / rhs, d / rhs); // exception guard + swap(result); + return *this; + } + public: + + BOOST_CXX14_CONSTEXPR quaternion & operator += (T const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + BOOST_CXX14_CONSTEXPR quaternion & operator += (::std::complex const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + template BOOST_CXX14_CONSTEXPR quaternion & operator += (quaternion const & rhs) { return do_add(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_CXX14_CONSTEXPR quaternion & operator -= (T const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + BOOST_CXX14_CONSTEXPR quaternion & operator -= (::std::complex const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + template BOOST_CXX14_CONSTEXPR quaternion & operator -= (quaternion const & rhs) { return do_subtract(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_CXX14_CONSTEXPR quaternion & operator *= (T const & rhs) { return do_multiply(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_CXX14_CONSTEXPR quaternion & operator *= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + quaternion result(a*ar - b*br, a*br + b*ar, c*ar + d*br, -c*br+d*ar); + swap(result); + return(*this); + } + + template + BOOST_CXX14_CONSTEXPR quaternion & operator *= (quaternion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + + quaternion result(a*ar - b*br - c*cr - d*dr, a*br + b*ar + c*dr - d*cr, a*cr - b*dr + c*ar + d*br, a*dr + b*cr - c*br + d*ar); + swap(result); + return(*this); + } + + BOOST_CXX14_CONSTEXPR quaternion & operator /= (T const & rhs) { return do_divide(rhs, detail::is_trivial_arithmetic_type()); } + + BOOST_CXX14_CONSTEXPR quaternion & operator /= (::std::complex const & rhs) + { + T ar = rhs.real(); + T br = rhs.imag(); + T denominator = ar*ar+br*br; + quaternion result((+a*ar + b*br) / denominator, (-a*br + b*ar) / denominator, (+c*ar - d*br) / denominator, (+c*br + d*ar) / denominator); + swap(result); + return(*this); + } + + template + BOOST_CXX14_CONSTEXPR quaternion & operator /= (quaternion const & rhs) + { + T ar = static_cast(rhs.R_component_1()); + T br = static_cast(rhs.R_component_2()); + T cr = static_cast(rhs.R_component_3()); + T dr = static_cast(rhs.R_component_4()); + + T denominator = ar*ar+br*br+cr*cr+dr*dr; + quaternion result((+a*ar+b*br+c*cr+d*dr)/denominator, (-a*br+b*ar-c*dr+d*cr)/denominator, (-a*cr+b*dr+c*ar-d*br)/denominator, (-a*dr-b*cr+c*br+d*ar)/denominator); + swap(result); + return(*this); + } + private: + T a, b, c, d; + + }; + +// swap: +template +BOOST_CXX14_CONSTEXPR void swap(quaternion& a, quaternion& b) { a.swap(b); } + +// operator+ +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator + (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() + b), a.R_component_2(), a.R_component_3(), a.R_component_4()); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator + (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(b.R_component_1() + a), b.R_component_2(), b.R_component_3(), b.R_component_4()); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator + (const quaternion& a, const std::complex& b) +{ + return quaternion(a.R_component_1() + std::real(b), a.R_component_2() + std::imag(b), a.R_component_3(), a.R_component_4()); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator + (const std::complex& a, const quaternion& b) +{ + return quaternion(b.R_component_1() + std::real(a), b.R_component_2() + std::imag(a), b.R_component_3(), b.R_component_4()); +} +template +inline constexpr quaternion operator + (const quaternion& a, const quaternion& b) +{ + return quaternion(a.R_component_1() + b.R_component_1(), a.R_component_2() + b.R_component_2(), a.R_component_3() + b.R_component_3(), a.R_component_4() + b.R_component_4()); +} +// operator- +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator - (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() - b), a.R_component_2(), a.R_component_3(), a.R_component_4()); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator - (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(a - b.R_component_1()), -b.R_component_2(), -b.R_component_3(), -b.R_component_4()); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator - (const quaternion& a, const std::complex& b) +{ + return quaternion(a.R_component_1() - std::real(b), a.R_component_2() - std::imag(b), a.R_component_3(), a.R_component_4()); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator - (const std::complex& a, const quaternion& b) +{ + return quaternion(std::real(a) - b.R_component_1(), std::imag(a) - b.R_component_2(), -b.R_component_3(), -b.R_component_4()); +} +template +inline constexpr quaternion operator - (const quaternion& a, const quaternion& b) +{ + return quaternion(a.R_component_1() - b.R_component_1(), a.R_component_2() - b.R_component_2(), a.R_component_3() - b.R_component_3(), a.R_component_4() - b.R_component_4()); +} + +// operator* +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator * (const quaternion& a, const T2& b) +{ + return quaternion(static_cast(a.R_component_1() * b), a.R_component_2() * b, a.R_component_3() * b, a.R_component_4() * b); +} +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator * (const T1& a, const quaternion& b) +{ + return quaternion(static_cast(a * b.R_component_1()), a * b.R_component_2(), a * b.R_component_3(), a * b.R_component_4()); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator * (const quaternion& a, const std::complex& b) +{ + quaternion result(a); + result *= b; + return result; +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator * (const std::complex& a, const quaternion& b) +{ + quaternion result(a); + result *= b; + return result; +} +template +inline BOOST_CXX14_CONSTEXPR quaternion operator * (const quaternion& a, const quaternion& b) +{ + quaternion result(a); + result *= b; + return result; +} + +// operator/ +template +inline constexpr typename std::enable_if::value, quaternion >::type +operator / (const quaternion& a, const T2& b) +{ + return quaternion(a.R_component_1() / b, a.R_component_2() / b, a.R_component_3() / b, a.R_component_4() / b); +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const T1& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const quaternion& a, const std::complex& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_CXX14_CONSTEXPR typename std::enable_if::value, quaternion >::type +operator / (const std::complex& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} +template +inline BOOST_CXX14_CONSTEXPR quaternion operator / (const quaternion& a, const quaternion& b) +{ + quaternion result(a); + result /= b; + return result; +} + + + template + inline constexpr const quaternion& operator + (quaternion const & q) + { + return q; + } + + + template + inline constexpr quaternion operator - (quaternion const & q) + { + return(quaternion(-q.R_component_1(),-q.R_component_2(),-q.R_component_3(),-q.R_component_4())); + } + + + template + inline constexpr typename std::enable_if::value, bool>::type operator == (R const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs)&& + (rhs.R_component_2() == static_cast(0))&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0)) + ); + } + + + template + inline constexpr typename std::enable_if::value, bool>::type operator == (quaternion const & lhs, R const & rhs) + { + return rhs == lhs; + } + + + template + inline constexpr bool operator == (::std::complex const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs.real())&& + (rhs.R_component_2() == lhs.imag())&& + (rhs.R_component_3() == static_cast(0))&& + (rhs.R_component_4() == static_cast(0)) + ); + } + + + template + inline constexpr bool operator == (quaternion const & lhs, ::std::complex const & rhs) + { + return rhs == lhs; + } + + + template + inline constexpr bool operator == (quaternion const & lhs, quaternion const & rhs) + { + return ( + (rhs.R_component_1() == lhs.R_component_1())&& + (rhs.R_component_2() == lhs.R_component_2())&& + (rhs.R_component_3() == lhs.R_component_3())&& + (rhs.R_component_4() == lhs.R_component_4()) + ); + } + + template inline constexpr bool operator != (R const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, R const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (::std::complex const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, ::std::complex const & rhs) { return !(lhs == rhs); } + template inline constexpr bool operator != (quaternion const & lhs, quaternion const & rhs) { return !(lhs == rhs); } + + + // Note: we allow the following formats, with a, b, c, and d reals + // a + // (a), (a,b), (a,b,c), (a,b,c,d) + // (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b),(c,d)) + template + ::std::basic_istream & operator >> ( ::std::basic_istream & is, + quaternion & q) + { + const ::std::ctype & ct = ::std::use_facet< ::std::ctype >(is.getloc()); + + T a = T(); + T b = T(); + T c = T(); + T d = T(); + + ::std::complex u = ::std::complex(); + ::std::complex v = ::std::complex(); + + charT ch = charT(); + char cc; + + is >> ch; // get the first lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "(", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)), ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is >> ch; // get the second lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "((", possible: ((a)), ((a),c), ((a),(c)), ((a),(c,d)), ((a,b)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is.putback(ch); + + is >> u; // we extract the first and second components + a = u.real(); + b = u.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the next lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: ((a)) or ((a,b)) + { + q = quaternion(a,b); + } + else if (cc == ',') // read "((a)," or "((a,b),", possible: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)), ((a,b,),(c,d,)) + { + is >> v; // we extract the third and fourth components + c = v.real(); + d = v.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the last lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: ((a),c), ((a),(c)), ((a),(c,d)), ((a,b),c), ((a,b),(c)) or ((a,b,),(c,d,)) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a", possible: (a), (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + is >> ch; // get the third lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a) + { + q = quaternion(a); + } + else if (cc == ',') // read "(a,", possible: (a,b), (a,b,c), (a,b,c,d), (a,(c)), (a,(c,d)) + { + is >> ch; // get the fourth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == '(') // read "(a,(", possible: (a,(c)), (a,(c,d)) + { + is.putback(ch); + + is >> v; // we extract the third and fourth component + + c = v.real(); + d = v.imag(); + + if (!is.good()) goto finish; + + is >> ch; // get the ninth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,(c)) or (a,(c,d)) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // read "(a,b", possible: (a,b), (a,b,c), (a,b,c,d) + { + is.putback(ch); + + is >> b; // we extract the second component + + if (!is.good()) goto finish; + + is >> ch; // get the fifth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b) + { + q = quaternion(a,b); + } + else if (cc == ',') // read "(a,b,", possible: (a,b,c), (a,b,c,d) + { + is >> c; // we extract the third component + + if (!is.good()) goto finish; + + is >> ch; // get the seventh lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b,c) + { + q = quaternion(a,b,c); + } + else if (cc == ',') // read "(a,b,c,", possible: (a,b,c,d) + { + is >> d; // we extract the fourth component + + if (!is.good()) goto finish; + + is >> ch; // get the ninth lexeme + + if (!is.good()) goto finish; + + cc = ct.narrow(ch, char()); + + if (cc == ')') // format: (a,b,c,d) + { + q = quaternion(a,b,c,d); + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // error + { + is.setstate(::std::ios_base::failbit); + } + } + } + else // format: a + { + is.putback(ch); + + is >> a; // we extract the first component + + if (!is.good()) goto finish; + + q = quaternion(a); + } + + finish: + return(is); + } + + + template + ::std::basic_ostream & operator << ( ::std::basic_ostream & os, + quaternion const & q) + { + ::std::basic_ostringstream s; + + s.flags(os.flags()); + s.imbue(os.getloc()); + s.precision(os.precision()); + + s << '(' << q.R_component_1() << ',' + << q.R_component_2() << ',' + << q.R_component_3() << ',' + << q.R_component_4() << ')'; + + return os << s.str(); + } + + + // values + + template + inline constexpr T real(quaternion const & q) + { + return(q.real()); + } + + + template + inline constexpr quaternion unreal(quaternion const & q) + { + return(q.unreal()); + } + + template + inline T sup(quaternion const & q) + { + using ::std::abs; + return (std::max)((std::max)(abs(q.R_component_1()), abs(q.R_component_2())), (std::max)(abs(q.R_component_3()), abs(q.R_component_4()))); + } + + + template + inline T l1(quaternion const & q) + { + using ::std::abs; + return abs(q.R_component_1()) + abs(q.R_component_2()) + abs(q.R_component_3()) + abs(q.R_component_4()); + } + + + template + inline T abs(quaternion const & q) + { + using ::std::abs; + using ::std::sqrt; + + T maxim = sup(q); // overflow protection + + if (maxim == static_cast(0)) + { + return(maxim); + } + else + { + T mixam = static_cast(1)/maxim; // prefer multiplications over divisions + + T a = q.R_component_1() * mixam; + T b = q.R_component_2() * mixam; + T c = q.R_component_3() * mixam; + T d = q.R_component_4() * mixam; + + a *= a; + b *= b; + c *= c; + d *= d; + + return(maxim * sqrt(a + b + c + d)); + } + + //return(sqrt(norm(q))); + } + + + // Note: This is the Cayley norm, not the Euclidean norm... + + template + inline BOOST_CXX14_CONSTEXPR T norm(quaternionconst & q) + { + return(real(q*conj(q))); + } + + + template + inline constexpr quaternion conj(quaternion const & q) + { + return(quaternion( +q.R_component_1(), + -q.R_component_2(), + -q.R_component_3(), + -q.R_component_4())); + } + + + template + inline quaternion spherical( T const & rho, + T const & theta, + T const & phi1, + T const & phi2) + { + using ::std::cos; + using ::std::sin; + + //T a = cos(theta)*cos(phi1)*cos(phi2); + //T b = sin(theta)*cos(phi1)*cos(phi2); + //T c = sin(phi1)*cos(phi2); + //T d = sin(phi2); + + T courrant = static_cast(1); + + T d = sin(phi2); + + courrant *= cos(phi2); + + T c = sin(phi1)*courrant; + + courrant *= cos(phi1); + + T b = sin(theta)*courrant; + T a = cos(theta)*courrant; + + return(rho*quaternion(a,b,c,d)); + } + + + template + inline quaternion semipolar( T const & rho, + T const & alpha, + T const & theta1, + T const & theta2) + { + using ::std::cos; + using ::std::sin; + + T a = cos(alpha)*cos(theta1); + T b = cos(alpha)*sin(theta1); + T c = sin(alpha)*cos(theta2); + T d = sin(alpha)*sin(theta2); + + return(rho*quaternion(a,b,c,d)); + } + + + template + inline quaternion multipolar( T const & rho1, + T const & theta1, + T const & rho2, + T const & theta2) + { + using ::std::cos; + using ::std::sin; + + T a = rho1*cos(theta1); + T b = rho1*sin(theta1); + T c = rho2*cos(theta2); + T d = rho2*sin(theta2); + + return(quaternion(a,b,c,d)); + } + + + template + inline quaternion cylindrospherical( T const & t, + T const & radius, + T const & longitude, + T const & latitude) + { + using ::std::cos; + using ::std::sin; + + + + T b = radius*cos(longitude)*cos(latitude); + T c = radius*sin(longitude)*cos(latitude); + T d = radius*sin(latitude); + + return(quaternion(t,b,c,d)); + } + + + template + inline quaternion cylindrical(T const & r, + T const & angle, + T const & h1, + T const & h2) + { + using ::std::cos; + using ::std::sin; + + T a = r*cos(angle); + T b = r*sin(angle); + + return(quaternion(a,b,h1,h2)); + } + + + // transcendentals + // (please see the documentation) + + + template + inline quaternion exp(quaternion const & q) + { + using ::std::exp; + using ::std::cos; + + using ::boost::math::sinc_pi; + + T u = exp(real(q)); + + T z = abs(unreal(q)); + + T w = sinc_pi(z); + + return(u*quaternion(cos(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion cos(quaternion const & q) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(q)); + + T w = -sin(q.real())*sinhc_pi(z); + + return(quaternion(cos(q.real())*cosh(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion sin(quaternion const & q) + { + using ::std::sin; + using ::std::cos; + using ::std::cosh; + + using ::boost::math::sinhc_pi; + + T z = abs(unreal(q)); + + T w = +cos(q.real())*sinhc_pi(z); + + return(quaternion(sin(q.real())*cosh(z), + w*q.R_component_2(), w*q.R_component_3(), + w*q.R_component_4())); + } + + + template + inline quaternion tan(quaternion const & q) + { + return(sin(q)/cos(q)); + } + + + template + inline quaternion cosh(quaternion const & q) + { + return((exp(+q)+exp(-q))/static_cast(2)); + } + + + template + inline quaternion sinh(quaternion const & q) + { + return((exp(+q)-exp(-q))/static_cast(2)); + } + + + template + inline quaternion tanh(quaternion const & q) + { + return(sinh(q)/cosh(q)); + } + + + template + quaternion pow(quaternion const & q, + int n) + { + if (n > 1) + { + int m = n>>1; + + quaternion result = pow(q, m); + + result *= result; + + if (n != (m<<1)) + { + result *= q; // n odd + } + + return(result); + } + else if (n == 1) + { + return(q); + } + else if (n == 0) + { + return(quaternion(static_cast(1))); + } + else /* n < 0 */ + { + return(pow(quaternion(static_cast(1))/q,-n)); + } + } + } +} + +#endif /* BOOST_QUATERNION_HPP */ diff --git a/libcxx/src/third-party/boost/math/special_functions.hpp b/libcxx/src/third-party/boost/math/special_functions.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions.hpp @@ -0,0 +1,83 @@ +// Copyright John Maddock 2006, 2007, 2012, 2014. +// Copyright Paul A. Bristow 2006, 2007, 2012 + +// 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) + +// This file includes *all* the special functions. +// this may be useful if many are used +// - to avoid including each function individually. + +#ifndef BOOST_MATH_SPECIAL_FUNCTIONS_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/acosh.hpp b/libcxx/src/third-party/boost/math/special_functions/acosh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/acosh.hpp @@ -0,0 +1,104 @@ +// boost asinh.hpp header file + +// (C) Copyright Eric Ford 2001 & Hubert Holin. +// (C) Copyright John Maddock 2008. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ACOSH_HPP +#define BOOST_ACOSH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic cosine function. + +namespace boost +{ + namespace math + { + namespace detail + { + template + inline T acosh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + + if((x < 1) || (boost::math::isnan)(x)) + { + return policies::raise_domain_error( + "boost::math::acosh<%1%>(%1%)", + "acosh requires x >= 1, but got x = %1%.", x, pol); + } + else if ((x - 1) >= tools::root_epsilon()) + { + if (x > 1 / tools::root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/06/01/0001/ + // approximation by laurent series in 1/x at 0+ order from -1 to 0 + return log(x) + constants::ln_two(); + } + else if(x < 1.5f) + { + // This is just a rearrangement of the standard form below + // devised to minimise loss of precision when x ~ 1: + T y = x - 1; + return boost::math::log1p(y + sqrt(y * y + 2 * y), pol); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ + return( log( x + sqrt(x * x - 1) ) ); + } + } + else + { + // see http://functions.wolfram.com/ElementaryFunctions/ArcCosh/06/01/04/01/0001/ + T y = x - 1; + + // approximation by taylor series in y at 0 up to order 2 + T result = sqrt(2 * y) * (1 - y /12 + 3 * y * y / 160); + return result; + } + } + } + + template + inline typename tools::promote_args::type acosh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::acosh_imp(static_cast(x), forwarding_policy()), + "boost::math::acosh<%1%>(%1%)"); + } + template + inline typename tools::promote_args::type acosh(T x) + { + return boost::math::acosh(x, policies::policy<>()); + } + + } +} + +#endif /* BOOST_ACOSH_HPP */ + + diff --git a/libcxx/src/third-party/boost/math/special_functions/airy.hpp b/libcxx/src/third-party/boost/math/special_functions/airy.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/airy.hpp @@ -0,0 +1,469 @@ +// Copyright John Maddock 2012. +// 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_AIRY_HPP +#define BOOST_MATH_AIRY_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +T airy_ai_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T ai = sqrt(-x) * (j1 + j2) / 3; + //T bi = sqrt(-x / 3) * (j2 - j1); + return ai; + } + else if(fabs(x * x * x) / 6 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::twothirds(), pol); + T ai = 1 / (pow(T(3), constants::twothirds()) * tg); + //T bi = 1 / (sqrt(boost::math::cbrt(T(3))) * tg); + return ai; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(1) / 3; + //T j1 = boost::math::cyl_bessel_i(-v, p, pol); + //T j2 = boost::math::cyl_bessel_i(v, p, pol); + // + // Note that although we can calculate ai from j1 and j2, the accuracy is horrible + // as we're subtracting two very large values, so use the Bessel K relation instead: + // + T ai = cyl_bessel_k(v, p, pol) * sqrt(x / 3) / boost::math::constants::pi(); //sqrt(x) * (j1 - j2) / 3; + //T bi = sqrt(x / 3) * (j1 + j2); + return ai; + } +} + +template +T airy_bi_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + //T ai = sqrt(-x) * (j1 + j2) / 3; + T bi = sqrt(-x / 3) * (j2 - j1); + return bi; + } + else if(fabs(x * x * x) / 6 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::twothirds(), pol); + //T ai = 1 / (pow(T(3), constants::twothirds()) * tg); + T bi = 1 / (sqrt(boost::math::cbrt(T(3), pol)) * tg); + return bi; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(1) / 3; + T j1 = boost::math::cyl_bessel_i(-v, p, pol); + T j2 = boost::math::cyl_bessel_i(v, p, pol); + T bi = sqrt(x / 3) * (j1 + j2); + return bi; + } +} + +template +T airy_ai_prime_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T aip = -x * (j1 - j2) / 3; + return aip; + } + else if(fabs(x * x) / 2 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::third(), pol); + T aip = 1 / (boost::math::cbrt(T(3), pol) * tg); + return -aip; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(2) / 3; + //T j1 = boost::math::cyl_bessel_i(-v, p, pol); + //T j2 = boost::math::cyl_bessel_i(v, p, pol); + // + // Note that although we can calculate ai from j1 and j2, the accuracy is horrible + // as we're subtracting two very large values, so use the Bessel K relation instead: + // + T aip = -cyl_bessel_k(v, p, pol) * x / (boost::math::constants::root_three() * boost::math::constants::pi()); + return aip; + } +} + +template +T airy_bi_prime_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(x < 0) + { + T p = (-x * sqrt(-x) * 2) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_j(v, p, pol); + T j2 = boost::math::cyl_bessel_j(-v, p, pol); + T aip = -x * (j1 + j2) / constants::root_three(); + return aip; + } + else if(fabs(x * x) / 2 < tools::epsilon()) + { + T tg = boost::math::tgamma(constants::third(), pol); + T bip = sqrt(boost::math::cbrt(T(3), pol)) / tg; + return bip; + } + else + { + T p = 2 * x * sqrt(x) / 3; + T v = T(2) / 3; + T j1 = boost::math::cyl_bessel_i(-v, p, pol); + T j2 = boost::math::cyl_bessel_i(v, p, pol); + T aip = x * (j1 + j2) / boost::math::constants::root_three(); + return aip; + } +} + +template +T airy_ai_zero_imp(int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error("boost::math::airy_ai_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must be 1 or more !", static_cast(m), pol); + } + + // Handle case when the zero'th zero is requested. + if(m == 0U) + { + return policies::raise_domain_error("boost::math::airy_ai_zero<%1%>(%1%,%1%)", + "The requested rank of the zero is %1%, but must be 1 or more !", static_cast(m), pol); + } + + // Set up the initial guess for the upcoming root-finding. + const T guess_root = boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess(m, pol); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast(static_cast(policies::digits() * 0.301F)); + + const std::uintmax_t iterations_allowed = static_cast((std::max)(12, my_digits10 * 2)); + + std::uintmax_t iterations_used = iterations_allowed; + + // Use a dynamic tolerance because the roots get closer the higher m gets. + T tolerance; + + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T am = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::airy_zero::airy_ai_zero_detail::function_object_ai_and_ai_prime(pol), + guess_root, + T(guess_root - tolerance), + T(guess_root + tolerance), + policies::digits(), + iterations_used); + + static_cast(iterations_used); + + return am; +} + +template +T airy_bi_zero_imp(int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Handle cases when a negative zero (negative rank) is requested. + if(m < 0) + { + return policies::raise_domain_error("boost::math::airy_bi_zero<%1%>(%1%, int)", + "Requested the %1%'th zero, but the rank must 1 or more !", static_cast(m), pol); + } + + // Handle case when the zero'th zero is requested. + if(m == 0U) + { + return policies::raise_domain_error("boost::math::airy_bi_zero<%1%>(%1%,%1%)", + "The requested rank of the zero is %1%, but must be 1 or more !", static_cast(m), pol); + } + // Set up the initial guess for the upcoming root-finding. + const T guess_root = boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess(m, pol); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const int my_digits10 = static_cast(static_cast(policies::digits() * 0.301F)); + + const std::uintmax_t iterations_allowed = static_cast((std::max)(12, my_digits10 * 2)); + + std::uintmax_t iterations_used = iterations_allowed; + + // Use a dynamic tolerance because the roots get closer the higher m gets. + T tolerance; + + if (m <= 10) { tolerance = T(0.3F); } + else if(m <= 100) { tolerance = T(0.1F); } + else if(m <= 1000) { tolerance = T(0.05F); } + else { tolerance = T(1) / sqrt(T(m)); } + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T bm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::airy_zero::airy_bi_zero_detail::function_object_bi_and_bi_prime(pol), + guess_root, + T(guess_root - tolerance), + T(guess_root + tolerance), + policies::digits(), + iterations_used); + + static_cast(iterations_used); + + return bm; +} + +} // namespace detail + +template +inline typename tools::promote_args::type airy_ai(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_ai_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type airy_ai(T x) +{ + return airy_ai(x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type airy_bi(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_bi_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type airy_bi(T x) +{ + return airy_bi(x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type airy_ai_prime(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_ai_prime_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type airy_ai_prime(T x) +{ + return airy_ai_prime(x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type airy_bi_prime(T x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::airy_bi_prime_imp(static_cast(x), forwarding_policy()), "boost::math::airy<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type airy_bi_prime(T x) +{ + return airy_bi_prime(x, policies::policy<>()); +} + +template +inline T airy_ai_zero(int m, const Policy& /*pol*/) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::airy_ai_zero_imp(m, forwarding_policy()), "boost::math::airy_ai_zero<%1%>(unsigned)"); +} + +template +inline T airy_ai_zero(int m) +{ + return airy_ai_zero(m, policies::policy<>()); +} + +template +inline OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + typedef T result_type; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + for(unsigned i = 0; i < number_of_zeros; ++i) + { + *out_it = boost::math::airy_ai_zero(start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +inline OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return airy_ai_zero(start_index, number_of_zeros, out_it, policies::policy<>()); +} + +template +inline T airy_bi_zero(int m, const Policy& /*pol*/) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::airy_bi_zero_imp(m, forwarding_policy()), "boost::math::airy_bi_zero<%1%>(unsigned)"); +} + +template +inline T airy_bi_zero(int m) +{ + return airy_bi_zero(m, policies::policy<>()); +} + +template +inline OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + typedef T result_type; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Airy value type must be a floating-point type."); + + for(unsigned i = 0; i < number_of_zeros; ++i) + { + *out_it = boost::math::airy_bi_zero(start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +inline OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return airy_bi_zero(start_index, number_of_zeros, out_it, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_AIRY_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/asinh.hpp b/libcxx/src/third-party/boost/math/special_functions/asinh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/asinh.hpp @@ -0,0 +1,112 @@ +// boost asinh.hpp header file + +// (C) Copyright Eric Ford & Hubert Holin 2001. +// (C) Copyright John Maddock 2008. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ASINH_HPP +#define BOOST_ASINH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + + +#include +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic sine function. + +namespace boost +{ + namespace math + { + namespace detail{ + template + inline T asinh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + + if((boost::math::isnan)(x)) + { + return policies::raise_domain_error( + "boost::math::asinh<%1%>(%1%)", + "asinh requires a finite argument, but got x = %1%.", x, pol); + } + if (x >= tools::forth_root_epsilon()) + { + if (x > 1 / tools::root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/06/01/0001/ + // approximation by laurent series in 1/x at 0+ order from -1 to 1 + return constants::ln_two() + log(x) + 1/ (4 * x * x); + } + else if(x < 0.5f) + { + // As below, but rearranged to preserve digits: + return boost::math::log1p(x + boost::math::sqrt1pm1(x * x, pol), pol); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ + return( log( x + sqrt(x*x+1) ) ); + } + } + else if (x <= -tools::forth_root_epsilon()) + { + return(-asinh(-x, pol)); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/06/01/03/01/0001/ + // approximation by taylor series in x at 0 up to order 2 + T result = x; + + if (abs(x) >= tools::root_epsilon()) + { + T x3 = x*x*x; + + // approximation by taylor series in x at 0 up to order 4 + result -= x3/static_cast(6); + } + + return(result); + } + } + } + + template + inline typename tools::promote_args::type asinh(T x) + { + return boost::math::asinh(x, policies::policy<>()); + } + template + inline typename tools::promote_args::type asinh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::asinh_imp(static_cast(x), forwarding_policy()), + "boost::math::asinh<%1%>(%1%)"); + } + + } +} + +#endif /* BOOST_ASINH_HPP */ + diff --git a/libcxx/src/third-party/boost/math/special_functions/atanh.hpp b/libcxx/src/third-party/boost/math/special_functions/atanh.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/atanh.hpp @@ -0,0 +1,122 @@ +// boost atanh.hpp header file + +// (C) Copyright Hubert Holin 2001. +// (C) Copyright John Maddock 2008. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_ATANH_HPP +#define BOOST_ATANH_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// This is the inverse of the hyperbolic tangent function. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the main fare + + template + inline T atanh_imp(const T x, const Policy& pol) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::atanh<%1%>(%1%)"; + + if(x < -1) + { + return policies::raise_domain_error( + function, + "atanh requires x >= -1, but got x = %1%.", x, pol); + } + else if(x > 1) + { + return policies::raise_domain_error( + function, + "atanh requires x <= 1, but got x = %1%.", x, pol); + } + else if((boost::math::isnan)(x)) + { + return policies::raise_domain_error( + function, + "atanh requires -1 <= x <= 1, but got x = %1%.", x, pol); + } + else if(x < -1 + tools::epsilon()) + { + // -Infinity: + return -policies::raise_overflow_error(function, nullptr, pol); + } + else if(x > 1 - tools::epsilon()) + { + // Infinity: + return policies::raise_overflow_error(function, nullptr, pol); + } + else if(abs(x) >= tools::forth_root_epsilon()) + { + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ + if(abs(x) < 0.5f) + return (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2; + return(log( (1 + x) / (1 - x) ) / 2); + } + else + { + // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/06/01/03/01/ + // approximation by taylor series in x at 0 up to order 2 + T result = x; + + if (abs(x) >= tools::root_epsilon()) + { + T x3 = x*x*x; + + // approximation by taylor series in x at 0 up to order 4 + result += x3/static_cast(3); + } + + return(result); + } + } + } + + template + inline typename tools::promote_args::type atanh(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::atanh_imp(static_cast(x), forwarding_policy()), + "boost::math::atanh<%1%>(%1%)"); + } + template + inline typename tools::promote_args::type atanh(T x) + { + return boost::math::atanh(x, policies::policy<>()); + } + + } +} + +#endif /* BOOST_ATANH_HPP */ + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/bernoulli.hpp b/libcxx/src/third-party/boost/math/special_functions/bernoulli.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/bernoulli.hpp @@ -0,0 +1,149 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2013 John Maddock +// Copyright 2013 Paul Bristow +// Distributed under 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_BERNOULLI_B2N_2013_05_30_HPP_ +#define _BOOST_BERNOULLI_B2N_2013_05_30_HPP_ + +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + +template +OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const std::integral_constant& tag) +{ + for(std::size_t i = start; (i <= max_bernoulli_b2n::value) && (i < start + n); ++i) + { + *out = unchecked_bernoulli_imp(i, tag); + ++out; + } + + for(std::size_t i = (std::max)(static_cast(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + // We must overflow: + *out = (i & 1 ? 1 : -1) * policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(n)", nullptr, T(i), pol); + ++out; + } + return out; +} + +template +OutputIterator bernoulli_number_imp(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol, const std::integral_constant& tag) +{ + for(std::size_t i = start; (i <= max_bernoulli_b2n::value) && (i < start + n); ++i) + { + *out = unchecked_bernoulli_imp(i, tag); + ++out; + } + // + // Short circuit return so we don't grab the mutex below unless we have to: + // + if(start + n <= max_bernoulli_b2n::value) + { + return out; + } + + return get_bernoulli_numbers_cache().copy_bernoulli_numbers(out, start, n, pol); +} + +} // namespace detail + +template +inline T bernoulli_b2n(const int i, const Policy &pol) +{ + using tag_type = std::integral_constant::value>; + if(i < 0) + { + return policies::raise_domain_error("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol); + } + + T result {}; + boost::math::detail::bernoulli_number_imp(&result, static_cast(i), 1u, pol, tag_type()); + return result; +} + +template +inline T bernoulli_b2n(const int i) +{ + return boost::math::bernoulli_b2n(i, policies::policy<>()); +} + +template +inline OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol) +{ + using tag_type = std::integral_constant::value>; + if(start_index < 0) + { + *out_it = policies::raise_domain_error("boost::math::bernoulli_b2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol); + return ++out_it; + } + + return boost::math::detail::bernoulli_number_imp(out_it, start_index, number_of_bernoullis_b2n, pol, tag_type()); +} + +template +inline OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it) +{ + return boost::math::bernoulli_b2n(start_index, number_of_bernoullis_b2n, out_it, policies::policy<>()); +} + +template +inline T tangent_t2n(const int i, const Policy &pol) +{ + if(i < 0) + { + return policies::raise_domain_error("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(i), pol); + } + + T result {}; + boost::math::detail::get_bernoulli_numbers_cache().copy_tangent_numbers(&result, i, 1, pol); + return result; +} + +template +inline T tangent_t2n(const int i) +{ + return boost::math::tangent_t2n(i, policies::policy<>()); +} + +template +inline OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_tangent_t2n, + OutputIterator out_it, + const Policy& pol) +{ + if(start_index < 0) + { + *out_it = policies::raise_domain_error("boost::math::tangent_t2n<%1%>", "Index should be >= 0 but got %1%", T(start_index), pol); + return ++out_it; + } + + return boost::math::detail::get_bernoulli_numbers_cache().copy_tangent_numbers(out_it, start_index, number_of_tangent_t2n, pol); +} + +template +inline OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_tangent_t2n, + OutputIterator out_it) +{ + return boost::math::tangent_t2n(start_index, number_of_tangent_t2n, out_it, policies::policy<>()); +} + +} } // namespace boost::math + +#endif // _BOOST_BERNOULLI_B2N_2013_05_30_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/bessel.hpp b/libcxx/src/third-party/boost/math/special_functions/bessel.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/bessel.hpp @@ -0,0 +1,768 @@ +// Copyright (c) 2007, 2013 John Maddock +// Copyright Christopher Kormanyos 2013. +// 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) +// +// This header just defines the function entry points, and adds dispatch +// to the right implementation method. Most of the implementation details +// are in separate headers and copyright Xiaogang Zhang. +// +#ifndef BOOST_MATH_BESSEL_HPP +#define BOOST_MATH_BESSEL_HPP + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 6326) // potential comparison of a constant with another constant +#endif + +namespace boost{ namespace math{ + +namespace detail{ + +template +struct sph_bessel_j_small_z_series_term +{ + typedef T result_type; + + sph_bessel_j_small_z_series_term(unsigned v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + if(v + 3 > max_factorial::value) + { + term = v * log(mult) - boost::math::lgamma(v+1+T(0.5f), Policy()); + term = exp(term); + } + else + term = pow(mult, T(v)) / boost::math::tgamma(v+1+T(0.5f), Policy()); + mult *= -mult; + } + T operator()() + { + T r = term; + ++N; + term *= mult / (N * T(N + v + 0.5f)); + return r; + } +private: + unsigned N; + unsigned v; + T mult; + T term; +}; + +template +inline T sph_bessel_j_small_z_series(unsigned v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + sph_bessel_j_small_z_series_term s(v, x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::sph_bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return result * sqrt(constants::pi() / 4); +} + +template +T cyl_bessel_j_imp(T v, T x, const bessel_no_int_tag& t, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::bessel_j<%1%>(%1%,%1%)"; + if(x < 0) + { + // better have integer v: + if(floor(v) == v) + { + T r = cyl_bessel_j_imp(v, T(-x), t, pol); + if(iround(v, pol) & 1) + r = -r; + return r; + } + else + return policies::raise_domain_error( + function, + "Got x = %1%, but we need x >= 0", x, pol); + } + + T j, y; + bessel_jy(v, x, &j, &y, need_j, pol); + return j; +} + +template +inline T cyl_bessel_j_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names. + int ival = detail::iconv(v, pol); + // If v is an integer, use the integer recursion + // method, both that and Steeds method are O(v): + if((0 == v - ival)) + { + return bessel_jn(ival, x, pol); + } + return cyl_bessel_j_imp(v, x, bessel_no_int_tag(), pol); +} + +template +inline T cyl_bessel_j_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + return bessel_jn(v, x, pol); +} + +template +inline T sph_bessel_j_imp(unsigned n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + if(x < 0) + return policies::raise_domain_error( + "boost::math::sph_bessel_j<%1%>(%1%,%1%)", + "Got x = %1%, but function requires x > 0.", x, pol); + // + // Special case, n == 0 resolves down to the sinus cardinal of x: + // + if(n == 0) + return boost::math::sinc_pi(x, pol); + // + // Special case for x == 0: + // + if(x == 0) + return 0; + // + // When x is small we may end up with 0/0, use series evaluation + // instead, especially as it converges rapidly: + // + if(x < 1) + return sph_bessel_j_small_z_series(n, x, pol); + // + // Default case is just a naive evaluation of the definition: + // + return sqrt(constants::pi() / (2 * x)) + * cyl_bessel_j_imp(T(T(n)+T(0.5f)), x, bessel_no_int_tag(), pol); +} + +template +T cyl_bessel_i_imp(T v, T x, const Policy& pol) +{ + // + // This handles all the bessel I functions, note that we don't optimise + // for integer v, other than the v = 0 or 1 special cases, as Millers + // algorithm is at least as inefficient as the general case (the general + // case has better error handling too). + // + BOOST_MATH_STD_USING + if(x < 0) + { + // better have integer v: + if(floor(v) == v) + { + T r = cyl_bessel_i_imp(v, T(-x), pol); + if(iround(v, pol) & 1) + r = -r; + return r; + } + else + return policies::raise_domain_error( + "boost::math::cyl_bessel_i<%1%>(%1%,%1%)", + "Got x = %1%, but we need x >= 0", x, pol); + } + if(x == 0) + { + return (v == 0) ? static_cast(1) : static_cast(0); + } + if(v == 0.5f) + { + // common special case, note try and avoid overflow in exp(x): + if(x >= tools::log_max_value()) + { + T e = exp(x / 2); + return e * (e / sqrt(2 * x * constants::pi())); + } + return sqrt(2 / (x * constants::pi())) * sinh(x); + } + if((policies::digits() <= 113) && (std::numeric_limits::digits <= 113) && (std::numeric_limits::radix == 2)) + { + if(v == 0) + { + return bessel_i0(x); + } + if(v == 1) + { + return bessel_i1(x); + } + } + if((v > 0) && (x / v < 0.25)) + return bessel_i_small_z_series(v, x, pol); + T I, K; + bessel_ik(v, x, &I, &K, need_i, pol); + return I; +} + +template +inline T cyl_bessel_k_imp(T v, T x, const bessel_no_int_tag& /* t */, const Policy& pol) +{ + static const char* function = "boost::math::cyl_bessel_k<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + if(x < 0) + { + return policies::raise_domain_error( + function, + "Got x = %1%, but we need x > 0", x, pol); + } + if(x == 0) + { + return (v == 0) ? policies::raise_overflow_error(function, nullptr, pol) + : policies::raise_domain_error( + function, + "Got x = %1%, but we need x > 0", x, pol); + } + T I, K; + bessel_ik(v, x, &I, &K, need_k, pol); + return K; +} + +template +inline T cyl_bessel_k_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + if((floor(v) == v)) + { + return bessel_kn(itrunc(v), x, pol); + } + return cyl_bessel_k_imp(v, x, bessel_no_int_tag(), pol); +} + +template +inline T cyl_bessel_k_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + return bessel_kn(v, x, pol); +} + +template +inline T cyl_neumann_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol) +{ + static const char* function = "boost::math::cyl_neumann<%1%>(%1%,%1%)"; + + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + if(x <= 0) + { + return (v == 0) && (x == 0) ? + policies::raise_overflow_error(function, nullptr, pol) + : policies::raise_domain_error( + function, + "Got x = %1%, but result is complex for x <= 0", x, pol); + } + T j, y; + bessel_jy(v, x, &j, &y, need_y, pol); + // + // Post evaluation check for internal overflow during evaluation, + // can occur when x is small and v is large, in which case the result + // is -INF: + // + if(!(boost::math::isfinite)(y)) + return -policies::raise_overflow_error(function, nullptr, pol); + return y; +} + +template +inline T cyl_neumann_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + if(floor(v) == v) + { + T r = bessel_yn(itrunc(v, pol), x, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + return r; + } + T r = cyl_neumann_imp(v, x, bessel_no_int_tag(), pol); + BOOST_MATH_INSTRUMENT_VARIABLE(r); + return r; +} + +template +inline T cyl_neumann_imp(int v, T x, const bessel_int_tag&, const Policy& pol) +{ + return bessel_yn(v, x, pol); +} + +template +inline T sph_neumann_imp(unsigned v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + static const char* function = "boost::math::sph_neumann<%1%>(%1%,%1%)"; + // + // Nothing much to do here but check for errors, and + // evaluate the function's definition directly: + // + if(x < 0) + return policies::raise_domain_error( + function, + "Got x = %1%, but function requires x > 0.", x, pol); + + if(x < 2 * tools::min_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result = cyl_neumann_imp(T(T(v)+0.5f), x, bessel_no_int_tag(), pol); + T tx = sqrt(constants::pi() / (2 * x)); + + if((tx > 1) && (tools::max_value() / tx < result)) + return -policies::raise_overflow_error(function, nullptr, pol); + + return result * tx; +} + +template +inline T cyl_bessel_j_zero_imp(T v, int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + static const char* function = "boost::math::cyl_bessel_j_zero<%1%>(%1%, int)"; + + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + // Handle non-finite order. + if (!(boost::math::isfinite)(v) ) + { + return policies::raise_domain_error(function, "Order argument is %1%, but must be finite >= 0 !", v, pol); + } + + // Handle negative rank. + if(m < 0) + { + // Zeros of Jv(x) with negative rank are not defined and requesting one raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast(m), pol); + } + + // Get the absolute value of the order. + const bool order_is_negative = (v < 0); + const T vv((!order_is_negative) ? v : T(-v)); + + // Check if the order is very close to zero or very close to an integer. + const bool order_is_zero = (vv < half_epsilon); + const bool order_is_integer = ((vv - floor(vv)) < half_epsilon); + + if(m == 0) + { + if(order_is_zero) + { + // The zero'th zero of J0(x) is not defined and requesting it raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of J0, but the rank must be > 0 !", static_cast(m), pol); + } + + // The zero'th zero of Jv(x) for v < 0 is not defined + // unless the order is a negative integer. + if(order_is_negative && (!order_is_integer)) + { + // For non-integer, negative order, requesting the zero'th zero raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of Jv for negative, non-integer order, but the rank must be > 0 !", static_cast(m), pol); + } + + // The zero'th zero does exist and its value is zero. + return T(0); + } + + // Set up the initial guess for the upcoming root-finding. + // If the order is a negative integer, then use the corresponding + // positive integer for the order. + const T guess_root = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess((order_is_integer ? vv : v), m, pol); + + // Select the maximum allowed iterations from the policy. + std::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T jvm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv_and_jv_prime((order_is_integer ? vv : v), order_is_zero, pol), + guess_root, + T(guess_root - delta_lo), + T(guess_root + 0.2F), + policies::digits(), + number_of_iterations); + + if(number_of_iterations >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate root in a reasonable time:" + " Current best guess is %1%", jvm, Policy()); + } + + return jvm; +} + +template +inline T cyl_neumann_zero_imp(T v, int m, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + static const char* function = "boost::math::cyl_neumann_zero<%1%>(%1%, int)"; + + // Handle non-finite order. + if (!(boost::math::isfinite)(v) ) + { + return policies::raise_domain_error(function, "Order argument is %1%, but must be finite >= 0 !", v, pol); + } + + // Handle negative rank. + if(m < 0) + { + return policies::raise_domain_error(function, "Requested the %1%'th zero, but the rank must be positive !", static_cast(m), pol); + } + + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + // Get the absolute value of the order. + const bool order_is_negative = (v < 0); + const T vv((!order_is_negative) ? v : T(-v)); + + const bool order_is_integer = ((vv - floor(vv)) < half_epsilon); + + // For negative integers, use reflection to positive integer order. + if(order_is_negative && order_is_integer) + return boost::math::detail::cyl_neumann_zero_imp(vv, m, pol); + + // Check if the order is very close to a negative half-integer. + const T delta_half_integer(vv - (floor(vv) + 0.5F)); + + const bool order_is_negative_half_integer = + (order_is_negative && ((delta_half_integer > -half_epsilon) && (delta_half_integer < +half_epsilon))); + + // The zero'th zero of Yv(x) for v < 0 is not defined + // unless the order is a negative integer. + if((m == 0) && (!order_is_negative_half_integer)) + { + // For non-integer, negative order, requesting the zero'th zero raises a domain error. + return policies::raise_domain_error(function, "Requested the %1%'th zero of Yv for negative, non-half-integer order, but the rank must be > 0 !", static_cast(m), pol); + } + + // For negative half-integers, use the corresponding + // spherical Bessel function of positive half-integer order. + if(order_is_negative_half_integer) + return boost::math::detail::cyl_bessel_j_zero_imp(vv, m, pol); + + // Set up the initial guess for the upcoming root-finding. + // If the order is a negative integer, then use the corresponding + // positive integer for the order. + const T guess_root = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(v, m, pol); + + // Select the maximum allowed iterations from the policy. + std::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + const T delta_lo = ((guess_root > 0.2F) ? T(0.2) : T(guess_root / 2U)); + + // Perform the root-finding using Newton-Raphson iteration from Boost.Math. + const T yvm = + boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv_and_yv_prime(v, pol), + guess_root, + T(guess_root - delta_lo), + T(guess_root + 0.2F), + policies::digits(), + number_of_iterations); + + if(number_of_iterations >= policies::get_max_root_iterations()) + { + return policies::raise_evaluation_error(function, "Unable to locate root in a reasonable time:" + " Current best guess is %1%", yvm, Policy()); + } + + return yvm; +} + +} // namespace detail + +template +inline typename detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_j_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_j<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_j(T1 v, T2 x) +{ + return cyl_bessel_j(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_bessel(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_bessel_j_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_bessel<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_bessel(unsigned v, T x) +{ + return sph_bessel(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_i(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_i_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_i<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_i(T1 v, T2 x) +{ + return cyl_bessel_i(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_k(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag128 tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_k_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_bessel_k<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_k(T1 v, T2 x) +{ + return cyl_bessel_k(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_neumann(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_neumann_imp(v, static_cast(x), tag_type(), forwarding_policy()), "boost::math::cyl_neumann<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_neumann(T1 v, T2 x) +{ + return cyl_neumann(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_neumann(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_neumann_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_neumann<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_neumann(unsigned v, T x) +{ + return sph_neumann(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::cyl_bessel_j_zero_imp(v, m, forwarding_policy()), "boost::math::cyl_bessel_j_zero<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_j_zero(T v, int m) +{ + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return cyl_bessel_j_zero >(v, m, policies::policy<>()); +} + +template +inline OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + for(int i = 0; i < static_cast(number_of_zeros); ++i) + { + *out_it = boost::math::cyl_bessel_j_zero(v, start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +inline OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_neumann_zero(T v, int m, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return policies::checked_narrowing_cast(detail::cyl_neumann_zero_imp(v, m, forwarding_policy()), "boost::math::cyl_neumann_zero<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_neumann_zero(T v, int m) +{ + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + return cyl_neumann_zero >(v, m, policies::policy<>()); +} + +template +inline OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy& pol) +{ + static_assert( false == std::numeric_limits::is_specialized + || ( true == std::numeric_limits::is_specialized + && false == std::numeric_limits::is_integer), + "Order must be a floating-point type."); + + for(int i = 0; i < static_cast(number_of_zeros); ++i) + { + *out_it = boost::math::cyl_neumann_zero(v, start_index + i, pol); + ++out_it; + } + return out_it; +} + +template +inline OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it) +{ + return cyl_neumann_zero(v, start_index, number_of_zeros, out_it, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_HPP + + diff --git a/libcxx/src/third-party/boost/math/special_functions/bessel_iterators.hpp b/libcxx/src/third-party/boost/math/special_functions/bessel_iterators.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/bessel_iterators.hpp @@ -0,0 +1,186 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_BESSEL_ITERATORS_HPP +#define BOOST_MATH_BESSEL_ITERATORS_HPP + +#include + +namespace boost { + namespace math { + namespace detail { + + template + struct bessel_jy_recurrence + { + bessel_jy_recurrence(T v, T z) : v(v), z(z) {} + boost::math::tuple operator()(int k) + { + return boost::math::tuple(1, -2 * (v + k) / z, 1); + } + + T v, z; + }; + template + struct bessel_ik_recurrence + { + bessel_ik_recurrence(T v, T z) : v(v), z(z) {} + boost::math::tuple operator()(int k) + { + return boost::math::tuple(1, -2 * (v + k) / z, -1); + } + + T v, z; + }; + } // namespace detail + + template > + struct bessel_j_backwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_j_backwards_iterator(const T& v, const T& x) + : it(detail::bessel_jy_recurrence(v, x), boost::math::cyl_bessel_j(v, x, Policy())) + { + if(v < 0) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v) + : it(detail::bessel_jy_recurrence(v, x), J_v) + { + if(v < 0) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v_plus_1, const T& J_v) + : it(detail::bessel_jy_recurrence(v, x), J_v_plus_1, J_v) + { + if (v < -1) + boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_j_backwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_j_backwards_iterator operator++(int) + { + bessel_j_backwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::backward_recurrence_iterator< detail::bessel_jy_recurrence > it; + }; + + template > + struct bessel_i_backwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_i_backwards_iterator(const T& v, const T& x) + : it(detail::bessel_ik_recurrence(v, x), boost::math::cyl_bessel_i(v, x, Policy())) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v_plus_1, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v_plus_1, I_v) + { + if(v < -1) + boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy()); + } + + bessel_i_backwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_i_backwards_iterator operator++(int) + { + bessel_i_backwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::backward_recurrence_iterator< detail::bessel_ik_recurrence > it; + }; + + template > + struct bessel_i_forwards_iterator + { + typedef std::ptrdiff_t difference_type; + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef std::input_iterator_tag iterator_category; + + bessel_i_forwards_iterator(const T& v, const T& x) + : it(detail::bessel_ik_recurrence(v, x), boost::math::cyl_bessel_i(v, x, Policy())) + { + if(v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v) + { + if (v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v_plus_1, const T& I_v) + : it(detail::bessel_ik_recurrence(v, x), I_v_plus_1, I_v) + { + if (v > 1) + boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy()); + } + + bessel_i_forwards_iterator& operator++() + { + ++it; + return *this; + } + + bessel_i_forwards_iterator operator++(int) + { + bessel_i_forwards_iterator t(*this); + ++(*this); + return t; + } + + T operator*() { return *it; } + + private: + boost::math::tools::forward_recurrence_iterator< detail::bessel_ik_recurrence > it; + }; + + } +} // namespaces + +#endif // BOOST_MATH_BESSEL_ITERATORS_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/bessel_prime.hpp b/libcxx/src/third-party/boost/math/special_functions/bessel_prime.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/bessel_prime.hpp @@ -0,0 +1,359 @@ +// Copyright (c) 2013 Anton Bikineev +// 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_BESSEL_DERIVATIVES_HPP +#define BOOST_MATH_BESSEL_DERIVATIVES_HPP + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +inline T cyl_bessel_j_prime_imp(T v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::cyl_bessel_j_prime<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + // + // Prevent complex result: + // + if (x < 0 && floor(v) != v) + return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function requires x >= 0", x, pol); + // + // Special cases for x == 0: + // + if (x == 0) + { + if (v == 1) + return 0.5; + else if (v == -1) + return -0.5; + else if (floor(v) == v || v > 1) + return 0; + else return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function is indeterminate for this order", x, pol); + } + // + // Special case for large x: use asymptotic expansion: + // + if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x)) + return boost::math::detail::asymptotic_bessel_j_derivative_large_x_2(v, x, pol); + // + // Special case for small x: use Taylor series: + // + if ((abs(x) < 5) || (abs(v) > x * x / 4)) + { + bool inversed = false; + if (floor(v) == v && v < 0) + { + v = -v; + if (itrunc(v, pol) & 1) + inversed = true; + } + T r = boost::math::detail::bessel_j_derivative_small_z_series(v, x, pol); + return inversed ? T(-r) : r; + } + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_bessel_j_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_j_derivative_linear(v, x, Tag(), pol); +} + +template +inline T sph_bessel_j_prime_imp(unsigned v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::sph_bessel_prime<%1%>(%1%,%1%)"; + // + // Prevent complex result: + // + if (x < 0) + return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function requires x >= 0.", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return (x == 0) ? boost::math::policies::raise_overflow_error(function, nullptr, pol) + : static_cast(-boost::math::detail::sph_bessel_j_imp(1, x, pol)); + // + // Special case for x == 0 and v > 0: + // + if (x == 0) + return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function is indeterminate for this order", x, pol); + // + // Default case: + // + return boost::math::detail::sph_bessel_j_derivative_linear(v, x, pol); +} + +template +inline T cyl_bessel_i_prime_imp(T v, T x, const Policy& pol) +{ + static const char* const function = "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)"; + BOOST_MATH_STD_USING + // + // Prevent complex result: + // + if (x < 0 && floor(v) != v) + return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function requires x >= 0", x, pol); + // + // Special cases for x == 0: + // + if (x == 0) + { + if (v == 1 || v == -1) + return 0.5; + else if (floor(v) == v || v > 1) + return 0; + else return boost::math::policies::raise_domain_error( + function, + "Got x = %1%, but function is indeterminate for this order", x, pol); + } + // + // Special case for v == 0: + // + if (v == 0) + return boost::math::detail::cyl_bessel_i_imp(1, x, pol); + // + // Default case: + // + return boost::math::detail::bessel_i_derivative_linear(v, x, pol); +} + +template +inline T cyl_bessel_k_prime_imp(T v, T x, const Policy& pol) +{ + // + // Prevent complex and indeterminate results: + // + if (x <= 0) + return boost::math::policies::raise_domain_error( + "boost::math::cyl_bessel_k_prime<%1%>(%1%,%1%)", + "Got x = %1%, but function requires x > 0", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_bessel_k_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_k_derivative_linear(v, x, Tag(), pol); +} + +template +inline T cyl_neumann_prime_imp(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Prevent complex and indeterminate results: + // + if (x <= 0) + return boost::math::policies::raise_domain_error( + "boost::math::cyl_neumann_prime<%1%>(%1%,%1%)", + "Got x = %1%, but function requires x > 0", x, pol); + // + // Special case for large x: use asymptotic expansion: + // + if (boost::math::detail::asymptotic_bessel_derivative_large_x_limit(v, x)) + return boost::math::detail::asymptotic_bessel_y_derivative_large_x_2(v, x, pol); + // + // Special case for small x: use Taylor series: + // + if (v > 0 && floor(v) != v) + { + const T eps = boost::math::policies::get_epsilon(); + if (log(eps / 2) > v * log((x * x) / (v * 4))) + return boost::math::detail::bessel_y_derivative_small_z_series(v, x, pol); + } + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::cyl_neumann_imp(1, x, Tag(), pol); + // + // Default case: + // + return boost::math::detail::bessel_y_derivative_linear(v, x, Tag(), pol); +} + +template +inline T sph_neumann_prime_imp(unsigned v, T x, const Policy& pol) +{ + // + // Prevent complex and indeterminate result: + // + if (x <= 0) + return boost::math::policies::raise_domain_error( + "boost::math::sph_neumann_prime<%1%>(%1%,%1%)", + "Got x = %1%, but function requires x > 0.", x, pol); + // + // Special case for v == 0: + // + if (v == 0) + return -boost::math::detail::sph_neumann_imp(1, x, pol); + // + // Default case: + // + return boost::math::detail::sph_neumann_derivative_linear(v, x, pol); +} + +} // namespace detail + +template +inline typename detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_j_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_j_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_j_prime(T1 v, T2 x) +{ + return cyl_bessel_j_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_bessel_j_prime_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_bessel_j_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_bessel_prime(unsigned v, T x) +{ + return sph_bessel_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_i_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_i_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_i_prime(T1 v, T2 x) +{ + return cyl_bessel_i_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_bessel_k_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_bessel_k_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_bessel_k_prime(T1 v, T2 x) +{ + return cyl_bessel_k_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::cyl_neumann_prime_imp(static_cast(v), static_cast(x), forwarding_policy()), "boost::math::cyl_neumann_prime<%1%,%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type cyl_neumann_prime(T1 v, T2 x) +{ + return cyl_neumann_prime(v, x, policies::policy<>()); +} + +template +inline typename detail::bessel_traits::result_type sph_neumann_prime(unsigned v, T x, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::sph_neumann_prime_imp(v, static_cast(x), forwarding_policy()), "boost::math::sph_neumann_prime<%1%>(%1%,%1%)"); +} + +template +inline typename detail::bessel_traits >::result_type sph_neumann_prime(unsigned v, T x) +{ + return sph_neumann_prime(v, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_BESSEL_DERIVATIVES_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/beta.hpp b/libcxx/src/third-party/boost/math/special_functions/beta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/beta.hpp @@ -0,0 +1,1604 @@ +// (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_BETA_HPP +#define BOOST_MATH_SPECIAL_BETA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +// +// Implementation of Beta(a,b) using the Lanczos approximation: +// +template +T beta_imp(T a, T b, const Lanczos&, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std names + + if(a <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol); + + T result; + + T prefix = 1; + T c = a + b; + + // Special cases: + if((c == a) && (b < tools::epsilon())) + return 1 / b; + else if((c == b) && (a < tools::epsilon())) + return 1 / a; + if(b == 1) + return 1/a; + else if(a == 1) + return 1/b; + else if(c < tools::epsilon()) + { + result = c / a; + result /= b; + return result; + } + + /* + // + // This code appears to be no longer necessary: it was + // used to offset errors introduced from the Lanczos + // approximation, but the current Lanczos approximations + // are sufficiently accurate for all z that we can ditch + // this. It remains in the file for future reference... + // + // If a or b are less than 1, shift to greater than 1: + if(a < 1) + { + prefix *= c / a; + c += 1; + a += 1; + } + if(b < 1) + { + prefix *= c / b; + c += 1; + b += 1; + } + */ + + if(a < b) + std::swap(a, b); + + // Lanczos calculation: + T agh = static_cast(a + Lanczos::g() - 0.5f); + T bgh = static_cast(b + Lanczos::g() - 0.5f); + T cgh = static_cast(c + Lanczos::g() - 0.5f); + result = Lanczos::lanczos_sum_expG_scaled(a) * (Lanczos::lanczos_sum_expG_scaled(b) / Lanczos::lanczos_sum_expG_scaled(c)); + T ambh = a - 0.5f - b; + if((fabs(b * ambh) < (cgh * 100)) && (a > 100)) + { + // Special case where the base of the power term is close to 1 + // compute (1+x)^y instead: + result *= exp(ambh * boost::math::log1p(-b / cgh, pol)); + } + else + { + result *= pow(agh / cgh, a - T(0.5) - b); + } + if(cgh > 1e10f) + // this avoids possible overflow, but appears to be marginally less accurate: + result *= pow((agh / cgh) * (bgh / cgh), b); + else + result *= pow((agh * bgh) / (cgh * cgh), b); + result *= sqrt(boost::math::constants::e() / bgh); + + // If a and b were originally less than 1 we need to scale the result: + result *= prefix; + + return result; +} // template beta_imp(T a, T b, const Lanczos&) + +// +// Generic implementation of Beta(a,b) without Lanczos approximation support +// (Caution this is slow!!!): +// +template +T beta_imp(T a, T b, const lanczos::undefined_lanczos& l, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(a <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error("boost::math::beta<%1%>(%1%,%1%)", "The arguments to the beta function must be greater than zero (got b=%1%).", b, pol); + + const T c = a + b; + + // Special cases: + if ((c == a) && (b < tools::epsilon())) + return 1 / b; + else if ((c == b) && (a < tools::epsilon())) + return 1 / a; + if (b == 1) + return 1 / a; + else if (a == 1) + return 1 / b; + else if (c < tools::epsilon()) + { + T result = c / a; + result /= b; + return result; + } + + // Regular cases start here: + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if(a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if(b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + long shift_c = shift_a + shift_b; + + if ((shift_a == 0) && (shift_b == 0)) + { + return pow(a / c, a) * pow(b / c, b) * scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol) / scaled_tgamma_no_lanczos(c, pol); + } + else if ((a < 1) && (b < 1)) + { + return boost::math::tgamma(a, pol) * (boost::math::tgamma(b, pol) / boost::math::tgamma(c)); + } + else if(a < 1) + return boost::math::tgamma(a, pol) * boost::math::tgamma_delta_ratio(b, a, pol); + else if(b < 1) + return boost::math::tgamma(b, pol) * boost::math::tgamma_delta_ratio(a, b, pol); + else + { + T result = beta_imp(T(a + shift_a), T(b + shift_b), l, pol); + // + // Recursion: + // + for (long i = 0; i < shift_c; ++i) + { + result *= c + i; + if (i < shift_a) + result /= a + i; + if (i < shift_b) + result /= b + i; + } + return result; + } + +} // template T beta_imp(T a, T b, const lanczos::undefined_lanczos& l) + + +// +// Compute the leading power terms in the incomplete Beta: +// +// (x^a)(y^b)/Beta(a,b) when normalised, and +// (x^a)(y^b) otherwise. +// +// Almost all of the error in the incomplete beta comes from this +// function: particularly when a and b are large. Computing large +// powers are *hard* though, and using logarithms just leads to +// horrendous cancellation errors. +// +template +T ibeta_power_terms(T a, + T b, + T x, + T y, + const Lanczos&, + bool normalised, + const Policy& pol, + T prefix = 1, + const char* function = "boost::math::ibeta<%1%>(%1%, %1%, %1%)") +{ + BOOST_MATH_STD_USING + + if(!normalised) + { + // can we do better here? + return pow(x, a) * pow(y, b); + } + + T result; + + T c = a + b; + + // combine power terms with Lanczos approximation: + T agh = static_cast(a + Lanczos::g() - 0.5f); + T bgh = static_cast(b + Lanczos::g() - 0.5f); + T cgh = static_cast(c + Lanczos::g() - 0.5f); + result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b)); + result *= prefix; + // combine with the leftover terms from the Lanczos approximation: + result *= sqrt(bgh / boost::math::constants::e()); + result *= sqrt(agh / cgh); + + // l1 and l2 are the base of the exponents minus one: + T l1 = (x * b - y * agh) / agh; + T l2 = (y * a - x * bgh) / bgh; + if(((std::min)(fabs(l1), fabs(l2)) < 0.2)) + { + // when the base of the exponent is very near 1 we get really + // gross errors unless extra care is taken: + if((l1 * l2 > 0) || ((std::min)(a, b) < 1)) + { + // + // This first branch handles the simple cases where either: + // + // * The two power terms both go in the same direction + // (towards zero or towards infinity). In this case if either + // term overflows or underflows, then the product of the two must + // do so also. + // *Alternatively if one exponent is less than one, then we + // can't productively use it to eliminate overflow or underflow + // from the other term. Problems with spurious overflow/underflow + // can't be ruled out in this case, but it is *very* unlikely + // since one of the power terms will evaluate to a number close to 1. + // + if(fabs(l1) < 0.1) + { + result *= exp(a * boost::math::log1p(l1, pol)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + result *= pow((x * cgh) / agh, a); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + if(fabs(l2) < 0.1) + { + result *= exp(b * boost::math::log1p(l2, pol)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + result *= pow((y * cgh) / bgh, b); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else if((std::max)(fabs(l1), fabs(l2)) < 0.5) + { + // + // Both exponents are near one and both the exponents are + // greater than one and further these two + // power terms tend in opposite directions (one towards zero, + // the other towards infinity), so we have to combine the terms + // to avoid any risk of overflow or underflow. + // + // We do this by moving one power term inside the other, we have: + // + // (1 + l1)^a * (1 + l2)^b + // = ((1 + l1)*(1 + l2)^(b/a))^a + // = (1 + l1 + l3 + l1*l3)^a ; l3 = (1 + l2)^(b/a) - 1 + // = exp((b/a) * log(1 + l2)) - 1 + // + // The tricky bit is deciding which term to move inside :-) + // By preference we move the larger term inside, so that the + // size of the largest exponent is reduced. However, that can + // only be done as long as l3 (see above) is also small. + // + bool small_a = a < b; + T ratio = b / a; + if((small_a && (ratio * l2 < 0.1)) || (!small_a && (l1 / ratio > 0.1))) + { + T l3 = boost::math::expm1(ratio * boost::math::log1p(l2, pol), pol); + l3 = l1 + l3 + l3 * l1; + l3 = a * boost::math::log1p(l3, pol); + result *= exp(l3); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + T l3 = boost::math::expm1(boost::math::log1p(l1, pol) / ratio, pol); + l3 = l2 + l3 + l3 * l2; + l3 = b * boost::math::log1p(l3, pol); + result *= exp(l3); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else if(fabs(l1) < fabs(l2)) + { + // First base near 1 only: + T l = a * boost::math::log1p(l1, pol) + + b * log((y * cgh) / bgh); + if((l <= tools::log_min_value()) || (l >= tools::log_max_value())) + { + l += log(result); + if(l >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + result = exp(l); + } + else + result *= exp(l); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // Second base near 1 only: + T l = b * boost::math::log1p(l2, pol) + + a * log((x * cgh) / agh); + if((l <= tools::log_min_value()) || (l >= tools::log_max_value())) + { + l += log(result); + if(l >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + result = exp(l); + } + else + result *= exp(l); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + else + { + // general case: + T b1 = (x * cgh) / agh; + T b2 = (y * cgh) / bgh; + l1 = a * log(b1); + l2 = b * log(b2); + BOOST_MATH_INSTRUMENT_VARIABLE(b1); + BOOST_MATH_INSTRUMENT_VARIABLE(b2); + BOOST_MATH_INSTRUMENT_VARIABLE(l1); + BOOST_MATH_INSTRUMENT_VARIABLE(l2); + if((l1 >= tools::log_max_value()) + || (l1 <= tools::log_min_value()) + || (l2 >= tools::log_max_value()) + || (l2 <= tools::log_min_value()) + ) + { + // Oops, under/overflow, sidestep if we can: + if(a < b) + { + T p1 = pow(b2, b / a); + T l3 = a * (log(b1) + log(p1)); + if((l3 < tools::log_max_value()) + && (l3 > tools::log_min_value())) + { + result *= pow(p1 * b1, a); + } + else + { + l2 += l1 + log(result); + if(l2 >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + result = exp(l2); + } + } + else + { + T p1 = pow(b1, a / b); + T l3 = (p1 != 0) && (b2 != 0) ? (log(p1) + log(b2)) * b : tools::max_value(); // arbitrary large value if the logs would fail! + if((l3 < tools::log_max_value()) + && (l3 > tools::log_min_value())) + { + result *= pow(p1 * b2, b); + } + else + { + l2 += l1 + log(result); + if(l2 >= tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + result = exp(l2); + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // finally the normal case: + result *= pow(b1, a) * pow(b2, b); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + + if (0 == result) + { + if ((a > 1) && (x == 0)) + return result; // true zero + if ((b > 1) && (y == 0)) + return result; // true zero + return boost::math::policies::raise_underflow_error(function, nullptr, pol); + } + + return result; +} +// +// Compute the leading power terms in the incomplete Beta: +// +// (x^a)(y^b)/Beta(a,b) when normalised, and +// (x^a)(y^b) otherwise. +// +// Almost all of the error in the incomplete beta comes from this +// function: particularly when a and b are large. Computing large +// powers are *hard* though, and using logarithms just leads to +// horrendous cancellation errors. +// +// This version is generic, slow, and does not use the Lanczos approximation. +// +template +T ibeta_power_terms(T a, + T b, + T x, + T y, + const boost::math::lanczos::undefined_lanczos& l, + bool normalised, + const Policy& pol, + T prefix = 1, + const char* = "boost::math::ibeta<%1%>(%1%, %1%, %1%)") +{ + BOOST_MATH_STD_USING + + if(!normalised) + { + return prefix * pow(x, a) * pow(y, b); + } + + T c = a + b; + + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if (a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if (b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + + if ((shift_a == 0) && (shift_b == 0)) + { + T power1, power2; + if (a < b) + { + power1 = pow((x * y * c * c) / (a * b), a); + power2 = pow((y * c) / b, b - a); + } + else + { + power1 = pow((x * y * c * c) / (a * b), b); + power2 = pow((x * c) / a, a - b); + } + if (!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2)) + { + // We have to use logs :( + return prefix * exp(a * log(x * c / a) + b * log(y * c / b)) * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol)); + } + return prefix * power1 * power2 * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol)); + } + + T power1 = pow(x, a); + T power2 = pow(y, b); + T bet = beta_imp(a, b, l, pol); + + if(!(boost::math::isnormal)(power1) || !(boost::math::isnormal)(power2) || !(boost::math::isnormal)(bet)) + { + int shift_c = shift_a + shift_b; + T result = ibeta_power_terms(T(a + shift_a), T(b + shift_b), x, y, l, normalised, pol, prefix); + if ((boost::math::isnormal)(result)) + { + for (int i = 0; i < shift_c; ++i) + { + result /= c + i; + if (i < shift_a) + { + result *= a + i; + result /= x; + } + if (i < shift_b) + { + result *= b + i; + result /= y; + } + } + return prefix * result; + } + else + { + T log_result = log(x) * a + log(y) * b + log(prefix); + if ((boost::math::isnormal)(bet)) + log_result -= log(bet); + else + log_result += boost::math::lgamma(c, pol) - boost::math::lgamma(a, pol) - boost::math::lgamma(b, pol); + return exp(log_result); + } + } + return prefix * power1 * (power2 / bet); +} +// +// Series approximation to the incomplete beta: +// +template +struct ibeta_series_t +{ + typedef T result_type; + ibeta_series_t(T a_, T b_, T x_, T mult) : result(mult), x(x_), apn(a_), poch(1-b_), n(1) {} + T operator()() + { + T r = result / apn; + apn += 1; + result *= poch * x / n; + ++n; + poch += 1; + return r; + } +private: + T result, x, apn, poch; + int n; +}; + +template +T ibeta_series(T a, T b, T x, T s0, const Lanczos&, bool normalised, T* p_derivative, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T result; + + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(normalised) + { + T c = a + b; + + // incomplete beta power term, combined with the Lanczos approximation: + T agh = static_cast(a + Lanczos::g() - 0.5f); + T bgh = static_cast(b + Lanczos::g() - 0.5f); + T cgh = static_cast(c + Lanczos::g() - 0.5f); + result = Lanczos::lanczos_sum_expG_scaled(c) / (Lanczos::lanczos_sum_expG_scaled(a) * Lanczos::lanczos_sum_expG_scaled(b)); + + T l1 = log(cgh / bgh) * (b - 0.5f); + T l2 = log(x * cgh / agh) * a; + // + // Check for over/underflow in the power terms: + // + if((l1 > tools::log_min_value()) + && (l1 < tools::log_max_value()) + && (l2 > tools::log_min_value()) + && (l2 < tools::log_max_value())) + { + if(a * b < bgh * 10) + result *= exp((b - 0.5f) * boost::math::log1p(a / bgh, pol)); + else + result *= pow(cgh / bgh, b - 0.5f); + result *= pow(x * cgh / agh, a); + result *= sqrt(agh / boost::math::constants::e()); + + if(p_derivative) + { + *p_derivative = result * pow(y, b); + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + } + else + { + // + // Oh dear, we need logs, and this *will* cancel: + // + result = log(result) + l1 + l2 + (log(agh) - 1) / 2; + if(p_derivative) + *p_derivative = exp(result + b * log(y)); + result = exp(result); + } + } + else + { + // Non-normalised, just compute the power: + result = pow(x, a); + } + if(result < tools::min_value()) + return s0; // Safeguard: series can't cope with denorms. + ibeta_series_t s(a, b, x, result); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, s0); + policies::check_series_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (with lanczos)", max_iter, pol); + return result; +} +// +// Incomplete Beta series again, this time without Lanczos support: +// +template +T ibeta_series(T a, T b, T x, T s0, const boost::math::lanczos::undefined_lanczos& l, bool normalised, T* p_derivative, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T result; + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(normalised) + { + const T min_sterling = minimum_argument_for_bernoulli_recursion(); + + long shift_a = 0; + long shift_b = 0; + + if (a < min_sterling) + shift_a = 1 + ltrunc(min_sterling - a); + if (b < min_sterling) + shift_b = 1 + ltrunc(min_sterling - b); + + T c = a + b; + + if ((shift_a == 0) && (shift_b == 0)) + { + result = pow(x * c / a, a) * pow(c / b, b) * scaled_tgamma_no_lanczos(c, pol) / (scaled_tgamma_no_lanczos(a, pol) * scaled_tgamma_no_lanczos(b, pol)); + } + else if ((a < 1) && (b > 1)) + result = pow(x, a) / (boost::math::tgamma(a, pol) * boost::math::tgamma_delta_ratio(b, a, pol)); + else + { + T power = pow(x, a); + T bet = beta_imp(a, b, l, pol); + if (!(boost::math::isnormal)(power) || !(boost::math::isnormal)(bet)) + { + result = exp(a * log(x) + boost::math::lgamma(c, pol) - boost::math::lgamma(a, pol) - boost::math::lgamma(b, pol)); + } + else + result = power / bet; + } + if(p_derivative) + { + *p_derivative = result * pow(y, b); + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + } + else + { + // Non-normalised, just compute the power: + result = pow(x, a); + } + if(result < tools::min_value()) + return s0; // Safeguard: series can't cope with denorms. + ibeta_series_t s(a, b, x, result); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, s0); + policies::check_series_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%) in ibeta_series (without lanczos)", max_iter, pol); + return result; +} + +// +// Continued fraction for the incomplete beta: +// +template +struct ibeta_fraction2_t +{ + typedef std::pair result_type; + + ibeta_fraction2_t(T a_, T b_, T x_, T y_) : a(a_), b(b_), x(x_), y(y_), m(0) {} + + result_type operator()() + { + T aN = (a + m - 1) * (a + b + m - 1) * m * (b - m) * x * x; + T denom = (a + 2 * m - 1); + aN /= denom * denom; + + T bN = static_cast(m); + bN += (m * (b - m) * x) / (a + 2*m - 1); + bN += ((a + m) * (a * y - b * x + 1 + m *(2 - x))) / (a + 2*m + 1); + + ++m; + + return std::make_pair(aN, bN); + } + +private: + T a, b, x, y; + int m; +}; +// +// Evaluate the incomplete beta via the continued fraction representation: +// +template +inline T ibeta_fraction2(T a, T b, T x, T y, const Policy& pol, bool normalised, T* p_derivative) +{ + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING + T result = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol); + if(p_derivative) + { + *p_derivative = result; + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + if(result == 0) + return result; + + ibeta_fraction2_t f(a, b, x, y); + T fract = boost::math::tools::continued_fraction_b(f, boost::math::policies::get_epsilon()); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result / fract; +} +// +// Computes the difference between ibeta(a,b,x) and ibeta(a+k,b,x): +// +template +T ibeta_a_step(T a, T b, T x, T y, int k, const Policy& pol, bool normalised, T* p_derivative) +{ + typedef typename lanczos::lanczos::type lanczos_type; + + BOOST_MATH_INSTRUMENT_VARIABLE(k); + + T prefix = ibeta_power_terms(a, b, x, y, lanczos_type(), normalised, pol); + if(p_derivative) + { + *p_derivative = prefix; + BOOST_MATH_ASSERT(*p_derivative >= 0); + } + prefix /= a; + if(prefix == 0) + return prefix; + T sum = 1; + T term = 1; + // series summation from 0 to k-1: + for(int i = 0; i < k-1; ++i) + { + term *= (a+b+i) * x / (a+i+1); + sum += term; + } + prefix *= sum; + + return prefix; +} +// +// This function is only needed for the non-regular incomplete beta, +// it computes the delta in: +// beta(a,b,x) = prefix + delta * beta(a+k,b,x) +// it is currently only called for small k. +// +template +inline T rising_factorial_ratio(T a, T b, int k) +{ + // calculate: + // (a)(a+1)(a+2)...(a+k-1) + // _______________________ + // (b)(b+1)(b+2)...(b+k-1) + + // This is only called with small k, for large k + // it is grossly inefficient, do not use outside it's + // intended purpose!!! + BOOST_MATH_INSTRUMENT_VARIABLE(k); + if(k == 0) + return 1; + T result = 1; + for(int i = 0; i < k; ++i) + result *= (a+i) / (b+i); + return result; +} +// +// Routine for a > 15, b < 1 +// +// Begin by figuring out how large our table of Pn's should be, +// quoted accuracies are "guesstimates" based on empirical observation. +// Note that the table size should never exceed the size of our +// tables of factorials. +// +template +struct Pn_size +{ + // This is likely to be enough for ~35-50 digit accuracy + // but it's hard to quantify exactly: + static constexpr unsigned value = + ::boost::math::max_factorial::value >= 100 ? 50 + : ::boost::math::max_factorial::value >= ::boost::math::max_factorial::value ? 30 + : ::boost::math::max_factorial::value >= ::boost::math::max_factorial::value ? 15 : 1; + static_assert(::boost::math::max_factorial::value >= ::boost::math::max_factorial::value, "Type does not provide for 35-50 digits of accuracy."); +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 15; // ~8-15 digit accuracy + static_assert(::boost::math::max_factorial::value >= 30, "Type does not provide for 8-15 digits of accuracy."); +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 30; // 16-20 digit accuracy + static_assert(::boost::math::max_factorial::value >= 60, "Type does not provide for 16-20 digits of accuracy."); +}; +template <> +struct Pn_size +{ + static constexpr unsigned value = 50; // ~35-50 digit accuracy + static_assert(::boost::math::max_factorial::value >= 100, "Type does not provide for ~35-50 digits of accuracy"); +}; + +template +T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Policy& pol, bool normalised) +{ + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING + // + // This is DiDonato and Morris's BGRAT routine, see Eq's 9 through 9.6. + // + // Some values we'll need later, these are Eq 9.1: + // + T bm1 = b - 1; + T t = a + bm1 / 2; + T lx, u; + if(y < 0.35) + lx = boost::math::log1p(-y, pol); + else + lx = log(x); + u = -t * lx; + // and from from 9.2: + T prefix; + T h = regularised_gamma_prefix(b, u, pol, lanczos_type()); + if(h <= tools::min_value()) + return s0; + if(normalised) + { + prefix = h / boost::math::tgamma_delta_ratio(a, b, pol); + prefix /= pow(t, b); + } + else + { + prefix = full_igamma_prefix(b, u, pol) / pow(t, b); + } + prefix *= mult; + // + // now we need the quantity Pn, unfortunately this is computed + // recursively, and requires a full history of all the previous values + // so no choice but to declare a big table and hope it's big enough... + // + T p[ ::boost::math::detail::Pn_size::value ] = { 1 }; // see 9.3. + // + // Now an initial value for J, see 9.6: + // + T j = boost::math::gamma_q(b, u, pol) / h; + // + // Now we can start to pull things together and evaluate the sum in Eq 9: + // + T sum = s0 + prefix * j; // Value at N = 0 + // some variables we'll need: + unsigned tnp1 = 1; // 2*N+1 + T lx2 = lx / 2; + lx2 *= lx2; + T lxp = 1; + T t4 = 4 * t * t; + T b2n = b; + + for(unsigned n = 1; n < sizeof(p)/sizeof(p[0]); ++n) + { + /* + // debugging code, enable this if you want to determine whether + // the table of Pn's is large enough... + // + static int max_count = 2; + if(n > max_count) + { + max_count = n; + std::cerr << "Max iterations in BGRAT was " << n << std::endl; + } + */ + // + // begin by evaluating the next Pn from Eq 9.4: + // + tnp1 += 2; + p[n] = 0; + T mbn = b - n; + unsigned tmp1 = 3; + for(unsigned m = 1; m < n; ++m) + { + mbn = m * b - n; + p[n] += mbn * p[n-m] / boost::math::unchecked_factorial(tmp1); + tmp1 += 2; + } + p[n] /= n; + p[n] += bm1 / boost::math::unchecked_factorial(tnp1); + // + // Now we want Jn from Jn-1 using Eq 9.6: + // + j = (b2n * (b2n + 1) * j + (u + b2n + 1) * lxp) / t4; + lxp *= lx2; + b2n += 2; + // + // pull it together with Eq 9: + // + T r = prefix * p[n] * j; + sum += r; + if(r > 1) + { + if(fabs(r) < fabs(tools::epsilon() * sum)) + break; + } + else + { + if(fabs(r / tools::epsilon()) < fabs(sum)) + break; + } + } + return sum; +} // template T beta_small_b_large_a_series(T a, T b, T x, T y, T s0, T mult, const Lanczos& l, bool normalised) + +// +// For integer arguments we can relate the incomplete beta to the +// complement of the binomial distribution cdf and use this finite sum. +// +template +T binomial_ccdf(T n, T k, T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + T result = pow(x, n); + + if(result > tools::min_value()) + { + T term = result; + for(unsigned i = itrunc(T(n - 1)); i > k; --i) + { + term *= ((i + 1) * y) / ((n - i) * x); + result += term; + } + } + else + { + // First term underflows so we need to start at the mode of the + // distribution and work outwards: + int start = itrunc(n * x); + if(start <= k + 1) + start = itrunc(k + 2); + result = pow(x, start) * pow(y, n - start) * boost::math::binomial_coefficient(itrunc(n), itrunc(start), pol); + if(result == 0) + { + // OK, starting slightly above the mode didn't work, + // we'll have to sum the terms the old fashioned way: + for(unsigned i = start - 1; i > k; --i) + { + result += pow(x, (int)i) * pow(y, n - i) * boost::math::binomial_coefficient(itrunc(n), itrunc(i), pol); + } + } + else + { + T term = result; + T start_term = result; + for(unsigned i = start - 1; i > k; --i) + { + term *= ((i + 1) * y) / ((n - i) * x); + result += term; + } + term = start_term; + for(unsigned i = start + 1; i <= n; ++i) + { + term *= (n - i + 1) * x / (i * y); + result += term; + } + } + } + + return result; +} + + +// +// The incomplete beta function implementation: +// This is just a big bunch of spaghetti code to divide up the +// input range and select the right implementation method for +// each domain: +// +template +T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised, T* p_derivative) +{ + static const char* function = "boost::math::ibeta<%1%>(%1%, %1%, %1%)"; + typedef typename lanczos::lanczos::type lanczos_type; + BOOST_MATH_STD_USING // for ADL of std math functions. + + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(inv); + BOOST_MATH_INSTRUMENT_VARIABLE(normalised); + + bool invert = inv; + T fract; + T y = 1 - x; + + BOOST_MATH_ASSERT((p_derivative == 0) || normalised); + + if(p_derivative) + *p_derivative = -1; // value not set. + + if((x < 0) || (x > 1)) + return policies::raise_domain_error(function, "Parameter x outside the range [0,1] in the incomplete beta function (got x=%1%).", x, pol); + + if(normalised) + { + if(a < 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be >= zero (got a=%1%).", a, pol); + if(b < 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be >= zero (got b=%1%).", b, pol); + // extend to a few very special cases: + if(a == 0) + { + if(b == 0) + return policies::raise_domain_error(function, "The arguments a and b to the incomplete beta function cannot both be zero, with x=%1%.", x, pol); + if(b > 0) + return static_cast(inv ? 0 : 1); + } + else if(b == 0) + { + if(a > 0) + return static_cast(inv ? 1 : 0); + } + } + else + { + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol); + } + + if(x == 0) + { + if(p_derivative) + { + *p_derivative = (a == 1) ? (T)1 : (a < 1) ? T(tools::max_value() / 2) : T(tools::min_value() * 2); + } + return (invert ? (normalised ? T(1) : boost::math::beta(a, b, pol)) : T(0)); + } + if(x == 1) + { + if(p_derivative) + { + *p_derivative = (b == 1) ? T(1) : (b < 1) ? T(tools::max_value() / 2) : T(tools::min_value() * 2); + } + return (invert == 0 ? (normalised ? 1 : boost::math::beta(a, b, pol)) : 0); + } + if((a == 0.5f) && (b == 0.5f)) + { + // We have an arcsine distribution: + if(p_derivative) + { + *p_derivative = 1 / constants::pi() * sqrt(y * x); + } + T p = invert ? asin(sqrt(y)) / constants::half_pi() : asin(sqrt(x)) / constants::half_pi(); + if(!normalised) + p *= constants::pi(); + return p; + } + if(a == 1) + { + std::swap(a, b); + std::swap(x, y); + invert = !invert; + } + if(b == 1) + { + // + // Special case see: http://functions.wolfram.com/GammaBetaErf/BetaRegularized/03/01/01/ + // + if(a == 1) + { + if(p_derivative) + *p_derivative = 1; + return invert ? y : x; + } + + if(p_derivative) + { + *p_derivative = a * pow(x, a - 1); + } + T p; + if(y < 0.5) + p = invert ? T(-boost::math::expm1(a * boost::math::log1p(-y, pol), pol)) : T(exp(a * boost::math::log1p(-y, pol))); + else + p = invert ? T(-boost::math::powm1(x, a, pol)) : T(pow(x, a)); + if(!normalised) + p /= a; + return p; + } + + if((std::min)(a, b) <= 1) + { + if(x > 0.5) + { + std::swap(a, b); + std::swap(x, y); + invert = !invert; + BOOST_MATH_INSTRUMENT_VARIABLE(invert); + } + if((std::max)(a, b) <= 1) + { + // Both a,b < 1: + if((a >= (std::min)(T(0.2), b)) || (pow(x, a) <= 0.9)) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + std::swap(a, b); + std::swap(x, y); + invert = !invert; + if(y >= 0.3) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + // Sidestep on a, and then use the series representation: + T prefix; + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+b), a, 20); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative); + if(!invert) + { + fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract -= (normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + } + } + else + { + // One of a, b < 1 only: + if((b <= 1) || ((x < 0.1) && (pow(b * x, a) <= 0.7))) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + std::swap(a, b); + std::swap(x, y); + invert = !invert; + + if(y >= 0.3) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else if(a >= 15) + { + if(!invert) + { + fract = beta_small_b_large_a_series(a, b, x, y, T(0), T(1), pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(a, b, x, y, fract, T(1), pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + // Sidestep to improve errors: + T prefix; + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+b), a, 20); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(a, b, x, y, 20, pol, normalised, p_derivative); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + if(!invert) + { + fract = beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract -= (normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -beta_small_b_large_a_series(T(a + 20), b, x, y, fract, prefix, pol, normalised); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + } + } + } + else + { + // Both a,b >= 1: + T lambda; + if(a < b) + { + lambda = a - (a + b) * x; + } + else + { + lambda = (a + b) * y - b; + } + if(lambda < 0) + { + std::swap(a, b); + std::swap(x, y); + invert = !invert; + BOOST_MATH_INSTRUMENT_VARIABLE(invert); + } + + if(b < 40) + { + if((floor(a) == a) && (floor(b) == b) && (a < static_cast((std::numeric_limits::max)() - 100)) && (y != 1)) + { + // relate to the binomial distribution and use a finite sum: + T k = a - 1; + T n = b + k; + fract = binomial_ccdf(n, k, x, y, pol); + if(!normalised) + fract *= boost::math::beta(a, b, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else if(b * x <= 0.7) + { + if(!invert) + { + fract = ibeta_series(a, b, x, T(0), lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = -(normalised ? 1 : boost::math::beta(a, b, pol)); + invert = false; + fract = -ibeta_series(a, b, x, fract, lanczos_type(), normalised, p_derivative, y, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else if(a > 15) + { + // sidestep so we can use the series representation: + int n = itrunc(T(floor(b)), pol); + if(n == b) + --n; + T bbar = b - n; + T prefix; + if(!normalised) + { + prefix = rising_factorial_ratio(T(a+bbar), bbar, n); + } + else + { + prefix = 1; + } + fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast(nullptr)); + fract = beta_small_b_large_a_series(a, bbar, x, y, fract, T(1), pol, normalised); + fract /= prefix; + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else if(normalised) + { + // The formula here for the non-normalised case is tricky to figure + // out (for me!!), and requires two pochhammer calculations rather + // than one, so leave it for now and only use this in the normalized case.... + int n = itrunc(T(floor(b)), pol); + T bbar = b - n; + if(bbar <= 0) + { + --n; + bbar += 1; + } + fract = ibeta_a_step(bbar, a, y, x, n, pol, normalised, static_cast(nullptr)); + fract += ibeta_a_step(a, bbar, x, y, 20, pol, normalised, static_cast(nullptr)); + if(invert) + fract -= 1; // Note this line would need changing if we ever enable this branch in non-normalized case + fract = beta_small_b_large_a_series(T(a+20), bbar, x, y, fract, T(1), pol, normalised); + if(invert) + { + fract = -fract; + invert = false; + } + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + else + { + fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + else + { + fract = ibeta_fraction2(a, b, x, y, pol, normalised, p_derivative); + BOOST_MATH_INSTRUMENT_VARIABLE(fract); + } + } + if(p_derivative) + { + if(*p_derivative < 0) + { + *p_derivative = ibeta_power_terms(a, b, x, y, lanczos_type(), true, pol); + } + T div = y * x; + + if(*p_derivative != 0) + { + if((tools::max_value() * div < *p_derivative)) + { + // overflow, return an arbitrarily large value: + *p_derivative = tools::max_value() / 2; + } + else + { + *p_derivative /= div; + } + } + } + return invert ? (normalised ? 1 : boost::math::beta(a, b, pol)) - fract : fract; +} // template T ibeta_imp(T a, T b, T x, const Lanczos& l, bool inv, bool normalised) + +template +inline T ibeta_imp(T a, T b, T x, const Policy& pol, bool inv, bool normalised) +{ + return ibeta_imp(a, b, x, pol, inv, normalised, static_cast(nullptr)); +} + +template +T ibeta_derivative_imp(T a, T b, T x, const Policy& pol) +{ + static const char* function = "ibeta_derivative<%1%>(%1%,%1%,%1%)"; + // + // start with the usual error checks: + // + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function must be greater than zero (got b=%1%).", b, pol); + if((x < 0) || (x > 1)) + return policies::raise_domain_error(function, "Parameter x outside the range [0,1] in the incomplete beta function (got x=%1%).", x, pol); + // + // Now the corner cases: + // + if(x == 0) + { + return (a > 1) ? 0 : + (a == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error(function, nullptr, pol); + } + else if(x == 1) + { + return (b > 1) ? 0 : + (b == 1) ? 1 / boost::math::beta(a, b, pol) : policies::raise_overflow_error(function, nullptr, pol); + } + // + // Now the regular cases: + // + typedef typename lanczos::lanczos::type lanczos_type; + T y = (1 - x) * x; + T f1 = ibeta_power_terms(a, b, x, 1 - x, lanczos_type(), true, pol, 1 / y, function); + return f1; +} +// +// Some forwarding functions that dis-ambiguate the third argument type: +// +template +inline typename tools::promote_args::type + beta(RT1 a, RT2 b, const Policy&, const std::true_type*) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::beta_imp(static_cast(a), static_cast(b), evaluation_type(), forwarding_policy()), "boost::math::beta<%1%>(%1%,%1%)"); +} +template +inline typename tools::promote_args::type + beta(RT1 a, RT2 b, RT3 x, const std::false_type*) +{ + return boost::math::beta(a, b, x, policies::policy<>()); +} +} // namespace detail + +// +// The actual function entry-points now follow, these just figure out +// which Lanczos approximation to use +// and forward to the implementation functions: +// +template +inline typename tools::promote_args::type + beta(RT1 a, RT2 b, A arg) +{ + typedef typename policies::is_policy::type tag; + return boost::math::detail::beta(a, b, arg, static_cast(nullptr)); +} + +template +inline typename tools::promote_args::type + beta(RT1 a, RT2 b) +{ + return boost::math::beta(a, b, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + beta(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), false, false), "boost::math::beta<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), true, false), "boost::math::betac<%1%>(%1%,%1%,%1%)"); +} +template +inline typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x) +{ + return boost::math::betac(a, b, x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), false, true), "boost::math::ibeta<%1%>(%1%,%1%,%1%)"); +} +template +inline typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibeta(a, b, x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy(), true, true), "boost::math::ibetac<%1%>(%1%,%1%,%1%)"); +} +template +inline typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibetac(a, b, x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::ibeta_derivative_imp(static_cast(a), static_cast(b), static_cast(x), forwarding_policy()), "boost::math::ibeta_derivative<%1%>(%1%,%1%,%1%)"); +} +template +inline typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x) +{ + return boost::math::ibeta_derivative(a, b, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#include +#include + +#endif // BOOST_MATH_SPECIAL_BETA_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/binomial.hpp b/libcxx/src/third-party/boost/math/special_functions/binomial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/binomial.hpp @@ -0,0 +1,89 @@ +// 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_SF_BINOMIAL_HPP +#define BOOST_MATH_SF_BINOMIAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +template +T binomial_coefficient(unsigned n, unsigned k, const Policy& pol) +{ + static_assert(!std::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING + static const char* function = "boost::math::binomial_coefficient<%1%>(unsigned, unsigned)"; + if(k > n) + return policies::raise_domain_error( + function, + "The binomial coefficient is undefined for k > n, but got k = %1%.", + static_cast(k), pol); + T result; + if((k == 0) || (k == n)) + return static_cast(1); + if((k == 1) || (k == n-1)) + return static_cast(n); + + if(n <= max_factorial::value) + { + // Use fast table lookup: + result = unchecked_factorial(n); + result /= unchecked_factorial(n-k); + result /= unchecked_factorial(k); + } + else + { + // Use the beta function: + if(k < n - k) + result = k * beta(static_cast(k), static_cast(n-k+1), pol); + else + result = (n - k) * beta(static_cast(k+1), static_cast(n-k), pol); + if(result == 0) + return policies::raise_overflow_error(function, nullptr, pol); + result = 1 / result; + } + // convert to nearest integer: + return ceil(result - 0.5f); +} +// +// Type float can only store the first 35 factorials, in order to +// increase the chance that we can use a table driven implementation +// we'll promote to double: +// +template <> +inline float binomial_coefficient >(unsigned n, unsigned k, const policies::policy<>&) +{ + typedef policies::normalise< + policies::policy<>, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(binomial_coefficient(n, k, forwarding_policy()), "boost::math::binomial_coefficient<%1%>(unsigned,unsigned)"); +} + +template +inline T binomial_coefficient(unsigned n, unsigned k) +{ + return binomial_coefficient(n, k, policies::policy<>()); +} + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_SF_BINOMIAL_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/cardinal_b_spline.hpp b/libcxx/src/third-party/boost/math/special_functions/cardinal_b_spline.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/cardinal_b_spline.hpp @@ -0,0 +1,218 @@ +// (C) Copyright Nick Thompson 2019. +// 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_CARDINAL_B_SPLINE_HPP +#define BOOST_MATH_SPECIAL_CARDINAL_B_SPLINE_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + + template + inline Real B1(Real x) + { + if (x < 0) + { + return B1(-x); + } + if (x < Real(1)) + { + return 1 - x; + } + return Real(0); + } +} + +template +Real cardinal_b_spline(Real x) { + static_assert(!std::is_integral::value, "Does not work with integral types."); + + if (x < 0) { + // All B-splines are even functions: + return cardinal_b_spline(-x); + } + + if (n==0) + { + if (x < Real(1)/Real(2)) { + return Real(1); + } + else if (x == Real(1)/Real(2)) { + return Real(1)/Real(2); + } + else { + return Real(0); + } + } + + if (n==1) + { + return detail::B1(x); + } + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Fill v with values of B1: + // At most two of these terms are nonzero, and at least 1. + // There is only one non-zero term when n is odd and x = 0. + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[0]; +} + + +template +Real cardinal_b_spline_prime(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integer types."); + + if (x < 0) + { + // All B-splines are even functions, so derivatives are odd: + return -cardinal_b_spline_prime(-x); + } + + + if (n==0) + { + // Kinda crazy but you get what you ask for! + if (x == Real(1)/Real(2)) + { + return std::numeric_limits::infinity(); + } + else + { + return Real(0); + } + } + + if (n==1) + { + if (x==0) + { + return Real(0); + } + if (x==1) + { + return -Real(1)/Real(2); + } + return Real(-1); + } + + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Now we want to evaluate B_{n}(x), but stop at the second to last step and collect B_{n-1}(x+1/2) and B_{n-1}(x-1/2): + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n - 1; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[1] - v[0]; +} + + +template +Real cardinal_b_spline_double_prime(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integer types."); + static_assert(n >= 3, "n>=3 for second derivatives of cardinal B-splines is required."); + + if (x < 0) + { + // All B-splines are even functions, so second derivatives are even: + return cardinal_b_spline_double_prime(-x); + } + + + Real supp_max = (n+1)/Real(2); + if (x >= supp_max) + { + return Real(0); + } + + // Now we want to evaluate B_{n}(x), but stop at the second to last step and collect B_{n-1}(x+1/2) and B_{n-1}(x-1/2): + std::array v; + Real z = x + 1 - supp_max; + for (unsigned i = 0; i < n; ++i) + { + v[i] = detail::B1(z); + z += 1; + } + + Real smx = supp_max - x; + for (unsigned j = 2; j <= n - 2; ++j) + { + Real a = (j + 1 - smx); + Real b = smx; + for(unsigned k = 0; k <= n - j; ++k) + { + v[k] = (a*v[k+1] + b*v[k])/Real(j); + a += 1; + b -= 1; + } + } + + return v[2] - 2*v[1] + v[0]; +} + + +template +Real forward_cardinal_b_spline(Real x) +{ + static_assert(!std::is_integral::value, "Cardinal B-splines do not work with integral types."); + return cardinal_b_spline(x - (n+1)/Real(2)); +} + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/cbrt.hpp b/libcxx/src/third-party/boost/math/special_functions/cbrt.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/cbrt.hpp @@ -0,0 +1,177 @@ +// (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_SF_CBRT_HPP +#define BOOST_MATH_SF_CBRT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail +{ + +struct big_int_type +{ + operator std::uintmax_t() const; +}; + +template +struct largest_cbrt_int_type +{ + using type = typename std::conditional< + std::is_convertible::value, + std::uintmax_t, + unsigned int + >::type; +}; + +template +T cbrt_imp(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // cbrt approximation for z in the range [0.5,1] + // It's hard to say what number of terms gives the optimum + // trade off between precision and performance, this seems + // to be about the best for double precision. + // + // Maximum Deviation Found: 1.231e-006 + // Expected Error Term: -1.231e-006 + // Maximum Relative Change in Control Points: 5.982e-004 + // + static const T P[] = { + static_cast(0.37568269008611818), + static_cast(1.3304968705558024), + static_cast(-1.4897101632445036), + static_cast(1.2875573098219835), + static_cast(-0.6398703759826468), + static_cast(0.13584489959258635), + }; + static const T correction[] = { + static_cast(0.62996052494743658238360530363911), // 2^-2/3 + static_cast(0.79370052598409973737585281963615), // 2^-1/3 + static_cast(1), + static_cast(1.2599210498948731647672106072782), // 2^1/3 + static_cast(1.5874010519681994747517056392723), // 2^2/3 + }; + if((boost::math::isinf)(z) || (z == 0)) + return z; + if(!(boost::math::isfinite)(z)) + { + return policies::raise_domain_error("boost::math::cbrt<%1%>(%1%)", "Argument to function must be finite but got %1%.", z, pol); + } + + int i_exp, sign(1); + if(z < 0) + { + z = -z; + sign = -sign; + } + + T guess = frexp(z, &i_exp); + int original_i_exp = i_exp; // save for later + guess = tools::evaluate_polynomial(P, guess); + int i_exp3 = i_exp / 3; + + using shift_type = typename largest_cbrt_int_type::type; + + static_assert( ::std::numeric_limits::radix == 2, "The radix of the type to shift to must be 2."); + + if(abs(i_exp3) < std::numeric_limits::digits) + { + if(i_exp3 > 0) + guess *= shift_type(1u) << i_exp3; + else + guess /= shift_type(1u) << -i_exp3; + } + else + { + guess = ldexp(guess, i_exp3); + } + i_exp %= 3; + guess *= correction[i_exp + 2]; + // + // Now inline Halley iteration. + // We do this here rather than calling tools::halley_iterate since we can + // simplify the expressions algebraically, and don't need most of the error + // checking of the boilerplate version as we know in advance that the function + // is well behaved... + // + using prec = typename policies::precision::type; + constexpr auto prec3 = prec::value / 3; + constexpr auto new_prec = prec3 + 3; + using new_policy = typename policies::normalise>::type; + // + // Epsilon calculation uses compile time arithmetic when it's available for type T, + // otherwise uses ldexp to calculate at runtime: + // + T eps = (new_prec > 3) ? policies::get_epsilon() : ldexp(T(1), -2 - tools::digits() / 3); + T diff; + + if(original_i_exp < std::numeric_limits::max_exponent - 3) + { + // + // Safe from overflow, use the fast method: + // + do + { + T g3 = guess * guess * guess; + diff = (g3 + z + z) / (g3 + g3 + z); + guess *= diff; + } + while(fabs(1 - diff) > eps); + } + else + { + // + // Either we're ready to overflow, or we can't tell because numeric_limits isn't + // available for type T: + // + do + { + T g2 = guess * guess; + diff = (g2 - z / guess) / (2 * guess + z / g2); + guess -= diff; + } + while((guess * eps) < fabs(diff)); + } + + return sign * guess; +} + +} // namespace detail + +template +inline typename tools::promote_args::type cbrt(T z, const Policy& pol) +{ + using result_type = typename tools::promote_args::type; + using value_type = typename policies::evaluation::type; + return static_cast(detail::cbrt_imp(value_type(z), pol)); +} + +template +inline typename tools::promote_args::type cbrt(T z) +{ + return cbrt(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SF_CBRT_HPP + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/chebyshev.hpp b/libcxx/src/third-party/boost/math/special_functions/chebyshev.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/chebyshev.hpp @@ -0,0 +1,288 @@ +// (C) Copyright Nick Thompson 2017. +// 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_CHEBYSHEV_HPP +#define BOOST_MATH_SPECIAL_CHEBYSHEV_HPP +#include +#include +#include +#include +#include +#include + +#if (__cplusplus > 201103) || (defined(_CPPLIB_VER) && (_CPPLIB_VER >= 610)) +# define BOOST_MATH_CHEB_USE_STD_ACOSH +#endif + +#ifndef BOOST_MATH_CHEB_USE_STD_ACOSH +# include +#endif + +namespace boost { namespace math { + +template +inline tools::promote_args_t chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1) +{ + return 2*x*Tn - Tn_1; +} + +namespace detail { + +template +inline Real chebyshev_imp(unsigned n, Real const & x, const Policy&) +{ +#ifdef BOOST_MATH_CHEB_USE_STD_ACOSH + using std::acosh; +#define BOOST_MATH_ACOSH_POLICY +#else + using boost::math::acosh; +#define BOOST_MATH_ACOSH_POLICY , Policy() +#endif + using std::cosh; + using std::pow; + using std::sqrt; + Real T0 = 1; + Real T1; + + BOOST_IF_CONSTEXPR (second) + { + if (x > 1 || x < -1) + { + Real t = sqrt(x*x -1); + return static_cast((pow(x+t, static_cast(n+1)) - pow(x-t, static_cast(n+1)))/(2*t)); + } + T1 = 2*x; + } + else + { + if (x > 1) + { + return cosh(n*acosh(x BOOST_MATH_ACOSH_POLICY)); + } + if (x < -1) + { + if (n & 1) + { + return -cosh(n*acosh(-x BOOST_MATH_ACOSH_POLICY)); + } + else + { + return cosh(n*acosh(-x BOOST_MATH_ACOSH_POLICY)); + } + } + T1 = x; + } + + if (n == 0) + { + return T0; + } + + unsigned l = 1; + while(l < n) + { + std::swap(T0, T1); + T1 = boost::math::chebyshev_next(x, T0, T1); + ++l; + } + return T1; +} +} // namespace detail + +template +inline tools::promote_args_t chebyshev_t(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + return policies::checked_narrowing_cast(detail::chebyshev_imp(n, static_cast(x), forwarding_policy()), "boost::math::chebyshev_t<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_t(unsigned n, Real const & x) +{ + return chebyshev_t(n, x, policies::policy<>()); +} + +template +inline tools::promote_args_t chebyshev_u(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + + return policies::checked_narrowing_cast(detail::chebyshev_imp(n, static_cast(x), forwarding_policy()), "boost::math::chebyshev_u<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_u(unsigned n, Real const & x) +{ + return chebyshev_u(n, x, policies::policy<>()); +} + +template +inline tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x, const Policy&) +{ + using result_type = tools::promote_args_t; + using value_type = typename policies::evaluation::type; + using forwarding_policy = typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type; + if (n == 0) + { + return result_type(0); + } + return policies::checked_narrowing_cast(n * detail::chebyshev_imp(n - 1, static_cast(x), forwarding_policy()), "boost::math::chebyshev_t_prime<%1%>(unsigned, %1%)"); +} + +template +inline tools::promote_args_t chebyshev_t_prime(unsigned n, Real const & x) +{ + return chebyshev_t_prime(n, x, policies::policy<>()); +} + +/* + * This is Algorithm 3.1 of + * Gil, Amparo, Javier Segura, and Nico M. Temme. + * Numerical methods for special functions. + * Society for Industrial and Applied Mathematics, 2007. + * https://www.siam.org/books/ot99/OT99SampleChapter.pdf + * However, our definition of c0 differs by a factor of 1/2, as stated in the docs. . . + */ +template +inline Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const T2& x) +{ + using boost::math::constants::half; + if (length < 2) + { + if (length == 0) + { + return 0; + } + return c[0]/2; + } + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*x*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return x*b1 - b2 + half()*c[0]; +} + + + +namespace detail { +template +inline Real unchecked_chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const Real & a, const Real & b, const Real& x) +{ + Real t; + Real u; + // This cutoff is not super well defined, but it's a good estimate. + // See "An Error Analysis of the Modified Clenshaw Method for Evaluating Chebyshev and Fourier Series" + // J. OLIVER, IMA Journal of Applied Mathematics, Volume 20, Issue 3, November 1977, Pages 379-391 + // https://doi.org/10.1093/imamat/20.3.379 + const Real cutoff = 0.6; + if (x - a < b - x) + { + u = 2*(x-a)/(b-a); + t = u - 1; + if (t > -cutoff) + { + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*t*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return t*b1 - b2 + c[0]/2; + } + else + { + Real b1 = c[length - 1]; + Real d = b1; + Real b2 = 0; + for (size_t r = length - 2; r >= 1; --r) + { + d = 2*u*b1 - d + c[r]; + b2 = b1; + b1 = d - b1; + } + return t*b1 - b2 + c[0]/2; + } + } + else + { + u = -2*(b-x)/(b-a); + t = u + 1; + if (t < cutoff) + { + Real b2 = 0; + Real b1 = c[length -1]; + for(size_t j = length - 2; j >= 1; --j) + { + Real tmp = 2*t*b1 - b2 + c[j]; + b2 = b1; + b1 = tmp; + } + return t*b1 - b2 + c[0]/2; + } + else + { + Real b1 = c[length - 1]; + Real d = b1; + Real b2 = 0; + for (size_t r = length - 2; r >= 1; --r) + { + d = 2*u*b1 + d + c[r]; + b2 = b1; + b1 = d + b1; + } + return t*b1 - b2 + c[0]/2; + } + } +} + +} // namespace detail + +template +inline Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const Real & a, const Real & b, const Real& x) +{ + if (x < a || x > b) + { + BOOST_MATH_THROW_EXCEPTION(std::domain_error("x in [a, b] is required.")); + } + if (length < 2) + { + if (length == 0) + { + return 0; + } + return c[0]/2; + } + return detail::unchecked_chebyshev_clenshaw_recurrence(c, length, a, b, x); +} + +}} // Namespace boost::math + +#endif // BOOST_MATH_SPECIAL_CHEBYSHEV_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/chebyshev_transform.hpp b/libcxx/src/third-party/boost/math/special_functions/chebyshev_transform.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/chebyshev_transform.hpp @@ -0,0 +1,237 @@ +// (C) Copyright Nick Thompson 2017. +// 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_CHEBYSHEV_TRANSFORM_HPP +#define BOOST_MATH_SPECIAL_CHEBYSHEV_TRANSFORM_HPP +#include +#include +#include +#include + +#ifdef BOOST_HAS_FLOAT128 +#include +#endif + +#ifdef __has_include +# if __has_include() +# include +# else +# error "This feature is unavailable without fftw3 installed" +#endif +#endif + +namespace boost { namespace math { + +namespace detail{ + +template +struct fftw_cos_transform; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, double* data1, double* data2) + { + plan = fftw_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftw_destroy_plan(plan); + } + void execute(double* data1, double* data2) + { + fftw_execute_r2r(plan, data1, data2); + } + static double cos(double x) { return std::cos(x); } + static double fabs(double x) { return std::fabs(x); } +private: + fftw_plan plan; +}; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, float* data1, float* data2) + { + plan = fftwf_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwf_destroy_plan(plan); + } + void execute(float* data1, float* data2) + { + fftwf_execute_r2r(plan, data1, data2); + } + static float cos(float x) { return std::cos(x); } + static float fabs(float x) { return std::fabs(x); } +private: + fftwf_plan plan; +}; + +template<> +struct fftw_cos_transform +{ + fftw_cos_transform(int n, long double* data1, long double* data2) + { + plan = fftwl_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwl_destroy_plan(plan); + } + void execute(long double* data1, long double* data2) + { + fftwl_execute_r2r(plan, data1, data2); + } + static long double cos(long double x) { return std::cos(x); } + static long double fabs(long double x) { return std::fabs(x); } +private: + fftwl_plan plan; +}; +#ifdef BOOST_HAS_FLOAT128 +template<> +struct fftw_cos_transform<__float128> +{ + fftw_cos_transform(int n, __float128* data1, __float128* data2) + { + plan = fftwq_plan_r2r_1d(n, data1, data2, FFTW_REDFT10, FFTW_ESTIMATE); + } + ~fftw_cos_transform() + { + fftwq_destroy_plan(plan); + } + void execute(__float128* data1, __float128* data2) + { + fftwq_execute_r2r(plan, data1, data2); + } + static __float128 cos(__float128 x) { return cosq(x); } + static __float128 fabs(__float128 x) { return fabsq(x); } +private: + fftwq_plan plan; +}; + +#endif +} + +template +class chebyshev_transform +{ +public: + template + chebyshev_transform(const F& f, Real a, Real b, + Real tol = 500 * std::numeric_limits::epsilon(), + size_t max_refinements = 16) : m_a(a), m_b(b) + { + if (a >= b) + { + throw std::domain_error("a < b is required.\n"); + } + using boost::math::constants::half; + using boost::math::constants::pi; + using std::cos; + using std::abs; + Real bma = (b-a)*half(); + Real bpa = (b+a)*half(); + size_t n = 256; + std::vector vf; + + size_t refinements = 0; + while(refinements < max_refinements) + { + vf.resize(n); + m_coeffs.resize(n); + + detail::fftw_cos_transform plan(static_cast(n), vf.data(), m_coeffs.data()); + Real inv_n = 1/static_cast(n); + for(size_t j = 0; j < n/2; ++j) + { + // Use symmetry cos((j+1/2)pi/n) = - cos((n-1-j+1/2)pi/n) + Real y = detail::fftw_cos_transform::cos(pi()*(j+half())*inv_n); + vf[j] = f(y*bma + bpa)*inv_n; + vf[n-1-j]= f(bpa-y*bma)*inv_n; + } + + plan.execute(vf.data(), m_coeffs.data()); + Real max_coeff = 0; + for (auto const & coeff : m_coeffs) + { + if (detail::fftw_cos_transform::fabs(coeff) > max_coeff) + { + max_coeff = detail::fftw_cos_transform::fabs(coeff); + } + } + size_t j = m_coeffs.size() - 1; + while (abs(m_coeffs[j])/max_coeff < tol) + { + --j; + } + // If ten coefficients are eliminated, the we say we've done all + // we need to do: + if (n - j > 10) + { + m_coeffs.resize(j+1); + return; + } + + n *= 2; + ++refinements; + } + } + + inline Real operator()(Real x) const + { + return chebyshev_clenshaw_recurrence(m_coeffs.data(), m_coeffs.size(), m_a, m_b, x); + } + + // Integral over entire domain [a, b] + Real integrate() const + { + Real Q = m_coeffs[0]/2; + for(size_t j = 2; j < m_coeffs.size(); j += 2) + { + Q += -m_coeffs[j]/((j+1)*(j-1)); + } + return (m_b - m_a)*Q; + } + + const std::vector& coefficients() const + { + return m_coeffs; + } + + Real prime(Real x) const + { + Real z = (2*x - m_a - m_b)/(m_b - m_a); + Real dzdx = 2/(m_b - m_a); + if (m_coeffs.size() < 2) + { + return 0; + } + Real b2 = 0; + Real d2 = 0; + Real b1 = m_coeffs[m_coeffs.size() -1]; + Real d1 = 0; + for(size_t j = m_coeffs.size() - 2; j >= 1; --j) + { + Real tmp1 = 2*z*b1 - b2 + m_coeffs[j]; + Real tmp2 = 2*z*d1 - d2 + 2*b1; + b2 = b1; + b1 = tmp1; + + d2 = d1; + d1 = tmp2; + } + return dzdx*(z*d1 - d2 + b1); + } + +private: + std::vector m_coeffs; + Real m_a; + Real m_b; +}; + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/cos_pi.hpp b/libcxx/src/third-party/boost/math/special_functions/cos_pi.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/cos_pi.hpp @@ -0,0 +1,88 @@ +// Copyright (c) 2007 John Maddock +// 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_COS_PI_HPP +#define BOOST_MATH_COS_PI_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T cos_pi_imp(T x, const Policy&) +{ + BOOST_MATH_STD_USING // ADL of std names + // cos of pi*x: + bool invert = false; + if(fabs(x) < 0.25) + return cos(constants::pi() * x); + + if(x < 0) + { + x = -x; + } + T rem = floor(x); + if(abs(floor(rem/2)*2 - rem) > std::numeric_limits::epsilon()) + { + invert = !invert; + } + rem = x - rem; + if(rem > 0.5f) + { + rem = 1 - rem; + invert = !invert; + } + if(rem == 0.5f) + return 0; + + if(rem > 0.25f) + { + rem = 0.5f - rem; + rem = sin(constants::pi() * rem); + } + else + rem = cos(constants::pi() * rem); + return invert ? T(-rem) : rem; +} + +} // namespace detail + +template +inline typename tools::promote_args::type cos_pi(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<>, + // We want to ignore overflows since the result is in [-1,1] and the + // check slows the code down considerably. + policies::overflow_error >::type forwarding_policy; + return policies::checked_narrowing_cast(boost::math::detail::cos_pi_imp(x, forwarding_policy()), "cos_pi"); +} + +template +inline typename tools::promote_args::type cos_pi(T x) +{ + return boost::math::cos_pi(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost +#endif + diff --git a/libcxx/src/third-party/boost/math/special_functions/daubechies_scaling.hpp b/libcxx/src/third-party/boost/math/special_functions/daubechies_scaling.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/daubechies_scaling.hpp @@ -0,0 +1,478 @@ +/* + * Copyright Nick Thompson, John Maddock 2020 + * 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_DAUBECHIES_SCALING_HPP +#define BOOST_MATH_SPECIAL_DAUBECHIES_SCALING_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math { + +template +std::vector daubechies_scaling_dyadic_grid(int64_t j_max) +{ + using std::isnan; + using std::sqrt; + auto c = boost::math::filters::daubechies_scaling_filter(); + Real scale = sqrt(static_cast(2))*(1 << order); + for (auto & x : c) + { + x *= scale; + } + + auto phik = detail::daubechies_scaling_integer_grid(); + + // Maximum sensible j for 32 bit floats is j_max = 22: + if (std::is_same_v) + { + if (j_max > 23) + { + throw std::logic_error("Requested dyadic grid more dense than number of representables on the interval."); + } + } + std::vector v(2*p + (2*p-1)*((1<::quiet_NaN()); + v[0] = 0; + v[v.size()-1] = 0; + for (int64_t i = 0; i < static_cast(phik.size()); ++i) { + v[i*(1uLL<= static_cast(v.size())) { + // std::cerr << "Delivery index out of range!\n"; + // continue; + //} + Real term = 0; + for (int64_t l = 0; l < static_cast(c.size()); ++l) + { + int64_t idx = k*(int64_t(1) << (j_max - j + 1)) - l*(int64_t(1) << j_max); + if (idx < 0) + { + break; + } + if (idx < static_cast(v.size())) + { + term += c[l]*v[idx]; + } + } + // Again, another nice check: + //if (!isnan(v[delivery_idx])) { + // std::cerr << "Delivery index already populated!, = " << v[delivery_idx] << "\n"; + // std::cerr << "would overwrite with " << term << "\n"; + //} + v[delivery_idx] = term; + } + } + return v; +} + +namespace detail { + +template +class matched_holder { +public: + using Real = typename RandomAccessContainer::value_type; + + matched_holder(RandomAccessContainer && y, RandomAccessContainer && dydx, int grid_refinements, Real x0) : x0_{x0}, y_{std::move(y)}, dy_{std::move(dydx)} + { + inv_h_ = (1 << grid_refinements); + Real h = 1/inv_h_; + for (auto & dy : dy_) + { + dy *= h; + } + } + + inline Real operator()(Real x) const + { + using std::floor; + using std::sqrt; + // This is the exact Holder exponent, but it's pessimistic almost everywhere! + // It's only exactly right at dyadic rationals. + //Real const alpha = 2 - log(1+sqrt(Real(3)))/log(Real(2)); + // We're gonna use alpha = 1/2, rather than 0.5500... + Real s = (x-x0_)*inv_h_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real dphi = dy_[i+1]; + Real diff = y_[i+1] - y_[i]; + return y_[i] + (2*dphi - diff)*t + 2*sqrt(t)*(diff-dphi); + } + + int64_t bytes() const + { + return 2*y_.size()*sizeof(Real) + sizeof(*this); + } + +private: + Real x0_; + Real inv_h_; + RandomAccessContainer y_; + RandomAccessContainer dy_; +}; + +template +class matched_holder_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + matched_holder_aos(RandomAccessContainer && data, int grid_refinements, Real x0) : x0_{x0}, data_{std::move(data)} + { + inv_h_ = Real(1uLL << grid_refinements); + Real h = 1/inv_h_; + for (auto & datum : data_) + { + datum[1] *= h; + } + } + + inline Real operator()(Real x) const + { + using std::floor; + using std::sqrt; + Real s = (x-x0_)*inv_h_; + Real ii = floor(s); + auto i = static_cast(ii); + Real t = s - ii; + Real y0 = data_[i][0]; + Real y1 = data_[i+1][0]; + Real dphi = data_[i+1][1]; + Real diff = y1 - y0; + return y0 + (2*dphi - diff)*t + 2*sqrt(t)*(diff-dphi); + } + + int64_t bytes() const + { + return data_.size()*data_[0].size()*sizeof(Real) + sizeof(*this); + } + +private: + Real x0_; + Real inv_h_; + RandomAccessContainer data_; +}; + + +template +class linear_interpolation { +public: + using Real = typename RandomAccessContainer::value_type; + + linear_interpolation(RandomAccessContainer && y, RandomAccessContainer && dydx, int grid_refinements) : y_{std::move(y)}, dydx_{std::move(dydx)} + { + s_ = (1 << grid_refinements); + } + + inline Real operator()(Real x) const + { + using std::floor; + Real y = x*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return (1-t)*y_[kk] + t*y_[kk+1]; + } + + inline Real prime(Real x) const + { + using std::floor; + Real y = x*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return (1-t)*dydx_[kk] + t*dydx_[kk+1]; + } + + int64_t bytes() const + { + return (1 + y_.size() + dydx_.size())*sizeof(Real) + sizeof(y_) + sizeof(dydx_); + } + +private: + Real s_; + RandomAccessContainer y_; + RandomAccessContainer dydx_; +}; + +template +class linear_interpolation_aos { +public: + using Point = typename RandomAccessContainer::value_type; + using Real = typename Point::value_type; + + linear_interpolation_aos(RandomAccessContainer && data, int grid_refinements, Real x0) : x0_{x0}, data_{std::move(data)} + { + s_ = Real(1uLL << grid_refinements); + } + + inline Real operator()(Real x) const + { + using std::floor; + Real y = (x-x0_)*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return (t != 0) ? (1-t)*data_[kk][0] + t*data_[kk+1][0] : data_[kk][0]; + } + + inline Real prime(Real x) const + { + using std::floor; + Real y = (x-x0_)*s_; + Real k = floor(y); + + int64_t kk = static_cast(k); + Real t = y - k; + return t != 0 ? (1-t)*data_[kk][1] + t*data_[kk+1][1] : data_[kk][1]; + } + + int64_t bytes() const + { + return sizeof(*this) + data_.size()*data_[0].size()*sizeof(Real); + } + +private: + Real x0_; + Real s_; + RandomAccessContainer data_; +}; + + +template +struct daubechies_eval_type +{ + typedef T type; + + static const std::vector& vector_cast(const std::vector& v) { return v; } + +}; +template <> +struct daubechies_eval_type +{ + typedef double type; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } +}; +template <> +struct daubechies_eval_type +{ + typedef long double type; + + inline static std::vector vector_cast(const std::vector& v) + { + std::vector result(v.size()); + for (unsigned i = 0; i < v.size(); ++i) + result[i] = static_cast(v[i]); + return result; + } +}; + +struct null_interpolator +{ + template + T operator()(const T&) + { + return 1; + } +}; + +} // namespace detail + +template +class daubechies_scaling { + // + // Some type manipulation so we know the type of the interpolator, and the vector type it requires: + // + typedef std::vector> vector_type; + // + // List our interpolators: + // + typedef std::tuple< + detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, + interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, + interpolators::detail::cardinal_septic_hermite_detail_aos > interpolator_list; + // + // Select the one we need: + // + typedef std::tuple_element_t< + p == 1 ? 0 : + p == 2 ? 1 : + p == 3 ? 2 : + p <= 5 ? 3 : + p <= 9 ? 4 : 5, interpolator_list> interpolator_type; + +public: + daubechies_scaling(int grid_refinements = -1) + { + static_assert(p < 20, "Daubechies scaling functions are only implemented for p < 20."); + static_assert(p > 0, "Daubechies scaling functions must have at least 1 vanishing moment."); + if constexpr (p == 1) + { + return; + } + else { + if (grid_refinements < 0) + { + if (std::is_same_v) + { + if (grid_refinements == -2) + { + // Control absolute error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; + grid_refinements = r[p]; + } + else + { + // Control relative error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; + grid_refinements = r[p]; + } + } + else if (std::is_same_v) + { + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 19, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; + } + else + { + grid_refinements = 21; + } + } + + // Compute the refined grid: + // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. + std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { + // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: + auto v = daubechies_scaling_dyadic_grid::type, p, 0>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + // Compute the derivative of the refined grid: + std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 1>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + // if necessary, compute the second and third derivative: + std::vector d2ydx2; + std::vector d3ydx3; + if constexpr (p >= 6) { + std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 2>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + if constexpr (p >= 10) { + std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_scaling_dyadic_grid::type, p, 3>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + d3ydx3 = t4.get(); + } + d2ydx2 = t3.get(); + } + + + auto y = t0.get(); + auto dydx = t1.get(); + + if constexpr (p >= 2) + { + vector_type data(y.size()); + for (size_t i = 0; i < y.size(); ++i) + { + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; + } + if constexpr (p <= 3) + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(0)); + else + m_interpolator = std::make_shared(std::move(data), Real(0), Real(1) / (1 << grid_refinements)); + } + else + m_interpolator = std::make_shared(); + } + } + + inline Real operator()(Real x) const + { + if (x <= 0 || x >= 2*p-1) + { + return 0; + } + return (*m_interpolator)(x); + } + + inline Real prime(Real x) const + { + static_assert(p > 2, "The 3-vanishing moment Daubechies scaling function is the first which is continuously differentiable."); + if (x <= 0 || x >= 2*p-1) + { + return 0; + } + return m_interpolator->prime(x); + } + + inline Real double_prime(Real x) const + { + static_assert(p >= 6, "Second derivatives require at least 6 vanishing moments."); + if (x <= 0 || x >= 2*p - 1) + { + return Real(0); + } + return m_interpolator->double_prime(x); + } + + std::pair support() const + { + return {Real(0), Real(2*p-1)}; + } + + int64_t bytes() const + { + return m_interpolator->bytes() + sizeof(m_interpolator); + } + +private: + std::shared_ptr m_interpolator; +}; + +} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/daubechies_wavelet.hpp b/libcxx/src/third-party/boost/math/special_functions/daubechies_wavelet.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/daubechies_wavelet.hpp @@ -0,0 +1,258 @@ +/* + * Copyright Nick Thompson, 2020 + * 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_DAUBECHIES_WAVELET_HPP +#define BOOST_MATH_SPECIAL_DAUBECHIES_WAVELET_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math { + + template + std::vector daubechies_wavelet_dyadic_grid(int64_t j_max) + { + if (j_max == 0) + { + throw std::domain_error("The wavelet dyadic grid is refined from the scaling integer grid, so its minimum amount of data is half integer widths."); + } + auto phijk = daubechies_scaling_dyadic_grid(j_max - 1); + //psi_j[l] = psi(-p+1 + l/2^j) = \sum_{k=0}^{2p-1} (-1)^k c_k \phi(1-2p+k + l/2^{j-1}) + //For derivatives just map c_k -> 2^order c_k. + auto d = boost::math::filters::daubechies_scaling_filter(); + Real scale = boost::math::constants::root_two() * (1 << order); + for (size_t i = 0; i < d.size(); ++i) + { + d[i] *= scale; + if (!(i & 1)) + { + d[i] = -d[i]; + } + } + + std::vector v(2 * p + (2 * p - 1) * ((int64_t(1) << j_max) - 1), std::numeric_limits::quiet_NaN()); + v[0] = 0; + v[v.size() - 1] = 0; + + for (int64_t l = 1; l < static_cast(v.size() - 1); ++l) + { + Real term = 0; + for (int64_t k = 0; k < static_cast(d.size()); ++k) + { + int64_t idx = (int64_t(1) << (j_max - 1)) * (1 - 2 * p + k) + l; + if (idx < 0 || idx >= static_cast(phijk.size())) + { + continue; + } + term += d[k] * phijk[idx]; + } + v[l] = term; + } + + return v; + } + + + template + class daubechies_wavelet { + // + // Some type manipulation so we know the type of the interpolator, and the vector type it requires: + // + using vector_type = std::vector < std::array < Real, p < 6 ? 2 : p < 10 ? 3 : 4>>; + // + // List our interpolators: + // + using interpolator_list = std::tuple< + detail::null_interpolator, detail::matched_holder_aos, detail::linear_interpolation_aos, + interpolators::detail::cardinal_cubic_hermite_detail_aos, interpolators::detail::cardinal_quintic_hermite_detail_aos, + interpolators::detail::cardinal_septic_hermite_detail_aos > ; + // + // Select the one we need: + // + using interpolator_type = std::tuple_element_t< + p == 1 ? 0 : + p == 2 ? 1 : + p == 3 ? 2 : + p <= 5 ? 3 : + p <= 9 ? 4 : 5, interpolator_list>; + public: + explicit daubechies_wavelet(int grid_refinements = -1) + { + static_assert(p < 20, "Daubechies wavelets are only implemented for p < 20."); + static_assert(p > 0, "Daubechies wavelets must have at least 1 vanishing moment."); + if (grid_refinements == 0) + { + throw std::domain_error("The wavelet requires at least 1 grid refinement."); + } + if constexpr (p == 1) + { + return; + } + else + { + if (grid_refinements < 0) + { + if constexpr (std::is_same_v) + { + if (grid_refinements == -2) + { + // Control absolute error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 18, 19, 16, 11, 8, 7, 7, 7, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3 }; + grid_refinements = r[p]; + } + else + { + // Control relative error: + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 17, 16, 15, 14, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11 }; + grid_refinements = r[p]; + } + } + else if constexpr (std::is_same_v) + { + // p= 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 + std::array r{ -1, -1, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 19, 18, 18, 18, 18, 18, 18, 18 }; + grid_refinements = r[p]; + } + else + { + grid_refinements = 21; + } + } + + // Compute the refined grid: + // In fact for float precision I know the grid must be computed in double precision and then cast back down, or else parts of the support are systematically inaccurate. + std::future> t0 = std::async(std::launch::async, [&grid_refinements]() { + // Computing in higher precision and downcasting is essential for 1ULP evaluation in float precision: + auto v = daubechies_wavelet_dyadic_grid::type, p, 0>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + // Compute the derivative of the refined grid: + std::future> t1 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 1>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + // if necessary, compute the second and third derivative: + std::vector d2ydx2; + std::vector d3ydx3; + if constexpr (p >= 6) { + std::future> t3 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 2>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + + if constexpr (p >= 10) { + std::future> t4 = std::async(std::launch::async, [&grid_refinements]() { + auto v = daubechies_wavelet_dyadic_grid::type, p, 3>(grid_refinements); + return detail::daubechies_eval_type::vector_cast(v); + }); + d3ydx3 = t4.get(); + } + d2ydx2 = t3.get(); + } + + + auto y = t0.get(); + auto dydx = t1.get(); + + if constexpr (p >= 2) + { + vector_type data(y.size()); + for (size_t i = 0; i < y.size(); ++i) + { + data[i][0] = y[i]; + data[i][1] = dydx[i]; + if constexpr (p >= 6) + data[i][2] = d2ydx2[i]; + if constexpr (p >= 10) + data[i][3] = d3ydx3[i]; + } + if constexpr (p <= 3) + m_interpolator = std::make_shared(std::move(data), grid_refinements, Real(-p + 1)); + else + m_interpolator = std::make_shared(std::move(data), Real(-p + 1), Real(1) / (1 << grid_refinements)); + } + else + m_interpolator = std::make_shared(); + } + } + + + inline Real operator()(Real x) const + { + if (x <= -p + 1 || x >= p) + { + return 0; + } + + if constexpr (p == 1) + { + if (x < Real(1) / Real(2)) + { + return 1; + } + else if (x == Real(1) / Real(2)) + { + return 0; + } + return -1; + } + else + { + return (*m_interpolator)(x); + } + } + + inline Real prime(Real x) const + { + static_assert(p > 2, "The 3-vanishing moment Daubechies wavelet is the first which is continuously differentiable."); + if (x <= -p + 1 || x >= p) + { + return 0; + } + return m_interpolator->prime(x); + } + + inline Real double_prime(Real x) const + { + static_assert(p >= 6, "Second derivatives of Daubechies wavelets require at least 6 vanishing moments."); + if (x <= -p + 1 || x >= p) + { + return Real(0); + } + return m_interpolator->double_prime(x); + } + + std::pair support() const + { + return std::make_pair(Real(-p + 1), Real(p)); + } + + int64_t bytes() const + { + return m_interpolator->bytes() + sizeof(*this); + } + + private: + std::shared_ptr m_interpolator; + }; + +} + +#endif // BOOST_MATH_SPECIAL_DAUBECHIES_WAVELET_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/airy_ai_bi_zero.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/airy_ai_bi_zero.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/airy_ai_bi_zero.hpp @@ -0,0 +1,204 @@ +// Copyright (c) 2013 Christopher Kormanyos +// 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) +// +// This work is based on an earlier work: +// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", +// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 +// +// This header contains implementation details for estimating the zeros +// of the Airy functions airy_ai and airy_bi on the negative real axis. +// +#ifndef BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ + #define BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ + + #include + #include + + namespace boost { namespace math { + namespace detail + { + // Forward declarations of the needed Airy function implementations. + template + T airy_ai_imp(T x, const Policy& pol); + template + T airy_bi_imp(T x, const Policy& pol); + template + T airy_ai_prime_imp(T x, const Policy& pol); + template + T airy_bi_prime_imp(T x, const Policy& pol); + + namespace airy_zero + { + template + T equation_as_10_4_105(const T& z, const Policy& pol) + { + const T one_over_z (T(1) / z); + const T one_over_z_squared(one_over_z * one_over_z); + + const T z_pow_third (boost::math::cbrt(z, pol)); + const T z_pow_two_thirds(z_pow_third * z_pow_third); + + // Implement the top line of Eq. 10.4.105. + const T fz(z_pow_two_thirds * ((((( + (T(162375596875.0) / 334430208UL) + * one_over_z_squared - ( T(108056875.0) / 6967296UL)) + * one_over_z_squared + ( T(77125UL) / 82944UL)) + * one_over_z_squared - ( T(5U) / 36U)) + * one_over_z_squared + ( T(5U) / 48U)) + * one_over_z_squared + 1)); + + return fz; + } + + namespace airy_ai_zero_detail + { + template + T initial_guess(const int m, const Policy& pol) + { + T guess; + + switch(m) + { + case 0: + guess = T(0); + break; + case 1: + guess = T(-2.33810741045976703849); + break; + case 2: + guess = T(-4.08794944413097061664); + break; + case 3: + guess = T(-5.52055982809555105913); + break; + case 4: + guess = T(-6.78670809007175899878); + break; + case 5: + guess = T(-7.94413358712085312314); + break; + case 6: + guess = T(-9.02265085334098038016); + break; + case 7: + guess = T(-10.0401743415580859306); + break; + case 8: + guess = T(-11.0085243037332628932); + break; + case 9: + guess = T(-11.9360155632362625170); + break; + case 10: + guess = T(-12.8287767528657572004); + break; + default: + const T t(((boost::math::constants::pi() * 3) * ((T(m) * 4) - 1)) / 8); + guess = -boost::math::detail::airy_zero::equation_as_10_4_105(t, pol); + break; + } + + return guess; + } + + template + class function_object_ai_and_ai_prime + { + public: + explicit function_object_ai_and_ai_prime(const Policy& pol) : my_pol(pol) { } + + function_object_ai_and_ai_prime(const function_object_ai_and_ai_prime&) = default; + + boost::math::tuple operator()(const T& x) const + { + // Return a tuple containing both Ai(x) and Ai'(x). + return boost::math::make_tuple( + boost::math::detail::airy_ai_imp (x, my_pol), + boost::math::detail::airy_ai_prime_imp(x, my_pol)); + } + + private: + const Policy& my_pol; + const function_object_ai_and_ai_prime& operator=(const function_object_ai_and_ai_prime&) = delete; + }; + } // namespace airy_ai_zero_detail + + namespace airy_bi_zero_detail + { + template + T initial_guess(const int m, const Policy& pol) + { + T guess; + + switch(m) + { + case 0: + guess = T(0); + break; + case 1: + guess = T(-1.17371322270912792492); + break; + case 2: + guess = T(-3.27109330283635271568); + break; + case 3: + guess = T(-4.83073784166201593267); + break; + case 4: + guess = T(-6.16985212831025125983); + break; + case 5: + guess = T(-7.37676207936776371360); + break; + case 6: + guess = T(-8.49194884650938801345); + break; + case 7: + guess = T(-9.53819437934623888663); + break; + case 8: + guess = T(-10.5299135067053579244); + break; + case 9: + guess = T(-11.4769535512787794379); + break; + case 10: + guess = T(-12.3864171385827387456); + break; + default: + const T t(((boost::math::constants::pi() * 3) * ((T(m) * 4) - 3)) / 8); + guess = -boost::math::detail::airy_zero::equation_as_10_4_105(t, pol); + break; + } + + return guess; + } + + template + class function_object_bi_and_bi_prime + { + public: + explicit function_object_bi_and_bi_prime(const Policy& pol) : my_pol(pol) { } + + function_object_bi_and_bi_prime(const function_object_bi_and_bi_prime&) = default; + + boost::math::tuple operator()(const T& x) const + { + // Return a tuple containing both Bi(x) and Bi'(x). + return boost::math::make_tuple( + boost::math::detail::airy_bi_imp (x, my_pol), + boost::math::detail::airy_bi_prime_imp(x, my_pol)); + } + + private: + const Policy& my_pol; + const function_object_bi_and_bi_prime& operator=(const function_object_bi_and_bi_prime&) = delete; + }; + } // namespace airy_bi_zero_detail + } // namespace airy_zero + } // namespace detail + } // namespace math + } // namespaces boost + +#endif // BOOST_MATH_AIRY_AI_BI_ZERO_2013_01_20_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bernoulli_details.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bernoulli_details.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bernoulli_details.hpp @@ -0,0 +1,629 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 John Maddock +// Distributed under 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_BERNOULLI_DETAIL_HPP +#define BOOST_MATH_BERNOULLI_DETAIL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_MATH_NO_ATOMIC_INT) +#include +#else +# define BOOST_MATH_BERNOULLI_NOTHREADS +#endif + +namespace boost{ namespace math{ namespace detail{ +// +// Asymptotic expansion for B2n due to +// Luschny LogB3 formula (http://www.luschny.de/math/primes/bernincl.html) +// +template +T b2n_asymptotic(int n) +{ + BOOST_MATH_STD_USING + const auto nx = static_cast(n); + const T nx2(nx * nx); + + const T approximate_log_of_bernoulli_bn = + ((boost::math::constants::half() + nx) * log(nx)) + + ((boost::math::constants::half() - nx) * log(boost::math::constants::pi())) + + (((T(3) / 2) - nx) * boost::math::constants::ln_two()) + + ((nx * (T(2) - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520)); + return ((n / 2) & 1 ? 1 : -1) * (approximate_log_of_bernoulli_bn > tools::log_max_value() + ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, nx, Policy()) + : static_cast(exp(approximate_log_of_bernoulli_bn))); +} + +template +T t2n_asymptotic(int n) +{ + BOOST_MATH_STD_USING + // Just get B2n and convert to a Tangent number: + T t2n = fabs(b2n_asymptotic(2 * n)) / (2 * n); + T p2 = ldexp(T(1), n); + if(tools::max_value() / p2 < t2n) + { + return policies::raise_overflow_error("boost::math::tangent_t2n<%1%>(std::size_t)", nullptr, T(n), Policy()); + } + t2n *= p2; + p2 -= 1; + if(tools::max_value() / p2 < t2n) + { + return policies::raise_overflow_error("boost::math::tangent_t2n<%1%>(std::size_t)", nullptr, Policy()); + } + t2n *= p2; + return t2n; +} +// +// We need to know the approximate value of /n/ which will +// cause bernoulli_b2n(n) to return infinity - this allows +// us to elude a great deal of runtime checking for values below +// n, and only perform the full overflow checks when we know that we're +// getting close to the point where our calculations will overflow. +// We use Luschny's LogB3 formula (http://www.luschny.de/math/primes/bernincl.html) +// to find the limit, and since we're dealing with the log of the Bernoulli numbers +// we need only perform the calculation at double precision and not with T +// (which may be a multiprecision type). The limit returned is within 1 of the true +// limit for all the types tested. Note that although the code below is basically +// the same as b2n_asymptotic above, it has been recast as a continuous real-valued +// function as this makes the root finding go smoother/faster. It also omits the +// sign of the Bernoulli number. +// +struct max_bernoulli_root_functor +{ + explicit max_bernoulli_root_functor(unsigned long long t) : target(static_cast(t)) {} + double operator()(double n) const + { + BOOST_MATH_STD_USING + + // Luschny LogB3(n) formula. + + const double nx2(n * n); + + const double approximate_log_of_bernoulli_bn + = ((boost::math::constants::half() + n) * log(n)) + + ((boost::math::constants::half() - n) * log(boost::math::constants::pi())) + + (((static_cast(3) / 2) - n) * boost::math::constants::ln_two()) + + ((n * (2 - (nx2 * 7) * (1 + ((nx2 * 30) * ((nx2 * 12) - 1))))) / (((nx2 * nx2) * nx2) * 2520)); + + return approximate_log_of_bernoulli_bn - target; + } +private: + double target; +}; + +template +inline std::size_t find_bernoulli_overflow_limit(const std::false_type&) +{ + // Set a limit on how large the result can ever be: + static const auto max_result = static_cast((std::numeric_limits::max)() - 1000u); + + unsigned long long t = lltrunc(boost::math::tools::log_max_value()); + max_bernoulli_root_functor fun(t); + boost::math::tools::equal_floor tol; + std::uintmax_t max_iter = boost::math::policies::get_max_root_iterations(); + double result = boost::math::tools::toms748_solve(fun, sqrt(static_cast(t)), static_cast(t), tol, max_iter).first / 2; + if (result > max_result) + { + result = max_result; + } + + return static_cast(result); +} + +template +inline std::size_t find_bernoulli_overflow_limit(const std::true_type&) +{ + return max_bernoulli_index::value>::value; +} + +template +std::size_t b2n_overflow_limit() +{ + // This routine is called at program startup if it's called at all: + // that guarantees safe initialization of the static variable. + using tag_type = std::integral_constant::value >= 1) && (bernoulli_imp_variant::value <= 3)>; + static const std::size_t lim = find_bernoulli_overflow_limit(tag_type()); + return lim; +} + +// +// The tangent numbers grow larger much more rapidly than the Bernoulli numbers do.... +// so to compute the Bernoulli numbers from the tangent numbers, we need to avoid spurious +// overflow in the calculation, we can do this by scaling all the tangent number by some scale factor: +// +template ::is_specialized && (std::numeric_limits::radix == 2), bool>::type = true> +inline T tangent_scale_factor() +{ + BOOST_MATH_STD_USING + return ldexp(T(1), std::numeric_limits::min_exponent + 5); +} + +template ::is_specialized || !(std::numeric_limits::radix == 2), bool>::type = true> +inline T tangent_scale_factor() +{ + return tools::min_value() * 16; +} + +// +// We need something to act as a cache for our calculated Bernoulli numbers. In order to +// ensure both fast access and thread safety, we need a stable table which may be extended +// in size, but which never reallocates: that way values already calculated may be accessed +// concurrently with another thread extending the table with new values. +// +// Very very simple vector class that will never allocate more than once, we could use +// boost::container::static_vector here, but that allocates on the stack, which may well +// cause issues for the amount of memory we want in the extreme case... +// +template +struct fixed_vector : private std::allocator +{ + using size_type = unsigned; + using iterator = T*; + using const_iterator = const T*; + fixed_vector() : m_used(0) + { + std::size_t overflow_limit = 5 + b2n_overflow_limit >(); + m_capacity = static_cast((std::min)(overflow_limit, static_cast(100000u))); + m_data = this->allocate(m_capacity); + } + ~fixed_vector() + { + using allocator_type = std::allocator; + using allocator_traits = std::allocator_traits; + allocator_type& alloc = *this; + for(unsigned i = 0; i < m_used; ++i) + { + allocator_traits::destroy(alloc, &m_data[i]); + } + allocator_traits::deallocate(alloc, m_data, m_capacity); + } + T& operator[](unsigned n) { BOOST_MATH_ASSERT(n < m_used); return m_data[n]; } + const T& operator[](unsigned n)const { BOOST_MATH_ASSERT(n < m_used); return m_data[n]; } + unsigned size()const { return m_used; } + unsigned size() { return m_used; } + bool resize(unsigned n, const T& val) + { + if(n > m_capacity) + { +#ifndef BOOST_NO_EXCEPTIONS + BOOST_MATH_THROW_EXCEPTION(std::runtime_error("Exhausted storage for Bernoulli numbers.")); +#else + return false; +#endif + } + for(unsigned i = m_used; i < n; ++i) + new (m_data + i) T(val); + m_used = n; + return true; + } + bool resize(unsigned n) { return resize(n, T()); } + T* begin() { return m_data; } + T* end() { return m_data + m_used; } + T* begin()const { return m_data; } + T* end()const { return m_data + m_used; } + unsigned capacity()const { return m_capacity; } + void clear() { m_used = 0; } +private: + T* m_data; + unsigned m_used {}; + unsigned m_capacity; +}; + +template +class bernoulli_numbers_cache +{ +public: + bernoulli_numbers_cache() : m_overflow_limit((std::numeric_limits::max)()) + , m_counter(0) + , m_current_precision(boost::math::tools::digits()) + {} + + using container_type = fixed_vector; + + bool tangent(std::size_t m) + { + static const std::size_t min_overflow_index = b2n_overflow_limit() - 1; + + if (!tn.resize(static_cast(m), T(0U))) + { + return false; + } + + BOOST_MATH_INSTRUMENT_VARIABLE(min_overflow_index); + + std::size_t prev_size = m_intermediates.size(); + m_intermediates.resize(m, T(0U)); + + if(prev_size == 0) + { + m_intermediates[1] = tangent_scale_factor() /*T(1U)*/; + tn[0U] = T(0U); + tn[1U] = tangent_scale_factor()/* T(1U)*/; + BOOST_MATH_INSTRUMENT_VARIABLE(tn[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(tn[1]); + } + + for(std::size_t i = std::max(2, prev_size); i < m; i++) + { + bool overflow_check = false; + if(i >= min_overflow_index && (boost::math::tools::max_value() / (i-1) < m_intermediates[1]) ) + { + std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value()); + break; + } + m_intermediates[1] = m_intermediates[1] * (i-1); + for(std::size_t j = 2; j <= i; j++) + { + overflow_check = + (i >= min_overflow_index) && ( + (boost::math::tools::max_value() / (i - j) < m_intermediates[j]) + || (boost::math::tools::max_value() / (i - j + 2) < m_intermediates[j-1]) + || (boost::math::tools::max_value() - m_intermediates[j] * (i - j) < m_intermediates[j-1] * (i - j + 2)) + || ((boost::math::isinf)(m_intermediates[j])) + ); + + if(overflow_check) + { + std::fill(tn.begin() + i, tn.end(), boost::math::tools::max_value()); + break; + } + m_intermediates[j] = m_intermediates[j] * (i - j) + m_intermediates[j-1] * (i - j + 2); + } + if(overflow_check) + break; // already filled the tn... + tn[static_cast(i)] = m_intermediates[i]; + BOOST_MATH_INSTRUMENT_VARIABLE(i); + BOOST_MATH_INSTRUMENT_VARIABLE(tn[static_cast(i)]); + } + return true; + } + + bool tangent_numbers_series(const std::size_t m) + { + BOOST_MATH_STD_USING + static const std::size_t min_overflow_index = b2n_overflow_limit() - 1; + + typename container_type::size_type old_size = bn.size(); + + if (!tangent(m)) + return false; + if (!bn.resize(static_cast(m))) + return false; + + if(!old_size) + { + bn[0] = 1; + old_size = 1; + } + + T power_two(ldexp(T(1), static_cast(2 * old_size))); + + for(std::size_t i = old_size; i < m; i++) + { + T b(static_cast(i * 2)); + // + // Not only do we need to take care to avoid spurious over/under flow in + // the calculation, but we also need to avoid overflow altogether in case + // we're calculating with a type where "bad things" happen in that case: + // + b = b / (power_two * tangent_scale_factor()); + b /= (power_two - 1); + bool overflow_check = (i >= min_overflow_index) && (tools::max_value() / tn[static_cast(i)] < b); + if(overflow_check) + { + m_overflow_limit = i; + while(i < m) + { + b = std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : tools::max_value(); + bn[static_cast(i)] = ((i % 2U) ? b : T(-b)); + ++i; + } + break; + } + else + { + b *= tn[static_cast(i)]; + } + + power_two = ldexp(power_two, 2); + + const bool b_neg = i % 2 == 0; + + bn[static_cast(i)] = ((!b_neg) ? b : T(-b)); + } + return true; + } + + template + OutputIterator copy_bernoulli_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol) + { + // + // There are basically 3 thread safety options: + // + // 1) There are no threads (BOOST_HAS_THREADS is not defined). + // 2) There are threads, but we do not have a true atomic integer type, + // in this case we just use a mutex to guard against race conditions. + // 3) There are threads, and we have an atomic integer: in this case we can + // use the double-checked locking pattern to avoid thread synchronisation + // when accessing values already in the cache. + // + // First off handle the common case for overflow and/or asymptotic expansion: + // + if(start + n > bn.capacity()) + { + if(start < bn.capacity()) + { + out = copy_bernoulli_numbers(out, start, bn.capacity() - start, pol); + n -= bn.capacity() - start; + start = static_cast(bn.capacity()); + } + if(start < b2n_overflow_limit() + 2u) + { + for(; n; ++start, --n) + { + *out = b2n_asymptotic(static_cast(start * 2U)); + ++out; + } + } + for(; n; ++start, --n) + { + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(start), pol); + ++out; + } + return out; + } + + #if defined(BOOST_HAS_THREADS) && defined(BOOST_MATH_BERNOULLI_NOTHREADS) && !defined(BOOST_MATH_BERNOULLI_UNTHREADED) + // Add a static_assert on instantiation if we have threads, but no C++11 threading support. + static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have either no atomic integers, or no std::mutex. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); + #elif defined(BOOST_MATH_BERNOULLI_NOTHREADS) + // + // Single threaded code, very simple: + // + if(m_current_precision < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + { + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + } + + for(std::size_t i = (std::max)(std::size_t(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + *out = (i >= m_overflow_limit) ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol) : bn[i]; + ++out; + } + #else + // + // Double-checked locking pattern, lets us access cached already cached values + // without locking: + // + // Get the counter and see if we need to calculate more constants: + // + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + std::lock_guard l(m_mutex); + + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + if(static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_counter.store(0, std::memory_order_release); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(std::size_t(start + n), std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(new_size), pol)); + } + m_counter.store(static_cast(bn.size()), std::memory_order_release); + } + } + + for(std::size_t i = (std::max)(static_cast(max_bernoulli_b2n::value + 1), start); i < start + n; ++i) + { + *out = (i >= m_overflow_limit) ? policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol) : bn[static_cast(i)]; + ++out; + } + + #endif // BOOST_HAS_THREADS + return out; + } + + template + OutputIterator copy_tangent_numbers(OutputIterator out, std::size_t start, std::size_t n, const Policy& pol) + { + // + // There are basically 3 thread safety options: + // + // 1) There are no threads (BOOST_HAS_THREADS is not defined). + // 2) There are threads, but we do not have a true atomic integer type, + // in this case we just use a mutex to guard against race conditions. + // 3) There are threads, and we have an atomic integer: in this case we can + // use the double-checked locking pattern to avoid thread synchronisation + // when accessing values already in the cache. + // + // + // First off handle the common case for overflow and/or asymptotic expansion: + // + if(start + n > bn.capacity()) + { + if(start < bn.capacity()) + { + out = copy_tangent_numbers(out, start, bn.capacity() - start, pol); + n -= bn.capacity() - start; + start = static_cast(bn.capacity()); + } + if(start < b2n_overflow_limit() + 2u) + { + for(; n; ++start, --n) + { + *out = t2n_asymptotic(static_cast(start)); + ++out; + } + } + for(; n; ++start, --n) + { + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(start), pol); + ++out; + } + return out; + } + + #if defined(BOOST_MATH_BERNOULLI_NOTHREADS) + // + // Single threaded code, very simple: + // + if(m_current_precision < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + + for(std::size_t i = start; i < start + n; ++i) + { + if(i >= m_overflow_limit) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + { + if(tools::max_value() * tangent_scale_factor() < tn[static_cast(i)]) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + *out = tn[static_cast(i)] / tangent_scale_factor(); + } + ++out; + } + #elif defined(BOOST_MATH_NO_ATOMIC_INT) + static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have no atomic integers. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); + #else + // + // Double-checked locking pattern, lets us access cached already cached values + // without locking: + // + // Get the counter and see if we need to calculate more constants: + // + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + std::lock_guard l(m_mutex); + + if((static_cast(m_counter.load(std::memory_order_consume)) < start + n) + || (static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits())) + { + if(static_cast(m_current_precision.load(std::memory_order_consume)) < boost::math::tools::digits()) + { + bn.clear(); + tn.clear(); + m_intermediates.clear(); + m_counter.store(0, std::memory_order_release); + m_current_precision = boost::math::tools::digits(); + } + if(start + n >= bn.size()) + { + std::size_t new_size = (std::min)((std::max)((std::max)(start + n, std::size_t(bn.size() + 20)), std::size_t(50)), std::size_t(bn.capacity())); + if (!tangent_numbers_series(new_size)) + return std::fill_n(out, n, policies::raise_evaluation_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", "Unable to allocate Bernoulli numbers cache for %1% values", T(start + n), pol)); + } + m_counter.store(static_cast(bn.size()), std::memory_order_release); + } + } + + for(std::size_t i = start; i < start + n; ++i) + { + if(i >= m_overflow_limit) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + { + if(tools::max_value() * tangent_scale_factor() < tn[static_cast(i)]) + *out = policies::raise_overflow_error("boost::math::bernoulli_b2n<%1%>(std::size_t)", nullptr, T(i), pol); + else + *out = tn[static_cast(i)] / tangent_scale_factor(); + } + ++out; + } + + #endif // BOOST_HAS_THREADS + return out; + } + +private: + // + // The caches for Bernoulli and tangent numbers, once allocated, + // these must NEVER EVER reallocate as it breaks our thread + // safety guarantees: + // + fixed_vector bn, tn; + std::vector m_intermediates; + // The value at which we know overflow has already occurred for the Bn: + std::size_t m_overflow_limit; + + #if !defined(BOOST_MATH_BERNOULLI_NOTHREADS) + std::mutex m_mutex; + atomic_counter_type m_counter, m_current_precision; + #else + int m_counter; + int m_current_precision; + #endif // BOOST_HAS_THREADS +}; + +template +inline typename std::enable_if<(std::numeric_limits::digits == 0) || (std::numeric_limits::digits >= INT_MAX), bernoulli_numbers_cache&>::type get_bernoulli_numbers_cache() +{ + // + // When numeric_limits<>::digits is zero, the type has either not specialized numeric_limits at all + // or it's precision can vary at runtime. So make the cache thread_local so that each thread can + // have it's own precision if required: + // + static +#ifndef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES + BOOST_MATH_THREAD_LOCAL +#endif + bernoulli_numbers_cache data; + return data; +} +template +inline typename std::enable_if::digits && (std::numeric_limits::digits < INT_MAX), bernoulli_numbers_cache&>::type get_bernoulli_numbers_cache() +{ + // + // Note that we rely on C++11 thread-safe initialization here: + // + static bernoulli_numbers_cache data; + return data; +} + +}}} + +#endif // BOOST_MATH_BERNOULLI_DETAIL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_derivatives_linear.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_derivatives_linear.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_derivatives_linear.hpp @@ -0,0 +1,87 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Linear combination for bessel derivatives are defined here +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +inline T bessel_j_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + return (boost::math::detail::cyl_bessel_j_imp(v-1, x, tag, pol) - boost::math::detail::cyl_bessel_j_imp(v+1, x, tag, pol)) / 2; +} + +template +inline T bessel_j_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + return (boost::math::detail::cyl_bessel_j_imp(itrunc(v-1), x, tag, pol) - boost::math::detail::cyl_bessel_j_imp(itrunc(v+1), x, tag, pol)) / 2; +} + +template +inline T sph_bessel_j_derivative_linear(unsigned v, T x, Policy pol) +{ + return (v / x) * boost::math::detail::sph_bessel_j_imp(v, x, pol) - boost::math::detail::sph_bessel_j_imp(v+1, x, pol); +} + +template +inline T bessel_i_derivative_linear(T v, T x, Policy pol) +{ + T result = boost::math::detail::cyl_bessel_i_imp(v - 1, x, pol); + if(result >= tools::max_value()) + return result; // result is infinite + T result2 = boost::math::detail::cyl_bessel_i_imp(v + 1, x, pol); + if(result2 >= tools::max_value() - result) + return result2; // result is infinite + return (result + result2) / 2; +} + +template +inline T bessel_k_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + T result = boost::math::detail::cyl_bessel_k_imp(v - 1, x, tag, pol); + if(result >= tools::max_value()) + return -result; // result is infinite + T result2 = boost::math::detail::cyl_bessel_k_imp(v + 1, x, tag, pol); + if(result2 >= tools::max_value() - result) + return -result2; // result is infinite + return (result + result2) / -2; +} + +template +inline T bessel_k_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + return (boost::math::detail::cyl_bessel_k_imp(itrunc(v-1), x, tag, pol) + boost::math::detail::cyl_bessel_k_imp(itrunc(v+1), x, tag, pol)) / -2; +} + +template +inline T bessel_y_derivative_linear(T v, T x, Tag tag, Policy pol) +{ + return (boost::math::detail::cyl_neumann_imp(v-1, x, tag, pol) - boost::math::detail::cyl_neumann_imp(v+1, x, tag, pol)) / 2; +} + +template +inline T bessel_y_derivative_linear(T v, T x, const bessel_int_tag& tag, Policy pol) +{ + return (boost::math::detail::cyl_neumann_imp(itrunc(v-1), x, tag, pol) - boost::math::detail::cyl_neumann_imp(itrunc(v+1), x, tag, pol)) / 2; +} + +template +inline T sph_neumann_derivative_linear(unsigned v, T x, Policy pol) +{ + return (v / x) * boost::math::detail::sph_neumann_imp(v, x, pol) - boost::math::detail::sph_neumann_imp(v+1, x, pol); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_BESSEL_DERIVATIVES_LINEAR_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i0.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i0.hpp @@ -0,0 +1,564 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 John Maddock +// 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_BESSEL_I0_HPP +#define BOOST_MATH_BESSEL_I0_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the first kind of order zero +// we use the approximating forms derived in: +// "Rational Approximations for the Modified Bessel Function of the First Kind - I0(x) for Computations with Double Precision" +// by Pavel Holoborodko, +// see http://www.advanpix.com/2015/11/11/rational-approximations-for-the-modified-bessel-function-of-the-first-kind-i0-computations-double-precision +// The actual coefficients used are our own, and extend Pavel's work to precision's other than double. + +namespace boost { namespace math { namespace detail{ + +template +T bessel_i0(const T& x); + +template +struct bessel_i0_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&) + { + bessel_i0(T(1)); + bessel_i0(T(8)); + bessel_i0(T(12)); + bessel_i0(T(40)); + bessel_i0(T(101)); + } + static void do_init(const std::integral_constant&) + { + bessel_i0(T(1)); + bessel_i0(T(10)); + bessel_i0(T(20)); + bessel_i0(T(40)); + bessel_i0(T(101)); + } + template + static void do_init(const U&) {} + void force_instantiate()const {} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_i0_initializer::init bessel_i0_initializer::initializer; + +template +T bessel_i0_imp(const T&, const std::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +T bessel_i0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Max error in interpolated form: 3.929e-08 + // Max Error found at float precision = Poly: 1.991226e-07 + static const float P[] = { + 1.00000003928615375e+00f, + 2.49999576572179639e-01f, + 2.77785268558399407e-02f, + 1.73560257755821695e-03f, + 6.96166518788906424e-05f, + 1.89645733877137904e-06f, + 4.29455004657565361e-08f, + 3.90565476357034480e-10f, + 1.48095934745267240e-11f + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 50) + { + // Max error in interpolated form: 5.195e-08 + // Max Error found at float precision = Poly: 8.502534e-08 + static const float P[] = { + 3.98942651588301770e-01f, + 4.98327234176892844e-02f, + 2.91866904423115499e-02f, + 1.35614940793742178e-02f, + 1.31409251787866793e-01f + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form: 1.782e-09 + // Max Error found at float precision = Poly: 6.473568e-08 + static const float P[] = { + 3.98942391532752700e-01f, + 4.98455950638200020e-02f, + 2.94835666900682535e-02f + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form : 3.042e-18 + // Max Error found at double precision = Poly : 5.106609e-16 Cheb : 5.239199e-16 + static const double P[] = { + 1.00000000000000000e+00, + 2.49999999999999909e-01, + 2.77777777777782257e-02, + 1.73611111111023792e-03, + 6.94444444453352521e-05, + 1.92901234513219920e-06, + 3.93675991102510739e-08, + 6.15118672704439289e-10, + 7.59407002058973446e-12, + 7.59389793369836367e-14, + 6.27767773636292611e-16, + 4.34709704153272287e-18, + 2.63417742690109154e-20, + 1.13943037744822825e-22, + 9.07926920085624812e-25 + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 500) + { + // Max error in interpolated form : 1.685e-16 + // Max Error found at double precision = Poly : 2.575063e-16 Cheb : 2.247615e+00 + static const double P[] = { + 3.98942280401425088e-01, + 4.98677850604961985e-02, + 2.80506233928312623e-02, + 2.92211225166047873e-02, + 4.44207299493659561e-02, + 1.30970574605856719e-01, + -3.35052280231727022e+00, + 2.33025711583514727e+02, + -1.13366350697172355e+04, + 4.24057674317867331e+05, + -1.23157028595698731e+07, + 2.80231938155267516e+08, + -5.01883999713777929e+09, + 7.08029243015109113e+10, + -7.84261082124811106e+11, + 6.76825737854096565e+12, + -4.49034849696138065e+13, + 2.24155239966958995e+14, + -8.13426467865659318e+14, + 2.02391097391687777e+15, + -3.08675715295370878e+15, + 2.17587543863819074e+15 + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form : 2.437e-18 + // Max Error found at double precision = Poly : 1.216719e-16 + static const double P[] = { + 3.98942280401432905e-01, + 4.98677850491434560e-02, + 2.80506308916506102e-02, + 2.92179096853915176e-02, + 4.53371208762579442e-02 + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form : 3.899e-20 + // Max Error found at float80 precision = Poly : 1.770840e-19 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 9.99999999999999999961011629e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.50000000000000001321873912e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.77777777777777703400424216e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.73611111111112764793802701e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94444444444251461247253525e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.92901234569262206386118739e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.93675988851131457141005209e-08), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.15118734688297476454205352e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59405797058091016449222685e-12), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59406599631719800679835140e-14), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.27598961062070013516660425e-16), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.35920318970387940278362992e-18), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.57372492687715452949437981e-20), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.33908663475949906992942204e-22), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.15976668870980234582896010e-25), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.46240478946376069211156548e-27) + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 10) + { + // Maximum Deviation Found: 6.906e-21 + // Expected Error Term : -6.903e-21 + // Maximum Relative Change in Control Points : 1.631e-04 + // Max Error found at float80 precision = Poly : 7.811948e-21 + static const T Y = 4.051098823547363281250e-01f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -6.158081780620616479492e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.883635969834048766148e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.892782002476195771920e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.478784996478070170327e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.988611837308006851257e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.140133766747436806179e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.117316447921276453271e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.942353667455141676001e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.493482682461387081534e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.228100538921466124653e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.195279248600467989454e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.601530760654337045917e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.504921137873298402679e+05) + }; + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else if(x < 15) + { + // Maximum Deviation Found: 4.083e-21 + // Expected Error Term : -4.025e-21 + // Maximum Relative Change in Control Points : 1.304e-03 + // Max Error found at float80 precision = Poly : 2.303527e-20 + static const T Y = 4.033188819885253906250e-01f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -4.376373876116109401062e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.982899138682911273321e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.109477529533515397644e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.163760580110576407673e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.776501832837367371883e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.101478069227776656318e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.892071912448960299773e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.417739279982328117483e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.296963447724067390552e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.598589306710589358747e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.903662411851774878322e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.622677059040339516093e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.227776578828667629347e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.727797957441040896878e+07) + }; + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else if(x < 50) + { + // Max error in interpolated form: 1.035e-21 + // Max Error found at float80 precision = Poly: 1.885872e-21 + static const T Y = 4.011702537536621093750e-01f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -2.227973351806078464328e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.986778486088017419036e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.805066823812285310011e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.921443721160964964623e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.517504941996594744052e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.316922639868793684401e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.535891099168810015433e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.706078229522448308087e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.351015763079160914632e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.948809013999277355098e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.967598958582595361757e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.346924657995383019558e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.998794574259956613472e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.016371355801690142095e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.768791455631826490838e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.441995678177349895640e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.482292669974971387738e+09) + }; + return exp(x) * (boost::math::tools::evaluate_polynomial(P, T(1 / x)) + Y) / sqrt(x); + } + else + { + // Bessel I0 over[50, INF] + // Max error in interpolated form : 5.587e-20 + // Max Error found at float80 precision = Poly : 8.776852e-20 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401432677955074061e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.98677850501789875615574058e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.80506290908675604202206833e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.92194052159035901631494784e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.47422430732256364094681137e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.05971614435738691235525172e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.29180522595459823234266708e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.15122547776140254569073131e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.48491812136365376477357324e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.45569740166506688169730713e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.66857566379480730407063170e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.71924083955641197750323901e+05), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.74276685704579268845870586e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -8.89753803265734681907148778e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.82590905134996782086242180e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.30623197145529889358596301e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.27310000726207055200805893e+10), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.64365417189215599168817064e+10) + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -34, 7.75] + // Max error in interpolated form : 1.274e-34 + // Max Error found at float128 precision = Poly : 3.096091e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000001273856e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4999999999999999999999999999999107477496e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7777777777777777777777777777881795230918e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7361111111111111111111111106290091648808e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444444444444445629960334523101e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9290123456790123456790105563456483249753e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9367598891408415217940836339080514004844e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.1511873267825648777900014857992724731476e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266233066162999610732449709209e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266232783124723601470051895304e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2760813455591936763439337059117957836078e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3583898233049738471136482147779094353096e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5789288895299965395422423848480340736308e-20), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3157800456718804437960453545507623434606e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.8479113149412360748032684260932041506493e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2843403488398038539283241944594140493394e-27), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9042925594356556196790242908697582021825e-30), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4395919891312152120710245152115597111101e-32), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.7580986145276689333214547502373003196707e-35), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6886514018062348877723837017198859723889e-37), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.8540558465757554512570197585002702777999e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.4684706070226893763741850944911705726436e-43), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.0210715309399646335858150349406935414314e-45) + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 15) + { + // Bessel I0 over[7.75, 15] + // Max error in interpolated form : 7.534e-35 + // Max Error found at float128 precision = Poly : 6.123912e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 9.9999999999999999992388573069504617493518e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5000000000000000007304739268173096975340e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7777777777777777744261405400543564492074e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7361111111111111209006987259719750726867e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444442399703186871329381908321e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9290123456790126709286741580242189785431e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9367598891408374246503061422528266924389e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.1511873267826068395343047827801353170966e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281262673459688011737168286944521e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281291583769928563167645746144508e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2760813455438840231126529638737436950274e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3583898233839583885132809584770578894948e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5789288891798658971960571838369339742994e-20), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3157800470129311623308216856009970266088e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.8479112701534604520063520412207286692581e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2843404822552330714586265081801727491890e-27), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9042888166225242675881424439818162458179e-30), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4396027771820721384198604723320045236973e-32), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.7577659910606076328136207973456511895030e-35), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6896548123724136624716224328803899914646e-37), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.8285850162160539150210466453921758781984e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.9419071894227736216423562425429524883562e-43), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.4720374049498608905571855665134539425038e-45), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7763533278527958112907118930154738930378e-48), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.1213839473168678646697528580511702663617e-51), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0648035313124146852372607519737686740964e-53), + -BOOST_MATH_BIG_CONSTANT(T, 113, 5.1255595184052024349371058585102280860878e-57), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4652470895944157957727948355523715335882e-59) + }; + T a = x * x / 4; + return a * boost::math::tools::evaluate_polynomial(P, a) + 1; + } + else if(x < 30) + { + // Max error in interpolated form : 1.808e-34 + // Max Error found at float128 precision = Poly : 2.399403e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040870793650581242239624530714032e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867780576714783790784348982178607842250e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8051948347934462928487999569249907599510e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8971143420388958551176254291160976367263e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.8197359701715582763961322341827341098897e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.3430484862908317377522273217643346601271e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7884507603213662610604413960838990199224e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.8304926482356755790062999202373909300514e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.8867173178574875515293357145875120137676e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.4261178812193528551544261731796888257644e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.6453010340778116475788083817762403540097e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.0432401330113978669454035365747869477960e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2462165331309799059332310595587606836357e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.3299800389951335932792950236410844978273e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5748218240248714177527965706790413406639e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8330014378766930869945511450377736037385e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.8494610073827453236940544799030787866218e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.7244661371420647691301043350229977856476e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.2386378807889388140099109087465781254321e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.1104000573102013529518477353943384110982e+21), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.9426541092239879262282594572224300191016e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4061439136301913488512592402635688101020e+23), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.2836554760521986358980180942859101564671e+24), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6270285589905206294944214795661236766988e+25), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.7278631455211972017740134341610659484259e+26), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.1971734473772196124736986948034978906801e+26), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.8669270707172568763908838463689093500098e+27), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2368879358870281916900125550129211146626e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.8296235063297831758204519071113999839858e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.1253861666023020670144616019148954773662e+28), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.8809536950051955163648980306847791014734e+28) }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Bessel I0 over[30, 100] + // Max error in interpolated form : 1.487e-34 + // Max Error found at float128 precision = Poly : 1.929924e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793996798658172135362278e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867785050179084714910130342157246539820e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8050629090725751585266360464766768437048e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.9219405302833158254515212437025679637597e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.4742214371598631578107310396249912330627e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.0602983776478659136184969363625092585520e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2839507231977478205885469900971893734770e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8925739165733823730525449511456529001868e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4238082222874015159424842335385854632223e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.6759648427182491050716309699208988458050e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.7292246491169360014875196108746167872215e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.1001411442786230340015781205680362993575e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.8277628835804873490331739499978938078848e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.1208326312801432038715638596517882759639e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.4813611580683862051838126076298945680803e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.1278197693321821164135890132925119054391e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3190303792682886967459489059860595063574e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.1580767338646580750893606158043485767644e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.0256008808415702780816006134784995506549e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.9044186472918017896554580836514681614475e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.2521078890073151875661384381880225635135e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3620352486836976842181057590770636605454e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.0375525734060401555856465179734887312420e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.6392664899881014534361728644608549445131e+16) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form : 5.459e-35 + // Max Error found at float128 precision = Poly : 1.472240e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793994605993438166526772e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9867785050179084742493257495245185241487e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8050629090725735167652437695397756897920e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.9219405302839307466358297347675795965363e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.4742214369972689474366968442268908028204e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.0602984099194778006610058410222616383078e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.2839502241666629677015839125593079416327e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8926354981801627920292655818232972385750e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4231921590621824187100989532173995000655e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.7264260959693775207585700654645245723497e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3890136225398811195878046856373030127018e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.1999720924619285464910452647408431234369e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2076909538525038580501368530598517194748e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5684635141332367730007149159063086133399e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.5178192543258299267923025833141286569141e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.2966297919851965784482163987240461837728e+05) }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i0_imp(const T& x, const std::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_i0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_i0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_i0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_i0_imp(x, std::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +inline T bessel_i0(const T& x) +{ + typedef std::integral_constant::digits == 0) || (std::numeric_limits::radix != 2)) ? + 0 : + std::numeric_limits::digits <= 24 ? + 24 : + std::numeric_limits::digits <= 53 ? + 53 : + std::numeric_limits::digits <= 64 ? + 64 : + std::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + bessel_i0_initializer::force_instantiate(); + return bessel_i0_imp(x, tag_type()); +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_I0_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i1.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_i1.hpp @@ -0,0 +1,592 @@ +// Copyright (c) 2017 John Maddock +// 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) + +// Modified Bessel function of the first kind of order zero +// we use the approximating forms derived in: +// "Rational Approximations for the Modified Bessel Function of the First Kind - I1(x) for Computations with Double Precision" +// by Pavel Holoborodko, +// see http://www.advanpix.com/2015/11/12/rational-approximations-for-the-modified-bessel-function-of-the-first-kind-i1-for-computations-with-double-precision/ +// The actual coefficients used are our own, and extend Pavel's work to precision's other than double. + +#ifndef BOOST_MATH_BESSEL_I1_HPP +#define BOOST_MATH_BESSEL_I1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the first kind of order one +// minimax rational approximations on intervals, see +// Blair and Edwards, Chalk River Report AECL-4928, 1974 + +namespace boost { namespace math { namespace detail{ + +template +T bessel_i1(const T& x); + +template +struct bessel_i1_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&) + { + bessel_i1(T(1)); + bessel_i1(T(15)); + bessel_i1(T(80)); + bessel_i1(T(101)); + } + static void do_init(const std::integral_constant&) + { + bessel_i1(T(1)); + bessel_i1(T(10)); + bessel_i1(T(14)); + bessel_i1(T(19)); + bessel_i1(T(34)); + bessel_i1(T(99)); + bessel_i1(T(101)); + } + template + static void do_init(const U&) {} + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_i1_initializer::init bessel_i1_initializer::initializer; + +template +T bessel_i1_imp(const T&, const std::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +T bessel_i1_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + //Max error in interpolated form : 1.348e-08 + // Max Error found at float precision = Poly : 1.469121e-07 + static const float P[] = { + 8.333333221e-02f, + 6.944453712e-03f, + 3.472097211e-04f, + 1.158047174e-05f, + 2.739745142e-07f, + 5.135884609e-09f, + 5.262251502e-11f, + 1.331933703e-12f + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else + { + // Max error in interpolated form: 9.000e-08 + // Max Error found at float precision = Poly: 1.044345e-07 + + static const float P[] = { + 3.98942115977513013e-01f, + -1.49581264836620262e-01f, + -4.76475741878486795e-02f, + -2.65157315524784407e-02f, + -1.47148600683672014e-01f + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i1_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form: 5.639e-17 + // Max Error found at double precision = Poly: 1.795559e-16 + + static const double P[] = { + 8.333333333333333803e-02, + 6.944444444444341983e-03, + 3.472222222225921045e-04, + 1.157407407354987232e-05, + 2.755731926254790268e-07, + 4.920949692800671435e-09, + 6.834657311305621830e-11, + 7.593969849687574339e-13, + 6.904822652741917551e-15, + 5.220157095351373194e-17, + 3.410720494727771276e-19, + 1.625212890947171108e-21, + 1.332898928162290861e-23 + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 500) + { + // Max error in interpolated form: 1.796e-16 + // Max Error found at double precision = Poly: 2.898731e-16 + + static const double P[] = { + 3.989422804014406054e-01, + -1.496033551613111533e-01, + -4.675104253598537322e-02, + -4.090895951581637791e-02, + -5.719036414430205390e-02, + -1.528189554374492735e-01, + 3.458284470977172076e+00, + -2.426181371595021021e+02, + 1.178785865993440669e+04, + -4.404655582443487334e+05, + 1.277677779341446497e+07, + -2.903390398236656519e+08, + 5.192386898222206474e+09, + -7.313784438967834057e+10, + 8.087824484994859552e+11, + -6.967602516005787001e+12, + 4.614040809616582764e+13, + -2.298849639457172489e+14, + 8.325554073334618015e+14, + -2.067285045778906105e+15, + 3.146401654361325073e+15, + -2.213318202179221945e+15 + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Max error in interpolated form: 1.320e-19 + // Max Error found at double precision = Poly: 7.065357e-17 + static const double P[] = { + 3.989422804014314820e-01, + -1.496033551467584157e-01, + -4.675105322571775911e-02, + -4.090421597376992892e-02, + -5.843630344778927582e-02 + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i1_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -16, 7.75] + // Max error in interpolated form: 8.086e-21 + // Max Error found at float80 precision = Poly: 7.225090e-20 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 8.33333333333333333340071817e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94444444444444442462728070e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.47222222222222318886683883e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.15740740740738880709555060e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.75573192240046222242685145e-07), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.92094986131253986838697503e-09), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.83465258979924922633502182e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.59405830675154933645967137e-13), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.90369179710633344508897178e-15), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.23003610041709452814262671e-17), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.35291901027762552549170038e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.83991379419781823063672109e-21), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.87732714140192556332037815e-24), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.32120654663773147206454247e-26), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.95294659305369207813486871e-28) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 20) + { + // Max error in interpolated form: 4.258e-20 + // Max Error found at float80 precision = Poly: 2.851105e-19 + // Maximum Deviation Found : 3.887e-20 + // Expected Error Term : 3.887e-20 + // Maximum Relative Change in Control Points : 1.681e-04 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942260530218897338680e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49599542849073670179540e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.70492865454119188276875e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.12389893307392002405869e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.49696126385202602071197e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.84206507612717711565967e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.14748094784412558689584e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.70652726663596993005669e+04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.01659736164815617174439e+06), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.04740659606466305607544e+07), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.38383394696382837263656e+08), + BOOST_MATH_BIG_CONSTANT(T, 64, -8.00779638649147623107378e+09), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.02338237858684714480491e+10), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.41198553664947312995879e+11), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.05915186909564986897554e+12), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.00907636964168581116181e+13), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.60855263982359981275199e+13), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.12901817219239205393806e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.14861794397709807823575e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.02808138522587680348583e+14), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.85505477056514919387171e+14) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Bessel I0 over [15, 50] + // Maximum Deviation Found: 2.444e-20 + // Expected Error Term : 2.438e-20 + // Maximum Relative Change in Control Points : 2.101e-03 + // Max Error found at float80 precision = Poly : 6.029974e-20 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401431675205845e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49603355149968887210170e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.67510486284376330257260e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.09071458907089270559464e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.75278280327696940044714e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10591299500956620739254e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.77061766699949309115618e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.42683771801837596371638e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.17021412070404158464316e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.04154379346763380543310e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.43462345357478348323006e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.98109660274422449523837e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.74438822767781410362757e+04) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form: 2.456e-20 + // Max Error found at float80 precision = Poly: 5.446356e-20 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98942280401432677958445e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.49603355150537411254359e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.67510484842456251368526e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.09071676503922479645155e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.75256179814881566010606e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10754910257965227825040e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.67858639515616079840294e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.17266479586791298924367e-01) + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i1_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x < 7.75) + { + // Bessel I0 over[10 ^ -34, 7.75] + // Max error in interpolated form: 1.835e-35 + // Max Error found at float128 precision = Poly: 1.645036e-34 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.3333333333333333333333333333333331804098e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9444444444444444444444444444445418303082e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.4722222222222222222222222222119082346591e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.1574074074074074074074074078415867655987e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.7557319223985890652557318255143448192453e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9209498614260519022423916850415000626427e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.8346525853139609753354247043900442393686e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.5940584281266233060080535940234144302217e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.9036894801151120925605467963949641957095e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.2300677879659941472662086395055636394839e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3526075563884539394691458717439115962233e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8420920639497841692288943167036233338434e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.7718669711748690065381181691546032291365e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.6549445715236427401845636880769861424730e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.3437296196812697924703896979250126739676e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.3912734588619073883015937023564978854893e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2839967682792395867255384448052781306897e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.3790094235693528861015312806394354114982e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.0423861671932104308662362292359563970482e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.7493858979396446292135661268130281652945e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.2786079392547776769387921361408303035537e-44), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.2335693685833531118863552173880047183822e-47) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 11) + { + // Max error in interpolated form: 8.574e-36 + // Maximum Deviation Found : 4.689e-36 + // Expected Error Term : 3.760e-36 + // Maximum Relative Change in Control Points : 5.204e-03 + // Max Error found at float128 precision = Poly : 2.882561e-34 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.333333333333333326889717360850080939e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.944444444444444511272790848815114507e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.472222222222221892451965054394153443e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.157407407407408437378868534321538798e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.755731922398566216824909767320161880e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.920949861426434829568192525456800388e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.834652585308926245465686943255486934e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.594058428179852047689599244015979196e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.903689479655006062822949671528763738e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.230067791254403974475987777406992984e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.352607536815161679702105115200693346e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.842092161364672561828681848278567885e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.771862912600611801856514076709932773e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.654958704184380914803366733193713605e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.343688672071130980471207297730607625e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.392252844664709532905868749753463950e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.282086786672692641959912811902298600e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.408812012322547015191398229942864809e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.681220437734066258673404589233009892e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.072417451640733785626701738789290055e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.352218520142636864158849446833681038e-44), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.407918492276267527897751358794783640e-46) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 15) + { + //Max error in interpolated form: 7.599e-36 + // Maximum Deviation Found : 1.766e-35 + // Expected Error Term : 1.021e-35 + // Maximum Relative Change in Control Points : 6.228e-03 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 8.333333333333255774414858563409941233e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.944444444444897867884955912228700291e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.472222222220954970397343617150959467e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.157407407409660682751155024932538578e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.755731922369973706427272809014190998e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.920949861702265600960449699129258153e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.834652583208361401197752793379677147e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.594058441128280500819776168239988143e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.903689413939268702265479276217647209e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.230068069012898202890718644753625569e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.352606552027491657204243201021677257e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.842095100698532984651921750204843362e-21), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.771789051329870174925649852681844169e-24), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.655114381199979536997025497438385062e-26), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.343415732516712339472538688374589373e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.396177019032432392793591204647901390e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.277563309255167951005939802771456315e-33), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.449201419305514579791370198046544736e-36), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.415430703400740634202379012388035255e-39), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.195458831864936225409005027914934499e-41), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.829726762743879793396637797534668039e-45), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.698302711685624490806751012380215488e-46), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.062520475425422618494185821587228317e-49), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.732372906742845717148185173723304360e-52) + }; + T a = x * x / 4; + T Q[3] = { 1, 0.5f, boost::math::tools::evaluate_polynomial(P, a) }; + return x * boost::math::tools::evaluate_polynomial(Q, a) / 2; + } + else if(x < 20) + { + // Max error in interpolated form: 8.864e-36 + // Max Error found at float128 precision = Poly: 8.522841e-35 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422793693152031514179994954750043e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496029423752889591425633234009799670e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.682975926820553021482820043377990241e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.138871171577224532369979905856458929e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.765350219426341341990447005798111212e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.321389275507714530941178258122955540e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.727748393898888756515271847678850411e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.123040820686242586086564998713862335e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.784112378374753535335272752884808068e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.054920416060932189433079126269416563e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.450129415468060676827180524327749553e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.758831882046487398739784498047935515e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.736936520262204842199620784338052937e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.051128683324042629513978256179115439e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.188008285959794869092624343537262342e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.108530004906954627420484180793165669e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.441516828490144766650287123765318484e+15), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.158251664797753450664499268756393535e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.467314522709016832128790443932896401e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.896222045367960462945885220710294075e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.273382139594876997203657902425653079e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.669871448568623680543943144842394531e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.813923031370708069940575240509912588e+18) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 35) + { + // Max error in interpolated form: 6.028e-35 + // Max Error found at float128 precision = Poly: 1.368313e-34 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422804012941975429616956496046931e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496033550576049830976679315420681402e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.675107835141866009896710750800622147e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.090104965125365961928716504473692957e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.842241652296980863361375208605487570e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.063604828033747303936724279018650633e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -9.113375972811586130949401996332817152e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.334748570425075872639817839399823709e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.759150758768733692594821032784124765e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.863672813448915255286274382558526321e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.798248643371718775489178767529282534e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.769963173932801026451013022000669267e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.381780137198278741566746511015220011e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.163891337116820832871382141011952931e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.764325864671438675151635117936912390e+13), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.925668307403332887856809510525154955e+14), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.416692606589060039334938090985713641e+16), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.892398600219306424294729851605944429e+17), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.107232903741874160308537145391245060e+18), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.930223393531877588898224144054112045e+19), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.427759576167665663373350433236061007e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.306019279465532835530812122374386654e+20), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.653753000392125229440044977239174472e+21), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.140760686989511568435076842569804906e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.249149337812510200795436107962504749e+22), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.101619088427348382058085685849420866e+22) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else if(x < 100) + { + // Max error in interpolated form: 5.494e-35 + // Max Error found at float128 precision = Poly: 1.214651e-34 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.989422804014326779399307367861631577e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.496033551505372542086590873271571919e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.675104848454290286276466276677172664e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.090716742397105403027549796269213215e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.752570419098513588311026680089351230e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.107369803696534592906420980901195808e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.699214194000085622941721628134575121e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.953006169077813678478720427604462133e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.746618809476524091493444128605380593e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.084446249943196826652788161656973391e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.020325182518980633783194648285500554e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.510195971266257573425196228564489134e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.241661863814900938075696173192225056e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.323374362891993686413568398575539777e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.112838452096066633754042734723911040e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.369270194978310081563767560113534023e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.704295412488936504389347368131134993e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.320829576277038198439987439508754886e+10), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.258818139077875493434420764260185306e+11), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.396791306321498426110315039064592443e+12), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.217617301585849875301440316301068439e+12) + }; + return exp(x) * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + } + else + { + // Bessel I0 over[100, INF] + // Max error in interpolated form: 6.081e-35 + // Max Error found at float128 precision = Poly: 1.407151e-34 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 3.9894228040143267793994605993438200208417e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4960335515053725422747977247811372936584e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.6751048484542891946087411826356811991039e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.0907167423975030452875828826630006305665e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.7525704189964886494791082898669060345483e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.1073698056568248642163476807108190176386e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.6992139012879749064623499618582631684228e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.9530409594026597988098934027440110587905e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.7462844478733532517044536719240098183686e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.0870711340681926669381449306654104739256e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.8510175413216969245241059608553222505228e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.4094682286011573747064907919522894740063e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.3128845936764406865199641778959502795443e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.1655901321962541203257516341266838487359e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.8019591025686295090160445920753823994556e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.7008089049178178697338128837158732831105e+05) + }; + T ex = exp(x / 2); + T result = ex * boost::math::tools::evaluate_polynomial(P, T(1 / x)) / sqrt(x); + result *= ex; + return result; + } +} + +template +T bessel_i1_imp(const T& x, const std::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_i1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_i1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_i1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_i1_imp(x, std::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +inline T bessel_i1(const T& x) +{ + typedef std::integral_constant::digits == 0) || (std::numeric_limits::radix != 2)) ? + 0 : + std::numeric_limits::digits <= 24 ? + 24 : + std::numeric_limits::digits <= 53 ? + 53 : + std::numeric_limits::digits <= 64 ? + 64 : + std::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + bessel_i1_initializer::force_instantiate(); + return bessel_i1_imp(x, tag_type()); +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_I1_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_ik.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_ik.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_ik.hpp @@ -0,0 +1,458 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_IK_HPP +#define BOOST_MATH_BESSEL_IK_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// Modified Bessel functions of the first and second kind of fractional order + +namespace boost { namespace math { + +namespace detail { + +template +struct cyl_bessel_i_small_z +{ + typedef T result_type; + + cyl_bessel_i_small_z(T v_, T z_) : k(0), v(v_), mult(z_*z_/4) + { + BOOST_MATH_STD_USING + term = 1; + } + + T operator()() + { + T result = term; + ++k; + term *= mult / k; + term /= k + v; + return result; + } +private: + unsigned k; + T v; + T term; + T mult; +}; + +template +inline T bessel_i_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if(v < max_factorial::value) + { + prefix = pow(x / 2, v) / boost::math::tgamma(v + 1, pol); + } + else + { + prefix = v * log(x / 2) - boost::math::lgamma(v + 1, pol); + prefix = exp(prefix); + } + if(prefix == 0) + return prefix; + + cyl_bessel_i_small_z s(v, x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +// Calculate K(v, x) and K(v+1, x) by method analogous to +// Temme, Journal of Computational Physics, vol 21, 343 (1976) +template +int temme_ik(T v, T x, T* K, T* K1, const Policy& pol) +{ + T f, h, p, q, coef, sum, sum1, tolerance; + T a, b, c, d, sigma, gamma1, gamma2; + unsigned long k; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + + // |x| <= 2, Temme series converge rapidly + // |x| > 2, the larger the |x|, the slower the convergence + BOOST_MATH_ASSERT(abs(x) <= 2); + BOOST_MATH_ASSERT(abs(v) <= 0.5f); + + T gp = boost::math::tgamma1pm1(v, pol); + T gm = boost::math::tgamma1pm1(-v, pol); + + a = log(x / 2); + b = exp(v * a); + sigma = -a * v; + c = abs(v) < tools::epsilon() ? + T(1) : T(boost::math::sin_pi(v, pol) / (v * pi())); + d = abs(sigma) < tools::epsilon() ? + T(1) : T(sinh(sigma) / sigma); + gamma1 = abs(v) < tools::epsilon() ? + T(-euler()) : T((0.5f / v) * (gp - gm) * c); + gamma2 = (2 + gp + gm) * c / 2; + + // initial values + p = (gp + 1) / (2 * b); + q = (1 + gm) * b / 2; + f = (cosh(sigma) * gamma1 + d * (-a) * gamma2) / c; + h = p; + coef = 1; + sum = coef * f; + sum1 = coef * h; + + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(f); + BOOST_MATH_INSTRUMENT_VARIABLE(sigma); + BOOST_MATH_INSTRUMENT_CODE(sinh(sigma)); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma1); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma2); + BOOST_MATH_INSTRUMENT_VARIABLE(c); + BOOST_MATH_INSTRUMENT_VARIABLE(d); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + + // series summation + tolerance = tools::epsilon(); + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + f = (k * f + p + q) / (k*k - v*v); + p /= k - v; + q /= k + v; + h = p - k * f; + coef *= x * x / (4 * k); + sum += coef * f; + sum1 += coef * h; + if (abs(coef * f) < abs(sum) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in temme_ik", k, pol); + + *K = sum; + *K1 = 2 * sum1 / x; + + return 0; +} + +// Evaluate continued fraction fv = I_(v+1) / I_v, derived from +// Abramowitz and Stegun, Handbook of Mathematical Functions, 1972, 9.1.73 +template +int CF1_ik(T v, T x, T* fv, const Policy& pol) +{ + T C, D, f, a, b, delta, tiny, tolerance; + unsigned long k; + + BOOST_MATH_STD_USING + + // |x| <= |v|, CF1_ik converges rapidly + // |x| > |v|, CF1_ik needs O(|x|) iterations to converge + + // modified Lentz's method, see + // Lentz, Applied Optics, vol 15, 668 (1976) + tolerance = 2 * tools::epsilon(); + BOOST_MATH_INSTRUMENT_VARIABLE(tolerance); + tiny = sqrt(tools::min_value()); + BOOST_MATH_INSTRUMENT_VARIABLE(tiny); + C = f = tiny; // b0 = 0, replace with tiny + D = 0; + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + a = 1; + b = 2 * (v + k) / x; + C = b + a / C; + D = b + a * D; + if (C == 0) { C = tiny; } + if (D == 0) { D = tiny; } + D = 1 / D; + delta = C * D; + f *= delta; + BOOST_MATH_INSTRUMENT_VARIABLE(delta-1); + if (abs(delta - 1) <= tolerance) + { + break; + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(k); + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in CF1_ik", k, pol); + + *fv = f; + + return 0; +} + +// Calculate K(v, x) and K(v+1, x) by evaluating continued fraction +// z1 / z0 = U(v+1.5, 2v+1, 2x) / U(v+0.5, 2v+1, 2x), see +// Thompson and Barnett, Computer Physics Communications, vol 47, 245 (1987) +template +int CF2_ik(T v, T x, T* Kv, T* Kv1, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + T S, C, Q, D, f, a, b, q, delta, tolerance, current, prev; + unsigned long k; + + // |x| >= |v|, CF2_ik converges rapidly + // |x| -> 0, CF2_ik fails to converge + + BOOST_MATH_ASSERT(abs(x) > 1); + + // Steed's algorithm, see Thompson and Barnett, + // Journal of Computational Physics, vol 64, 490 (1986) + tolerance = tools::epsilon(); + a = v * v - 0.25f; + b = 2 * (x + 1); // b1 + D = 1 / b; // D1 = 1 / b1 + f = delta = D; // f1 = delta1 = D1, coincidence + prev = 0; // q0 + current = 1; // q1 + Q = C = -a; // Q1 = C1 because q1 = 1 + S = 1 + Q * delta; // S1 + BOOST_MATH_INSTRUMENT_VARIABLE(tolerance); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + BOOST_MATH_INSTRUMENT_VARIABLE(D); + BOOST_MATH_INSTRUMENT_VARIABLE(f); + + for (k = 2; k < policies::get_max_series_iterations(); k++) // starting from 2 + { + // continued fraction f = z1 / z0 + a -= 2 * (k - 1); + b += 2; + D = 1 / (b + a * D); + delta *= b * D - 1; + f += delta; + + // series summation S = 1 + \sum_{n=1}^{\infty} C_n * z_n / z_0 + q = (prev - (b - 2) * current) / a; + prev = current; + current = q; // forward recurrence for q + C *= -a / k; + Q += C * q; + S += Q * delta; + // + // Under some circumstances q can grow very small and C very + // large, leading to under/overflow. This is particularly an + // issue for types which have many digits precision but a narrow + // exponent range. A typical example being a "double double" type. + // To avoid this situation we can normalise q (and related prev/current) + // and C. All other variables remain unchanged in value. A typical + // test case occurs when x is close to 2, for example cyl_bessel_k(9.125, 2.125). + // + if(q < tools::epsilon()) + { + C *= q; + prev /= q; + current /= q; + q = 1; + } + + // S converges slower than f + BOOST_MATH_INSTRUMENT_VARIABLE(Q * delta); + BOOST_MATH_INSTRUMENT_VARIABLE(abs(S) * tolerance); + BOOST_MATH_INSTRUMENT_VARIABLE(S); + if (abs(Q * delta) < abs(S) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_ik<%1%>(%1%,%1%) in CF2_ik", k, pol); + + if(x >= tools::log_max_value()) + *Kv = exp(0.5f * log(pi() / (2 * x)) - x - log(S)); + else + *Kv = sqrt(pi() / (2 * x)) * exp(-x) / S; + *Kv1 = *Kv * (0.5f + v + x + (v * v - 0.25f) * f) / x; + BOOST_MATH_INSTRUMENT_VARIABLE(*Kv); + BOOST_MATH_INSTRUMENT_VARIABLE(*Kv1); + + return 0; +} + +enum{ + need_i = 1, + need_k = 2 +}; + +// Compute I(v, x) and K(v, x) simultaneously by Temme's method, see +// Temme, Journal of Computational Physics, vol 19, 324 (1975) +template +int bessel_ik(T v, T x, T* I, T* K, int kind, const Policy& pol) +{ + // Kv1 = K_(v+1), fv = I_(v+1) / I_v + // Ku1 = K_(u+1), fu = I_(u+1) / I_u + T u, Iv, Kv, Kv1, Ku, Ku1, fv; + T W, current, prev, next; + bool reflect = false; + unsigned n, k; + int org_kind = kind; + BOOST_MATH_INSTRUMENT_VARIABLE(v); + BOOST_MATH_INSTRUMENT_VARIABLE(x); + BOOST_MATH_INSTRUMENT_VARIABLE(kind); + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + static const char* function = "boost::math::bessel_ik<%1%>(%1%,%1%)"; + + if (v < 0) + { + reflect = true; + v = -v; // v is non-negative from here + kind |= need_k; + } + n = iround(v, pol); + u = v - n; // -1/2 <= u < 1/2 + BOOST_MATH_INSTRUMENT_VARIABLE(n); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + + if (x < 0) + { + *I = *K = policies::raise_domain_error(function, + "Got x = %1% but real argument x must be non-negative, complex number result not supported.", x, pol); + return 1; + } + if (x == 0) + { + Iv = (v == 0) ? static_cast(1) : static_cast(0); + if(kind & need_k) + { + Kv = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + Kv = std::numeric_limits::quiet_NaN(); // any value will do + } + + if(reflect && (kind & need_i)) + { + T z = (u + n % 2); + Iv = boost::math::sin_pi(z, pol) == 0 ? + Iv : + policies::raise_overflow_error(function, nullptr, pol); // reflection formula + } + + *I = Iv; + *K = Kv; + return 0; + } + + // x is positive until reflection + W = 1 / x; // Wronskian + if (x <= 2) // x in (0, 2] + { + temme_ik(u, x, &Ku, &Ku1, pol); // Temme series + } + else // x in (2, \infty) + { + CF2_ik(u, x, &Ku, &Ku1, pol); // continued fraction CF2_ik + } + BOOST_MATH_INSTRUMENT_VARIABLE(Ku); + BOOST_MATH_INSTRUMENT_VARIABLE(Ku1); + prev = Ku; + current = Ku1; + T scale = 1; + T scale_sign = 1; + for (k = 1; k <= n; k++) // forward recurrence for K + { + T fact = 2 * (u + k) / x; + // Check for overflow: if (max - |prev|) / fact > max, then overflow + // (max - |prev|) / fact > max + // max * (1 - fact) > |prev| + // if fact < 1: safe to compute overflow check + // if fact >= 1: won't overflow + const bool will_overflow = (fact < 1) + ? tools::max_value() * (1 - fact) > fabs(prev) + : false; + if(!will_overflow && ((tools::max_value() - fabs(prev)) / fact < fabs(current))) + { + prev /= current; + scale /= current; + scale_sign *= boost::math::sign(current); + current = 1; + } + next = fact * current + prev; + prev = current; + current = next; + } + Kv = prev; + Kv1 = current; + BOOST_MATH_INSTRUMENT_VARIABLE(Kv); + BOOST_MATH_INSTRUMENT_VARIABLE(Kv1); + if(kind & need_i) + { + T lim = (4 * v * v + 10) / (8 * x); + lim *= lim; + lim *= lim; + lim /= 24; + if((lim < tools::epsilon() * 10) && (x > 100)) + { + // x is huge compared to v, CF1 may be very slow + // to converge so use asymptotic expansion for large + // x case instead. Note that the asymptotic expansion + // isn't very accurate - so it's deliberately very hard + // to get here - probably we're going to overflow: + Iv = asymptotic_bessel_i_large_x(v, x, pol); + } + else if((v > 0) && (x / v < 0.25)) + { + Iv = bessel_i_small_z_series(v, x, pol); + } + else + { + CF1_ik(v, x, &fv, pol); // continued fraction CF1_ik + Iv = scale * W / (Kv * fv + Kv1); // Wronskian relation + } + } + else + Iv = std::numeric_limits::quiet_NaN(); // any value will do + + if (reflect) + { + T z = (u + n % 2); + T fact = (2 / pi()) * (boost::math::sin_pi(z, pol) * Kv); + if(fact == 0) + *I = Iv; + else if(tools::max_value() * scale < fact) + *I = (org_kind & need_i) ? T(sign(fact) * scale_sign * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *I = Iv + fact / scale; // reflection formula + } + else + { + *I = Iv; + } + if(tools::max_value() * scale < Kv) + *K = (org_kind & need_k) ? T(sign(Kv) * scale_sign * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *K = Kv / scale; + BOOST_MATH_INSTRUMENT_VARIABLE(*I); + BOOST_MATH_INSTRUMENT_VARIABLE(*K); + return 0; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_IK_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j0.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j0.hpp @@ -0,0 +1,219 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_J0_HPP +#define BOOST_MATH_BESSEL_J0_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the first kind of order zero +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +T bessel_j0(T x); + +template +struct bessel_j0_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + bessel_j0(T(1)); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_j0_initializer::init bessel_j0_initializer::initializer; + +template +T bessel_j0(T x) +{ + bessel_j0_initializer::force_instantiate(); + +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if (!b) + { + std::cout << "bessel_j0 called with " << typeid(x).name() << std::endl; + std::cout << "double = " << typeid(double).name() << std::endl; + std::cout << "long double = " << typeid(long double).name() << std::endl; + b = true; + } +#endif + + static const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.1298668500990866786e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7282507878605942706e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.2140700423540120665e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6302997904833794242e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.6629814655107086448e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0344222815443188943e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2117036164593528341e-01)) + }; + static const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.3883787996332290397e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.6328198300859648632e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3985097372263433271e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.5612696224219938200e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.3614022392337710626e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + static const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8319397969392084011e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2254078161378989535e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -7.2879702464464618998e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0341910641583726701e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1725046279757103576e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.4176707025325087628e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.4321196680624245801e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.8591703355916499363e+01)) + }; + static const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.5783478026152301072e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4599102262586308984e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.4055062591169562211e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8680990008359188352e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.9458766545509337327e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3307310774649071172e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.5258076240801555057e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684302e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1345386639580765797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1170523380864944322e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4806486443249270347e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5376201909008354296e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.8961548424210455236e-01)) + }; + static const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684318e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1370412495510416640e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1215350561880115730e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5028735138235608207e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5711159858080893649e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.9226600200800094098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8591953644342993800e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1183429920482737611e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2300261666214198472e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2441026745835638459e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.8033303048680751817e-03)) + }; + static const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.7105024128512061905e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1951131543434613647e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2642780169211018836e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4887231232283756582e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.0593769594993125859e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4048255576957727686e+00)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.5200781102863106496e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.160e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.42444230422723137837e-03)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4130e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.46860286310649596604e-04)); + + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + if (x < 0) + { + x = -x; // even function + } + if (x == 0) + { + return static_cast(1); + } + if (x <= 4) // x in (0, 4] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P1) == sizeof(Q1)); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12); + value = factor * r; + } + else if (x <= 8.0) // x in (4, 8] + { + T y = 1 - (x * x)/64; + BOOST_MATH_ASSERT(sizeof(P2) == sizeof(Q2)); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22); + value = factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + BOOST_MATH_ASSERT(sizeof(PC) == sizeof(QC)); + BOOST_MATH_ASSERT(sizeof(PS) == sizeof(QS)); + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = constants::one_div_root_pi() / sqrt(x); + // + // What follows is really just: + // + // T z = x - pi/4; + // value = factor * (rc * cos(z) - y * rs * sin(z)); + // + // But using the addition formulae for sin and cos, plus + // the special values for sin/cos of pi/4. + // + T sx = sin(x); + T cx = cos(x); + BOOST_MATH_INSTRUMENT_VARIABLE(rc); + BOOST_MATH_INSTRUMENT_VARIABLE(rs); + BOOST_MATH_INSTRUMENT_VARIABLE(factor); + BOOST_MATH_INSTRUMENT_VARIABLE(sx); + BOOST_MATH_INSTRUMENT_VARIABLE(cx); + value = factor * (rc * (cx + sx) - y * rs * (sx - cx)); + } + + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_J0_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j1.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_j1.hpp @@ -0,0 +1,209 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_J1_HPP +#define BOOST_MATH_BESSEL_J1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the first kind of order one +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math{ namespace detail{ + +template +T bessel_j1(T x); + +template +struct bessel_j1_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + bessel_j1(T(1)); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_j1_initializer::init bessel_j1_initializer::initializer; + +template +T bessel_j1(T x) +{ + bessel_j1_initializer::force_instantiate(); + + static const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4258509801366645672e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6781041261492395835e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1548696764841276794e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.8062904098958257677e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4615792982775076130e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0650724020080236441e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0767857011487300348e-02)) + }; + static const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1868604460820175290e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.2091902282580133541e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.0228375140097033958e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.9117614494174794095e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0742272239517380498e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + static const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.7527881995806511112e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.6608531731299018674e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.6658018905416665164e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5580665670910619166e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8113931269860667829e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.0793266148011179143e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -7.5023342220781607561e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.6179191852758252278e+00)) + }; + static const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7253905888447681194e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7128800897135812012e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.4899346165481429307e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7622777286244082666e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.4872502899596389593e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1267125065029138050e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3886978985861357615e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278571e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9422465050776411957e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.6033732483649391093e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5235293511811373833e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0982405543459346727e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.6116166443246101165e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + static const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278568e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9341243899345856590e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.5853394797230870728e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5118095066341608816e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0726385991103820119e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4550094401904961825e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3220913409857223519e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.5145160675335701966e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6178836581270835179e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8494262873223866797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7063754290207680021e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5265133846636032186e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)) + }; + static const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0871281941028743574e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8194580422439972989e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4194606696037208929e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0029443582266975117e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7890229745772202641e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6383677696049909675e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)) + }; + static const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.8317059702075123156e+00)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0155866698156187535e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.810e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.2527979248768438556e-04)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7960e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.8330184381246462950e-05)); + + T value, factor, r, rc, rs, w; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + w = abs(x); + if (x == 0) + { + return static_cast(0); + } + if (w <= 4) // w in (0, 4] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P1) == sizeof(Q1)); + r = evaluate_rational(P1, Q1, y); + factor = w * (w + x1) * ((w - x11/256) - x12); + value = factor * r; + } + else if (w <= 8) // w in (4, 8] + { + T y = x * x; + BOOST_MATH_ASSERT(sizeof(P2) == sizeof(Q2)); + r = evaluate_rational(P2, Q2, y); + factor = w * (w + x2) * ((w - x21/256) - x22); + value = factor * r; + } + else // w in (8, \infty) + { + T y = 8 / w; + T y2 = y * y; + BOOST_MATH_ASSERT(sizeof(PC) == sizeof(QC)); + BOOST_MATH_ASSERT(sizeof(PS) == sizeof(QS)); + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = 1 / (sqrt(w) * constants::root_pi()); + // + // What follows is really just: + // + // T z = w - 0.75f * pi(); + // value = factor * (rc * cos(z) - y * rs * sin(z)); + // + // but using the sin/cos addition rules plus constants + // for the values of sin/cos of 3PI/4 which then cancel + // out with corresponding terms in "factor". + // + T sx = sin(x); + T cx = cos(x); + value = factor * (rc * (sx - cx) + y * rs * (sx + cx)); + } + + if (x < 0) + { + value *= -1; // odd function + } + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_J1_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jn.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jn.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jn.hpp @@ -0,0 +1,133 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_JN_HPP +#define BOOST_MATH_BESSEL_JN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +// Bessel function of the first kind of integer order +// J_n(z) is the minimal solution +// n < abs(z), forward recurrence stable and usable +// n >= abs(z), forward recurrence unstable, use Miller's algorithm + +namespace boost { namespace math { namespace detail{ + +template +T bessel_jn(int n, T x, const Policy& pol) +{ + T value(0), factor, current, prev, next; + + BOOST_MATH_STD_USING + + // + // Reflection has to come first: + // + if (n < 0) + { + factor = static_cast((n & 0x1) ? -1 : 1); // J_{-n}(z) = (-1)^n J_n(z) + n = -n; + } + else + { + factor = 1; + } + if(x < 0) + { + factor *= (n & 0x1) ? -1 : 1; // J_{n}(-z) = (-1)^n J_n(z) + x = -x; + } + // + // Special cases: + // + if(asymptotic_bessel_large_x_limit(T(n), x)) + return factor * asymptotic_bessel_j_large_x_2(T(n), x, pol); + if (n == 0) + { + return factor * bessel_j0(x); + } + if (n == 1) + { + return factor * bessel_j1(x); + } + + if (x == 0) // n >= 2 + { + return static_cast(0); + } + + BOOST_MATH_ASSERT(n > 1); + T scale = 1; + if (n < abs(x)) // forward recurrence + { + prev = bessel_j0(x); + current = bessel_j1(x); + policies::check_series_iterations("boost::math::bessel_j_n<%1%>(%1%,%1%)", n, pol); + for (int k = 1; k < n; k++) + { + T fact = 2 * k / x; + // + // rescale if we would overflow or underflow: + // + if((fabs(fact) > 1) && ((tools::max_value() - fabs(prev)) / fabs(fact) < fabs(current))) + { + scale /= current; + prev /= current; + current = 1; + } + value = fact * current - prev; + prev = current; + current = value; + } + } + else if((x < 1) || (n > x * x / 4) || (x < 5)) + { + return factor * bessel_j_small_z_series(T(n), x, pol); + } + else // backward recurrence + { + T fn; int s; // fn = J_(n+1) / J_n + // |x| <= n, fast convergence for continued fraction CF1 + boost::math::detail::CF1_jy(static_cast(n), x, &fn, &s, pol); + prev = fn; + current = 1; + // Check recursion won't go on too far: + policies::check_series_iterations("boost::math::bessel_j_n<%1%>(%1%,%1%)", n, pol); + for (int k = n; k > 0; k--) + { + T fact = 2 * k / x; + if((fabs(fact) > 1) && ((tools::max_value() - fabs(prev)) / fabs(fact) < fabs(current))) + { + prev /= current; + scale /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + value = bessel_j0(x) / current; // normalization + scale = 1 / scale; + } + value *= factor; + + if(tools::max_value() * scale < fabs(value)) + return policies::raise_overflow_error("boost::math::bessel_jn<%1%>(%1%,%1%)", nullptr, pol); + + return value / scale; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JN_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy.hpp @@ -0,0 +1,586 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_JY_HPP +#define BOOST_MATH_BESSEL_JY_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Bessel functions of the first and second kind of fractional order + +namespace boost { namespace math { + + namespace detail { + + // + // Simultaneous calculation of A&S 9.2.9 and 9.2.10 + // for use in A&S 9.2.5 and 9.2.6. + // This series is quick to evaluate, but divergent unless + // x is very large, in fact it's pretty hard to figure out + // with any degree of precision when this series actually + // *will* converge!! Consequently, we may just have to + // try it and see... + // + template + bool hankel_PQ(T v, T x, T* p, T* q, const Policy& ) + { + BOOST_MATH_STD_USING + T tolerance = 2 * policies::get_epsilon(); + *p = 1; + *q = 0; + T k = 1; + T z8 = 8 * x; + T sq = 1; + T mu = 4 * v * v; + T term = 1; + bool ok = true; + do + { + term *= (mu - sq * sq) / (k * z8); + *q += term; + k += 1; + sq += 2; + T mult = (sq * sq - mu) / (k * z8); + ok = fabs(mult) < 0.5f; + term *= mult; + *p += term; + k += 1; + sq += 2; + } + while((fabs(term) > tolerance * *p) && ok); + return ok; + } + + // Calculate Y(v, x) and Y(v+1, x) by Temme's method, see + // Temme, Journal of Computational Physics, vol 21, 343 (1976) + template + int temme_jy(T v, T x, T* Y, T* Y1, const Policy& pol) + { + T g, h, p, q, f, coef, sum, sum1, tolerance; + T a, d, e, sigma; + unsigned long k; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + BOOST_MATH_ASSERT(fabs(v) <= 0.5f); // precondition for using this routine + + T gp = boost::math::tgamma1pm1(v, pol); + T gm = boost::math::tgamma1pm1(-v, pol); + T spv = boost::math::sin_pi(v, pol); + T spv2 = boost::math::sin_pi(v/2, pol); + T xp = pow(x/2, v); + + a = log(x / 2); + sigma = -a * v; + d = abs(sigma) < tools::epsilon() ? + T(1) : sinh(sigma) / sigma; + e = abs(v) < tools::epsilon() ? T(v*pi()*pi() / 2) + : T(2 * spv2 * spv2 / v); + + T g1 = (v == 0) ? T(-euler()) : T((gp - gm) / ((1 + gp) * (1 + gm) * 2 * v)); + T g2 = (2 + gp + gm) / ((1 + gp) * (1 + gm) * 2); + T vspv = (fabs(v) < tools::epsilon()) ? T(1/constants::pi()) : T(v / spv); + f = (g1 * cosh(sigma) - g2 * a * d) * 2 * vspv; + + p = vspv / (xp * (1 + gm)); + q = vspv * xp / (1 + gp); + + g = f + e * q; + h = p; + coef = 1; + sum = coef * g; + sum1 = coef * h; + + T v2 = v * v; + T coef_mult = -x * x / 4; + + // series summation + tolerance = policies::get_epsilon(); + for (k = 1; k < policies::get_max_series_iterations(); k++) + { + f = (k * f + p + q) / (k*k - v2); + p /= k - v; + q /= k + v; + g = f + e * q; + h = p - k * g; + coef *= coef_mult / k; + sum += coef * g; + sum1 += coef * h; + if (abs(coef * g) < abs(sum) * tolerance) + { + break; + } + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in temme_jy", k, pol); + *Y = -sum; + *Y1 = -2 * sum1 / x; + + return 0; + } + + // Evaluate continued fraction fv = J_(v+1) / J_v, see + // Abramowitz and Stegun, Handbook of Mathematical Functions, 1972, 9.1.73 + template + int CF1_jy(T v, T x, T* fv, int* sign, const Policy& pol) + { + T C, D, f, a, b, delta, tiny, tolerance; + unsigned long k; + int s = 1; + + BOOST_MATH_STD_USING + + // |x| <= |v|, CF1_jy converges rapidly + // |x| > |v|, CF1_jy needs O(|x|) iterations to converge + + // modified Lentz's method, see + // Lentz, Applied Optics, vol 15, 668 (1976) + tolerance = 2 * policies::get_epsilon(); + tiny = sqrt(tools::min_value()); + C = f = tiny; // b0 = 0, replace with tiny + D = 0; + for (k = 1; k < policies::get_max_series_iterations() * 100; k++) + { + a = -1; + b = 2 * (v + k) / x; + C = b + a / C; + D = b + a * D; + if (C == 0) { C = tiny; } + if (D == 0) { D = tiny; } + D = 1 / D; + delta = C * D; + f *= delta; + if (D < 0) { s = -s; } + if (abs(delta - 1) < tolerance) + { break; } + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in CF1_jy", k / 100, pol); + *fv = -f; + *sign = s; // sign of denominator + + return 0; + } + // + // This algorithm was originally written by Xiaogang Zhang + // using std::complex to perform the complex arithmetic. + // However, that turns out to 10x or more slower than using + // all real-valued arithmetic, so it's been rewritten using + // real values only. + // + template + int CF2_jy(T v, T x, T* p, T* q, const Policy& pol) + { + BOOST_MATH_STD_USING + + T Cr, Ci, Dr, Di, fr, fi, a, br, bi, delta_r, delta_i, temp; + T tiny; + unsigned long k; + + // |x| >= |v|, CF2_jy converges rapidly + // |x| -> 0, CF2_jy fails to converge + BOOST_MATH_ASSERT(fabs(x) > 1); + + // modified Lentz's method, complex numbers involved, see + // Lentz, Applied Optics, vol 15, 668 (1976) + T tolerance = 2 * policies::get_epsilon(); + tiny = sqrt(tools::min_value()); + Cr = fr = -0.5f / x; + Ci = fi = 1; + //Dr = Di = 0; + T v2 = v * v; + a = (0.25f - v2) / x; // Note complex this one time only! + br = 2 * x; + bi = 2; + temp = Cr * Cr + 1; + Ci = bi + a * Cr / temp; + Cr = br + a / temp; + Dr = br; + Di = bi; + if (fabs(Cr) + fabs(Ci) < tiny) { Cr = tiny; } + if (fabs(Dr) + fabs(Di) < tiny) { Dr = tiny; } + temp = Dr * Dr + Di * Di; + Dr = Dr / temp; + Di = -Di / temp; + delta_r = Cr * Dr - Ci * Di; + delta_i = Ci * Dr + Cr * Di; + temp = fr; + fr = temp * delta_r - fi * delta_i; + fi = temp * delta_i + fi * delta_r; + for (k = 2; k < policies::get_max_series_iterations(); k++) + { + a = k - 0.5f; + a *= a; + a -= v2; + bi += 2; + temp = Cr * Cr + Ci * Ci; + Cr = br + a * Cr / temp; + Ci = bi - a * Ci / temp; + Dr = br + a * Dr; + Di = bi + a * Di; + if (fabs(Cr) + fabs(Ci) < tiny) { Cr = tiny; } + if (fabs(Dr) + fabs(Di) < tiny) { Dr = tiny; } + temp = Dr * Dr + Di * Di; + Dr = Dr / temp; + Di = -Di / temp; + delta_r = Cr * Dr - Ci * Di; + delta_i = Ci * Dr + Cr * Di; + temp = fr; + fr = temp * delta_r - fi * delta_i; + fi = temp * delta_i + fi * delta_r; + if (fabs(delta_r - 1) + fabs(delta_i) < tolerance) + break; + } + policies::check_series_iterations("boost::math::bessel_jy<%1%>(%1%,%1%) in CF2_jy", k, pol); + *p = fr; + *q = fi; + + return 0; + } + + static const int need_j = 1; + static const int need_y = 2; + + // Compute J(v, x) and Y(v, x) simultaneously by Steed's method, see + // Barnett et al, Computer Physics Communications, vol 8, 377 (1974) + template + int bessel_jy(T v, T x, T* J, T* Y, int kind, const Policy& pol) + { + BOOST_MATH_ASSERT(x >= 0); + + T u, Jv, Ju, Yv, Yv1, Yu, Yu1(0), fv, fu; + T W, p, q, gamma, current, prev, next; + bool reflect = false; + unsigned n, k; + int s; + int org_kind = kind; + T cp = 0; + T sp = 0; + + static const char* function = "boost::math::bessel_jy<%1%>(%1%,%1%)"; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + if (v < 0) + { + reflect = true; + v = -v; // v is non-negative from here + } + if (v > static_cast((std::numeric_limits::max)())) + { + *J = *Y = policies::raise_evaluation_error(function, "Order of Bessel function is too large to evaluate: got %1%", v, pol); + return 1; + } + n = iround(v, pol); + u = v - n; // -1/2 <= u < 1/2 + + if(reflect) + { + T z = (u + n % 2); + cp = boost::math::cos_pi(z, pol); + sp = boost::math::sin_pi(z, pol); + if(u != 0) + kind = need_j|need_y; // need both for reflection formula + } + + if(x == 0) + { + if(v == 0) + *J = 1; + else if((u == 0) || !reflect) + *J = 0; + else if(kind & need_j) + *J = policies::raise_domain_error(function, "Value of Bessel J_v(x) is complex-infinity at %1%", x, pol); // complex infinity + else + *J = std::numeric_limits::quiet_NaN(); // any value will do, not using J. + + if((kind & need_y) == 0) + *Y = std::numeric_limits::quiet_NaN(); // any value will do, not using Y. + else if(v == 0) + *Y = -policies::raise_overflow_error(function, nullptr, pol); + else + *Y = policies::raise_domain_error(function, "Value of Bessel Y_v(x) is complex-infinity at %1%", x, pol); // complex infinity + return 1; + } + + // x is positive until reflection + W = T(2) / (x * pi()); // Wronskian + T Yv_scale = 1; + if(((kind & need_y) == 0) && ((x < 1) || (v > x * x / 4) || (x < 5))) + { + // + // This series will actually converge rapidly for all small + // x - say up to x < 20 - but the first few terms are large + // and divergent which leads to large errors :-( + // + Jv = bessel_j_small_z_series(v, x, pol); + Yv = std::numeric_limits::quiet_NaN(); + } + else if((x < 1) && (u != 0) && (log(policies::get_epsilon() / 2) > v * log((x/2) * (x/2) / v))) + { + // Evaluate using series representations. + // This is particularly important for x << v as in this + // area temme_jy may be slow to converge, if it converges at all. + // Requires x is not an integer. + if(kind&need_j) + Jv = bessel_j_small_z_series(v, x, pol); + else + Jv = std::numeric_limits::quiet_NaN(); + if((org_kind&need_y && (!reflect || (cp != 0))) + || (org_kind & need_j && (reflect && (sp != 0)))) + { + // Only calculate if we need it, and if the reflection formula will actually use it: + Yv = bessel_y_small_z_series(v, x, &Yv_scale, pol); + } + else + Yv = std::numeric_limits::quiet_NaN(); + } + else if((u == 0) && (x < policies::get_epsilon())) + { + // Truncated series evaluation for small x and v an integer, + // much quicker in this area than temme_jy below. + if(kind&need_j) + Jv = bessel_j_small_z_series(v, x, pol); + else + Jv = std::numeric_limits::quiet_NaN(); + if((org_kind&need_y && (!reflect || (cp != 0))) + || (org_kind & need_j && (reflect && (sp != 0)))) + { + // Only calculate if we need it, and if the reflection formula will actually use it: + Yv = bessel_yn_small_z(n, x, &Yv_scale, pol); + } + else + Yv = std::numeric_limits::quiet_NaN(); + } + else if(asymptotic_bessel_large_x_limit(v, x)) + { + if(kind&need_y) + { + Yv = asymptotic_bessel_y_large_x_2(v, x, pol); + } + else + Yv = std::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + if(kind&need_j) + { + Jv = asymptotic_bessel_j_large_x_2(v, x, pol); + } + else + Jv = std::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + } + else if((x > 8) && hankel_PQ(v, x, &p, &q, pol)) + { + // + // Hankel approximation: note that this method works best when x + // is large, but in that case we end up calculating sines and cosines + // of large values, with horrendous resulting accuracy. It is fast though + // when it works.... + // + // Normally we calculate sin/cos(chi) where: + // + // chi = x - fmod(T(v / 2 + 0.25f), T(2)) * boost::math::constants::pi(); + // + // But this introduces large errors, so use sin/cos addition formulae to + // improve accuracy: + // + T mod_v = fmod(T(v / 2 + 0.25f), T(2)); + T sx = sin(x); + T cx = cos(x); + T sv = boost::math::sin_pi(mod_v, pol); + T cv = boost::math::cos_pi(mod_v, pol); + + T sc = sx * cv - sv * cx; // == sin(chi); + T cc = cx * cv + sx * sv; // == cos(chi); + T chi = boost::math::constants::root_two() / (boost::math::constants::root_pi() * sqrt(x)); //sqrt(2 / (boost::math::constants::pi() * x)); + Yv = chi * (p * sc + q * cc); + Jv = chi * (p * cc - q * sc); + } + else if (x <= 2) // x in (0, 2] + { + if(temme_jy(u, x, &Yu, &Yu1, pol)) // Temme series + { + // domain error: + *J = *Y = Yu; + return 1; + } + prev = Yu; + current = Yu1; + T scale = 1; + policies::check_series_iterations(function, n, pol); + for (k = 1; k <= n; k++) // forward recurrence for Y + { + T fact = 2 * (u + k) / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + scale /= current; + prev /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + Yv = prev; + Yv1 = current; + if(kind&need_j) + { + CF1_jy(v, x, &fv, &s, pol); // continued fraction CF1_jy + Jv = scale * W / (Yv * fv - Yv1); // Wronskian relation + } + else + Jv = std::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + Yv_scale = scale; + } + else // x in (2, \infty) + { + // Get Y(u, x): + + T ratio; + CF1_jy(v, x, &fv, &s, pol); + // tiny initial value to prevent overflow + T init = sqrt(tools::min_value()); + BOOST_MATH_INSTRUMENT_VARIABLE(init); + prev = fv * s * init; + current = s * init; + if(v < max_factorial::value) + { + policies::check_series_iterations(function, n, pol); + for (k = n; k > 0; k--) // backward recurrence for J + { + next = 2 * (u + k) * current / x - prev; + prev = current; + current = next; + } + ratio = (s * init) / current; // scaling ratio + // can also call CF1_jy() to get fu, not much difference in precision + fu = prev / current; + } + else + { + // + // When v is large we may get overflow in this calculation + // leading to NaN's and other nasty surprises: + // + policies::check_series_iterations(function, n, pol); + bool over = false; + for (k = n; k > 0; k--) // backward recurrence for J + { + T t = 2 * (u + k) / x; + if((t > 1) && (tools::max_value() / t < current)) + { + over = true; + break; + } + next = t * current - prev; + prev = current; + current = next; + } + if(!over) + { + ratio = (s * init) / current; // scaling ratio + // can also call CF1_jy() to get fu, not much difference in precision + fu = prev / current; + } + else + { + ratio = 0; + fu = 1; + } + } + CF2_jy(u, x, &p, &q, pol); // continued fraction CF2_jy + T t = u / x - fu; // t = J'/J + gamma = (p - t) / q; + // + // We can't allow gamma to cancel out to zero completely as it messes up + // the subsequent logic. So pretend that one bit didn't cancel out + // and set to a suitably small value. The only test case we've been able to + // find for this, is when v = 8.5 and x = 4*PI. + // + if(gamma == 0) + { + gamma = u * tools::epsilon() / x; + } + BOOST_MATH_INSTRUMENT_VARIABLE(current); + BOOST_MATH_INSTRUMENT_VARIABLE(W); + BOOST_MATH_INSTRUMENT_VARIABLE(q); + BOOST_MATH_INSTRUMENT_VARIABLE(gamma); + BOOST_MATH_INSTRUMENT_VARIABLE(p); + BOOST_MATH_INSTRUMENT_VARIABLE(t); + Ju = sign(current) * sqrt(W / (q + gamma * (p - t))); + BOOST_MATH_INSTRUMENT_VARIABLE(Ju); + + Jv = Ju * ratio; // normalization + + Yu = gamma * Ju; + Yu1 = Yu * (u/x - p - q/gamma); + + if(kind&need_y) + { + // compute Y: + prev = Yu; + current = Yu1; + policies::check_series_iterations(function, n, pol); + for (k = 1; k <= n; k++) // forward recurrence for Y + { + T fact = 2 * (u + k) / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + prev /= current; + Yv_scale /= current; + current = 1; + } + next = fact * current - prev; + prev = current; + current = next; + } + Yv = prev; + } + else + Yv = std::numeric_limits::quiet_NaN(); // any value will do, we're not using it. + } + + if (reflect) + { + if((sp != 0) && (tools::max_value() * fabs(Yv_scale) < fabs(sp * Yv))) + *J = org_kind & need_j ? T(-sign(sp) * sign(Yv) * (Yv_scale != 0 ? sign(Yv_scale) : 1) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *J = cp * Jv - (sp == 0 ? T(0) : T((sp * Yv) / Yv_scale)); // reflection formula + if((cp != 0) && (tools::max_value() * fabs(Yv_scale) < fabs(cp * Yv))) + *Y = org_kind & need_y ? T(-sign(cp) * sign(Yv) * (Yv_scale != 0 ? sign(Yv_scale) : 1) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *Y = (sp != 0 ? sp * Jv : T(0)) + (cp == 0 ? T(0) : T((cp * Yv) / Yv_scale)); + } + else + { + *J = Jv; + if(tools::max_value() * fabs(Yv_scale) < fabs(Yv)) + *Y = org_kind & need_y ? T(sign(Yv) * sign(Yv_scale) * policies::raise_overflow_error(function, nullptr, pol)) : T(0); + else + *Y = Yv / Yv_scale; + } + + return 0; + } + + } // namespace detail + +}} // namespaces + +#endif // BOOST_MATH_BESSEL_JY_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_asym.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_asym.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_asym.hpp @@ -0,0 +1,223 @@ +// Copyright (c) 2007 John Maddock +// 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Contains asymptotic expansions for Bessel J(v,x) and Y(v,x) +// functions, as x -> INF. +// +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_JY_ASYM_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline T asymptotic_bessel_amplitude(T v, T x) +{ + // Calculate the amplitude of J(v, x) and Y(v, x) for large + // x: see A&S 9.2.28. + BOOST_MATH_STD_USING + T s = 1; + T mu = 4 * v * v; + T txq = 2 * x; + txq *= txq; + + s += (mu - 1) / (2 * txq); + s += 3 * (mu - 1) * (mu - 9) / (txq * txq * 8); + s += 15 * (mu - 1) * (mu - 9) * (mu - 25) / (txq * txq * txq * 8 * 6); + + return sqrt(s * 2 / (constants::pi() * x)); +} + +template +T asymptotic_bessel_phase_mx(T v, T x) +{ + // + // Calculate the phase of J(v, x) and Y(v, x) for large x. + // See A&S 9.2.29. + // Note that the result returned is the phase less (x - PI(v/2 + 1/4)) + // which we'll factor in later when we calculate the sines/cosines of the result: + // + T mu = 4 * v * v; + T denom = 4 * x; + T denom_mult = denom * denom; + + T s = 0; + s += (mu - 1) / (2 * denom); + denom *= denom_mult; + s += (mu - 1) * (mu - 25) / (6 * denom); + denom *= denom_mult; + s += (mu - 1) * (mu * mu - 114 * mu + 1073) / (5 * denom); + denom *= denom_mult; + s += (mu - 1) * (5 * mu * mu * mu - 1535 * mu * mu + 54703 * mu - 375733) / (14 * denom); + return s; +} + +template +inline T asymptotic_bessel_y_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.19. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + T ampl = asymptotic_bessel_amplitude(v, x); + T phase = asymptotic_bessel_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 + 1/4) term not added to the + // phase when we calculated it. + // + T cx = cos(x); + T sx = sin(x); + T ci = boost::math::cos_pi(v / 2 + 0.25f, pol); + T si = boost::math::sin_pi(v / 2 + 0.25f, pol); + T sin_phase = sin(phase) * (cx * ci + sx * si) + cos(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + return sin_phase * ampl; +} + +template +inline T asymptotic_bessel_j_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.19. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + T ampl = asymptotic_bessel_amplitude(v, x); + T phase = asymptotic_bessel_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 + 1/4) term not added to the + // phase when we calculated it. + // + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + T cx = cos(x); + T sx = sin(x); + T ci = boost::math::cos_pi(v / 2 + 0.25f, pol); + T si = boost::math::sin_pi(v / 2 + 0.25f, pol); + T sin_phase = cos(phase) * (cx * ci + sx * si) - sin(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_VARIABLE(sin_phase); + return sin_phase * ampl; +} + +template +inline bool asymptotic_bessel_large_x_limit(int v, const T& x) +{ + BOOST_MATH_STD_USING + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + BOOST_MATH_ASSERT(v >= 0); + return (v ? v : 1) < x * 0.004f; +} + +template +inline bool asymptotic_bessel_large_x_limit(const T& v, const T& x) +{ + BOOST_MATH_STD_USING + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + return (std::max)(T(fabs(v)), T(1)) < x * sqrt(tools::forth_root_epsilon()); +} + +template +void temme_asyptotic_y_small_x(T v, T x, T* Y, T* Y1, const Policy& pol) +{ + T c = 1; + T p = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, -v) / boost::math::tgamma(1 - v, pol); + T q = (v / boost::math::sin_pi(v, pol)) * pow(x / 2, v) / boost::math::tgamma(1 + v, pol); + T f = (p - q) / v; + T g_prefix = boost::math::sin_pi(v / 2, pol); + g_prefix *= g_prefix * 2 / v; + T g = f + g_prefix * q; + T h = p; + T c_mult = -x * x / 4; + + T y(c * g), y1(c * h); + + for(int k = 1; k < policies::get_max_series_iterations(); ++k) + { + f = (k * f + p + q) / (k*k - v*v); + p /= k - v; + q /= k + v; + c *= c_mult / k; + T c1 = pow(-x * x / 4, k) / factorial(k, pol); + g = f + g_prefix * q; + h = -k * g + p; + y += c * g; + y1 += c * h; + if(c * g / tools::epsilon() < y) + break; + } + + *Y = -y; + *Y1 = (-2 / x) * y1; +} + +template +T asymptotic_bessel_i_large_x(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + T s = 1; + T mu = 4 * v * v; + T ex = 8 * x; + T num = mu - 1; + T denom = ex; + + s -= num / denom; + + num *= mu - 9; + denom *= ex * 2; + s += num / denom; + + num *= mu - 25; + denom *= ex * 3; + s -= num / denom; + + // Try and avoid overflow to the last minute: + T e = exp(x/2); + + s = e * (e * s / sqrt(2 * x * constants::pi())); + + return (boost::math::isfinite)(s) ? + s : policies::raise_overflow_error("boost::math::asymptotic_bessel_i_large_x<%1%>(%1%,%1%)", nullptr, pol); +} + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_asym.hpp @@ -0,0 +1,141 @@ +// Copyright (c) 2013 Anton Bikineev +// 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) + +// +// This is a partial header, do not include on it's own!!! +// +// Contains asymptotic expansions for derivatives of Bessel J(v,x) and Y(v,x) +// functions, as x -> INF. +#ifndef BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP +#define BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math{ namespace detail{ + +template +inline T asymptotic_bessel_derivative_amplitude(T v, T x) +{ + // Calculate the amplitude for J'(v,x) and I'(v,x) + // for large x: see A&S 9.2.30. + BOOST_MATH_STD_USING + T s = 1; + const T mu = 4 * v * v; + T txq = 2 * x; + txq *= txq; + + s -= (mu - 3) / (2 * txq); + s -= ((mu - 1) * (mu - 45)) / (txq * txq * 8); + + return sqrt(s * 2 / (boost::math::constants::pi() * x)); +} + +template +inline T asymptotic_bessel_derivative_phase_mx(T v, T x) +{ + // Calculate the phase of J'(v, x) and Y'(v, x) for large x. + // See A&S 9.2.31. + // Note that the result returned is the phase less (x - PI(v/2 - 1/4)) + // which we'll factor in later when we calculate the sines/cosines of the result: + const T mu = 4 * v * v; + const T mu2 = mu * mu; + const T mu3 = mu2 * mu; + T denom = 4 * x; + T denom_mult = denom * denom; + + T s = 0; + s += (mu + 3) / (2 * denom); + denom *= denom_mult; + s += (mu2 + (46 * mu) - 63) / (6 * denom); + denom *= denom_mult; + s += (mu3 + (185 * mu2) - (2053 * mu) + 1899) / (5 * denom); + return s; +} + +template +inline T asymptotic_bessel_y_derivative_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.20. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + const T ampl = asymptotic_bessel_derivative_amplitude(v, x); + const T phase = asymptotic_bessel_derivative_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 - 1/4) term not added to the + // phase when we calculated it. + // + const T cx = cos(x); + const T sx = sin(x); + const T vd2shifted = (v / 2) - 0.25f; + const T ci = cos_pi(vd2shifted, pol); + const T si = sin_pi(vd2shifted, pol); + const T sin_phase = sin(phase) * (cx * ci + sx * si) + cos(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + return sin_phase * ampl; +} + +template +inline T asymptotic_bessel_j_derivative_large_x_2(T v, T x, const Policy& pol) +{ + // See A&S 9.2.20. + BOOST_MATH_STD_USING + // Get the phase and amplitude: + const T ampl = asymptotic_bessel_derivative_amplitude(v, x); + const T phase = asymptotic_bessel_derivative_phase_mx(v, x); + BOOST_MATH_INSTRUMENT_VARIABLE(ampl); + BOOST_MATH_INSTRUMENT_VARIABLE(phase); + // + // Calculate the sine of the phase, using + // sine/cosine addition rules to factor in + // the x - PI(v/2 - 1/4) term not added to the + // phase when we calculated it. + // + BOOST_MATH_INSTRUMENT_CODE(cos(phase)); + BOOST_MATH_INSTRUMENT_CODE(cos(x)); + BOOST_MATH_INSTRUMENT_CODE(sin(phase)); + BOOST_MATH_INSTRUMENT_CODE(sin(x)); + const T cx = cos(x); + const T sx = sin(x); + const T vd2shifted = (v / 2) - 0.25f; + const T ci = cos_pi(vd2shifted, pol); + const T si = sin_pi(vd2shifted, pol); + const T sin_phase = cos(phase) * (cx * ci + sx * si) - sin(phase) * (sx * ci - cx * si); + BOOST_MATH_INSTRUMENT_VARIABLE(sin_phase); + return sin_phase * ampl; +} + +template +inline bool asymptotic_bessel_derivative_large_x_limit(const T& v, const T& x) +{ + BOOST_MATH_STD_USING + // + // This function is the copy of math::asymptotic_bessel_large_x_limit + // It means that we use the same rules for determining how x is large + // compared to v. + // + // Determines if x is large enough compared to v to take the asymptotic + // forms above. From A&S 9.2.28 we require: + // v < x * eps^1/8 + // and from A&S 9.2.29 we require: + // v^12/10 < 1.5 * x * eps^1/10 + // using the former seems to work OK in practice with broadly similar + // error rates either side of the divide for v < 10000. + // At double precision eps^1/8 ~= 0.01. + // + return (std::max)(T(fabs(v)), T(1)) < x * sqrt(boost::math::tools::forth_root_epsilon()); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_BESSEL_JY_DERIVATIVES_ASYM_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_derivatives_series.hpp @@ -0,0 +1,216 @@ +// Copyright (c) 2013 Anton Bikineev +// 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_BESSEL_JY_DERIVATIVES_SERIES_HPP +#define BOOST_MATH_BESSEL_JY_DERIVATIVES_SERIES_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct bessel_j_derivative_small_z_series_term +{ + typedef T result_type; + + bessel_j_derivative_small_z_series_term(T v_, T x) + : N(0), v(v_), term(1), mult(x / 2) + { + mult *= -mult; + // iterate if v == 0; otherwise result of + // first term is 0 and tools::sum_series stops + if (v == 0) + iterate(); + } + T operator()() + { + T r = term * (v + 2 * N); + iterate(); + return r; + } +private: + void iterate() + { + ++N; + term *= mult / (N * (N + v)); + } + unsigned N; + T v; + T term; + T mult; +}; +// +// Series evaluation for BesselJ'(v, z) as z -> 0. +// It's derivative of http://functions.wolfram.com/Bessel-TypeFunctions/BesselJ/06/01/04/01/01/0003/ +// Converges rapidly for all z << v. +// +template +inline T bessel_j_derivative_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if (v < boost::math::max_factorial::value) + { + prefix = pow(x / 2, v - 1) / 2 / boost::math::tgamma(v + 1, pol); + } + else + { + prefix = (v - 1) * log(x / 2) - constants::ln_two() - boost::math::lgamma(v + 1, pol); + prefix = exp(prefix); + } + if (0 == prefix) + return prefix; + + bessel_j_derivative_small_z_series_term s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + boost::math::policies::check_series_iterations("boost::math::bessel_j_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +template +struct bessel_y_derivative_small_z_series_term_a +{ + typedef T result_type; + + bessel_y_derivative_small_z_series_term_a(T v_, T x) + : N(0), v(v_) + { + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term * (-v + 2 * N); + ++N; + term *= mult / (N * (N - v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; + +template +struct bessel_y_derivative_small_z_series_term_b +{ + typedef T result_type; + + bessel_y_derivative_small_z_series_term_b(T v_, T x) + : N(0), v(v_) + { + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term * (v + 2 * N); + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series form for BesselY' as z -> 0, +// It's derivative of http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/01/0003/ +// This series is only useful when the second term is small compared to the first +// otherwise we get catastrophic cancellation errors. +// +// Approximating tgamma(v) by v^v, and assuming |tgamma(-z)| < eps we end up requiring: +// eps/2 * v^v(x/2)^-v > (x/2)^v or log(eps/2) > v log((x/2)^2/v) +// +template +inline T bessel_y_derivative_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "bessel_y_derivative_small_z_series<%1%>(%1%,%1%)"; + T prefix; + T gam; + T p = log(x / 2); + T scale = 1; + bool need_logs = (v >= boost::math::max_factorial::value) || (boost::math::tools::log_max_value() / v < fabs(p)); + if (!need_logs) + { + gam = boost::math::tgamma(v, pol); + p = pow(x / 2, v + 1) * 2; + if (boost::math::tools::max_value() * p < gam) + { + scale /= gam; + gam = 1; + if (boost::math::tools::max_value() * p < gam) + { + // This term will overflow to -INF, when combined with the series below it becomes +INF: + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -gam / (boost::math::constants::pi() * p); + } + else + { + gam = boost::math::lgamma(v, pol); + p = (v + 1) * p + constants::ln_two(); + prefix = gam - log(boost::math::constants::pi()) - p; + if (boost::math::tools::log_max_value() < prefix) + { + prefix -= log(boost::math::tools::max_value() / 4); + scale /= (boost::math::tools::max_value() / 4); + if (boost::math::tools::log_max_value() < prefix) + { + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -exp(prefix); + } + bessel_y_derivative_small_z_series_term_a s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + boost::math::policies::check_series_iterations("boost::math::bessel_y_derivative_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + result *= prefix; + + p = pow(x / 2, v - 1) / 2; + if (!need_logs) + { + prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v, pol) * p / boost::math::constants::pi(); + } + else + { + int sgn; + prefix = boost::math::lgamma(-v, &sgn, pol) + (v - 1) * log(x / 2) - constants::ln_two(); + prefix = exp(prefix) * sgn / boost::math::constants::pi(); + } + bessel_y_derivative_small_z_series_term_b s2(v, x); + max_iter = boost::math::policies::get_max_series_iterations(); + + T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon(), max_iter); + + result += scale * prefix * b; + return result; +} + +// Calculating of BesselY'(v,x) with small x (x < epsilon) and integer x using derivatives +// of formulas in http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/02/ +// seems to lose precision. Instead using linear combination of regular Bessel is preferred. + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JY_DERIVATVIES_SERIES_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_series.hpp @@ -0,0 +1,256 @@ +// Copyright (c) 2011 John Maddock +// 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_BESSEL_JN_SERIES_HPP +#define BOOST_MATH_BESSEL_JN_SERIES_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost { namespace math { namespace detail{ + +template +struct bessel_j_small_z_series_term +{ + typedef T result_type; + + bessel_j_small_z_series_term(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term; + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series evaluation for BesselJ(v, z) as z -> 0. +// See http://functions.wolfram.com/Bessel-TypeFunctions/BesselJ/06/01/04/01/01/0003/ +// Converges rapidly for all z << v. +// +template +inline T bessel_j_small_z_series(T v, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T prefix; + if(v < max_factorial::value) + { + prefix = pow(x / 2, v) / boost::math::tgamma(v+1, pol); + } + else + { + prefix = v * log(x / 2) - boost::math::lgamma(v+1, pol); + prefix = exp(prefix); + } + if(0 == prefix) + return prefix; + + bessel_j_small_z_series_term s(v, x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_j_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + return prefix * result; +} + +template +struct bessel_y_small_z_series_term_a +{ + typedef T result_type; + + bessel_y_small_z_series_term_a(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + BOOST_MATH_STD_USING + T r = term; + ++N; + term *= mult / (N * (N - v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; + +template +struct bessel_y_small_z_series_term_b +{ + typedef T result_type; + + bessel_y_small_z_series_term_b(T v_, T x) + : N(0), v(v_) + { + BOOST_MATH_STD_USING + mult = x / 2; + mult *= -mult; + term = 1; + } + T operator()() + { + T r = term; + ++N; + term *= mult / (N * (N + v)); + return r; + } +private: + unsigned N; + T v; + T mult; + T term; +}; +// +// Series form for BesselY as z -> 0, +// see: http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/01/0003/ +// This series is only useful when the second term is small compared to the first +// otherwise we get catastrophic cancellation errors. +// +// Approximating tgamma(v) by v^v, and assuming |tgamma(-z)| < eps we end up requiring: +// eps/2 * v^v(x/2)^-v > (x/2)^v or log(eps/2) > v log((x/2)^2/v) +// +template +inline T bessel_y_small_z_series(T v, T x, T* pscale, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "bessel_y_small_z_series<%1%>(%1%,%1%)"; + T prefix; + T gam; + T p = log(x / 2); + T scale = 1; + bool need_logs = (v >= max_factorial::value) || (tools::log_max_value() / v < fabs(p)); + if(!need_logs) + { + gam = boost::math::tgamma(v, pol); + p = pow(x / 2, v); + if(tools::max_value() * p < gam) + { + scale /= gam; + gam = 1; + if(tools::max_value() * p < gam) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -gam / (constants::pi() * p); + } + else + { + gam = boost::math::lgamma(v, pol); + p = v * p; + prefix = gam - log(constants::pi()) - p; + if(tools::log_max_value() < prefix) + { + prefix -= log(tools::max_value() / 4); + scale /= (tools::max_value() / 4); + if(tools::log_max_value() < prefix) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + } + prefix = -exp(prefix); + } + bessel_y_small_z_series_term_a s(v, x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + *pscale = scale; + + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::bessel_y_small_z_series<%1%>(%1%,%1%)", max_iter, pol); + result *= prefix; + + if(!need_logs) + { + prefix = boost::math::tgamma(-v, pol) * boost::math::cos_pi(v, pol) * p / constants::pi(); + } + else + { + int sgn; + prefix = boost::math::lgamma(-v, &sgn, pol) + p; + prefix = exp(prefix) * sgn / constants::pi(); + } + bessel_y_small_z_series_term_b s2(v, x); + max_iter = policies::get_max_series_iterations(); + + T b = boost::math::tools::sum_series(s2, boost::math::policies::get_epsilon(), max_iter); + + result -= scale * prefix * b; + return result; +} + +template +T bessel_yn_small_z(int n, T z, T* scale, const Policy& pol) +{ + // + // See http://functions.wolfram.com/Bessel-TypeFunctions/BesselY/06/01/04/01/02/ + // + // Note that when called we assume that x < epsilon and n is a positive integer. + // + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(n >= 0); + BOOST_MATH_ASSERT((z < policies::get_epsilon())); + + if(n == 0) + { + return (2 / constants::pi()) * (log(z / 2) + constants::euler()); + } + else if(n == 1) + { + return (z / constants::pi()) * log(z / 2) + - 2 / (constants::pi() * z) + - (z / (2 * constants::pi())) * (1 - 2 * constants::euler()); + } + else if(n == 2) + { + return (z * z) / (4 * constants::pi()) * log(z / 2) + - (4 / (constants::pi() * z * z)) + - ((z * z) / (8 * constants::pi())) * (T(3)/2 - 2 * constants::euler()); + } + else + { + T p = pow(z / 2, n); + T result = -((boost::math::factorial(n - 1, pol) / constants::pi())); + if(p * tools::max_value() < result) + { + T div = tools::max_value() / 8; + result /= div; + *scale /= div; + if(p * tools::max_value() < result) + { + return -policies::raise_overflow_error("bessel_yn_small_z<%1%>(%1%,%1%)", nullptr, pol); + } + } + return result / p; + } +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_JN_SERIES_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_zero.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_zero.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_jy_zero.hpp @@ -0,0 +1,627 @@ +// Copyright (c) 2013 Christopher Kormanyos +// 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) +// +// This work is based on an earlier work: +// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", +// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 +// +// This header contains implementation details for estimating the zeros +// of cylindrical Bessel and Neumann functions on the positive real axis. +// Support is included for both positive as well as negative order. +// Various methods are used to estimate the roots. These include +// empirical curve fitting and McMahon's asymptotic approximation +// for small order, uniform asymptotic expansion for large order, +// and iteration and root interlacing for negative order. +// +#ifndef BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ + #define BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ + + #include + #include + #include + #include + #include + + namespace boost { namespace math { + namespace detail + { + namespace bessel_zero + { + template + T equation_nist_10_21_19(const T& v, const T& a) + { + // Get the initial estimate of the m'th root of Jv or Yv. + // This subroutine is used for the order m with m > 1. + // The order m has been used to create the input parameter a. + + // This is Eq. 10.21.19 in the NIST Handbook. + const T mu = (v * v) * 4U; + const T mu_minus_one = mu - T(1); + const T eight_a_inv = T(1) / (a * 8U); + const T eight_a_inv_squared = eight_a_inv * eight_a_inv; + + const T term3 = ((mu_minus_one * 4U) * ((mu * 7U) - T(31U) )) / 3U; + const T term5 = ((mu_minus_one * 32U) * ((((mu * 83U) - T(982U) ) * mu) + T(3779U) )) / 15U; + const T term7 = ((mu_minus_one * 64U) * ((((((mu * 6949U) - T(153855UL)) * mu) + T(1585743UL)) * mu) - T(6277237UL))) / 105U; + + return a + (((( - term7 + * eight_a_inv_squared - term5) + * eight_a_inv_squared - term3) + * eight_a_inv_squared - mu_minus_one) + * eight_a_inv); + } + + template + class equation_as_9_3_39_and_its_derivative + { + public: + explicit equation_as_9_3_39_and_its_derivative(const T& zt) : zeta(zt) { } + + equation_as_9_3_39_and_its_derivative(const equation_as_9_3_39_and_its_derivative&) = default; + + boost::math::tuple operator()(const T& z) const + { + BOOST_MATH_STD_USING // ADL of std names, needed for acos, sqrt. + + // Return the function of zeta that is implicitly defined + // in A&S Eq. 9.3.39 as a function of z. The function is + // returned along with its derivative with respect to z. + + const T zsq_minus_one_sqrt = sqrt((z * z) - T(1)); + + const T the_function( + zsq_minus_one_sqrt + - ( acos(T(1) / z) + ((T(2) / 3U) * (zeta * sqrt(zeta))))); + + const T its_derivative(zsq_minus_one_sqrt / z); + + return boost::math::tuple(the_function, its_derivative); + } + + private: + const equation_as_9_3_39_and_its_derivative& operator=(const equation_as_9_3_39_and_its_derivative&) = delete; + const T zeta; + }; + + template + static T equation_as_9_5_26(const T& v, const T& ai_bi_root, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for log, sqrt. + + // Obtain the estimate of the m'th zero of Jv or Yv. + // The order m has been used to create the input parameter ai_bi_root. + // Here, v is larger than about 2.2. The estimate is computed + // from Abramowitz and Stegun Eqs. 9.5.22 and 9.5.26, page 371. + // + // The inversion of z as a function of zeta is mentioned in the text + // following A&S Eq. 9.5.26. Here, we accomplish the inversion by + // performing a Taylor expansion of Eq. 9.3.39 for large z to order 2 + // and solving the resulting quadratic equation, thereby taking + // the positive root of the quadratic. + // In other words: (2/3)(-zeta)^(3/2) approx = z + 1/(2z) - pi/2. + // This leads to: z^2 - [(2/3)(-zeta)^(3/2) + pi/2]z + 1/2 = 0. + // + // With this initial estimate, Newton-Raphson iteration is used + // to refine the value of the estimate of the root of z + // as a function of zeta. + + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + // Obtain zeta using the order v combined with the m'th root of + // an airy function, as shown in A&S Eq. 9.5.22. + const T zeta = v_pow_minus_two_thirds * (-ai_bi_root); + + const T zeta_sqrt = sqrt(zeta); + + // Set up a quadratic equation based on the Taylor series + // expansion mentioned above. + const T b = -((((zeta * zeta_sqrt) * 2U) / 3U) + boost::math::constants::half_pi()); + + // Solve the quadratic equation, taking the positive root. + const T z_estimate = (-b + sqrt((b * b) - T(2))) / 2U; + + // Establish the range, the digits, and the iteration limit + // for the upcoming root-finding. + const T range_zmin = (std::max)(z_estimate - T(1), T(1)); + const T range_zmax = z_estimate + T(1); + + const auto my_digits10 = static_cast(static_cast(boost::math::tools::digits() * 0.301F)); + + // Select the maximum allowed iterations based on the number + // of decimal digits in the numeric type T, being at least 12. + const auto iterations_allowed = static_cast((std::max)(12, my_digits10 * 2)); + + std::uintmax_t iterations_used = iterations_allowed; + + // Calculate the root of z as a function of zeta. + const T z = boost::math::tools::newton_raphson_iterate( + boost::math::detail::bessel_zero::equation_as_9_3_39_and_its_derivative(zeta), + z_estimate, + range_zmin, + range_zmax, + (std::min)(boost::math::tools::digits(), boost::math::tools::digits()), + iterations_used); + + static_cast(iterations_used); + + // Continue with the implementation of A&S Eq. 9.3.39. + const T zsq_minus_one = (z * z) - T(1); + const T zsq_minus_one_sqrt = sqrt(zsq_minus_one); + + // This is A&S Eq. 9.3.42. + const T b0_term_5_24 = T(5) / ((zsq_minus_one * zsq_minus_one_sqrt) * 24U); + const T b0_term_1_8 = T(1) / ( zsq_minus_one_sqrt * 8U); + const T b0_term_5_48 = T(5) / ((zeta * zeta) * 48U); + + const T b0 = -b0_term_5_48 + ((b0_term_5_24 + b0_term_1_8) / zeta_sqrt); + + // This is the second line of A&S Eq. 9.5.26 for f_k with k = 1. + const T f1 = ((z * zeta_sqrt) * b0) / zsq_minus_one_sqrt; + + // This is A&S Eq. 9.5.22 expanded to k = 1 (i.e., one term in the series). + return (v * z) + (f1 / v); + } + + namespace cyl_bessel_j_zero_detail + { + template + T equation_nist_10_21_40_a(const T& v, const Policy& pol) + { + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + return v * ((((( + T(0.043) + * v_pow_minus_two_thirds - T(0.0908)) + * v_pow_minus_two_thirds - T(0.00397)) + * v_pow_minus_two_thirds + T(1.033150)) + * v_pow_minus_two_thirds + T(1.8557571)) + * v_pow_minus_two_thirds + T(1)); + } + + template + class function_object_jv + { + public: + function_object_jv(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + function_object_jv(const function_object_jv&) = default; + + T operator()(const T& x) const + { + return boost::math::cyl_bessel_j(my_v, x, my_pol); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_jv& operator=(const function_object_jv&) = delete; + }; + + template + class function_object_jv_and_jv_prime + { + public: + function_object_jv_and_jv_prime(const T& v, + const bool order_is_zero, + const Policy& pol) : my_v(v), + my_order_is_zero(order_is_zero), + my_pol(pol) { } + + function_object_jv_and_jv_prime(const function_object_jv_and_jv_prime&) = default; + + boost::math::tuple operator()(const T& x) const + { + // Obtain Jv(x) and Jv'(x). + // Chris's original code called the Bessel function implementation layer direct, + // but that circumvented optimizations for integer-orders. Call the documented + // top level functions instead, and let them sort out which implementation to use. + T j_v; + T j_v_prime; + + if(my_order_is_zero) + { + j_v = boost::math::cyl_bessel_j(0, x, my_pol); + j_v_prime = -boost::math::cyl_bessel_j(1, x, my_pol); + } + else + { + j_v = boost::math::cyl_bessel_j( my_v, x, my_pol); + const T j_v_m1 (boost::math::cyl_bessel_j(T(my_v - 1), x, my_pol)); + j_v_prime = j_v_m1 - ((my_v * j_v) / x); + } + + // Return a tuple containing both Jv(x) and Jv'(x). + return boost::math::make_tuple(j_v, j_v_prime); + } + + private: + const T my_v; + const bool my_order_is_zero; + const Policy& my_pol; + const function_object_jv_and_jv_prime& operator=(const function_object_jv_and_jv_prime&) = delete; + }; + + template bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; } + + template + T initial_guess(const T& v, const int m, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + // Compute an estimate of the m'th root of cyl_bessel_j. + + T guess; + + // There is special handling for negative order. + if(v < 0) + { + if((m == 1) && (v > -0.5F)) + { + // For small, negative v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselJZero[n, 1]}, {n, -(1/2), 0, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.2321156900729) + * v - T(0.1493247777488)) + * v - T(0.15205419167239)) + * v + T(0.07814930561249)) + * v - T(0.17757573537688)) + * v + T(1.542805677045663)) + * v + T(2.40482555769577277); + + return guess; + } + + // Create the positive order and extract its positive floor integer part. + const T vv(-v); + const T vv_floor(floor(vv)); + + // The to-be-found root is bracketed by the roots of the + // Bessel function whose reflected, positive integer order + // is less than, but nearest to vv. + + T root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m, pol); + T root_lo; + + if(m == 1) + { + // The estimate of the first root for negative order is found using + // an adaptive range-searching algorithm. + root_lo = T(root_hi - 0.1F); + + const bool hi_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_hi, pol) < 0); + + while((root_lo > boost::math::tools::epsilon())) + { + const bool lo_end_of_bracket_is_negative = (boost::math::cyl_bessel_j(v, root_lo, pol) < 0); + + if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative) + { + break; + } + + root_hi = root_lo; + + // Decrease the lower end of the bracket using an adaptive algorithm. + if(root_lo > 0.5F) + { + root_lo -= 0.5F; + } + else + { + root_lo *= 0.75F; + } + } + } + else + { + root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(vv_floor, m - 1, pol); + } + + // Perform several steps of bisection iteration to refine the guess. + std::uintmax_t number_of_iterations(12U); + + // Do the bisection iteration. + const boost::math::tuple guess_pair = + boost::math::tools::bisect( + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::function_object_jv(v, pol), + root_lo, + root_hi, + boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::my_bisection_unreachable_tolerance, + number_of_iterations); + + return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U; + } + + if(m == 1U) + { + // Get the initial estimate of the first root. + + if(v < 2.2F) + { + // For small v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselJZero[n, 1]}, {n, 0, 22/10, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.0008342379046010) + * v + T(0.007590035637410)) + * v - T(0.030640914772013)) + * v + T(0.078232088020106)) + * v - T(0.169668712590620)) + * v + T(1.542187960073750)) + * v + T(2.4048359915254634); + } + else + { + // For larger v, use the first line of Eqs. 10.21.40 in the NIST Handbook. + guess = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::equation_nist_10_21_40_a(v, pol); + } + } + else + { + if(v < 2.2F) + { + // Use Eq. 10.21.19 in the NIST Handbook. + const T a(((v + T(m * 2U)) - T(0.5)) * boost::math::constants::half_pi()); + + guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a); + } + else + { + // Get an estimate of the m'th root of airy_ai. + const T airy_ai_root(boost::math::detail::airy_zero::airy_ai_zero_detail::initial_guess(m, pol)); + + // Use Eq. 9.5.26 in the A&S Handbook. + guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_ai_root, pol); + } + } + + return guess; + } + } // namespace cyl_bessel_j_zero_detail + + namespace cyl_neumann_zero_detail + { + template + T equation_nist_10_21_40_b(const T& v, const Policy& pol) + { + const T v_pow_third(boost::math::cbrt(v, pol)); + const T v_pow_minus_two_thirds(T(1) / (v_pow_third * v_pow_third)); + + return v * ((((( - T(0.001) + * v_pow_minus_two_thirds - T(0.0060)) + * v_pow_minus_two_thirds + T(0.01198)) + * v_pow_minus_two_thirds + T(0.260351)) + * v_pow_minus_two_thirds + T(0.9315768)) + * v_pow_minus_two_thirds + T(1)); + } + + template + class function_object_yv + { + public: + function_object_yv(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + function_object_yv(const function_object_yv&) = default; + + T operator()(const T& x) const + { + return boost::math::cyl_neumann(my_v, x, my_pol); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_yv& operator=(const function_object_yv&) = delete; + }; + + template + class function_object_yv_and_yv_prime + { + public: + function_object_yv_and_yv_prime(const T& v, + const Policy& pol) : my_v(v), + my_pol(pol) { } + + function_object_yv_and_yv_prime(const function_object_yv_and_yv_prime&) = default; + + boost::math::tuple operator()(const T& x) const + { + const T half_epsilon(boost::math::tools::epsilon() / 2U); + + const bool order_is_zero = ((my_v > -half_epsilon) && (my_v < +half_epsilon)); + + // Obtain Yv(x) and Yv'(x). + // Chris's original code called the Bessel function implementation layer direct, + // but that circumvented optimizations for integer-orders. Call the documented + // top level functions instead, and let them sort out which implementation to use. + T y_v; + T y_v_prime; + + if(order_is_zero) + { + y_v = boost::math::cyl_neumann(0, x, my_pol); + y_v_prime = -boost::math::cyl_neumann(1, x, my_pol); + } + else + { + y_v = boost::math::cyl_neumann( my_v, x, my_pol); + const T y_v_m1 (boost::math::cyl_neumann(T(my_v - 1), x, my_pol)); + y_v_prime = y_v_m1 - ((my_v * y_v) / x); + } + + // Return a tuple containing both Yv(x) and Yv'(x). + return boost::math::make_tuple(y_v, y_v_prime); + } + + private: + const T my_v; + const Policy& my_pol; + const function_object_yv_and_yv_prime& operator=(const function_object_yv_and_yv_prime&) = delete; + }; + + template bool my_bisection_unreachable_tolerance(const T&, const T&) { return false; } + + template + T initial_guess(const T& v, const int m, const Policy& pol) + { + BOOST_MATH_STD_USING // ADL of std names, needed for floor. + + // Compute an estimate of the m'th root of cyl_neumann. + + T guess; + + // There is special handling for negative order. + if(v < 0) + { + // Create the positive order and extract its positive floor and ceiling integer parts. + const T vv(-v); + const T vv_floor(floor(vv)); + + // The to-be-found root is bracketed by the roots of the + // Bessel function whose reflected, positive integer order + // is less than, but nearest to vv. + + // The special case of negative, half-integer order uses + // the relation between Yv and spherical Bessel functions + // in order to obtain the bracket for the root. + // In these special cases, cyl_neumann(-n/2, x) = sph_bessel_j(+n/2, x) + // for v = -n/2. + + T root_hi; + T root_lo; + + if(m == 1) + { + // The estimate of the first root for negative order is found using + // an adaptive range-searching algorithm. + // Take special precautions for the discontinuity at negative, + // half-integer orders and use different brackets above and below these. + if(T(vv - vv_floor) < 0.5F) + { + root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol); + } + else + { + root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol); + } + + root_lo = T(root_hi - 0.1F); + + const bool hi_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_hi, pol) < 0); + + while((root_lo > boost::math::tools::epsilon())) + { + const bool lo_end_of_bracket_is_negative = (boost::math::cyl_neumann(v, root_lo, pol) < 0); + + if(hi_end_of_bracket_is_negative != lo_end_of_bracket_is_negative) + { + break; + } + + root_hi = root_lo; + + // Decrease the lower end of the bracket using an adaptive algorithm. + if(root_lo > 0.5F) + { + root_lo -= 0.5F; + } + else + { + root_lo *= 0.75F; + } + } + } + else + { + if(T(vv - vv_floor) < 0.5F) + { + root_lo = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m - 1, pol); + root_hi = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::initial_guess(vv_floor, m, pol); + root_lo += 0.01F; + root_hi += 0.01F; + } + else + { + root_lo = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m - 1, pol); + root_hi = boost::math::detail::bessel_zero::cyl_bessel_j_zero_detail::initial_guess(T(vv_floor + 0.5F), m, pol); + root_lo += 0.01F; + root_hi += 0.01F; + } + } + + // Perform several steps of bisection iteration to refine the guess. + std::uintmax_t number_of_iterations(12U); + + // Do the bisection iteration. + const boost::math::tuple guess_pair = + boost::math::tools::bisect( + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::function_object_yv(v, pol), + root_lo, + root_hi, + boost::math::detail::bessel_zero::cyl_neumann_zero_detail::my_bisection_unreachable_tolerance, + number_of_iterations); + + return (boost::math::get<0>(guess_pair) + boost::math::get<1>(guess_pair)) / 2U; + } + + if(m == 1U) + { + // Get the initial estimate of the first root. + + if(v < 2.2F) + { + // For small v, use the results of empirical curve fitting. + // Mathematica(R) session for the coefficients: + // Table[{n, BesselYZero[n, 1]}, {n, 0, 22/10, 1/10}] + // N[%, 20] + // Fit[%, {n^0, n^1, n^2, n^3, n^4, n^5, n^6}, n] + guess = ((((( - T(0.0025095909235652) + * v + T(0.021291887049053)) + * v - T(0.076487785486526)) + * v + T(0.159110268115362)) + * v - T(0.241681668765196)) + * v + T(1.4437846310885244)) + * v + T(0.89362115190200490); + } + else + { + // For larger v, use the second line of Eqs. 10.21.40 in the NIST Handbook. + guess = boost::math::detail::bessel_zero::cyl_neumann_zero_detail::equation_nist_10_21_40_b(v, pol); + } + } + else + { + if(v < 2.2F) + { + // Use Eq. 10.21.19 in the NIST Handbook. + const T a(((v + T(m * 2U)) - T(1.5)) * boost::math::constants::half_pi()); + + guess = boost::math::detail::bessel_zero::equation_nist_10_21_19(v, a); + } + else + { + // Get an estimate of the m'th root of airy_bi. + const T airy_bi_root(boost::math::detail::airy_zero::airy_bi_zero_detail::initial_guess(m, pol)); + + // Use Eq. 9.5.26 in the A&S Handbook. + guess = boost::math::detail::bessel_zero::equation_as_9_5_26(v, airy_bi_root, pol); + } + } + + return guess; + } + } // namespace cyl_neumann_zero_detail + } // namespace bessel_zero + } } } // namespace boost::math::detail + +#endif // BOOST_MATH_BESSEL_JY_ZERO_2013_01_18_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k0.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k0.hpp @@ -0,0 +1,519 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 John Maddock +// 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_BESSEL_K0_HPP +#define BOOST_MATH_BESSEL_K0_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the second kind of order zero +// minimax rational approximations on intervals, see +// Russon and Blair, Chalk River Report AECL-3461, 1969, +// as revised by Pavel Holoborodko in "Rational Approximations +// for the Modified Bessel Function of the Second Kind - K0(x) +// for Computations with Double Precision", see +// http://www.advanpix.com/2015/11/25/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k0-for-computations-with-double-precision/ +// +// The actual coefficients used are our own derivation (by JM) +// since we extend to both greater and lesser precision than the +// references above. We can also improve performance WRT to +// Holoborodko without loss of precision. + +namespace boost { namespace math { namespace detail{ + +template +T bessel_k0(const T& x); + +template +struct bessel_k0_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&) + { + bessel_k0(T(0.5)); + bessel_k0(T(1.5)); + } + static void do_init(const std::integral_constant&) + { + bessel_k0(T(0.5)); + bessel_k0(T(1.5)); + } + template + static void do_init(const U&){} + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_k0_initializer::init bessel_k0_initializer::initializer; + + +template +T bessel_k0_imp(const T&, const std::integral_constant&) +{ + BOOST_MATH_ASSERT(0); + return 0; +} + +template +T bessel_k0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found : 2.358e-09 + // Expected Error Term : -2.358e-09 + // Maximum Relative Change in Control Points : 9.552e-02 + // Max Error found at float precision = Poly : 4.448220e-08 + static const T Y = 1.137250900268554688f; + static const T P[] = + { + -1.372508979104259711e-01f, + 2.622545986273687617e-01f, + 5.047103728247919836e-03f + }; + static const T Q[] = + { + 1.000000000000000000e+00f, + -8.928694018000029415e-02f, + 2.985980684180969241e-03f + }; + T a = x * x / 4; + a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 1.346e-09 + // Expected Error Term : -1.343e-09 + // Maximum Relative Change in Control Points : 2.405e-02 + // Max Error found at float precision = Poly : 1.354814e-07 + static const T P2[] = { + 1.159315158e-01f, + 2.789828686e-01f, + 2.524902861e-02f, + 8.457241514e-04f, + 1.530051997e-05f + }; + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 1.587e-08 + // Expected Error Term : 1.531e-08 + // Maximum Relative Change in Control Points : 9.064e-02 + // Max Error found at float precision = Poly : 5.065020e-08 + + static const T P[] = + { + 2.533141220e-01f, + 5.221502603e-01f, + 6.380180669e-02f, + -5.934976547e-02f + }; + static const T Q[] = + { + 1.000000000e+00f, + 2.679722431e+00f, + 1.561635813e+00f, + 1.573660661e-01f + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * ex / sqrt(x)) * ex; + } + } +} + +template +T bessel_k0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 6.077e-17 + // Expected Error Term : -6.077e-17 + // Maximum Relative Change in Control Points : 7.797e-02 + // Max Error found at double precision = Poly : 1.003156e-16 + static const T Y = 1.137250900268554688; + static const T P[] = + { + -1.372509002685546267e-01, + 2.574916117833312855e-01, + 1.395474602146869316e-02, + 5.445476986653926759e-04, + 7.125159422136622118e-06 + }; + static const T Q[] = + { + 1.000000000000000000e+00, + -5.458333438017788530e-02, + 1.291052816975251298e-03, + -1.367653946978586591e-05 + }; + + T a = x * x / 4; + a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 3.429e-18 + // Expected Error Term : 3.392e-18 + // Maximum Relative Change in Control Points : 2.041e-02 + // Max Error found at double precision = Poly : 2.513112e-16 + static const T P2[] = + { + 1.159315156584124484e-01, + 2.789828789146031732e-01, + 2.524892993216121934e-02, + 8.460350907213637784e-04, + 1.491471924309617534e-05, + 1.627106892422088488e-07, + 1.208266102392756055e-09, + 6.611686391749704310e-12 + }; + + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 4.316e-17 + // Expected Error Term : 9.570e-18 + // Maximum Relative Change in Control Points : 2.757e-01 + // Max Error found at double precision = Poly : 1.001560e-16 + + static const T Y = 1; + static const T P[] = + { + 2.533141373155002416e-01, + 3.628342133984595192e+00, + 1.868441889406606057e+01, + 4.306243981063412784e+01, + 4.424116209627428189e+01, + 1.562095339356220468e+01, + -1.810138978229410898e+00, + -1.414237994269995877e+00, + -9.369168119754924625e-02 + }; + static const T Q[] = + { + 1.000000000000000000e+00, + 1.494194694879908328e+01, + 8.265296455388554217e+01, + 2.162779506621866970e+02, + 2.845145155184222157e+02, + 1.851714491916334995e+02, + 5.486540717439723515e+01, + 6.118075837628957015e+00, + 1.586261269326235053e-01 + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +T bessel_k0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 2.180e-22 + // Expected Error Term : 2.180e-22 + // Maximum Relative Change in Control Points : 2.943e-01 + // Max Error found at float80 precision = Poly : 3.923207e-20 + static const T Y = 1.137250900268554687500e+00; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.372509002685546875002e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.566481981037407600436e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.551881122448948854873e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.646112454323276529650e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.213747930378196492543e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.423709328020389560844e-08) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.843828412587773008342e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.088484822515098936140e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.374724008530702784829e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.452665455952581680339e-08) + }; + + + T a = x * x / 4; + a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 2.440e-21 + // Expected Error Term : -2.434e-21 + // Maximum Relative Change in Control Points : 2.459e-02 + // Max Error found at float80 precision = Poly : 1.482487e-19 + static const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.159315156584124488110e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.764832791416047889734e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.926062887220923354112e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.660777862036966089410e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.094942446930673386849e-06) + }; + static const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.156100313881251616320e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.315993873344905957033e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.529444499350703363451e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.524988589917857531177e-09) + }; + return tools::evaluate_rational(P2, Q2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 4.291e-20 + // Expected Error Term : 2.236e-21 + // Maximum Relative Change in Control Points : 3.021e-01 + //Max Error found at float80 precision = Poly : 8.727378e-20 + static const T Y = 1; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 2.533141373155002512056e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.417942070721928652715e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.477464607463971754433e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.838745728725943889876e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.009736314927811202517e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.557411293123609803452e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.360222564015361268955e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.385435333168505701022e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.750195760942181592050e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.059789241612946683713e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.612783121537333908889e-01) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.200669254769325861404e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.900177593527144126549e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.361003989965786932682e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.041319870804843395893e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.828491555113790345068e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.190342229261529076624e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.003330795963812219852e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.773371397243777891569e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.368634935531158398439e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.543310879400359967327e-01) + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +T bessel_k0_imp(const T& x, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 5.682e-37 + // Expected Error Term : 5.682e-37 + // Maximum Relative Change in Control Points : 6.094e-04 + // Max Error found at float128 precision = Poly : 5.338213e-35 + static const T Y = 1.137250900268554687500000000000000000e+00f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -1.372509002685546875000000000000000006e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.556212905071072782462974351698081303e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.742459135264203478530904179889103929e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.077860530453688571555479526961318918e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.868173911669241091399374307788635148e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.496405768838992243478709145123306602e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.752489221949580551692915881999762125e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.243010555737173524710512824955368526e-12) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.095631064064621099785696980653193721e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.313880983725212151967078809725835532e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.095229912293480063501285562382835142e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.022828799511943141130509410251996277e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.860874007419812445494782795829046836e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.107297802344970725756092082686799037e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.460529579244623559164763757787600944e-15) + }; + T a = x * x / 4; + a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1; + + // Maximum Deviation Found: 5.173e-38 + // Expected Error Term : 5.105e-38 + // Maximum Relative Change in Control Points : 9.734e-03 + // Max Error found at float128 precision = Poly : 1.688806e-34 + static const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.159315156584124488107200313757741370e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.789828789146031122026800078439435369e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.524892993216269451266750049024628432e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.460350907082229957222453839935101823e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.491471929926042875260452849503857976e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.627105610481598430816014719558896866e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.208426165007797264194914898538250281e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.508697838747354949164182457073784117e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.659784680639805301101014383907273109e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.531090131964391104248859415958109654e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.205195117066478034260323124669936314e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.692219280289030165761119775783115426e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.362350161092532344171965861545860747e-25), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.277990623924628999539014980773738258e-27) + }; + + return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a; + } + else + { + // Maximum Deviation Found: 1.462e-34 + // Expected Error Term : 4.917e-40 + // Maximum Relative Change in Control Points : 3.385e-01 + // Max Error found at float128 precision = Poly : 1.567573e-34 + static const T Y = 1; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 2.533141373155002512078826424055226265e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.001949740768235770078339977110749204e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.991516715983883248363351472378349986e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.429587951594593159075690819360687720e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.911933815201948768044660065771258450e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.769943016204926614862175317962439875e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.170866154649560750500954150401105606e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.634687099724383996792011977705727661e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.989524036456492581597607246664394014e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.160394785715328062088529400178080360e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.778173054417826368076483100902201433e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.335667778588806892764139643950439733e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.283635100080306980206494425043706838e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.300616188213640626577036321085025855e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.277591957076162984986406540894621482e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.564360536834214058158565361486115932e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.043505161612403359098596828115690596e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.217035248223503605127967970903027314e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.422938158797326748375799596769964430e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.229125746200586805278634786674745210e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.201632288615609937883545928660649813e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.690820607338480548346746717311811406e+01) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.964877874035741452203497983642653107e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.808929943826193766839360018583294769e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.814524004679994110944366890912384139e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.897794522506725610540209610337355118e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.456339470955813675629523617440433672e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.057818717813969772198911392875127212e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.513821619536852436424913886081133209e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.255938846873380596038513316919990776e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.537077551699028079347581816919572141e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.176769339768120752974843214652367321e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.828722317390455845253191337207432060e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.698864296569996402006511705803675890e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.007803261356636409943826918468544629e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.016564631288740308993071395104715469e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.595893010619754750655947035567624730e+09), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.241241839120481076862742189989406856e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.168778094393076220871007550235840858e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.156200301360388147635052029404211109e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.752130382550379886741949463587008794e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.370574966987293592457152146806662562e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.871254714311063594080644835895740323e+01) + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } +} + +template +T bessel_k0_imp(const T& x, const std::integral_constant&) +{ + if(boost::math::tools::digits() <= 24) + return bessel_k0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_k0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_k0_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_k0_imp(x, std::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; +} + +template +inline T bessel_k0(const T& x) +{ + typedef std::integral_constant::digits == 0) || (std::numeric_limits::radix != 2)) ? + 0 : + std::numeric_limits::digits <= 24 ? + 24 : + std::numeric_limits::digits <= 53 ? + 53 : + std::numeric_limits::digits <= 64 ? + 64 : + std::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + bessel_k0_initializer::force_instantiate(); + return bessel_k0_imp(x, tag_type()); +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_K0_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k1.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_k1.hpp @@ -0,0 +1,561 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2017 John Maddock +// 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_BESSEL_K1_HPP +#define BOOST_MATH_BESSEL_K1_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Modified Bessel function of the second kind of order zero +// minimax rational approximations on intervals, see +// Russon and Blair, Chalk River Report AECL-3461, 1969, +// as revised by Pavel Holoborodko in "Rational Approximations +// for the Modified Bessel Function of the Second Kind - K0(x) +// for Computations with Double Precision", see +// http://www.advanpix.com/2016/01/05/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k1-for-computations-with-double-precision/ +// +// The actual coefficients used are our own derivation (by JM) +// since we extend to both greater and lesser precision than the +// references above. We can also improve performance WRT to +// Holoborodko without loss of precision. + +namespace boost { namespace math { namespace detail{ + + template + T bessel_k1(const T&); + + template + struct bessel_k1_initializer + { + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&) + { + bessel_k1(T(0.5)); + bessel_k1(T(2)); + bessel_k1(T(6)); + } + static void do_init(const std::integral_constant&) + { + bessel_k1(T(0.5)); + bessel_k1(T(6)); + } + template + static void do_init(const U&) {} + void force_instantiate()const {} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } + }; + + template + const typename bessel_k1_initializer::init bessel_k1_initializer::initializer; + + + template + inline T bessel_k1_imp(const T&, const std::integral_constant&) + { + BOOST_MATH_ASSERT(0); + return 0; + } + + template + T bessel_k1_imp(const T& x, const std::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 3.090e-12 + // Expected Error Term : -3.053e-12 + // Maximum Relative Change in Control Points : 4.927e-02 + // Max Error found at float precision = Poly : 7.918347e-10 + static const T Y = 8.695471287e-02f; + static const T P[] = + { + -3.621379531e-03f, + 7.131781976e-03f, + -1.535278300e-05f + }; + static const T Q[] = + { + 1.000000000e+00f, + -5.173102701e-02f, + 9.203530671e-04f + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 3.556e-08 + // Expected Error Term : -3.541e-08 + // Maximum Relative Change in Control Points : 8.203e-02 + static const T P2[] = + { + -3.079657469e-01f, + -8.537108913e-02f, + -4.640275408e-03f, + -1.156442414e-04f + }; + + return tools::evaluate_polynomial(P2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 3.369e-08 + // Expected Error Term : -3.227e-08 + // Maximum Relative Change in Control Points : 9.917e-02 + // Max Error found at float precision = Poly : 6.084411e-08 + static const T Y = 1.450342178f; + static const T P[] = + { + -1.970280088e-01f, + 2.188747807e-02f, + 7.270394756e-01f, + 2.490678196e-01f + }; + static const T Q[] = + { + 1.000000000e+00f, + 2.274292882e+00f, + 9.904984851e-01f, + 4.585534549e-02f + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + T bessel_k1_imp(const T& x, const std::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 1.922e-17 + // Expected Error Term : 1.921e-17 + // Maximum Relative Change in Control Points : 5.287e-03 + // Max Error found at double precision = Poly : 2.004747e-17 + static const T Y = 8.69547128677368164e-02f; + static const T P[] = + { + -3.62137953440350228e-03, + 7.11842087490330300e-03, + 1.00302560256614306e-05, + 1.77231085381040811e-06 + }; + static const T Q[] = + { + 1.00000000000000000e+00, + -4.80414794429043831e-02, + 9.85972641934416525e-04, + -8.91196859397070326e-06 + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 4.053e-17 + // Expected Error Term : -4.053e-17 + // Maximum Relative Change in Control Points : 3.103e-04 + // Max Error found at double precision = Poly : 1.246698e-16 + + static const T P2[] = + { + -3.07965757829206184e-01, + -7.80929703673074907e-02, + -2.70619343754051620e-03, + -2.49549522229072008e-05 + }; + static const T Q2[] = + { + 1.00000000000000000e+00, + -2.36316836412163098e-02, + 2.64524577525962719e-04, + -1.49749618004162787e-06 + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 8.883e-17 + // Expected Error Term : -1.641e-17 + // Maximum Relative Change in Control Points : 2.786e-01 + // Max Error found at double precision = Poly : 1.258798e-16 + + static const T Y = 1.45034217834472656f; + static const T P[] = + { + -1.97028041029226295e-01, + -2.32408961548087617e+00, + -7.98269784507699938e+00, + -2.39968410774221632e+00, + 3.28314043780858713e+01, + 5.67713761158496058e+01, + 3.30907788466509823e+01, + 6.62582288933739787e+00, + 3.08851840645286691e-01 + }; + static const T Q[] = + { + 1.00000000000000000e+00, + 1.41811409298826118e+01, + 7.35979466317556420e+01, + 1.77821793937080859e+02, + 2.11014501598705982e+02, + 1.19425262951064454e+02, + 2.88448064302447607e+01, + 2.27912927104139732e+00, + 2.50358186953478678e-02 + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + T bessel_k1_imp(const T& x, const std::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 5.549e-23 + // Expected Error Term : -5.548e-23 + // Maximum Relative Change in Control Points : 2.002e-03 + // Max Error found at float80 precision = Poly : 9.352785e-22 + static const T Y = 8.695471286773681640625e-02f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -3.621379534403483072861e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.102135866103952705932e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.167545240236717601167e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.537484002571894870830e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.603228256820000135990e-09) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.354457194045068370363e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.709137201220209072820e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.676151796359590545143e-06), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.162715192766245311659e-08) + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 1.995e-23 + // Expected Error Term : 1.995e-23 + // Maximum Relative Change in Control Points : 8.174e-04 + // Max Error found at float80 precision = Poly : 4.137325e-20 + static const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -3.079657578292062244054e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -7.963049154965966503231e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.103277523735639924895e-03), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.023052834702215699504e-05), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.719459155018493821839e-07) + }; + static const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.863917670410152669768e-02), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.699367098849735298090e-04), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.309358790546076298429e-07), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.708893480271612711933e-09) + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else + { + // Maximum Deviation Found: 9.785e-20 + // Expected Error Term : -3.302e-21 + // Maximum Relative Change in Control Points : 3.432e-01 + // Max Error found at float80 precision = Poly : 1.083755e-19 + static const T Y = 1.450342178344726562500e+00f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.970280410292263112917e-01), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.058564803062959169322e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.036658174194917777473e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -9.576825392332820142173e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, -6.706969489248020941949e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.264572499406168221382e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.584972047303151034100e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.422082733280017909550e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.738005441471368178383e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.016938390144121276609e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.319614662598089438939e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.710715864316521856193e-02) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.298433045824439052398e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.082047745067709230037e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 9.662367854250262046592e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.504148628460454004686e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.712730364911389908905e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.108002081150068641112e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.400149940532448553143e+03), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.083303048095846226299e+02), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.748706060530351833346e+01), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.321900849331506946977e-01), + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + T bessel_k1_imp(const T& x, const std::integral_constant&) + { + BOOST_MATH_STD_USING + if(x <= 1) + { + // Maximum Deviation Found: 7.120e-35 + // Expected Error Term : -7.119e-35 + // Maximum Relative Change in Control Points : 1.207e-03 + // Max Error found at float128 precision = Poly : 7.143688e-35 + static const T Y = 8.695471286773681640625000000000000000e-02f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -3.621379534403483072916666666666595475e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.074117676930975433219826471336547627e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.631337631362776369069668419033041661e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.468935967870048731821071646104412775e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.956705020559599861444492614737168261e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.347140307321161346703214099534250263e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.569608494081482873946791086435679661e-13) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.580768910152105375615558920428350204e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.197467671701485365363068445534557369e-04), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.707466533308630411966030561446666237e-06), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.846687802282250112624373388491123527e-08), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.248493131151981569517383040323900343e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.319279786372775264555728921709381080e-13) + }; + + T a = x * x / 4; + a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2; + + // Maximum Deviation Found: 4.473e-37 + // Expected Error Term : 4.473e-37 + // Maximum Relative Change in Control Points : 8.550e-04 + // Max Error found at float128 precision = Poly : 8.167701e-35 + static const T P2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -3.079657578292062244053600156878870690e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.133183745732467770755578848987414875e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.548968792764174773125420229299431951e-03), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.886125468718182876076972186152445490e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.506712111733707245745396404449639865e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.632502325880313239698965376754406011e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.311973065898784812266544485665624227e-12) + }; + static const T Q2[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.311471216733781016657962995723287450e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.571876054797365417068164018709472969e-05), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.630181215268238731442496851497901293e-07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.070176111227805048604885986867484807e-09), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.129046580769872602793220056461084761e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.294906469421390890762001971790074432e-15) + }; + + return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a; + } + else if(x < 4) + { + // Max error in interpolated form: 5.307e-37 + // Max Error found at float128 precision = Poly: 7.087862e-35 + static const T Y = 1.5023040771484375f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -2.489899398329369710528254347931380044e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.819080211203854781858815596508456873e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.599915699069767382647695624952723034e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.450211910821295507926582231071300718e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.451374687870925175794150513723956533e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.405805746895098802803503988539098226e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.638808326778389656403861103277220518e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.513958744081268456191778822780865708e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.121301640926540743072258116122834804e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.080094900175649541266613109971296190e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.896531083639613332407534434915552429e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.856602122319645694042555107114028437e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.237121918853145421414003823957537419e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.842072954561323076230238664623893504e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.039705646510167437971862966128055524e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.008418100718254816100425022904039530e-02) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.927456835239137986889227412815459529e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.598985593265577043711382994516531273e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.449897377085510281395819892689690579e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.025555887684561913263090023158085327e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.774140447181062463181892531100679195e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.962055507843204417243602332246120418e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.908269326976180183216954452196772931e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.655160454422016855911700790722577942e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.383586885019548163464418964577684608e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.679920375586960324298491662159976419e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.478586421028842906987799049804565008e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.565384974896746094224942654383537090e+02), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.902617937084010911005732488607114511e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.429293010387921526110949911029094926e-01), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.880342607911083143560111853491047663e-04) + }; + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + } + else + { + // Maximum Deviation Found: 4.359e-37 + // Expected Error Term : -6.565e-40 + // Maximum Relative Change in Control Points : 1.880e-01 + // Max Error found at float128 precision = Poly : 2.943572e-35 + static const T Y = 1.308816909790039062500000000000000000f; + static const T P[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, -5.550277247453881129211735759447737350e-02), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.485883080219574328217554864956175929e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.903760658131484239300875153154881958e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.144813672213626237418235110712293337e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, -6.498400501156131446691826557494158173e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.573531831870363502604119835922166116e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.417416550054632009958262596048841154e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.271266450613557412825896604269130661e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.898386013314389952534433455681107783e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.353798784656436259250791761023512750e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.839619195427352438957774052763490067e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.169246368651532232388152442538005637e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.696368884166831199967845883371116431e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.810226630422736458064005843327500169e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.854996610560406127438950635716757614e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.981057433937398731355768088809437625e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.519440069856232098711793483639792952e+04) + }; + static const T Q[] = + { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.127348248283623146544565916604103560e+01), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.205092684176906740104488180754982065e+03), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.911249195069050636298346469740075758e+04), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.426103406579046249654548481377792614e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.365861555422488771286500241966208541e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.765377714160383676864913709252529840e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.453822726931857253365138260720815246e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.643207885048369990391975749439783892e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.882540678243694621895816336640877878e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.410120808992380266174106812005338148e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.628138016559335882019310900426773027e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.250794693811010646965360198541047961e+08), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.378723408195485594610593014072950078e+07), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.488253856312453816451380319061865560e+06), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.202167197882689873967723350537104582e+05), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.673233230356966539460728211412989843e+03) + }; + if(x < tools::log_max_value()) + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x)); + else + { + T ex = exp(-x / 2); + return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex; + } + } + } + + template + T bessel_k1_imp(const T& x, const std::integral_constant&) + { + if(boost::math::tools::digits() <= 24) + return bessel_k1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 53) + return bessel_k1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 64) + return bessel_k1_imp(x, std::integral_constant()); + else if(boost::math::tools::digits() <= 113) + return bessel_k1_imp(x, std::integral_constant()); + BOOST_MATH_ASSERT(0); + return 0; + } + + template + inline T bessel_k1(const T& x) + { + typedef std::integral_constant::digits == 0) || (std::numeric_limits::radix != 2)) ? + 0 : + std::numeric_limits::digits <= 24 ? + 24 : + std::numeric_limits::digits <= 53 ? + 53 : + std::numeric_limits::digits <= 64 ? + 64 : + std::numeric_limits::digits <= 113 ? + 113 : -1 + > tag_type; + + bessel_k1_initializer::force_instantiate(); + return bessel_k1_imp(x, tag_type()); + } + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_K1_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_kn.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_kn.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_kn.hpp @@ -0,0 +1,86 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_KN_HPP +#define BOOST_MATH_BESSEL_KN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +// Modified Bessel function of the second kind of integer order +// K_n(z) is the dominant solution, forward recurrence always OK (though unstable) + +namespace boost { namespace math { namespace detail{ + +template +T bessel_kn(int n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T value, current, prev; + + using namespace boost::math::tools; + + static const char* function = "boost::math::bessel_kn<%1%>(%1%,%1%)"; + + if (x < 0) + { + return policies::raise_domain_error(function, + "Got x = %1%, but argument x must be non-negative, complex number result not supported.", x, pol); + } + if (x == 0) + { + return policies::raise_overflow_error(function, nullptr, pol); + } + + if (n < 0) + { + n = -n; // K_{-n}(z) = K_n(z) + } + if (n == 0) + { + value = bessel_k0(x); + } + else if (n == 1) + { + value = bessel_k1(x); + } + else + { + prev = bessel_k0(x); + current = bessel_k1(x); + int k = 1; + BOOST_MATH_ASSERT(k < n); + T scale = 1; + do + { + T fact = 2 * k / x; + if((tools::max_value() - fabs(prev)) / fact < fabs(current)) + { + scale /= current; + prev /= current; + current = 1; + } + value = fact * current + prev; + prev = current; + current = value; + ++k; + } + while(k < n); + if(tools::max_value() * scale < fabs(value)) + return sign(scale) * sign(value) * policies::raise_overflow_error(function, nullptr, pol); + value /= scale; + } + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_KN_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y0.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y0.hpp @@ -0,0 +1,240 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_Y0_HPP +#define BOOST_MATH_BESSEL_Y0_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the second kind of order zero +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +T bessel_y0(T x, const Policy&); + +template +struct bessel_y0_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + bessel_y0(T(1), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_y0_initializer::init bessel_y0_initializer::initializer; + +template +T bessel_y0(T x, const Policy& pol) +{ + bessel_y0_initializer::force_instantiate(); + + static const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0723538782003176831e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.3716255451260504098e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.0422274357376619816e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.1287548474401797963e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0102532948020907590e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8402381979244993524e+01)), + }; + static const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.8873865738997033405e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.1617187777290363573e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.5662956624278251596e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.3889393209447253406e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6475986689240190091e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2213976967566192242e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.5107435206722644429e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.3600098638603061642e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.9590439394619619534e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.6905288611678631510e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4566865832663635920e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7427031242901594547e+01)), + }; + static const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.3386146580707264428e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4266824419412347550e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4015103849971240096e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3960202770986831075e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0669982352539552018e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.3030857612070288823e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T P3[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.0728726905150210443e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.7016641869173237784e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2829912364088687306e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.9363051266772083678e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1958827170518100757e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0085539923498211426e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1363534169313901632e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.7439661319197499338e+01)), + }; + static const T Q3[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4563724628846457519e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.9272425569640309819e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2598377924042897629e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6926121104209825246e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.4727219475672302327e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.3924739209768057030e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.7903362168128450017e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684302e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1345386639580765797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1170523380864944322e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.4806486443249270347e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5376201909008354296e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.8961548424210455236e-01)), + }; + static const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2779090197304684318e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1370412495510416640e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1215350561880115730e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5028735138235608207e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.5711159858080893649e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.9226600200800094098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.8591953644342993800e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1183429920482737611e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2300261666214198472e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2441026745835638459e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -8.8033303048680751817e-03)), + }; + static const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.7105024128512061905e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1951131543434613647e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2642780169211018836e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4887231232283756582e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.0593769594993125859e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.9357696627916752158e-01)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.9576784193148578684e+00)), + x3 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0860510603017726976e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.280e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.9519662791675215849e-03)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0130e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.4716931485786837568e-04)), + x31 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8140e+03)), + x32 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1356030177269762362e-04)) + ; + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + static const char* function = "boost::math::bessel_y0<%1%>(%1%,%1%)"; + + if (x < 0) + { + return policies::raise_domain_error(function, + "Got x = %1% but x must be non-negative, complex result not supported.", x, pol); + } + if (x == 0) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + if (x <= 3) // x in (0, 3] + { + T y = x * x; + T z = 2 * log(x/x1) * bessel_j0(x) / pi(); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12); + value = z + factor * r; + } + else if (x <= 5.5f) // x in (3, 5.5] + { + T y = x * x; + T z = 2 * log(x/x2) * bessel_j0(x) / pi(); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22); + value = z + factor * r; + } + else if (x <= 8) // x in (5.5, 8] + { + T y = x * x; + T z = 2 * log(x/x3) * bessel_j0(x) / pi(); + r = evaluate_rational(P3, Q3, y); + factor = (x + x3) * ((x - x31/256) - x32); + value = z + factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = constants::one_div_root_pi() / sqrt(x); + // + // The following code is really just: + // + // T z = x - 0.25f * pi(); + // value = factor * (rc * sin(z) + y * rs * cos(z)); + // + // But using the sin/cos addition formulae and constant values for + // sin/cos of PI/4 which then cancel part of the "factor" term as they're all + // 1 / sqrt(2): + // + T sx = sin(x); + T cx = cos(x); + value = factor * (rc * (sx - cx) + y * rs * (cx + sx)); + } + + return value; +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_Y0_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y1.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_y1.hpp @@ -0,0 +1,212 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_Y1_HPP +#define BOOST_MATH_BESSEL_Y1_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +// Bessel function of the second kind of order one +// x <= 8, minimax rational approximations on root-bracketing intervals +// x > 8, Hankel asymptotic expansion in Hart, Computer Approximations, 1968 + +namespace boost { namespace math { namespace detail{ + +template +T bessel_y1(T x, const Policy&); + +template +struct bessel_y1_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + bessel_y1(T(1), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename bessel_y1_initializer::init bessel_y1_initializer::initializer; + +template +T bessel_y1(T x, const Policy& pol) +{ + bessel_y1_initializer::force_instantiate(); + + static const T P1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0535726612579544093e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4708611716525426053e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.7595974497819597599e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.2144548214502560419e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.9157479997408395984e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.2157953222280260820e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -3.1714424660046133456e+02)), + }; + static const T Q1[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0737873921079286084e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.1272286200406461981e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.7800352738690585613e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.2250435122182963220e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.8136470753052572164e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.2079908168393867438e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T P2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1514276357909013326e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.6808094574724204577e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.3638408497043134724e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0686275289804744814e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -5.9530713129741981618e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7453673962438488783e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1957961912070617006e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.9153806858264202986e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2337180442012953128e+03)), + }; + static const T Q2[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.3321844313316185697e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.6968198822857178911e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0837179548112881950e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.1187010065856971027e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.0221766852960403645e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.3550318087088919566e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0453748201934079734e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.2855164849321609336e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T PC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278571e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9422465050776411957e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.6033732483649391093e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5235293511811373833e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0982405543459346727e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.6116166443246101165e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)), + }; + static const T QC[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4357578167941278568e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -9.9341243899345856590e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.5853394797230870728e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5118095066341608816e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0726385991103820119e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -1.4550094401904961825e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T PS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.3220913409857223519e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.5145160675335701966e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6.6178836581270835179e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8494262873223866797e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.7063754290207680021e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.5265133846636032186e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0)), + }; + static const T QS[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 7.0871281941028743574e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8194580422439972989e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.4194606696037208929e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.0029443582266975117e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3.7890229745772202641e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 8.6383677696049909675e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)), + }; + static const T x1 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.1971413260310170351e+00)), + x2 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.4296810407941351328e+00)), + x11 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5.620e+02)), + x12 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.8288260310170351490e-03)), + x21 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3900e+03)), + x22 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -6.4592058648672279948e-06)) + ; + T value, factor, r, rc, rs; + + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + if (x <= 0) + { + return policies::raise_domain_error("boost::math::bessel_y1<%1%>(%1%,%1%)", + "Got x == %1%, but x must be > 0, complex result not supported.", x, pol); + } + if (x <= 4) // x in (0, 4] + { + T y = x * x; + T z = 2 * log(x/x1) * bessel_j1(x) / pi(); + r = evaluate_rational(P1, Q1, y); + factor = (x + x1) * ((x - x11/256) - x12) / x; + value = z + factor * r; + } + else if (x <= 8) // x in (4, 8] + { + T y = x * x; + T z = 2 * log(x/x2) * bessel_j1(x) / pi(); + r = evaluate_rational(P2, Q2, y); + factor = (x + x2) * ((x - x21/256) - x22) / x; + value = z + factor * r; + } + else // x in (8, \infty) + { + T y = 8 / x; + T y2 = y * y; + rc = evaluate_rational(PC, QC, y2); + rs = evaluate_rational(PS, QS, y2); + factor = 1 / (sqrt(x) * root_pi()); + // + // This code is really just: + // + // T z = x - 0.75f * pi(); + // value = factor * (rc * sin(z) + y * rs * cos(z)); + // + // But using the sin/cos addition rules, plus constants for sin/cos of 3PI/4 + // which then cancel out with corresponding terms in "factor". + // + T sx = sin(x); + T cx = cos(x); + value = factor * (y * rs * (sx - cx) - rc * (sx + cx)); + } + + return value; +} + +}}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_BESSEL_Y1_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/bessel_yn.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_yn.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/bessel_yn.hpp @@ -0,0 +1,112 @@ +// Copyright (c) 2006 Xiaogang Zhang +// 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_BESSEL_YN_HPP +#define BOOST_MATH_BESSEL_YN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +// Bessel function of the second kind of integer order +// Y_n(z) is the dominant solution, forward recurrence always OK (though unstable) + +namespace boost { namespace math { namespace detail{ + +template +T bessel_yn(int n, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + T value, factor, current, prev; + + using namespace boost::math::tools; + + static const char* function = "boost::math::bessel_yn<%1%>(%1%,%1%)"; + + if ((x == 0) && (n == 0)) + { + return -policies::raise_overflow_error(function, nullptr, pol); + } + if (x <= 0) + { + return policies::raise_domain_error(function, + "Got x = %1%, but x must be > 0, complex result not supported.", x, pol); + } + + // + // Reflection comes first: + // + if (n < 0) + { + factor = static_cast((n & 0x1) ? -1 : 1); // Y_{-n}(z) = (-1)^n Y_n(z) + n = -n; + } + else + { + factor = 1; + } + if(x < policies::get_epsilon()) + { + T scale = 1; + value = bessel_yn_small_z(n, x, &scale, pol); + if(tools::max_value() * fabs(scale) < fabs(value)) + return boost::math::sign(scale) * boost::math::sign(value) * policies::raise_overflow_error(function, nullptr, pol); + value /= scale; + } + else if(asymptotic_bessel_large_x_limit(n, x)) + { + value = factor * asymptotic_bessel_y_large_x_2(static_cast(abs(n)), x, pol); + } + else if (n == 0) + { + value = bessel_y0(x, pol); + } + else if (n == 1) + { + value = factor * bessel_y1(x, pol); + } + else + { + prev = bessel_y0(x, pol); + current = bessel_y1(x, pol); + int k = 1; + BOOST_MATH_ASSERT(k < n); + policies::check_series_iterations("boost::math::bessel_y_n<%1%>(%1%,%1%)", n, pol); + T mult = 2 * k / x; + value = mult * current - prev; + prev = current; + current = value; + ++k; + if((mult > 1) && (fabs(current) > 1)) + { + prev /= current; + factor /= current; + value /= current; + current = 1; + } + while(k < n) + { + mult = 2 * k / x; + value = mult * current - prev; + prev = current; + current = value; + ++k; + } + if(fabs(tools::max_value() * factor) < fabs(value)) + return sign(value) * sign(factor) * policies::raise_overflow_error(function, nullptr, pol); + value /= factor; + } + return value; +} + +}}} // namespaces + +#endif // BOOST_MATH_BESSEL_YN_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp @@ -0,0 +1,244 @@ +/* + * Copyright Nick Thompson, 2019 + * Copyright John Maddock, 2020 + * 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) + */ +// THIS FILE GENERATED BY EXAMPLE/DAUBECHIES_SCALING_INTEGER_GRID.CPP, DO NOT EDIT. +#ifndef BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP +#define BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP +#include +#include +#include +/* +In order to keep the character count as small as possible and speed up +compiler parsing times, we define a macro C_ which appends an appropriate +suffix to each literal, and then casts it to type Real. +The suffix is as follows: + +* Q, when we have __float128 support. +* L, when we have either 80 or 128 bit long doubles. +* Nothing otherwise. +*/ + +#ifdef BOOST_MATH_USE_FLOAT128 +# define C_(x) static_cast(x##Q) +#elif (LDBL_MANT_DIG > DBL_MANT_DIG) +# define C_(x) static_cast(x##L) +#else +# define C_(x) static_cast(x) +#endif + +namespace boost::math::detail { + +template struct daubechies_scaling_integer_grid_imp; + +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5db3d742c265539d92ba16b83c5cp+0), C_(-0x1.76cf5d0b09954e764ae85ae0f17p-2), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1p+0), C_(-0x1p+0), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.494d414ee19a0fc1701f9345a28bp+0), C_(-0x1.8b18d8251ec886399fc357ab26c9p-2), C_(0x1.863743274d78cfe42daf1d262e43p-4), C_(0x1.158087f14084ceb4f650d2c442e1p-8), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a3719cd426dbd5c2283e8b6cd98bp+0), C_(-0x1.1dcb0537f52904105ab1d13c6abfp+1), C_(0x1.19ae7cc6c0211df5e41745563cbbp-1), C_(0x1.69a5e70c6cb46c73632e8c1bb2d3p-5), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cef9cbb90bf242979b344cdd1e02p-1), C_(-0x1.b676b19591eb63e368ce734bad03p+0), C_(0x1.6ced632b23d6c7c6d19ce6975a06p-1), C_(0x1.8831a237a06deb43265d99170ff1p-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.01d5e443d831d2252369827793d3p+0), C_(-0x1.15313c61b3acb474231dab078158p-5), C_(0x1.447d293e37264e578b865081223fp-5), C_(-0x1.817e96e0425ed094fa1a3a5cf10cp-7), C_(-0x1.3a0992ca5111744ed1b4ed1a6607p-10), C_(0x1.3be7b6cb6309fefbda0c9fa167f8p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c6aca7b3a61af838bb320835a00cp+0), C_(-0x1.6486543c8460b11f1a4b4a357fbcp+1), C_(0x1.314491c6de2d2b798153746ca822p+0), C_(-0x1.0d0e14f1f7dc5a54f21ce3ff424bp-3), C_(-0x1.b6da96c702377f43a25f74c9467p-5), C_(0x1.d0194bee1a1742cd9ebfbba717b8p-10), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cf8cc69cc42a410e51b272a7a3c6p+0), C_(-0x1.0eaaa0c1e1c354610b35262e9078p+2), C_(0x1.66e46b718b500bb2be3ec05c7ac3p+1), C_(-0x1.26d9a4de19b73d34cbab42cdd8ccp-3), C_(-0x1.0ae7c18dd841d8689ede2f52570cp-2), C_(0x1.3a82a1b96295b447f46661fe5bd8p-6), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bb2f43bc30b80d947c8a537a20b2p-1), C_(-0x1.2d48b852668c646a630392a2b66dp+1), C_(0x1.c2596fe640cadf6ca968f3b30ff3p+0), C_(0x1.83800be8c4de9681c9e31925ce79p-3), C_(-0x1.233972e07202850d1be1b9fc8392p-1), C_(0x1.bcd16d394575254330d81aed4886p-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.646bf1ec64a308c5df07d89c8e9bp-1), C_(0x1.cbd5c1bab5148530b0e77ecbff92p-2), C_(-0x1.754196833f706c7834855fa5579ep-3), C_(0x1.3100cab7c3f5f4fa75b80a67ed4bp-5), C_(0x1.8dd2be8c89c51e7b28b04315346bp-10), C_(-0x1.c4ab558ff2dcebdfdc6142054ddep-10), C_(0x1.3b27d2d798eecea1adaf099c04dp-15), C_(0x1.75f2b16626e9875840e692dcf344p-23), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8eee7927087b240ec5ade1ac81aep+0), C_(-0x1.37cf445237f1b72a99ae1be2616ep+1), C_(0x1.3c64475174b4a0c9b8a3ee3dfc2p+0), C_(-0x1.7841978e876db6599aa4ad10992fp-2), C_(-0x1.64d969ffaac153a6af06dc9cfb72p-6), C_(0x1.08fcfb4783fa7d234eba36053968p-5), C_(-0x1.5e1fef6185af966378a125175a7fp-10), C_(-0x1.984da1089743964ff5ac0959c3bcp-17), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.22c5cb8d3f23b44faf592c365f5dp+1), C_(-0x1.83cca07a3ead78a73330d7cf1a39p+2), C_(0x1.5245172406b77d1d4fdfd2192d87p+2), C_(-0x1.2d10dba463fc1840fd45963c568fp+0), C_(-0x1.549f4c5e04f3991456e630b1555ep-1), C_(0x1.882ac9029ddc72b4c74d388da98p-2), C_(-0x1.3d5d0eda32d8b61e7ff27a395899p-5), C_(-0x1.65cdc06ecf6547344a6a8d527f6ap-11), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9877ac926fb3bdd992f46d848f57p+1), C_(-0x1.48c27a70b93cdddc043571f47b88p+3), C_(0x1.f7fdf60845cfba22e0c6bd043e1ep+2), C_(0x1.0b1ea0ee5f9ed06f5107d79a1aafp+3), C_(-0x1.15aaf38ada16a6358cd77355f075p+4), C_(0x1.4a45041b91e1bb24fe9a63ad188p+3), C_(-0x1.05013480812df4c7388d78daa7bap+1), C_(-0x1.13ee46114fd8519c5d7f29b7d91dp-4), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.13b9e8c4fdc4ff9d9c7b93fda5d3p-1), C_(-0x1.e1e5e5cfd0a801f531eaef0fe6ap+0), C_(0x1.29ab2ec864d44a65c8f8abfdabb3p+1), C_(-0x1.3d6cc61e0f6a43e21f6553d10792p+0), C_(0x1.0227f72aa277daecfc1fddb3c5aep-1), C_(-0x1.9ada2a6a9a217e8dbe2b55c6bb8bp-2), C_(0x1.2c68da3893cd5c4c84ac50c60f2ap-3), C_(0x1.1a66dc6d2cfbf029033eb2e70439p-7), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bf65e79817d27ca7c78972c65f3p-2), C_(0x1.aa2466d50e4a4fcbbebe54f94c3cp-1), C_(-0x1.89fd104c6ff149bf7514a7ddf37fp-2), C_(0x1.24737e6f8ebf0ec8bb9fcc85bb71p-3), C_(-0x1.a1e9c758a51a08321aa63e9af1d7p-6), C_(-0x1.cec09a7ccf05b6ee1ea8f3c17f4ep-9), C_(0x1.cd4feb82d24938f30e41e1af2eap-10), C_(0x1.05937b8388af24ac43ec83967a2ep-16), C_(-0x1.5a00cfad970a7cbc309138fd3facp-19), C_(0x1.0fbc42c672231485a0bcbfe7e34bp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2faeacbb8e753b40eb856e00f522p+0), C_(-0x1.8014975295b2136d5a1adb454387p+0), C_(0x1.05033635f5401c9b60636a32526ap-1), C_(-0x1.0ffe44cc8bc7ea4a6ce4734d8d36p-2), C_(0x1.0b11b28c7d67ad63229fbc3aa7dap-4), C_(0x1.721a1d14b8322b2431432e8b800fp-7), C_(-0x1.af662c52c3b7ae55063672df3c7fp-8), C_(-0x1.a69b860b67a33179a8c7a5f6b2acp-15), C_(0x1.45b12643cf8203bdf796367d51eep-16), C_(-0x1.01892163486cb41cb64453f7616fp-24), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1e62ddd540b05b0cc5ce587007d5p+1), C_(-0x1.980b3fe2011f7bc878be7d399794p+2), C_(0x1.a34dea8cd59b4187717c6efb0662p+2), C_(-0x1.45eb5e5e7e3c9e9ae26ca4aa207cp+1), C_(-0x1.0310f5a5d86de60ba877dea685a5p-1), C_(0x1.da7724c65802bc95482213f980a5p-1), C_(-0x1.4137cfe85b9e5b04e10239758a3cp-2), C_(0x1.7eb866ddca6ba425f9e4eb854a4dp-6), C_(0x1.4ebb22d1ac0760e1461881059843p-9), C_(-0x1.0c5bdfb916a449da5acc3ccfdc72p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.422f9f5227e7facaa94dd7d9e31p-2), C_(-0x1.255a76df553cbf84e8a0b0613039p+0), C_(0x1.484b537c56deca3daefc656e3b6ep+3), C_(-0x1.3c98d8a74cd7736b60af4e604261p+5), C_(0x1.10b7f9c607064185ab2dfc58353fp+6), C_(-0x1.d54dd14cd31af65e5343fc875b57p+5), C_(0x1.8049478b6740d0c6b010047a06c3p+4), C_(-0x1.77f8847acd28ad3549099ae2105ep+1), C_(-0x1.d3687a3bc39335bac7f281e76bbep-2), C_(0x1.816ef86832621ebc63e47cd2b70fp-8), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8faeef62b3a7fd26eb98dd7f984ap+0), C_(-0x1.93816e52ba1c8483ff81ea3e324ep+2), C_(0x1.337880b3a9a717e67b9cd7fec812p+3), C_(-0x1.c3f2cd3d53132aa78f87aee07639p+2), C_(0x1.c7801db7678046e8ebdb22cf642bp+1), C_(-0x1.46377db27f624959a2b9b7777bb1p+1), C_(0x1.77a6f5e8321cd39a930db39033fap+0), C_(-0x1.c4188733407f241acae534ed0f5dp-3), C_(-0x1.f8b0a606c7f795229d5947447836p-5), C_(0x1.b965933f534b1af276b67227f89dp-10), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cb91942378a6b29e2dd51c51bfa9p-2), C_(-0x1.e6b982120ca31c68b89329c09872p+0), C_(0x1.7b2e4714b270342ea6ba899785ecp+1), C_(-0x1.fa645ee8ca231003817fbe32a47bp+0), C_(0x1.29da9349c32a19bed5b810cc4b88p-1), C_(-0x1.8461e6acf9cb2af90934d76c7932p-2), C_(0x1.67c137342024d6c8052e3d876acdp-2), C_(-0x1.c1a09b7773a59d1a65f356773daap-5), C_(-0x1.0c11f4efd5c0b7d44ac1c3a0720ap-5), C_(0x1.0ac90a45b7a47759a7a92738fc7ep-9), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.033291a6c76d6a2177301a6491e8p-2), C_(0x1.027f6bf7952cdbcf397ade5b83ap+0), C_(-0x1.919d92c6034c44a7ed45a578713cp-2), C_(0x1.7a0ca906acc4841a1191b023a485p-3), C_(-0x1.1142c3515ec433047c393c69962fp-4), C_(0x1.50e2d6421ee2654230b309723685p-7), C_(0x1.d0243aab613f83777184da54a80dp-10), C_(-0x1.1d4c6c249bf0ee08cde9105ae0e2p-11), C_(-0x1.17d0b3032ba5c5edbe3115298755p-14), C_(0x1.310ffd8b564011dafec30497e547p-19), C_(-0x1.509d126dab99ceafee21c5b15f2ep-25), C_(-0x1.57f8e6955253718d03dd42dcc06ep-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9ec434341eaed8ccc6e8d7244a33p-1), C_(-0x1.ca0692ca77439e8f752ca148c144p-2), C_(-0x1.2d988a986b0dea756341b6b8b7c2p-1), C_(0x1.145887eacb10f9d392eed69a9335p-2), C_(-0x1.4ab3cf0bae2a5b8432a0a181639cp-6), C_(-0x1.4e8938899ee371e40cd7b7528ae9p-5), C_(0x1.5cb5de436bfadb9e555d33c55719p-6), C_(-0x1.051eebbefaf7bd71954e297a61ffp-8), C_(0x1.0efaec65edbcc11b181ba7073e2cp-14), C_(0x1.6a87a6b931edc5ab5423dbf1babfp-15), C_(-0x1.4e8b2a27fe064ec01f627183042bp-23), C_(-0x1.54fd8f0625f118cd9bcdded88d81p-33), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e0eacca617ebb860573873f7b1a4p+0), C_(-0x1.5362d7fe36c56b6a443e9d6141a8p+2), C_(0x1.70aa17b7adc0e75a9ffe0b5a33b6p+2), C_(-0x1.86bc52429f3a3f79bb4f1cb73763p+1), C_(0x1.5709310e8d1f635f77e733f31613p-2), C_(0x1.9d599937b31fafd3d66db2bf1cbbp-1), C_(-0x1.18b244e50df675a487d76601b0e9p-1), C_(0x1.fe16d1a3cfb3e7ecc6834f2061cfp-4), C_(0x1.eb4cc917dd1cd56dce6a9280b03bp-12), C_(-0x1.4e09cf12f0cdcfd873bae5583582p-9), C_(0x1.c4a78957d279804ccd5115f6146ap-16), C_(0x1.cb0ccbca08e7961d7bc2f676b666p-25), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4ca9343b3236825367445e2a7e79p-1), C_(-0x1.492e70f2635c16c262e6190afacep+1), C_(0x1.171de5ca88cec2afbea5499914ebp+4), C_(-0x1.1e704d84a10750732762c3f4d8bap+6), C_(0x1.23bcc34d6a529b0b422faf672516p+7), C_(-0x1.415156a34428a6a6c08cde7dee49p+7), C_(0x1.7ff7929036ddd78bf54cfc378272p+6), C_(-0x1.a43b4147c122c6f143d7b591007fp+4), C_(0x1.833e6f5afaca4c566ce598593c06p-4), C_(0x1.13b5aaaf6c71d5b914583e48ae7dp+0), C_(-0x1.6365af2495a86c5f48d9bd1a47dp-6), C_(-0x1.64d19861a833792a3ce80f84d83cp-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.525f0cb11c2720485c66b9e19f02p+1), C_(-0x1.7eda4b6a23328f4e2cec098f6666p+3), C_(0x1.578437542fe4f5fbe4cefec73f0cp+4), C_(-0x1.40c582473fa8c93703a1216d1613p+4), C_(0x1.9815cb7223c105bc2b63ed01a5fep+3), C_(-0x1.222479cd96ee9d17f59bff4df592p+3), C_(0x1.8c2cccc6ee34ca0f24458389d35dp+2), C_(-0x1.ffd4fb5b3918044492967474d1cep+0), C_(-0x1.3be427404fe7d12432d600f4382ep-3), C_(0x1.7c490d447fad2e27fa6b12a0d504p-3), C_(-0x1.23f9756392d0ee9915448c1be2b1p-7), C_(-0x1.1f66b1e7815295f48755fd4e3126p-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.80a316d21a0eed480c84ea711d9ep+0), C_(-0x1.ce7e6827143677fbd12dabe06e9fp+2), C_(0x1.ac8b3ccd718c41df56b9c167f638p+3), C_(-0x1.74c81d1a27df5c33454de2219e89p+3), C_(0x1.4010d1eedca99cac8148c11888d4p+2), C_(-0x1.34da807d2aaec910bcf3aa770bf1p+1), C_(0x1.2d09c9846b581b01a4323f49de6p+1), C_(-0x1.97de12ea03ca10913f6e6b1c03cap-1), C_(-0x1.9df5b4fe2e271a26f87f7a1f78fbp-2), C_(0x1.16c54a229aae12ed509d340bab6bp-2), C_(-0x1.e323c5b92bd166e33ab5b4f9635p-6), C_(-0x1.c9a573f22c19a9032c5430df4c8ep-12), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a096c8f7fc8ab1575820ee7a8d4ep-3), C_(-0x1.01d8c748e11fa735da05e73f8394p+0), C_(0x1.099a073a7c7b41898468a5bd14cep+1), C_(-0x1.40ce386ca776e06ba6f31ba7dadep+1), C_(0x1.2a57634989c51fb583fc11fc2c8bp+1), C_(-0x1.e6f030cb23fbfde6dfddcd33a7b8p+0), C_(0x1.3544c2755b1d82eac792a5860a61p+0), C_(-0x1.6af581a622d416ac06a3c40b5b79p-1), C_(0x1.256afda077267e050d8164debfb4p-1), C_(-0x1.6569331439297d46e21a065d5029p-2), C_(0x1.4b88409bdd1172b9682df8963184p-4), C_(0x1.24061e2653bdb3c5fd153e823b33p-9), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.184a0c288d22add7ea26104df2f3p-3), C_(0x1.fbaa047a94a613069e6f550b4e09p-1), C_(-0x1.596f5b6b28cb0681bf78a3e54b72p-3), C_(0x1.234875f46000e28dce7c3f342092p-4), C_(-0x1.90a568ef3b94afacf755834bab9ap-5), C_(0x1.82b42ea0f8a1613dc5ff9725c05p-6), C_(-0x1.96b60b10e59567d6b2c6577bad3bp-8), C_(0x1.8430d19335684e7577fd3b699763p-11), C_(-0x1.92df0230079088d5ad0746147153p-14), C_(0x1.da6faa767962723e71f08f2e9083p-16), C_(0x1.b237bc2c3b5257b1d937078b7396p-20), C_(0x1.66eb1a28068ae3ea1bd5d2683257p-25), C_(-0x1.f6ebd7398c4a3aa441e024a5714bp-33), C_(0x1.5690727034a8a4b1353895ae261dp-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.03033f41d994757a2b4934423538p-1), C_(0x1.8347da7a3030b8b37cdc36ec3c9cp-2), C_(-0x1.7d2f17f2a95af6988be8eca125f4p+0), C_(0x1.c3013eaebde946f9eaa42bce8cf9p-1), C_(-0x1.4be40ed86f2cd0c168ad249492a4p-2), C_(0x1.4580356ca34ff1cf3c18408b1d74p-6), C_(0x1.7e9e8eefc30b45959dcb8ab52383p-5), C_(-0x1.594cf912461bb959724fb77ad3bbp-6), C_(0x1.27c56651be6ed873712071c19324p-9), C_(0x1.e972a09b0f4dc8fdb93114f9ed4p-12), C_(-0x1.1649ec5e541409b8483ac00aa989p-14), C_(0x1.c99c42a59648ab096d412a58741fp-23), C_(0x1.81519dee82f001d0cfd286a4bf1ep-26), C_(-0x1.06b5ee4f0711fc96e3337209d4e2p-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.666d532df9def8a39e69d4c9dbd1p+0), C_(-0x1.c0374596ee4d8e750b0b0f065b11p+1), C_(0x1.a43eb9f4500c29913bdae70f2e12p+1), C_(-0x1.d627359f84d250c8825852fe20e7p+0), C_(0x1.891e36789053a132cb4397963bd6p-1), C_(0x1.a23c19ecf2deb44f4177f3e9336bp-6), C_(-0x1.d9c16d05d77872764189280b3978p-3), C_(0x1.b6728d569b4c6b3f03c9c20fd79fp-4), C_(-0x1.66849bebd2ebdfafabb131375ec9p-7), C_(-0x1.fc6301aedca903a123de4bceca69p-9), C_(0x1.7e62ae52149bd7e06a18746f5b91p-11), C_(-0x1.2c21c0130a3eaea0bd3721b2b8d6p-17), C_(-0x1.15f344e8ed1b26069acbf2a1a453p-21), C_(0x1.7bbd836b1bf84d53feb61580dc74p-32), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.b44c4e267cbb4d43745305f720c9p+1), C_(-0x1.c1f7df3ad7ab79897dce80d62718p+3), C_(0x1.1601a8a979c78f82e398ce8545b9p+4), C_(0x1.e5bffb29b3c52bb885497a60d3d6p+3), C_(-0x1.38f35bf0e9ee0ae5b1772951f4d5p+6), C_(0x1.d1869b3f8e2b44288688d26e70d1p+6), C_(-0x1.70d2038145a54625eb25d875d7e5p+6), C_(0x1.34930dde67aea02e0a703b76a197p+5), C_(-0x1.4b77b4fb3674956338abd1824db4p+2), C_(-0x1.d27f3b25c1fd6ce83b2a8b0a4ac9p+0), C_(0x1.32a2c5a3dfe8119d379b71453288p-1), C_(-0x1.2fc64ff8d3420e31f2a6dd47d615p-7), C_(-0x1.c48021ad9bc1646021c012f5b071p-11), C_(0x1.364c0a7c4c64aef45189b312edb4p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.afe05c7a6ada1cb6172616d2c6a8p+1), C_(-0x1.0a8c44cdd47bf4e495a5398413fbp+4), C_(0x1.0f6c0325c5e1414a9285f59e5f14p+5), C_(-0x1.306ff1c62c8336aad5c3f9886bcep+5), C_(0x1.da69559cc91130d28dd4b63660e6p+4), C_(-0x1.6a2c1f828fe2d81030f1ad524eb7p+4), C_(0x1.0e28c771588c30581ce7071741b8p+4), C_(-0x1.ee4b3cc46d890789fa8b15b7da8p+2), C_(0x1.050e3e4d4732a1c55c0c971f3557p-1), C_(0x1.0ea6cad7a5a7fae2eab7d74b22a1p+0), C_(-0x1.6566f5ac7d80487971d04a5944efp-2), C_(0x1.0b828ad29e43eb178f6b65b8f31p-6), C_(0x1.3201b5c3bc1c21bf7086981ccb12p-10), C_(-0x1.a6f0242017b1488503cf0ef046e5p-19), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.77885e6e270a744c868654d7cbb5p+1), C_(-0x1.f5abb22b1b6ebb333fd9f11e8f7cp+3), C_(0x1.0a779dee6c7bddbff2f0d8b9981bp+5), C_(-0x1.164d9f148bde4aa13b66fabbc2fp+5), C_(0x1.2333738e736f124a0ec3de563f7bp+4), C_(-0x1.af306993826a689f7543995893acp+2), C_(0x1.6dba5c59397a4426e98586aad789p+2), C_(-0x1.17ffc928dd1d8bf0f209d0c36abep+1), C_(-0x1.9f39e7400cf5d234f22720c7748ap+1), C_(0x1.d0d0a8f3b805dafc2d2b539d9bb4p+1), C_(-0x1.4ac5cadf9fb14bc48382ff0ecfb1p+0), C_(0x1.049faf6ae689948e66d5e5134564p-3), C_(0x1.5ad3792bdac35c5163486d9087edp-7), C_(-0x1.e6e9a51e36639d68c6db7d7495a4p-15), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1912b6ad90d43603284e290418eep+0), C_(-0x1.85c00c80d7a18fcc693e47644de7p+2), C_(0x1.b7d753e3c818997a04ded98f86e3p+3), C_(-0x1.076d50e7f7850b94ae780b4bf285p+4), C_(0x1.92a29d7ac0e1e0002558af869ed1p+3), C_(-0x1.20f516098425bb22664ce4ad84a9p+3), C_(0x1.dcba519c323cedf78dcb7794def8p+2), C_(-0x1.3fe31292805c0462ca96ae20fe5p+2), C_(0x1.5e9b74431b072dba61e526c0393fp+1), C_(-0x1.a6996ae95f76ef890f12b5a6c626p+0), C_(0x1.806826de1640aff2fbfd8d0d7d09p-1), C_(-0x1.ddc83de4acfaf20be5fee513819ep-4), C_(-0x1.e09e81650c6b74fbce41e5378d99p-7), C_(0x1.5c5b71613d71b7692e7e5f0ba23p-13), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.eae80165a34ad1f2080107f7b7a5p-3), C_(-0x1.5a965a7535366541f0a1afe5172fp+0), C_(0x1.851adfd49d1a76d9d23c35315fc3p+1), C_(-0x1.b139c010d5d8ef58fb69c4f0efd8p+1), C_(0x1.ffefb7038043737a18fc832f1fb7p+0), C_(-0x1.0254056f57103b364cf4bcafdd14p+0), C_(0x1.ff103b26e087e22aa6dbe2498954p-1), C_(-0x1.7a4f70cc2f5d7a6d2a4e62aee34dp-1), C_(0x1.09dce627745a61500e9471981ea7p-2), C_(-0x1.c2f7ce5c8a37b8fcabdaf25d6d6bp-4), C_(0x1.41c46b919c33ee1c6941aae7132bp-4), C_(-0x1.03531c096423a7a88f95e3dc08eep-6), C_(-0x1.c24ed1e998c51356546e2437d6p-9), C_(0x1.5d1ed72a09587166cbb2e531d26cp-14), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1d2fbfac23949a1e129ec9f8391bp-4), C_(0x1.b1b6520101e0e6c7ddaa9da59f23p-1), C_(0x1.8b08d5cd4a2ad4b181244736a713p-3), C_(-0x1.4aef16c7e666f719f7698e178af1p-3), C_(0x1.fd1877f1138be38ba53889d724ecp-5), C_(-0x1.7ee87092fa242b1ef789aaf8def8p-8), C_(-0x1.09758849af60512fff4fa06073a6p-7), C_(0x1.3d3ef7388a3ade9f5adf4b3f580dp-8), C_(-0x1.29147421d57112477f4b7b3491f7p-10), C_(0x1.b33acccf47f1bda17f46b8106497p-15), C_(0x1.7e6498cdbddd4dce209effce7062p-16), C_(-0x1.53f9494edf1282277c1de6dc67e4p-19), C_(-0x1.58c1d88e09b30b0364784ebc1f68p-24), C_(0x1.278ba12dc249a4cd49c8d69ab623p-29), C_(-0x1.705a7a4d83450688cb9e189ad73ep-38), C_(-0x1.4fb4ee678fa0e1946f2bc7ed6f9ap-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2b90f770700937399f9f525fd17p-2), C_(0x1.af96b810375ae30c4c41bf8dddd3p-1), C_(-0x1.d3c16b16ba8799042d28d9c49845p+0), C_(0x1.1690032de8cfad91fdf041ea0eb6p+0), C_(-0x1.1f4f37268ff73d0393fe0f67790ep-1), C_(0x1.82c9256a70f8e96c68d16f2e3327p-3), C_(-0x1.540e9bea7c732170245209a302fbp-7), C_(-0x1.49841c554fed1d5f2443e15a5a95p-6), C_(0x1.96a364065f27ccd19657d67cdf64p-8), C_(0x1.0c49493de5a6ec95d0bb4c3aca89p-11), C_(-0x1.b592fbb7be41b5e92f003f6109fcp-12), C_(0x1.9d3f09be0cea6d8d6f8ed455255ap-16), C_(0x1.8562af0388b7df01536ccb66a5b4p-23), C_(-0x1.13cc2e0d34f2575dd283b068f4bap-24), C_(0x1.2234e02ed8630c149658a9630026p-34), C_(0x1.08644a120d1ef6f0d4b961ae1879p-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e4c00e361fc67a2e12b083b2df48p-1), C_(-0x1.aad6ffd5d77f153c17f1c8823935p+0), C_(0x1.135c57711e67099c1758b9c717c8p-2), C_(0x1.5b41454ff095722d0f803ea68127p-1), C_(-0x1.c92ba77b267a297500d5b5d44785p-4), C_(-0x1.4f00ea2c2d363149504e045fbe84p-2), C_(0x1.61aa479f9dc67b53226c771010fp-2), C_(-0x1.667619426289632c2e8907dc1851p-3), C_(0x1.7235017b58d31cc6ca2ab84f7b8bp-5), C_(-0x1.85c5f4a449272d8bf24d90db58c1p-10), C_(-0x1.2bb318efa4d23587f50785ea34e5p-9), C_(0x1.b3d73e818e5c9557fa6b95207f02p-12), C_(0x1.bca3f26f194cf877e2358ca6efddp-17), C_(-0x1.261d8947cb7277733f476ea3b7dfp-20), C_(0x1.36693a4632268e426c40140353cep-28), C_(0x1.1a9906065291eec094ff6b8172d8p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.27d6df36685a79598b6c86ce474dp+1), C_(-0x1.2ded79e41fdb0c43d1210e12de17p+3), C_(0x1.e79fd7c0b1c0ebd84f460885ecf3p+3), C_(-0x1.304a1a210a5f9ce8bc8b8a0cdf19p+3), C_(-0x1.effd2573aa9aafcb53e588a096b7p+2), C_(0x1.7ce72fdc2cb91189ae6d5e090c6bp+4), C_(-0x1.985f0196c72e53e6d1cfdee84e02p+4), C_(0x1.d3cfac07a9d2a8c51198c074937dp+3), C_(-0x1.e1a24f8472a680b7d24d058147a3p+1), C_(-0x1.9b8563bd7c7d7dc5768ba3df017ep-2), C_(0x1.fe4766e3faf53b0d124828083686p-2), C_(-0x1.73f12d4155f35b3e8452b4ff00abp-4), C_(-0x1.20dddf659ee509c6befdf1c7addep-10), C_(0x1.ffd28fb3400bf45efe5c328fc188p-12), C_(-0x1.fa83788d3f78d19a901b7477bae6p-20), C_(-0x1.cc794a76e5f165fc8108c92b057bp-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c7ced0f66aeaccfcda16588f9d75p+1), C_(-0x1.2ab8c9c81252e46b55777de43246p+4), C_(0x1.4df684dede46d3a014591fcfc934p+5), C_(-0x1.af3bf949d62b9c07b05b4ac4bf21p+5), C_(0x1.8eeb17bed133c367f65a67fc6e9fp+5), C_(-0x1.541e9c27826e49d24f626bb1a338p+5), C_(0x1.12ea47c60dec043f14d3664c7b9cp+5), C_(-0x1.35c8b07214e140ed7f1d446f3113p+4), C_(0x1.d829e1a7628821bc837255b88e76p+1), C_(0x1.69d6e9c20f73cb2d14ff7351adb6p+1), C_(-0x1.0235621854eeef97bfd3d4e3b1cp+1), C_(0x1.b423243b8b46906701ef92e0fa6p-2), C_(-0x1.2e290398a3fe2fc8cc3aebacf78cp-8), C_(-0x1.22b4e2598d44b0dd2f4a293dacc9p-8), C_(0x1.654cdf573874b672ebfe3509d857p-16), C_(0x1.43e711e67867252f78e7e45afce7p-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1617a4f9d885755cd3477307254fp+2), C_(-0x1.94d9c534a28d3ee0a8bf210cb612p+4), C_(0x1.dd0eb6aa76ffda42c87706ac442ap+5), C_(-0x1.168c0447c1b6e90c330602b02462p+6), C_(0x1.24c19c047007f67f0d2fc486ec63p+5), C_(-0x1.016a68491e4d871ca5058cc8b9fbp+0), C_(-0x1.c94ed28aba0f51cc92c5b4dc5aacp+2), C_(0x1.669c08c9522f315c7b041fb5fb05p+3), C_(-0x1.88dca456f345655b7cb4359a3262p+4), C_(0x1.b958d77e385a9163a2eb3b4f73aep+4), C_(-0x1.eccebab605f4b2d725512d8939ecp+3), C_(0x1.f4375d664ce342e4e51867996bcdp+1), C_(-0x1.2ade5d60c45811382f7ff19a5bd5p-3), C_(-0x1.491f178ce56460d544cbe167fd8cp-4), C_(0x1.5bccddec65e53c1b0416c330319fp-11), C_(0x1.398367062ce373b6810676d67904p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3841475e9a3639fcb27c2a85a863p+1), C_(-0x1.dd3c5aa19c52e5c8a273f6da1b5ap+3), C_(0x1.303529a28e46fac3a8f56ea5a2b3p+5), C_(-0x1.a86d9ebb6edc3ca33aa7af7132e4p+5), C_(0x1.7d0e6c4e24170b40a4b9574c4b78p+5), C_(-0x1.25c8439d2df89fa5007905a011dap+5), C_(0x1.f5b3e1ac9966686ed844c7042856p+4), C_(-0x1.815ee05c85e8aa704180612d3a88p+4), C_(0x1.ca4482f4236a5516d7f638f2b575p+3), C_(-0x1.050825dec75a966028608d12e5c4p+3), C_(0x1.1eeca8acc3a791ffedf80be8793bp+2), C_(-0x1.6df69657c972c8ebec75c924bb61p+0), C_(0x1.75a7ac677c4eee273d03fc609c7dp-5), C_(0x1.ebd49f3810c888c69855752e166p-5), C_(-0x1.4344372e1b6fc786ddf90f275fd2p-10), C_(-0x1.20264586c6bb91b0aa0b4d170d57p-18), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.041f759e862aa2196b99e32b0e5p+0), C_(-0x1.96fe795439508b28db4265486c81p+2), C_(0x1.04a7fd5b5e5923f7f627bd6af411p+4), C_(-0x1.5c5ede521aae5e58438f3722aadep+4), C_(0x1.0b593b29c51bbefd0a21a469361ap+4), C_(-0x1.3ddf512850559b028d83098aa4f2p+3), C_(0x1.12f0bcbe3fa44419a6b52304dc22p+3), C_(-0x1.d4ebfbf56d99633e38e5753902fdp+2), C_(0x1.d31827f76dc61557ae5c1ea99bcdp+1), C_(-0x1.6bf237312f18cf3b573ffc6eb123p+0), C_(0x1.d1d5c0ac4dc0c7147f916f90f5c1p-1), C_(-0x1.794e93c6506dcbe26714d9f89e44p-2), C_(-0x1.2e59e90e0a11c8b7ce9f9105aca7p-6), C_(0x1.26fbfe966bb82001d50ae928dc43p-5), C_(-0x1.e662faa96110f417469ce785ece9p-10), C_(-0x1.a81802ebf94f0a8bc8124e2acfbp-17), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9024e0f887aa33deb80194db4775p-3), C_(-0x1.3caa56e1c68f9f7ad07fd686ffdbp+0), C_(0x1.947e636a9e373f489450f999fe93p+1), C_(-0x1.033a79f260cef0d616212b14afddp+2), C_(0x1.51b6c9e0d0443759a67a3c3505fdp+1), C_(-0x1.0bd62fc1e045579c86e940e51c15p+0), C_(0x1.028bee5b6619ea0406791e99a571p+0), C_(-0x1.1620d9bfc03eb662d8d654bb6c17p+0), C_(0x1.b5ef819dccd9a27cb2716f32a404p-2), C_(-0x1.b7954b06be8aeb961960232f51e9p-6), C_(0x1.054d18d1cc90c79a1ef036069b3dp-4), C_(-0x1.4817258dd284697ebc00b788ccd7p-5), C_(-0x1.8ce86e181d4254ae37719aa28183p-6), C_(0x1.2926b8981e2a739eefaa1e5b0722p-6), C_(-0x1.20ae937e7a9305bbde13268a4994p-9), C_(-0x1.e260b0ee2a092f8355b87bfdf959p-16), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.12cb0a33640b56e423474a1328bap-5), C_(0x1.4e2c27be21e0e479b88ad4851607p-1), C_(0x1.1c4636ef189eccc399682014d9d6p-1), C_(-0x1.85d2edb33e46dde58a5a504a9ab1p-2), C_(0x1.9e3dada7662a9865be6b99b24294p-3), C_(-0x1.494bbf8e53bfc023fe7e0915ab63p-4), C_(0x1.1d23df75685c890f2df5ab229b96p-6), C_(0x1.d4ed15a06848811344377f87f7eap-10), C_(-0x1.2885ec240634157f42540c2ec5a5p-9), C_(0x1.94f202846521b8fb6dee9352c088p-12), C_(0x1.44e94de53f6f632a67cbb5854d1fp-14), C_(-0x1.b37df99b75f08af621654dd8f54ep-16), C_(0x1.403905df41d323c0c33072aaf3cp-24), C_(0x1.c94370d7ecc9194547661e1cf7cp-24), C_(-0x1.58dbb791a7fb6c3e33eb2a850b1bp-28), C_(0x1.db358382953c45bea25d9891f3bcp-37), C_(0x1.afee7cd299cd64600d2193c416f4p-44), C_(-0x1.0988745ca3ec3e945e33c4d42e22p-59), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.43cfcb9d739232114ccf7b42f286p-3), C_(0x1.f5f9c20090df2cd39669639ec7fdp-1), C_(-0x1.94bc27297b9f96d98ca06b8b780fp+0), C_(0x1.61584eb9fe3a67acec590408bca7p-1), C_(-0x1.a2cb67ff996a90130726bb551867p-2), C_(0x1.eef0eaaf4989e29be4ba95e2f12bp-3), C_(-0x1.ac22308c89e820172f07afea77d8p-4), C_(0x1.c84ec23c8cdbe0f0d252ca4a5fdap-6), C_(-0x1.213456d8479d5a0a002e8a35424cp-8), C_(0x1.2c315a17e4063f457d1b74aaa54fp-10), C_(-0x1.f375455c5c9e61be4fa670796c8cp-12), C_(0x1.ce035ff90a79b6418f9714e02027p-15), C_(0x1.06ba9aa22e87c46e9b5b517bf9e8p-17), C_(0x1.2eea964fb1e803735b7cbdec445fp-21), C_(0x1.f125f98e34b07ec90a3117922ea9p-26), C_(-0x1.51db791710be9863d69c55fb8f8fp-33), C_(-0x1.3ced9d37da5d28d7002692ae731fp-40), C_(0x1.85b82452d92694835d294f84ac62p-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2d6cb779664d44484073db45447cp-1), C_(-0x1.01b00cc8d5d0650bb7d9e8758312p-2), C_(-0x1.0fd0995df5aa2a4c5f39f93180c2p+1), C_(0x1.8bd77a675e82837408b645325bb2p+1), C_(-0x1.c8684eac579b3e1019c502de8594p+0), C_(0x1.6e6d859b2e72f80278552877464cp-2), C_(0x1.86e851ba85834ec58a127f16fe28p-2), C_(-0x1.9dcbe6db3790670c84be0eec2f7fp-2), C_(0x1.55c762fd5a0df64b9c06acd53195p-3), C_(-0x1.35a481158ac33b4716b6e91c5435p-6), C_(-0x1.51b88ceed7addc9a97168ddbed49p-7), C_(0x1.0767285c8f10645316c4c221fa2p-8), C_(-0x1.67961ae7bb99fbfcc0d26144bc53p-12), C_(-0x1.2b4a0836ed60ae3a1490ad53cc1ep-15), C_(0x1.bb4b6c6c9a6faf8c7dd84be23c4bp-19), C_(0x1.3f418b80d3d44c3e61fe90bb843bp-28), C_(-0x1.0d99c100eff2e6c61779a485054cp-32), C_(0x1.4b9c0643323fb1c0ce2d07b0b092p-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a8dadfc02dd0428b41cd0c1bb0afp+0), C_(-0x1.8d688d31d04a4214094b65c4cddp+2), C_(0x1.317cc4a10faf3ff9c44aa07180dp+3), C_(-0x1.00fa12867f49132d26f6109f1a1ep+3), C_(0x1.9e984b48af59218135976f585487p+1), C_(0x1.0dcc3bbac5e0885ef946fb573bd9p+1), C_(-0x1.41a435a1df480f6b501eca7093bep+2), C_(0x1.075a464fd9703954dc501fa9230ap+2), C_(-0x1.9984cb75bad50ddd23b7c6a931c3p+0), C_(0x1.9cf2e7196d1cbd2ef1ba36ca5473p-5), C_(0x1.c915787e3612e2d3277f4d8526a2p-3), C_(-0x1.60b8b0c3b1138df4716646253571p-4), C_(0x1.324229742ef4416185466d935171p-7), C_(0x1.dd5da666efa58ec47474db0b6e86p-11), C_(-0x1.351528a4bd8176153593c8a5a1a8p-13), C_(-0x1.03c4250827b68f69b983f4479114p-22), C_(0x1.77139f17861eb1acd308dc031079p-26), C_(-0x1.cd96fccfe9f0afba4ba09dac3a7dp-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a04f8069ea8b4e447d853aa2b3fp+1), C_(-0x1.18f0a34d9f68e4d06a24b5c8413dp+4), C_(0x1.4ce3831796a61ef6af32be9a023fp+5), C_(-0x1.dc75f9b0b9a1041da91933762b9bp+5), C_(0x1.fdbc97313e6ed6865f9096ac8807p+5), C_(-0x1.eefc0cdda4efa281b21fc89e970ap+5), C_(0x1.b92a7c1b6a889c31c867c0ce8c52p+5), C_(-0x1.2299d502734c3c9b7e4c9a6f523fp+5), C_(0x1.6502b707871df45089990b5055fdp+3), C_(0x1.11f33f4ede647d59a412fb3857a3p+2), C_(-0x1.73b0a319e6889e9aa2e82f2679b8p+2), C_(0x1.244d452e7630092d6c490c8cc448p+1), C_(-0x1.35466c5650c61e120220d045b2f3p-2), C_(-0x1.fc20c8dd92f19b8d6ed30b1d9872p-6), C_(0x1.0d9c8b9d476f7d129de2a5d13304p-7), C_(0x1.a4010b80e5495d0ed9331140ed28p-19), C_(-0x1.49b0c99eb9c648511ea730b4e4dp-19), C_(0x1.962a6dd57b7daa6dc5023a314835p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.55886d2f64380baeb961078fa176p+2), C_(-0x1.09d95f1cede31fcd15d2c7fab39ep+5), C_(0x1.505f98e4bf27766f2f4d3b7ea8ddp+6), C_(-0x1.96ec354b303069fd664614786911p+6), C_(0x1.17b23075f8010224c348afb3ebb9p+5), C_(0x1.fc17211fa4d6f3f6a32616561c88p+5), C_(-0x1.b35f4a36b31c3849a4f062a53c98p+6), C_(0x1.d17f22f2480f88bf1a425e0d999bp+6), C_(-0x1.12118c5678b4d442de8a0eef777p+7), C_(0x1.207a74ca5ad8bfc2ee103b7bf96dp+7), C_(-0x1.934735f943481c7f74f56dd5b187p+6), C_(0x1.3fa55ba9206e3812ee32da2442b6p+5), C_(-0x1.959601005ec548729558e21c9eb1p+2), C_(-0x1.9505e84d98e613cfe4ec3f6fdae5p-1), C_(0x1.43d2632e32cd0df0bb4a95d727cp-2), C_(-0x1.38e017336cd0614a6ed2ffd943cap-10), C_(-0x1.968e83ac595b8c6d9c172a00fddap-13), C_(0x1.f5ed4b124df3ad0700a32c86e4bbp-24), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f3cda2f9b135402362018230e37ap+1), C_(-0x1.9eeda12641b61ebb7d840ecfaa6cp+4), C_(0x1.260fdaadd19eb1efc078d7fded1bp+6), C_(-0x1.d673d80eeade4a070ce0e7052e5ep+6), C_(0x1.f01b2fa154d0352990b16aa70967p+6), C_(-0x1.addb2c4ad791e217324c7aafb066p+6), C_(0x1.7db87bda6fdf8a74bb08213b9495p+6), C_(-0x1.3f9860f6c4905e7132b1781ae693p+6), C_(0x1.ae731643e9198e621648583330d8p+5), C_(-0x1.fb5cc3351ebc176988bf6478c6bp+4), C_(0x1.259afcbb8804d6eae552ab39c09p+4), C_(-0x1.fe186e460309fdcedab5ec38f6a8p+2), C_(0x1.4d0298c21892754606c3d8ebb24fp+0), C_(0x1.a1f0a66406a122ae435ed98406f7p-2), C_(-0x1.40c0addfd85543af466cc7de08d7p-3), C_(0x1.ba72fac37f087c7aee39dd6d7d9ep-9), C_(0x1.c193f16bb678e5af6510cd4d8f9fp-13), C_(-0x1.16b4995bb4f073263c20b5b2b14bp-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3586d9a9e0e3d99d2b93a01af7d5p+1), C_(-0x1.08fa63342ecc1c41a46b365c4c22p+4), C_(0x1.7c41f01d6960cbda171d22b314bap+5), C_(-0x1.276b64d22e134fe39031785d1e73p+6), C_(0x1.14f1cf74869c077b4ddd600b6793p+6), C_(-0x1.83d54ac636b8244258f1e3c9d507p+5), C_(0x1.4053c8a2c8d2fc6aef1621e8f43ep+5), C_(-0x1.209b538b18df262448ee3cebbe29p+5), C_(0x1.65783340b3782c7d703e94b54e85p+4), C_(-0x1.2ddf670e51dfca7d85e8eeab11aep+3), C_(0x1.38744fdae212579791ea9e59ba4ep+2), C_(-0x1.4065c212ba5c0456783637741afcp+1), C_(0x1.6763c5d11b774e2d99bb54d3a752p-4), C_(0x1.181d4d676ea1f03e7d8c57b5965ap-1), C_(-0x1.87564028831fbd4eb29dad95b0cfp-3), C_(0x1.843d22529bb49b17cf15d645bef3p-7), C_(0x1.52be3b0b8c7af55af9d914b56a01p-11), C_(-0x1.a79c626c8654ebdb591ae5793d64p-20), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7a3cf471120ec198713994eca41fp+0), C_(-0x1.48b25e52d274b1e47c8864a7164p+3), C_(0x1.cbd93276e7d596419b912da6ea19p+4), C_(-0x1.37885d5242030806d66e5cf9cc78p+5), C_(0x1.4db4fb7a5ecdb9227e8824c1b905p+4), C_(0x1.74ac2dca21f55bb24886b2e8488cp+2), C_(-0x1.11ca2f9f0b7d05f1c16189874d5cp+3), C_(0x1.9fa6aaf0c8d980502f82ac3f1ed7p-4), C_(-0x1.8ceb3288570cd32c25919a739d51p+2), C_(0x1.e686e3fbc3fbf35811a68b06fad4p+3), C_(-0x1.7e0b780d60231a4c786ec3f17781p+3), C_(0x1.7e1a3482e160bfcf5bb1945be474p+2), C_(-0x1.247b57131543bcbee8b05ee74f53p+2), C_(0x1.b8a4e1c96768c895a2f3649c4cc8p+1), C_(-0x1.4f17d502240a8e6f55c9dea2c968p+0), C_(0x1.4b408438ac8689521da23d7beaedp-3), C_(0x1.7264788c9473dca575636b8d6c86p-7), C_(-0x1.d74fd6a021547c7f9f7dd044fd0ep-15), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f6438a3a88460091e0ea8516e904p-4), C_(-0x1.b7ba9255f9c77a442c3315f3c4dep-1), C_(0x1.3f509b3842148b5acdb05dfc7ebdp+1), C_(-0x1.eac616f0d4f869be16ce06d469adp+1), C_(0x1.ae9244fef585d2a56f1cb69c0c8dp+1), C_(-0x1.00d5d03220f3bbc8a51448aa67eep+1), C_(0x1.9413f3bab26fc85ab60692eb482fp+0), C_(-0x1.9bd9847a10dd537f2de875e0ae85p+0), C_(0x1.16aae27d18a67638fdda8c9d9188p+0), C_(-0x1.1587682f48215c21c42b36d23f1dp-1), C_(0x1.8145e3cc3cfcbcc409c895dd9662p-2), C_(-0x1.faf556e68970db4f5325d20bccb9p-3), C_(0x1.8ec972676b06aaf4a1909e5ab3bfp-4), C_(-0x1.49980ed40883cadc7b702f6c3e9fp-5), C_(0x1.5730c48bae56a4ea4426b047bab7p-6), C_(-0x1.0952d6b855c638b977457b4c3a4p-8), C_(-0x1.ce071dd8df1eee9d16331f022e54p-12), C_(0x1.30a4361eb25b38fd9207742aba25p-18), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f82d860ed311d7772f0a5fc02a6dp-7), C_(0x1.da87adf545dea36f29603c50206cp-2), C_(0x1.a074ea6831a179cbcefe13bdeb26p-1), C_(-0x1.d3dbc22db33632cb9d3eeea93097p-2), C_(0x1.07dc8c4b588098d99d74923fef1p-2), C_(-0x1.17e06a0deb06ffc5a354422c2913p-3), C_(0x1.d85300a8e9a59db3d8e328544719p-5), C_(-0x1.0710616766f9db787dd78480360dp-6), C_(0x1.0182a0c9a44ba81f2b490da87cf1p-9), C_(0x1.d91cd19825f46395eba40bde2534p-14), C_(0x1.f2bfaace30f58a825ed0b3a11e2p-15), C_(-0x1.d7e9ba7b3ac4736029b548526137p-15), C_(0x1.5c274e2e04a6575e26e75abeb4c3p-18), C_(0x1.63562e1b18da7fac5905b88575e8p-20), C_(-0x1.0af5800900ccbea5a647053aa052p-26), C_(0x1.1409cb495cfaa9cc50f1fb279896p-28), C_(-0x1.1601287f207dc804b32b2b372befp-35), C_(-0x1.4f944d6c974a0ba10244cbd7bf57p-42), C_(-0x1.ad914b3b9c6449c459a4d882621ap-53), C_(-0x1.65d8440cb5909e7eb82f547cb81ep-70), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4988f615d8fc2101372678651696p-4), C_(0x1.cd9786f046dbd06d9795ae5305eep-1), C_(-0x1.f034187a5d75333e9dbb5b1046e1p-1), C_(-0x1.075e3bcf1d71f31524cf997afbe8p-3), C_(0x1.303436308c600230256305532d57p-3), C_(-0x1.71d07ef81053ea5196f6a9c9ea93p-12), C_(-0x1.321c6b5970b994e47d89204a7726p-4), C_(0x1.0f00f0747578208709a35dbb5672p-4), C_(-0x1.fec807d6bcde2f6b9da93df4aa6dp-6), C_(0x1.092c0960e80ebe73a0fb5f592a81p-7), C_(-0x1.1857810566102a80b03f6d57486cp-11), C_(-0x1.693105a2bb706882bf9e39158aa2p-12), C_(0x1.a2acf3b1f9d0749452e4dc44d918p-14), C_(-0x1.c4d81f25bbab666371fdd702fceap-19), C_(-0x1.e0284772a21eeb07c87b76642d8fp-20), C_(0x1.7db784c0b013093ad9874c402637p-25), C_(0x1.739c15dc80c555f970d134b64517p-30), C_(-0x1.d9433a2520a2e30f13e7c351f17bp-36), C_(0x1.651bd505e5aaae5cab5b708f20cp-46), C_(0x1.29782f98b98d8b31230d837a9eccp-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5c07e5083d7090314f404490267fp-2), C_(0x1.307a2a8e783ea1f99bb361a3ce3fp-1), C_(-0x1.a41fd4c6e53047b890408086b518p+1), C_(0x1.08f3303fd9b5f02cbec87edc442ap+2), C_(-0x1.6a2a8758fd08bb3ed6b347424cecp+1), C_(0x1.5f04ae9c9034ab19fcfae00d09b9p+0), C_(-0x1.150c77d31565d35edf80240e5e1cp-2), C_(-0x1.78ed1cb9b0ec1e760990f81b60f9p-3), C_(0x1.4f99902d11603738023acee050bdp-3), C_(-0x1.41156e1c846c464a303629e298b7p-5), C_(-0x1.6c5861062a83616dee9275c18c97p-7), C_(0x1.21e04958552e6f03502dd7935724p-7), C_(-0x1.cd1c35ab2ad92bf156188522c5bfp-10), C_(0x1.af6480e4adc46cb9e0c7649b6f56p-17), C_(0x1.0136c3fb4b19b9b10157d7a834f7p-15), C_(-0x1.6928b0e495d07fb474aad6800549p-19), C_(-0x1.6377af73884bfae0ae8534a7569p-25), C_(0x1.64323c063686a79e3f723a6f6b93p-30), C_(-0x1.6fb51174aa8e375496c635af829fp-40), C_(-0x1.32449da1b960881894abd2226adap-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1c297e1a722977a767a1ff227742p+0), C_(-0x1.a72bc3c00615f73ba93716b01e65p+1), C_(0x1.8e98178e99b31d46ae26eec0b1cap+1), C_(-0x1.8f506e2a5e0eb5edc0313f13b62bp-1), C_(0x1.02364935e2222846b9cdda1bc87p-1), C_(-0x1.0fb2290536b31f2a2fbff3404bbdp+1), C_(0x1.80597d49465bf4c4d8869fb534fap+1), C_(-0x1.38ad9781c750136475272cd6e902p+1), C_(0x1.339d144fd9550bb8463b544a6643p+0), C_(-0x1.08b97b33caecc76a026ab8335d28p-2), C_(-0x1.3f8a268debfb77a1cde76d550fe7p-4), C_(0x1.2b8bd1a4fd0eaf4aaa08a96cf3ep-4), C_(-0x1.35b764060a713cc242948b5c4153p-6), C_(0x1.f33a86db42465a05a6ee3ed1f4ffp-12), C_(0x1.1c307da269dee355c5c2d340dfe6p-11), C_(-0x1.950dcb7c8e981d2c1ff88549cb89p-15), C_(-0x1.f904916865d4cb30ef383c46ae0fp-21), C_(0x1.8b6cb6bf7586b0f4f1fcded4430cp-25), C_(-0x1.21dedfd7476c5553241f507ac2d7p-34), C_(-0x1.e2c7778c519a040a7c97727ee351p-49), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.51d8dbccf9206bcc4420e8d9ae07p+1), C_(-0x1.c33b049bfbce5ed995e58045194fp+3), C_(0x1.0e79522ccf3dd0b86ea89a5531bfp+5), C_(-0x1.9aba40cee29c09f71dc38c35a548p+5), C_(0x1.f144c4df7513d73b0fd71dc9df3fp+5), C_(-0x1.17ce56ad9d9026c80fe9053e3b69p+6), C_(0x1.1abf8d1adcc3e5071c7209bb8006p+6), C_(-0x1.aeeda88b7fe87fd16bcf8e054d05p+5), C_(0x1.6d1975fc2f42e1b2096263c969bbp+4), C_(0x1.64c18afe2844c60255dd74d07edbp+1), C_(-0x1.4b3d36d8f9770ee95e2721f907e9p+3), C_(0x1.8e75251a7f5bee7754c2a9513fecp+2), C_(-0x1.9e20d16541319f6d732cb61c018ap+0), C_(0x1.8f713f264dac28b16bf91d504bd5p-5), C_(0x1.002e9aac591974da848a16c844c8p-4), C_(-0x1.22b5d07d79f24f7de83980b5ed9fp-7), C_(-0x1.695b63166e6d63ad77759faf33b7p-13), C_(0x1.ba1b21857af82fb76bf4742957f6p-17), C_(-0x1.df066d7576ffcacbc6c94f3c14p-26), C_(-0x1.8ec06f9de2f7d48618cf3f2e0232p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.553841cb8504c59ec8828722c9cp+2), C_(-0x1.1648a261cfac86a07a577122f4eep+5), C_(0x1.7429c31b8bcdc777e06851df4ff3p+6), C_(-0x1.d2259be1a7818ecd1bf98b71d684p+6), C_(0x1.36cbd86221f4c1c381302622675ep+4), C_(0x1.4a282d1320ed73864b5c73d42965p+7), C_(-0x1.2e04ab290e2e062d6018a7405d3cp+8), C_(0x1.5f18c6755ba04a0fe5846dc7ce5fp+8), C_(-0x1.80bbefefb89592a7731263e58b6ep+8), C_(0x1.90ad4b61c673e71a7b1a638ff4cp+8), C_(-0x1.4159e0e62036c0e7d3a9372888dep+8), C_(0x1.4eba06db33d52e049a499539c59ap+7), C_(-0x1.6db5a82568a43d359e1324f88c7ep+5), C_(0x1.6613709f48645b09020d1137193bp-1), C_(0x1.7dbb7d4fa2b472146ed131c42bb3p+1), C_(-0x1.1851a9519e35d94904835e4c0f44p-1), C_(-0x1.230c93cadc0b78607a6df63dd398p-7), C_(0x1.7e95e283d8ce34ce8180e79a24c3p-10), C_(-0x1.136d2374e371184371f11564efd5p-18), C_(-0x1.ca2f0f4b750065dbf1a91e494693p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.43e579b56aec6db8f44fad1a2ca3p+2), C_(-0x1.2015783789a1305c4b04f4299082p+5), C_(0x1.be9eb07640a6e4dcf71e8edd1986p+6), C_(-0x1.917bfbcd50104121d7cf2e5fb61ap+7), C_(0x1.e7564ac670464ea6f5bb03253324p+7), C_(-0x1.dd46b6e14bd993fb7d27e4be31d5p+7), C_(0x1.c24b2cb18bb303674bf661030f65p+7), C_(-0x1.9299f7098407dc40f69f41f42557p+7), C_(0x1.2da088f392f175bbf1502b058265p+7), C_(-0x1.7f74fc0a8fbbbd2a662926cc0952p+6), C_(0x1.cafceab55c22225d33d140f11ba1p+5), C_(-0x1.cfad0a751fefca13c3b326a88e5bp+4), C_(0x1.f4f5eade96653abb41ce93f1a983p+2), C_(0x1.14b6d949957a5646a550369bc7aap+0), C_(-0x1.5e908a00f74d9f8f6b65d286f0e6p+0), C_(0x1.1ee7d490234e22c547ade0704929p-2), C_(-0x1.1e667fbdaff187310b0173bcb94dp-11), C_(-0x1.81c4231f27f23e6bc64b0c2f2493p-10), C_(0x1.28216d550397d430f8799924705dp-18), C_(0x1.ebdb45ca159a64fa9f199a16a149p-30), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0e918e0751a5f26d66d326215241p+2), C_(-0x1.f54b1dc71e94b922c8b7d974b91p+4), C_(0x1.8cc935a5962f326b8767e9c68e69p+6), C_(-0x1.5d87f4fd9af883e7ca8f85ba9a3ep+7), C_(0x1.7fbdfc1f5c92ac9439f72d5fc5fbp+7), C_(-0x1.356154b8ce2bfbb26ff26135d3d6p+7), C_(0x1.00a2f00b6f35fbd2365b8c4d7e4cp+7), C_(-0x1.d61ad68084631dc5b1cb350d96d3p+6), C_(0x1.4b192d7116369fcf46bbc7590d76p+6), C_(-0x1.2bd7eeccbbd8b3529c9ec7ea0986p+5), C_(0x1.d23af72a9213134d138ab79fb28fp+3), C_(-0x1.a5a3f6309aca858b5548cc51629cp+2), C_(-0x1.0097ba319005f0b824ee39f7e25p+0), C_(0x1.29abec5ca24e481b150656fa7b24p+2), C_(-0x1.6d63c669ef72a15dead10bbf465bp+1), C_(0x1.521b96f1f011ffd834fe0c4deb25p-1), C_(-0x1.89a1e9b6409a39917b2558fc77d9p-6), C_(-0x1.cc0f8b0b31975b1da167d6d21402p-8), C_(0x1.9e94a90cc2ee8162e5d90cf2df7p-16), C_(0x1.5739a9ee6eb1c850a9597f22010bp-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c2a4ffe9661190c09a7af8b79479p+0), C_(-0x1.a9c9682497d4356cc97c7817608dp+3), C_(0x1.5bbb8c487ae5bb615e8e73227ceep+5), C_(-0x1.452573aebb3bf474bf24d5595fd4p+6), C_(0x1.91c80b52c3671525c3375a1dd5efp+6), C_(-0x1.84d65b83affb5ca97ccaf8b73947p+6), C_(0x1.678e1d36597adc53993fd96dab7ap+6), C_(-0x1.4933025bdb6895888c173cc7b2a5p+6), C_(0x1.14413c8e18075f1444cc540dc34bp+6), C_(-0x1.b51d99f6678421b18139d5beb61cp+5), C_(0x1.483818775e0cb14480b32b95042cp+5), C_(-0x1.a72562d5d8064b092b7bae77a4cbp+4), C_(0x1.e00e48c9f77143cec0c43c67669bp+3), C_(-0x1.1522f77734c2edb19342e41508e1p+3), C_(0x1.152961e6e0f56f5672007e36f948p+2), C_(-0x1.3d9d88a64fae43ec46db73db181ap+0), C_(0x1.3f1c58e4e2a682bc6ff059fa1f8dp-4), C_(0x1.b3efb441a4e1aa6b7bfceb788233p-6), C_(-0x1.baa159e67dd4ea14a46828d67fefp-13), C_(-0x1.6c2d94cde3ae1bef5e760e39de7cp-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.480f31520e3f310c306bdafaf042p-1), C_(-0x1.38fe2f09aac57b92aacdaa15d1b7p+2), C_(0x1.f8f411bacc9f961bc5fe5499f875p+3), C_(-0x1.bc60c3b54f90a9241998e0192f5ep+4), C_(0x1.d3d44a6a16adb2540f6bfe5db93ap+4), C_(-0x1.536d6f833b66773a970214ff031cp+4), C_(0x1.0953a7a524aca913282b24103258p+4), C_(-0x1.0c0dca303e8e262fc9682f1cf736p+4), C_(0x1.af56b1534f29dd21b9240915b75ap+3), C_(-0x1.f628948ceff73b6d1ae732743415p+2), C_(0x1.3ef834c3289aa35b262757674e4bp+2), C_(-0x1.c75ab5e1afc75a2d9d28a11fcce2p+1), C_(0x1.cb38bb2c5f4bebadf622e599ec8fp+0), C_(-0x1.624785bf15dbe093496b9f1d5135p-1), C_(0x1.61b17ae5ff0c0c37a77be972ec5ep-2), C_(-0x1.0b62472bd3d7849095f6dced344cp-3), C_(0x1.c9b3ef0688e890b76d9f130077d8p-8), C_(0x1.7c528a3f2156c588899985294901p-8), C_(-0x1.0c4738028aec930d4308df6549ap-13), C_(-0x1.b40e785cb88086ef360909630572p-22), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a25fe79d1c4ddac335be8819a8ap-4), C_(-0x1.79dddd860d2147a7416541793f71p-1), C_(0x1.2f92842080f0827925b022200689p+1), C_(-0x1.04a53246109b6b6c0d3ef73b505ap+2), C_(0x1.fbc727fc23eefb6381085fb0ea64p+1), C_(-0x1.2e8a4ebac6b5e49a84fad5dff777p+1), C_(0x1.96ff87cfe4cc502ebda973db1ba2p+0), C_(-0x1.db8c7f7bf2c3a242351f9975276ep+0), C_(0x1.8867eccd39d1aef372869101502fp+0), C_(-0x1.7019bc278ffc03b406b2ff135206p-1), C_(0x1.a30d20b4e67c690471d7cbcbb0dfp-2), C_(-0x1.7340e7a399e63a19859bd6b84d4cp-2), C_(0x1.68181929e64c530045ddd9e48ddfp-3), C_(-0x1.50a6f5e8f3b308d50e585f11b7ap-5), C_(0x1.8d3b211eb839ac11193734372a7dp-6), C_(-0x1.b7227d5381373569d6206c572353p-7), C_(-0x1.a3114fdf2fbc06953fcb9931063cp-12), C_(0x1.71e7a3b4d88bf16a9f3c256dd239p-10), C_(-0x1.4eea023db8bd4900ec558c766ab3p-14), C_(-0x1.09aed93888304346e30d148d3c14p-21), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ba5636194c0939c427c9ec59581bp-8), C_(0x1.3af72853b1890334601f92a1284ap-2), C_(0x1.da1521352f487f1b71f5ba208041p-1), C_(-0x1.5c6f665240adde3380bdc0aea438p-2), C_(0x1.4840a35a3e5076b07b9bb98536cdp-3), C_(-0x1.9d4fdc34ae4edcb2a06a461fd21ap-4), C_(0x1.042a86a360591d6b2ba9327c6214p-4), C_(-0x1.08554bd18ab256f6f2efbe750de9p-5), C_(0x1.86c905bef28a68962be82a3bfae8p-7), C_(-0x1.8785b403c86f6f7548c23ebef922p-9), C_(0x1.f00fc00fce26eee7a53c75fa9287p-12), C_(-0x1.43b7ce1fa4e5b162d9e05ba1624fp-15), C_(-0x1.dafa2eb6c7f5cbd9451ac8b8db32p-18), C_(0x1.2d678c174b94d04aa232fc24fe09p-18), C_(-0x1.f0554b8e5712d06e0273c8cb503bp-22), C_(-0x1.934a0de4da29338aed7c3945f15bp-24), C_(-0x1.3a5d95f1928eec0223d4d93358b6p-29), C_(0x1.0e0d2138861875f5d48c437e1957p-33), C_(-0x1.652333b327609e7169123d062941p-41), C_(0x1.02e74c07e60809b1acff78842ce2p-47), C_(0x1.bb358cf4adf4da69e5fa9c480499p-60), C_(-0x1.f67e04f08f2152aabe6eb786996dp-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3daa1461d0cf47fff25f3df963e7p-5), C_(0x1.716f56bac1b1102dab376b1a3fe7p-1), C_(-0x1.16bee9987071960277d4321df078p-2), C_(-0x1.f51bd9fa1cf2d9e12262aabd1401p-1), C_(0x1.97243be7bf08455883f653e158edp-1), C_(-0x1.b8eef0110c9fa4de8e71d38444bcp-2), C_(0x1.2402bce395301d2ffcfa2c7a4938p-3), C_(0x1.80595820660c8830537a9f5a0e29p-10), C_(-0x1.fa47fa3f4b021cbace01025dd941p-6), C_(0x1.025a88022a413b155a9680077b35p-6), C_(-0x1.3d712aaad77758afb71e5644bf72p-9), C_(-0x1.c5c0d04fc87430265835a2d868c3p-11), C_(0x1.c45b69075cdb62e0f0501d72eab3p-12), C_(-0x1.6a1670435bfdd529f00d82c5e437p-15), C_(-0x1.13c0d643a27dc3e64f7aa5ea1b1dp-17), C_(0x1.b2cff794384635cf6c5bd8331af5p-20), C_(-0x1.9ee90facd3d1333133d7e205e062p-25), C_(-0x1.c87e1185ca55b3b93aa74571695cp-29), C_(0x1.b076e966620448a8ccbae1de5619p-34), C_(0x1.71c42c5b1e646b3eaaa36a5a302fp-44), C_(-0x1.e6d8e5785ac9381d9a7b90929674p-52), C_(0x1.13fd176d0c254d2994cc4f8bbae7p-69), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.77fed2e01693602fb84977597092p-3), C_(0x1.e1d10780fb06110288f8999dc16cp-1), C_(-0x1.9e9c7ce63835ce70bd9f1949b4bp+1), C_(0x1.bc153af50c24b9575bdc1b7eea9p+1), C_(-0x1.240fe3f248860f90966b383ce203p+1), C_(0x1.80cee17390c17dd6afdc8b5e9bd2p+0), C_(-0x1.abf5df7fd7abfb9aaab015caa888p-1), C_(0x1.50c7e71a108baf578aa06cfc537p-2), C_(-0x1.4654ed4660723ccc0f0acc159e52p-4), C_(0x1.091b1dd62c3e5f033d13bd90e92bp-6), C_(-0x1.59c475f85d7f3ec16b121b44eccep-7), C_(0x1.935e464b93aa450281cf24f671a9p-8), C_(-0x1.8fe1513629011cd322fa61848df6p-10), C_(0x1.90feb0894b434ddffdbc8185f2a5p-15), C_(0x1.09bd1f2d4e386644ae469eb863f8p-15), C_(-0x1.da6da6ad5e76b858534775753bfcp-19), C_(0x1.a3886fa6d48c5693a0b3ec42e08ep-21), C_(0x1.0f7850b94c92b737f20b8005c4e4p-26), C_(-0x1.63226d50629bfc487dd5a4e8ef38p-31), C_(-0x1.84d7e34db15d3108fdfa03f5836dp-38), C_(0x1.75cc98099352929e39911fd43962p-48), C_(-0x1.a7d23115de5731da90d3ce0c96c3p-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.60087b087d2ef4b82953952d9084p-1), C_(-0x1.1c49e2797e56cac67a206b14e7b4p+0), C_(-0x1.f023b1706ef0dac15d9852fec6b7p+0), C_(0x1.8d30c07e51574352c1f1eb2006b7p+2), C_(-0x1.80e0de445b219fbdea6ef733a307p+2), C_(0x1.c1feac4e70c181d6b4fca6d1ffb9p+0), C_(0x1.3621ab0ea1b052aecf48cff7492ap+1), C_(-0x1.f3ab98611d47a796d9c546361f74p+1), C_(0x1.5e6794d526a24de36780aeb9efa6p+1), C_(-0x1.c702eca93a33cb508d7b1d00211fp-1), C_(-0x1.ee149aa686bb2faa29ff6d4bcf1dp-4), C_(0x1.ffde0ca5fc1a1519c08ba08ef931p-3), C_(-0x1.a2cbb989ecd0a0b85c48b0eeedfp-4), C_(0x1.d58bf4f6c76ea5b68a5554193d1p-7), C_(0x1.206affc103ba0a875625f4581693p-9), C_(-0x1.dfc88961f6b157e54f77890bbc2ap-11), C_(0x1.f86e53415f2a00da542f82562b56p-15), C_(0x1.28c920e4a3f6bb0fc001a36c54d3p-18), C_(-0x1.9c90e430666c8d48daf021826ab7p-23), C_(-0x1.7e8cf0898f3336a3b6d1b959b3ebp-32), C_(0x1.cc8984cca607f1a4cd24395b33dcp-39), C_(-0x1.051a1f819156ba9bc5cb80611a1ep-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.efa01fe281c907b167ef08b2a819p+0), C_(-0x1.34df3dac7fcd3f885ed5b13d2111p+3), C_(0x1.5961138d5be957877d8cfd1f8beep+4), C_(-0x1.014d7a672544a1c4d790253c77afp+5), C_(0x1.5a4b6fa251eaf90e3115b0c8a7d1p+5), C_(-0x1.d72d9b409f2b1bb94911072e35d5p+5), C_(0x1.1a6ca7d65632cc9e3b88e527a77dp+6), C_(-0x1.f8d9ef0a2890c5946bb98eca1feap+5), C_(0x1.142ce1c1f06e19e0c6f07b093cf5p+5), C_(-0x1.90f390767ce4703536c74e99b357p+1), C_(-0x1.822b1a96e2d91cc911472934db6dp+3), C_(0x1.52a34d125b1be5508a31d4593a7ep+3), C_(-0x1.0b934a511e088d9de4577e6b9d58p+2), C_(0x1.335fd67def29efb717b66730db11p-1), C_(0x1.17c48a3b6f0b811400fc04e29772p-3), C_(-0x1.0033850ae88073da0780e3e4b1ccp-4), C_(0x1.68d4635bbce683527c347878fb17p-8), C_(0x1.b6ad0e03e206f2cc34c3ad57b135p-12), C_(-0x1.c361dbb11082ba0b86af7e7039cep-16), C_(-0x1.d59d4ba004a567edb22672d12e01p-25), C_(0x1.f6c8c69c71b982736f46aec1c2fcp-31), C_(-0x1.1d186572e3d30ab58425e9b0d124p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1672f76c48a3b085a419d3d84efep+2), C_(-0x1.d05e83fe81471c548c37702884afp+4), C_(0x1.49fc051fc99a825862e53c41bd9dp+6), C_(-0x1.e442104e65335b30f1932ff3fcdp+6), C_(0x1.09c52f838d2fca1c275b6ba1ca01p+6), C_(0x1.677b64cbf326e55bcfc76402e361p+6), C_(-0x1.fbf39786bea7b138ef97d391fb5cp+7), C_(0x1.628081b6fdd810aa965a5c98d2cp+8), C_(-0x1.a2714ddd5c22b603c83ee77be92bp+8), C_(0x1.cb4de777b4f362d79e6f05e8e906p+8), C_(-0x1.9cacd3aee3a7e296cd71908c1c97p+8), C_(0x1.055f4806a834671e4070618a5f49p+8), C_(-0x1.8ddf94a470b86c5104b74cbf3618p+6), C_(0x1.95561c2d77ea7cb1b418f1ad675dp+3), C_(0x1.8ab9cc38b4948a55522c2ec1bb2ep+2), C_(-0x1.6e4f007cb3f6f6544bd7c8aa8418p+1), C_(0x1.43d7023213a802dd64335ed45bfdp-2), C_(0x1.951cff21de4ac7e4a1f0a692a613p-6), C_(-0x1.5137c147339bc2af2a690f130f2cp-9), C_(-0x1.3e3df8b2da2752dcb7f745d4f5a7p-18), C_(0x1.78040f51a9567ebaa0b6d793cafp-23), C_(-0x1.aa8cd8e6f8971ce4ff33741ce32dp-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6688e31cf50e0564efea7c707539p+2), C_(-0x1.50ba2688bc0430a9ee7461099f42p+5), C_(0x1.18d5fc503a1772d2730b3ea50efdp+7), C_(-0x1.16422099d0e700c2cc83b554b1d3p+8), C_(0x1.7cdc33f38c2d168782ab512e0152p+8), C_(-0x1.a2f3c3b8e6e4ab101396a900d9eap+8), C_(0x1.aa319d6af6ec967e381e232c3d8cp+8), C_(-0x1.958a02a1024489567edfcd9f60c3p+8), C_(0x1.4bb5b15c50a647500af490b1348fp+8), C_(-0x1.caa9291eb011f2ccec525396312bp+7), C_(0x1.1f2d7abf22a7296277eac06229bap+7), C_(-0x1.3b920d0f7e0d09abc1f29bae2433p+6), C_(0x1.bc14b21b62b9334a0ec0723419b6p+4), C_(0x1.8c237a0fa26d7404976151e77cdep-1), C_(-0x1.7f694c35d9d2245677a758a1954ep+2), C_(0x1.3f67e104a689bca4d8d6dcd2113cp+1), C_(-0x1.4cc6c058f371d1d7aadbd425ad1p-2), C_(-0x1.6b557354b8d84aa675e72eefd888p-6), C_(0x1.38d6e371bb0518c7efdfa510e3cep-8), C_(0x1.260d95329ea8e0edce58683df434p-17), C_(-0x1.5c7911e0053bc1a14fff7c706e19p-21), C_(0x1.8b88d3fa551bf844985173c27b89p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.80f665163dff60603105460968d1p+2), C_(-0x1.7dd2228ef04492e49ffcbc26de51p+5), C_(0x1.48b0d88030936751bd070f0b70d7p+7), C_(-0x1.41512ba753d055c75dc8c75f4172p+8), C_(0x1.8f56f07493ef05c30063bd380daep+8), C_(-0x1.675a39773b2485da34f83484320cp+8), C_(0x1.2e9626a21624df1cdd8e35d51165p+8), C_(-0x1.1263590aebe88d200657c008c834p+8), C_(0x1.9699942af2221429cba47418cbf5p+7), C_(-0x1.59e9b6e0b9c21128db1641974871p+6), C_(0x1.09d1a0b7c583242c5ad30248e848p+3), C_(0x1.cc8ab1005087bf119ad7a75bf51cp+3), C_(-0x1.93c8d5094509572acb009457fd8ep+4), C_(0x1.013c24badc62703530bdc2a89abep+5), C_(-0x1.784654bbd73679c9f2def5413da7p+4), C_(0x1.21acdd98ca7e3a8d97a584ca3cd3p+3), C_(-0x1.6fa583815aba1a21d8ba9c3f6b87p+0), C_(-0x1.39156fe5f0a3b45977f7c9849262p-4), C_(0x1.34372727b2154e0f63382ce7b14dp-5), C_(0x1.c53d49d19717546a3333946ded1p-15), C_(-0x1.57bc52155abea4723bbb438d51fep-17), C_(0x1.869c11b6398bbfee9ec137b2aadp-29), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d573db31c98a592a2b6a796753f8p+1), C_(-0x1.ddfb9c5686a4efd2bd1e36073e0cp+4), C_(0x1.a873c238f1ad89ace04b7607dff2p+6), C_(-0x1.b2204de17a53a3315364d57fc2b6p+7), C_(0x1.23910ebcbe60d3ac86902adcdaa4p+8), C_(-0x1.29c6cec6860250c0db3c6f8b8962p+8), C_(0x1.1c64b27b4c107ca71ade24985867p+8), C_(-0x1.156985f5c8bce6de73bf23e5601fp+8), C_(0x1.ef2b60fc7ce315a6b8de2d939461p+7), C_(-0x1.84734ae811782beee80a7af9899ep+7), C_(0x1.20e874beb6697ebef627268d4461p+7), C_(-0x1.93d454c0120c50c5e5f45ca0c342p+6), C_(0x1.e8c645d5034483f58d32c0b8709p+5), C_(-0x1.0a8b2e2c06173020781b6687242cp+5), C_(0x1.14ef6d11452bbb05715fcae8f362p+4), C_(-0x1.bab6f3f4dbb55284f9925c8a3ab9p+2), C_(0x1.4e6aaf12e910db6611cb145f554fp+0), C_(0x1.e57ecc0ee730e09fd58c293b9a01p-4), C_(-0x1.0f174cea8c305d809bddd1a456bfp-4), C_(0x1.a1f2dc12ec55c96d12f54fd03177p-12), C_(0x1.4002914419fbb27ad65f422d91cep-15), C_(-0x1.6c7e600f14b10472b7579cd8544fp-26), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d2f4e044749b4e7a1c71b105042dp+0), C_(-0x1.e196df480fe71bea5cbbf6f938ep+3), C_(0x1.ab061d20276f0750e2a72080d7a9p+5), C_(-0x1.a7b259e6037ebf7c8e2adb89e41bp+6), C_(0x1.04d3977e22f60f45b515e3221088p+7), C_(-0x1.c308c46a51aa08f31731ad9b7844p+6), C_(0x1.759cb70549060301bbf1ea932595p+6), C_(-0x1.73a4db524ebc2efdc465e09da17dp+6), C_(0x1.4d02e405c663ff8abf63f28cd74p+6), C_(-0x1.c4dfc682dd95df4b0a54f646c034p+5), C_(0x1.217c835a844bf319c913aad35977p+5), C_(-0x1.9d3e5e5e092523c01057547d3214p+4), C_(0x1.eced01c912f6c17b1d536b46140dp+3), C_(-0x1.ab15772777a65a90ae2d7ecf56cbp+2), C_(0x1.780b7892927c5280dd5bee9ee8edp+1), C_(-0x1.59e4e79f9d38488dc3c59417b41ap+0), C_(0x1.04013ac7f90eca1ecf033aafa30cp-2), C_(0x1.63e903ad632e7f30307040928615p-4), C_(-0x1.26b339b06c46eff13165e32f7c85p-5), C_(0x1.1fc083a0e2c35a300d5c6fbf948ep-10), C_(0x1.9c18e59aa15ab3ece464b6468819p-15), C_(-0x1.d792baac952f2e4df120dee003e6p-25), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.19eec26520f7247ef7c6a243923bp-1), C_(-0x1.249f95db3c6a85ee06007305aedcp+2), C_(0x1.0297dba66cdd344c6014ab433b38p+4), C_(-0x1.f4e8dc0eb78aa7eff1fa727c9c71p+4), C_(0x1.1efd1b3c60e0b36de4fe266b9d8ap+5), C_(-0x1.a397a05a5f774f4ee2078a58f21cp+4), C_(0x1.239464bf9e82c4fc4fdd79af7e82p+4), C_(-0x1.3946d065739beaad7a01650a25b9p+4), C_(0x1.2898316e66a7f2a70e1a6a12eca5p+4), C_(-0x1.5bb8e2c4642782930886e32d2ea4p+3), C_(0x1.68255c99ba4c6b07d82156e3f9d9p+2), C_(-0x1.21aae7ae7df31c29928804e58d84p+2), C_(0x1.64fab317448fb0474311942daf3fp+1), C_(-0x1.75b64c97e09686a5bb55f9818d82p-1), C_(0x1.22ff2ac4d8b9c4ff1397fddfa477p-3), C_(-0x1.07ed621dcab476dea8f9bcc8470ap-3), C_(-0x1.4a01e6ee0860d89681b645bb0864p-6), C_(0x1.2e7cdbbc900312ead84b8d7e757cp-4), C_(-0x1.b7f6865bae122ce58cd5b4105bcap-6), C_(0x1.17b65cad3d540e056708b80ca432p-9), C_(0x1.910e0462410b5b96ed51c4c46ef3p-14), C_(-0x1.cf434a44d45d4684dfb9a827c309p-23), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a6c51bc471a3098c7c3ba4b2e396p-5), C_(-0x1.b8315371d42a542d22b52e160edap-2), C_(0x1.89e13c889a74c808a95f3ae5db18p+0), C_(-0x1.8aa497719f070f6dc765c7af4f82p+1), C_(0x1.eb2b7ee2bc88d2eef92b780b6136p+1), C_(-0x1.a91739cfcb4374adc78a339981b3p+1), C_(0x1.4e87023b22be1f061884b91ff276p+1), C_(-0x1.31bb74af8ae4dfa54f812e36b5bep+1), C_(0x1.0e1263d4463c809bd8442e6ab9d2p+1), C_(-0x1.9cd0db1b42b96cb6927f614da713p+0), C_(0x1.3cec213a53551ad84004d758bdadp+0), C_(-0x1.daf35f59b2441d717c1690c25188p-1), C_(0x1.329c321d7ff6b77198e76070d6c7p-1), C_(-0x1.8936ae8cb907bb56ce7124a40ebp-2), C_(0x1.00dee0f339229a14bdfc063bfb91p-2), C_(-0x1.07bd180d959690eaf41df5a4ee44p-3), C_(0x1.cec01fe9b05f624125be250b50a9p-5), C_(-0x1.e6ef9d5209f879f2bf7a379cfa32p-6), C_(0x1.8f4f47250e3a4f324676c24519f5p-7), C_(-0x1.e72d4f4950c89aa59da6edc504bdp-10), C_(-0x1.e19176d7ba69146eb048e9181ac9p-14), C_(0x1.1b79fa688c946fc4993e527c8905p-21), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.749078c0867a9a724454443e75a7p-9), C_(0x1.8ae6a79b4938fbd909b199343609p-3), C_(0x1.d008898983913d9bf1d194ac98f7p-1), C_(-0x1.20e16d5539e3f25296b1c6880b53p-4), C_(-0x1.f688bd1280c70194203f744266d5p-5), C_(0x1.2fca4301354a4e285e82fc4b6183p-5), C_(-0x1.505c64431d7a6f1e36954a7c80cp-12), C_(-0x1.0145189baf0142f2a8862b8be415p-6), C_(0x1.c908becee5a6a6fcccc95605355fp-7), C_(-0x1.beac12be1e7de0939dd15f031644p-8), C_(0x1.0006a916adee342c6b2792c6bd7ep-9), C_(-0x1.d4cc286b09e13557f3e87a0f9caep-13), C_(-0x1.a08b65bbb598677114fddb7b661ep-15), C_(0x1.5f413ab3a7eb94dcb396b2657edap-16), C_(-0x1.5c34d16af592037a11107a487b39p-20), C_(-0x1.2dc4454eebde3379c7645c4ba87ep-21), C_(0x1.74f33a2ccbc6518fcdedc7d5aa01p-24), C_(0x1.ddb5df0a412fd407d061c573b81ep-29), C_(-0x1.07969b3a158bd160a5cdad0ece81p-32), C_(0x1.2c5958b74836c10a9059d0bfc767p-38), C_(0x1.52fae6e83091fa686190e11a0d2cp-45), C_(-0x1.d83da475a639c307966abb294b63p-53), C_(0x1.1342e56840ec19da921d2c329c6fp-65), C_(0x1.aa25edf8f64fee132e1b30933b5p-86), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.23923550f457ca7814b0bb3fd653p-6), C_(0x1.0c0767795d12ae5d156ec5cf4423p-1), C_(0x1.3373be839b47c40b1d36ec3e47ecp-2), C_(-0x1.856d7e6b6468c2deff8342e75baep+0), C_(0x1.22d30ac28dd9c9a5de5413538cd2p+0), C_(-0x1.72e38df054a23a8a5ebabc499005p-1), C_(0x1.8e439b194a1c16626ebcbea59c81p-2), C_(-0x1.3bc2524066e83eb2d5b3ff97e1edp-3), C_(0x1.1bc8f6e41059663daa79bf4a8b55p-5), C_(0x1.2884461caa1e3207b6de1334a7c9p-11), C_(-0x1.db22a9804aa1133069d05b96cb0fp-10), C_(-0x1.3482dca87f01c45e946a258c3e06p-11), C_(0x1.3285223dae55992a1d57ada1533cp-11), C_(-0x1.bbf1c4306d1a37f02d18135ce323p-14), C_(-0x1.17497a4dcd44ffdc92c6ebd1a068p-16), C_(0x1.bebec0cbd1f99371a7867cbe3fbap-18), C_(-0x1.bc40d833ef3598561d72cdf89bb4p-22), C_(0x1.6454c6cebdf97f43adbbdee1eeb8p-26), C_(0x1.5fce040bf0fa22a0bb7f52a52e7bp-29), C_(-0x1.1241493325c926f92e656210ed16p-33), C_(-0x1.ce70ab06ee7eb593175a3e65f68ep-41), C_(0x1.8616f674ef405eeabf053da9c72dp-48), C_(-0x1.7b38ad7c07a3a058098173d3a8bcp-60), C_(-0x1.258ba4702de85ac45e001504a52p-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7e9e99d93265e1ecb27f1a82e385p-4), C_(0x1.e81e73bf7d4e6759d9f3db761257p-1), C_(-0x1.368292c7be10e513188a104c5c4ap+1), C_(0x1.a1c192a939b9674ffcca9b2f1e48p+0), C_(-0x1.58e6f9045a40dd2a472104dd0f2ep-2), C_(0x1.2f82100ba4f2879faa0ab7316342p-2), C_(-0x1.f8fd9be6cc910f763e95aa8aafdap-2), C_(0x1.017de77081fc30f9ad09eddaf43dp-1), C_(-0x1.5831ad14642112326c714ae42463p-2), C_(0x1.30d718554c4cabcfafc1434f8a7fp-3), C_(-0x1.30a6075105b3aa4d5336fc1950e8p-5), C_(-0x1.632f9e9eb99fc711faf42ce203b1p-11), C_(0x1.1cbed37ba4dbd96c225d81054e88p-8), C_(-0x1.77d86fa7164bfc8c126a64816ac4p-10), C_(0x1.50ec238da00966f5e3d28fc9265ep-14), C_(0x1.f99c3b6dd2e633388ada35d1bfe8p-15), C_(-0x1.8453f2cbc2d996b7775a123e9384p-17), C_(-0x1.b4056601f4bff8b5e7d36857cb2ap-23), C_(0x1.4c2776a5f116e1d85dd046bd9786p-24), C_(-0x1.287daf168a219aa1132a37934711p-29), C_(-0x1.b00a66e2af603b8210a104b463bdp-36), C_(0x1.401eb1fad689de068ef9a337dfddp-42), C_(-0x1.71528144e6954a34804ddc8b7672p-54), C_(-0x1.1de10823e626bbef4adf3610f4fep-72), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.95e033565cd465e59fc64a849ff5p-2), C_(0x1.e7908dd5753c97550b1b562a02c1p-3), C_(-0x1.293799fcf6c8da1f93fe2d057e3ap+2), C_(0x1.36cc467b08bf7d8a89d5be8f934fp+3), C_(-0x1.4335983e135774c5e5156a45190ap+3), C_(0x1.9c4d14b5414867b3e2c99a21a031p+2), C_(-0x1.ef81d85b23a01ac83af86d64d1abp+0), C_(-0x1.2378e73c6b10a2f7957b04478d3fp+0), C_(0x1.c6e27151761e3e586f5403563b06p+0), C_(-0x1.c857e67243153a965a648f8e6a77p-1), C_(0x1.3531afa42b77f4c754018d3dff11p-8), C_(0x1.05f57c1a6464d742d9d2e202da9bp-2), C_(-0x1.38a2db882124dfc4e44179ad6816p-3), C_(0x1.35c4a5041d9b9456d2520e65bc23p-5), C_(-0x1.fddc3c9f813d6aef1f4f22d0ffb3p-14), C_(-0x1.2653a0321997d1fa4ad992783a03p-9), C_(0x1.ec5d6f7ab50c177dc61e0a189fcdp-12), C_(-0x1.dc01f8633f4c61396f200866480ap-17), C_(-0x1.379717b64ca37d0f86a74f664124p-18), C_(0x1.7e5cfdc9a1b17dce328c7c0b5cf9p-23), C_(0x1.a124166c5786174e1b984a588c59p-29), C_(-0x1.4171311c3a7b2623f4df8ab8200ep-35), C_(0x1.65f402b77f1ab227d7a791609ed8p-46), C_(0x1.15123cc4efb60d3af1736012e615p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.4c5d516dd5340d0879832abfae77p+0), C_(-0x1.5d2571cda5543923016a360261d3p+2), C_(0x1.24b0f03522629e31e5a0ddf9b0acp+3), C_(-0x1.39e0f8d13e8db1f029ce62587cecp+3), C_(0x1.f006cc927be5328f1a33d6aed069p+3), C_(-0x1.0ce2ffa4646117df99ed92fff69cp+5), C_(0x1.b8b8afcf323d00e8ad39d1ccb61dp+5), C_(-0x1.e6925570e3f510211d732b9179c8p+5), C_(0x1.503102590c0b7b7ae2742f43b1bp+5), C_(-0x1.6d86add093f074bc432a452b5189p+3), C_(-0x1.35b5dc1025f2d34a60aa7bf9f93dp+3), C_(0x1.a6237c764b4a28340b8488817371p+3), C_(-0x1.cda455c3ae3929d25c3c5a324857p+2), C_(0x1.d5a02bb93708a320124accef7fd1p+0), C_(0x1.ecd4c4adc075fe2457753c0ae29ap-5), C_(-0x1.660ee59df078b432fb4f889b38bfp-3), C_(0x1.5158e51b27e5dbfe89f577f9dcaep-5), C_(-0x1.73814bfd57b681fa89fa6df52a98p-10), C_(-0x1.23460c48f636fa706d007acb283p-11), C_(0x1.fa353cdebaaaaa09ad0c40e9cfcp-16), C_(0x1.19c5738584246e6431d3352c6ae1p-21), C_(-0x1.4bb4308ed51fff3108f30cb71f7ep-27), C_(0x1.fc9a1f4f09858f536f1a575d9e29p-38), C_(0x1.89a8b7b9d28d1d71597812aa68c7p-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a35157d8dba56b3359c55dbb3245p+1), C_(-0x1.5a1bc35a1cc0dbb69c71add31e17p+4), C_(0x1.fa0a0878d9a933860f511fa37af4p+5), C_(-0x1.a68f6523a82701663e04e3ed3779p+6), C_(0x1.98403a971e63162a02dd92c33da9p+6), C_(-0x1.03810e60e02049d57e6cc9d05d6p+5), C_(-0x1.14faaec76846550eede58601f0cdp+6), C_(0x1.3d735b94c105436aa6c6accd08c9p+7), C_(-0x1.cdbd7de801407d716cbc38649987p+7), C_(0x1.20043470ad456af43bde8d7a0984p+8), C_(-0x1.2591e882d85cd18b0dca9775a589p+8), C_(0x1.b621996a63c17e6687cb0aeb2864p+7), C_(-0x1.a875ba068d8449d487f82d8f98a2p+6), C_(0x1.85c7d166f26b7783d793e4b535e5p+4), C_(0x1.1c0e0d6b929f95b9e528987efc33p+2), C_(-0x1.36efc345fd87e7f12a7cd8cf55f7p+2), C_(0x1.3e3f5c2c93c347939cad28d35ff2p+0), C_(-0x1.bffc3922a312894449dea079023bp-5), C_(-0x1.75f52c4bce3944c6d40bd8c68e83p-6), C_(0x1.dea5b49d2b299f2f3407a959506bp-10), C_(0x1.10aa3eff5f8aac0902d8bf4b6addp-15), C_(-0x1.ea6ed6c321e753c1b3e92351b813p-21), C_(0x1.089ab261bfe1c8b7f19aebdff953p-30), C_(0x1.9990a3735f2b8137827c03e7b5fp-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5d159c98a090a206b1f5a487328bp+2), C_(-0x1.54873e7e1b3d210625d277e6898dp+5), C_(0x1.2c245e185ac8b14c7baac4033f4ap+7), C_(-0x1.416f5cc6c22c1fc04eeda9dfb493p+8), C_(0x1.e67e2b7f933044475571e632011ap+8), C_(-0x1.298ee57db6ed5fd4bacad0de9695p+9), C_(0x1.48ee3d90a4e34a8f4d18f98b7344p+9), C_(-0x1.4e6b4521eb7a56c1ef75797e43fdp+9), C_(0x1.2782e95d7bf9f5fc360d37ee013bp+9), C_(-0x1.bb493883e544d446bc2b8bcc693p+8), C_(0x1.25dfd4b9fa45afe8f2d50abdb77ep+8), C_(-0x1.575e0c206b7ee6818931b6231d56p+7), C_(0x1.1c028f2725fce675841ea5e425e4p+6), C_(-0x1.08a1fe0ac6819f96e8258a0368bp+2), C_(-0x1.12ed1d6ca77301d9871c862435c4p+4), C_(0x1.66791e904ad3b41e47b43fe289f8p+3), C_(-0x1.7aa9733036515afd48134b03fe32p+1), C_(0x1.41600caa02955d88aadf08f58823p-3), C_(0x1.275514f436a31e564b7d019a87cbp-4), C_(-0x1.29373f56ac1095884f483f83febcp-7), C_(-0x1.51ea7d9f345040b9bbf67fd2c9c4p-13), C_(0x1.deb156b08b87ef0592d66bd4c9c7p-18), C_(-0x1.6e30fae8c34ed8366ddfb0cc8561p-27), C_(-0x1.1b57abb7d7f1ba81ca336dd9e4d6p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d4fe27a0835ae1a04e0830be24cp+2), C_(-0x1.ecb0f32ca76fb494d571b0a3e338p+5), C_(0x1.c6da62a20cd0a85f32742b3dd231p+7), C_(-0x1.e3622dd5ba05d80a963a5e3e0d7dp+8), C_(0x1.49508717a90e836846bfe76665d8p+9), C_(-0x1.3d934aacf56d0a27027f03a0039p+9), C_(0x1.068600d74e1c90df9e5939a69755p+9), C_(-0x1.bb4eb52dbc23c8aa9dac0b1ae5b9p+8), C_(0x1.2c2d3c048caae8b4e7ebc3a10a9fp+8), C_(-0x1.6a6f07f5d07dd28cc71310327c39p+5), C_(-0x1.48c0f7b3bed9dd4e2bcfc6df9159p+7), C_(0x1.bce28601020e5546efe49f4f2facp+7), C_(-0x1.9e035ea535c3aebdf12735df11cep+7), C_(0x1.737017c34f7deef2722c9d811907p+7), C_(-0x1.15bd065f2789c251ed52867c6e81p+7), C_(0x1.1609d2e86de1f46bc02dc6e0a8fcp+6), C_(-0x1.30b382548235fc08ce2a6ea99e65p+4), C_(0x1.34c266d274d020226722064f6a4ap+0), C_(0x1.56d14dbd1c0ef8dc071f1d5be26fp-1), C_(-0x1.f82518456ddfa0a1ea7fb11fa704p-4), C_(-0x1.1d5d333a03734067f69cdf063e2dp-9), C_(0x1.599f88826e1df7529e25322303e3p-13), C_(-0x1.742b04eba227022dc2784e1aeb19p-22), C_(-0x1.1fd835e2f3ac373e68a1719919f7p-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6f91b1fb16e463903f2417b8bc33p+2), C_(-0x1.8fef11e8059ceda062deb12c9387p+5), C_(0x1.809c444472a8d8415a2c7a9afbefp+7), C_(-0x1.b10bf090c92b5336357cfbd2f863p+8), C_(0x1.45258188f71468e863f92b55998cp+9), C_(-0x1.7231afc08bd276307932b219a0cfp+9), C_(0x1.7af82162ac359965f69e6fcab693p+9), C_(-0x1.823e9f8992b59fc66e1876f1aa68p+9), C_(0x1.6f4bc124eb7dc2e04c11a11579edp+9), C_(-0x1.32f291524b4fc819caccc41f919dp+9), C_(0x1.d856007cb8fa074ef0836c00fb93p+8), C_(-0x1.59b2f057a74e4aae3ebb4a35f68fp+8), C_(0x1.c4898ffe6b603cfd7a5fa627ad77p+7), C_(-0x1.01b04bb5c7e4ece20624945e7d4ap+7), C_(0x1.0ee550f2b46fb0067dbfbe5f34b2p+6), C_(-0x1.f149829700499105abd07323449cp+4), C_(0x1.21413698e7cf1b5b76cf50d81657p+3), C_(-0x1.1e358290df39caefe5b52d405e07p-2), C_(-0x1.54f12799790c9591a372397a1538p-1), C_(0x1.1dedd290f907f8d2a852f01bdfd7p-3), C_(0x1.2b8db385d6eeb017f64738645db6p-10), C_(-0x1.7cd67d6099898e46f355480e2303p-12), C_(0x1.c1758243d6f68f11163695671c33p-21), C_(0x1.5b5402fbe8db7e6e4a3332e846cap-33), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e00f201ca9b47bec13b3bceeec35p+1), C_(-0x1.09aad588fc6e1d2e5e320a1b6965p+5), C_(0x1.0083b1ed3add1dfc189ab7aaac2p+7), C_(-0x1.1b01639f15a47195db844f5df4eap+8), C_(0x1.8e74c5b415b4c982c62a28306ab1p+8), C_(-0x1.907a858da198db5b4a86eef21cd8p+8), C_(0x1.68e4a68143eb6280f78231820634p+8), C_(-0x1.685dfe59eb94f38e35f487b91dc1p+8), C_(0x1.592f39b72049a36e7924f8b1defp+8), C_(-0x1.09589acf597f567d3772f2b218afp+8), C_(0x1.658b66c44d2d9f09118af69ddd27p+7), C_(-0x1.f90c71880a91658c0d9a38574dffp+6), C_(0x1.49a9a7009f2b267b39bab54a8a34p+6), C_(-0x1.441338caa52cfa0e2a27d488fb3dp+5), C_(0x1.0b7b2a297fde14bc6faf3e06bf71p+4), C_(-0x1.d98372b1c68d3f52be82670d6ee1p+2), C_(0x1.f43ec1f2a32806088746ff9dc715p+0), C_(0x1.6165b77555fca80d9c5c14948139p-1), C_(-0x1.4f8a8171bb08fcb9ccd7f4688dddp-1), C_(0x1.267683e93d2b771765dfc5bfe73cp-3), C_(-0x1.8ddc624d415c8d8d9889292068a5p-9), C_(-0x1.979cae945ae1031f8b5a56752269p-11), C_(0x1.95627b187fdb196e7b60fd3122a7p-20), C_(0x1.38bcd286c35de60d5fb4c84a2f35p-31), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ddc9914b8fce26e89a34c64d6d6p+0), C_(-0x1.0aa6a6fe4749ff9a53419e5cb74fp+4), C_(0x1.ffd30a30f104e3ad2ade2b583021p+5), C_(-0x1.1076bbdb4cf7527cd039bd2ee863p+7), C_(0x1.5b314fd5bd8427278ea0f14850c8p+7), C_(-0x1.15e629a2f07ab3b285fb28d62142p+7), C_(0x1.73ecdaa7dbcd11927e445f4fc04ap+6), C_(-0x1.7ea4991281a803e96d951a02ad23p+6), C_(0x1.92fe5087093b614dba0f2e58af18p+6), C_(-0x1.e50ce86c3eca30ad8c357a5bc172p+5), C_(0x1.23fe36ce5250d05c3006a508171cp+4), C_(-0x1.1183a5ac74636a4f4f8077863f2cp+3), C_(0x1.325da71616787b1a97cd6b487bbp+2), C_(0x1.b5b93d37eb78f2e235cc59568f84p+2), C_(-0x1.6174cc292a977e8769fcc13572c1p+3), C_(0x1.b8e78e1a9ada492b4dd6fe85e7f5p+2), C_(-0x1.ffc6e54f09b8a6376ab9c26e41bp+1), C_(0x1.807b43d233e13293cd8f6f610b94p+1), C_(-0x1.949effe4fd5f10b6f0bb69f9fc41p+0), C_(0x1.99c706ee33d33292c4de755a9043p-2), C_(-0x1.8b4255eb2ab52df50469eaf1f575p-6), C_(-0x1.25fbde4ae0e29153ac78daabb6bap-8), C_(0x1.a2ffd5a58a3e625ad5baf547df1dp-17), C_(0x1.4225e5d67d6a903058f380dcef3ap-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.82555f0fca681c9ced300bba3465p-2), C_(-0x1.b108ac4bd9d5de90a612fa91bba4p+1), C_(0x1.a3af9f5e28533d44a218819eab18p+3), C_(-0x1.c92e2a69bebea1255ad98910de81p+4), C_(0x1.336156f19a3eab19184560490c7ep+5), C_(-0x1.154d20c532d37d99d550b554251fp+5), C_(0x1.af95c6a7f034f7267500247c3a39p+4), C_(-0x1.a382ed435f8ed2216764cb0a372p+4), C_(0x1.a5a57db59b67be50825ea51ac179p+4), C_(-0x1.48587bdb4781058d9836884c3b74p+4), C_(0x1.c6519b1cdb292e6d292e4f1f9c11p+3), C_(-0x1.64406dc5dece20ec3c4c58b87407p+3), C_(0x1.05a0da2a87dafe77cb9a54ec8326p+3), C_(-0x1.34062a3bf7c109c05654bbca487fp+2), C_(0x1.65a3327bcf1ac1cee14ebea4c8b6p+1), C_(-0x1.b27cf7ab49be37cde0f46679310bp+0), C_(0x1.a5bdc7192b9c3a20ece9060c1ba9p-1), C_(-0x1.571ac2983f85e3a6dc62f13fd384p-2), C_(0x1.31767817c6adec541d6996364d3fp-3), C_(-0x1.904f3491bf69c7251d1b40c4f69ep-5), C_(0x1.0ee4f3163f55f45905e2ddfb93a4p-8), C_(0x1.2584f1f36b43e7bbd83744e7e8bep-10), C_(-0x1.373cf584c03ee906a072cfcde9b5p-17), C_(-0x1.db60a068c3377c744925f382f6d8p-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8dbb03fad2c2ff4e565f682fc387p-5), C_(-0x1.bebdc5d3b23911ed145126163ba8p-2), C_(0x1.aeb7a5ea21052a1c43ba381385e3p+0), C_(-0x1.cb9851522d20abcc6f87f331e722p+1), C_(0x1.240bf59871b997fc41c935dfbef9p+2), C_(-0x1.cab7cf1ed537e0d17c393ba768f6p+1), C_(0x1.1fd4543a5fd8cb1e3fd209bf00ffp+1), C_(-0x1.1ce9744c1c9756de9b809c9cc5acp+1), C_(0x1.3bab08bd76344b447fe47382a836p+1), C_(-0x1.c40e7b4e77556f5ef8447dfa81f7p+0), C_(0x1.feadc8c7ce87a8fc67e2732ba34ap-1), C_(-0x1.a643a47d84b4da70d0fb0b9b5ca8p-1), C_(0x1.543b964e0f03a3a71ec489e8760ap-1), C_(-0x1.577aa576ffa64efb7d0e9a7c6b39p-2), C_(0x1.499f6f7a97a22bd1178c8279f046p-3), C_(-0x1.d5a15151b901635be5a327439552p-4), C_(0x1.d4c5badb46707713b03f6550ccfep-5), C_(-0x1.094f5215690db085443c42ab246bp-6), C_(0x1.cd0926fb9e142792dd84020c8a8bp-8), C_(-0x1.b2091c2c73dd02f84cb3796bc045p-9), C_(0x1.fdc7350edfadd24f5fb7a32829d8p-13), C_(0x1.4af17513fc3a876960b7cf51425ap-13), C_(-0x1.fd199a3cefa31b76bcac261239c5p-19), C_(-0x1.7fa406e41ed65db974ed315201c3p-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2e3c0bb3f3ad4d49ee7e86ec562p-10), C_(0x1.d73cdc4f17147d4ff78a1eaebc89p-4), C_(0x1.980f074dbd462038712882b2223p-1), C_(0x1.0b8da7807c2738b0ef8a21bd41d9p-2), C_(-0x1.381b88314120b0755faac9b6a208p-2), C_(0x1.a64053bd4da4144d5c6645aafa5p-3), C_(-0x1.be6cb26620f84322f5bc9ad124p-4), C_(0x1.5369f32b472a8bf80c2615157588p-5), C_(-0x1.e553bfb83c481ee1c85b1021810cp-8), C_(-0x1.5b97376b07916025b5f5ed690f77p-9), C_(0x1.3ad93e070eb79f317793c09c0451p-9), C_(-0x1.6c8658d1b206dd40e11227faae77p-11), C_(0x1.421437e7b839d2e408af08229906p-16), C_(0x1.359cb55b7d335b5bc8ff9070d38p-15), C_(-0x1.16b1cde08937e6520514fc007dd3p-18), C_(-0x1.1e470298289ae452c29404b9c746p-19), C_(0x1.16b7d7c52ecb6bf5c9c270fe3977p-21), C_(-0x1.2a9017a9058ec8631bfea23cf0f2p-27), C_(-0x1.e6603a12c62203e481a6f751bb0fp-29), C_(0x1.ad635a5532ad9d7f9b990f3258b1p-33), C_(-0x1.0b7166f3d598041c11f82d418c5ep-37), C_(-0x1.2dcc8d3c8b0cf63074ab4d9fba6ep-43), C_(0x1.994c7452dcd30c07dade8e0a0b5bp-50), C_(0x1.d3e7db27a70ee63bd0dc60e06dc1p-60), C_(-0x1.ad34c0383fa643c903234154af78p-72), C_(0x1.c6fd0b1a8d6a2b5f9f47659e9cb5p-94), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ffe6a833f41d1e41c335a1d66225p-8), C_(0x1.6878956519ce3162ba29291a8504p-2), C_(0x1.4f6222726462315c1311b1bd0b69p-1), C_(-0x1.9d7a4f00f9dc035ff30a13b3dd54p+0), C_(0x1.ee1a7236f71e3afe8c9241dc280bp-1), C_(-0x1.3a4c3d150c11dd01e59680a43c1ap-1), C_(0x1.a5124e1ab47a907fdd8a56cf5fd2p-2), C_(-0x1.fd47140509eb33a71307cdb49b3fp-3), C_(0x1.efeb8355fd2f814144fb4db02bdbp-4), C_(-0x1.695e5e5e49cf847101e5144b6fefp-5), C_(0x1.73cae05387f642ba0d652b2dbcabp-7), C_(-0x1.fa774911ba2d3bb25d61e69c8c8ep-10), C_(0x1.13b07ddddb3b836ee57d12843693p-13), C_(0x1.7cb11c0b4280a9d8a95e4eb20e72p-14), C_(-0x1.d2cbfff6e2a582bd1061aa2f380bp-15), C_(0x1.74388c9fd28e69e7d9f0c5af3fddp-17), C_(0x1.21ff895bfb5f2915922793fd222dp-21), C_(-0x1.156307b5c128c175f7e3a71477b9p-22), C_(-0x1.19b91bff8bef4f88f1ed76cce8eap-25), C_(0x1.f7d83e4d41c76f94d46210e4d1f2p-31), C_(0x1.5090626b206a430059df75028168p-34), C_(-0x1.405683426ad010e44f0a98cc929p-40), C_(0x1.6ac079eed130df81302e2b26c482p-46), C_(-0x1.9a49f0637a3b64a9eb35bd52aa23p-55), C_(-0x1.88bc66cc087f1d558950f224d6c9p-67), C_(0x1.a0541eb1bdceab613773d4dc3dd7p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.70e38d13c6dccf6333417be4b4fbp-5), C_(0x1.98429094e12d1953c234a36b137bp-1), C_(-0x1.5a23aee5cfcf330386719e085aa1p+0), C_(-0x1.ca3a85e30ebf60ba5eccc5b7b84bp-2), C_(0x1.f2911f6caea6ac421bc7b6d2ce04p+0), C_(-0x1.902df5acb98563fb6c85941263b7p+0), C_(0x1.6e5d8a32fe3ae7b3c23b4e6e9c7ap-1), C_(-0x1.7cd7499a11b87c3bc4909e0bdb58p-5), C_(-0x1.cb51389df1436d54630b5c4050fbp-3), C_(0x1.8970fdea96db48b13c52294d029p-3), C_(-0x1.2e3ba43116d4ee1d14ccd7ef1eb6p-4), C_(0x1.a437288ed51ab324c667ecc7c439p-9), C_(0x1.5d8afaeb5ec2a57500ea441b58aap-7), C_(-0x1.3f213a25a4c39a4ee9f8ca7fc5f5p-8), C_(0x1.438df66495fed0569b1e6607263bp-11), C_(0x1.92aacb344e1aac45946a6dd95b1dp-13), C_(-0x1.4a2a2b6937dca67c2fb96409eaabp-14), C_(0x1.061494c076ea4c2b5c794f2371b4p-17), C_(0x1.1c61500cd5ff603bf7260846f007p-21), C_(-0x1.fed404b96c72e77fac42699e644dp-24), C_(0x1.9900fa8d5cb81723cdb543a2521ap-29), C_(0x1.4b71c6cbb7be353ab93ac21700e3p-33), C_(-0x1.f4e20f23251aa513b13eb0ad0eafp-40), C_(-0x1.ae764159a5bb5c8d340066c07578p-50), C_(0x1.0753e4c918ed6b59ce15c4a9365bp-59), C_(-0x1.1725d8c4676c38ff70e1cc359512p-79), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.b6406454732d4d440405d44a6a49p-3), C_(0x1.b949541f458cd808c01c6f4442bcp-1), C_(-0x1.49bc84198d8eee0e1769477dd34dp+2), C_(0x1.255157167a5528a3714c438e2bbbp+3), C_(-0x1.254591e8b6e06babda61e0b5bd92p+3), C_(0x1.bfdd01aa9e6916b30d7fb866cb4dp+2), C_(-0x1.258cb0e12f407e788c8d24c043p+2), C_(0x1.244b687910817f75269b9b13d0aap+1), C_(-0x1.76e9c86768fd81ae0140e512f91dp-1), C_(0x1.2db90e1b7e223907d65e1858ad53p-3), C_(-0x1.adc00aab7f786622c376bd60c25fp-4), C_(0x1.077b01cdc29a9bffc55813096431p-3), C_(-0x1.4e1bd3d7c8106ffe51d90e297c64p-4), C_(0x1.a8b1719f76969f8051acdf38ae9p-6), C_(-0x1.1b67a8fdd5d395a5e1003bc2df39p-9), C_(-0x1.5aa2219e8b072017d97056f432f5p-10), C_(0x1.0c296ebe05b6e9c7cf2917908081p-11), C_(-0x1.315112d6e2648d659715640aac77p-14), C_(-0x1.aa34a64782e3fdc563417212e36cp-23), C_(0x1.718ac2125512de66d6a9b5d79809p-20), C_(-0x1.4ed202350e6d4103a23efe811aep-25), C_(-0x1.6a2c3e7b115c942fffc924e2aa83p-29), C_(0x1.03cb1bd946e2daf6230de1902b89p-35), C_(0x1.d2ce73e99c2943d672b79f3df3dfp-46), C_(-0x1.110d7f1b0bfbfc4b48ffe175513cp-54), C_(0x1.2175be08d4af39d29c43830b5338p-73), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9bd3bc24739608dd1ea0727f797p-1), C_(-0x1.218b20c923a72ab49d783c3c2182p+1), C_(-0x1.8f073ee2485429a822c3456748ddp-2), C_(0x1.10368c3ad14ec0121ffa10beccc4p+3), C_(-0x1.6e5fd027a16b3fa71b0c68881f6dp+3), C_(-0x1.fee6b19288528fc99125553bcb88p-2), C_(0x1.5dae0c64ec100c07cb64acfb530ap+4), C_(-0x1.253938fa65f9cdca9dcd99a2d96bp+5), C_(0x1.0846ca351ee337bf1cde15f6a892p+5), C_(-0x1.d3379cfd6d392ab0067070d38b2ap+3), C_(-0x1.bc1cbd5de053b1b3e6030cd2eb44p+1), C_(0x1.49e86d68d4cf8c86d82167732746p+3), C_(-0x1.e4ade08c4a6c2c8507d0731ef456p+2), C_(0x1.651f390634956dee37faca7ade61p+1), C_(-0x1.14e32e1f9b6bac3d6ef9b665a8dep-2), C_(-0x1.c20b1d287136abbd5724af54edd7p-3), C_(0x1.9dc73570ee73f3a5d7e75adc1efap-4), C_(-0x1.dbb9ebdd9c09deccb1020147719ep-7), C_(-0x1.c7f5c1ec60f696f9a40d5c2f13dep-11), C_(0x1.a5fc856e52fad70c72c88b43b17bp-12), C_(-0x1.07f65daa0049b089e54b5e492044p-16), C_(-0x1.0e378f07aff0a4003d557ea13ebap-20), C_(0x1.69bc58d5ec0ccbef38bec2915824p-26), C_(0x1.872aa1bcf368769fc21e287db36p-36), C_(-0x1.7b84969608016d06bfce8c098437p-44), C_(0x1.92548cc9b5b71c86f11e26fc3a07p-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.29b15e8e05f4922e7d4e47048a9cp+1), C_(-0x1.cfd365d6145278198eca9c82d9f8p+3), C_(0x1.440caad9c12360807dafb3bad1d1p+5), C_(-0x1.116de9d813b38a3407c462c9c8afp+6), C_(0x1.3b639c503b3cf7fe4e226236b434p+6), C_(-0x1.0040f57e975e1a258b9875fe1f17p+6), C_(0x1.e6fde6a95ce32902224ee9a0f717p+4), C_(0x1.5c1e9e155aab7b67b6f0684e8054p+3), C_(-0x1.b1e5da7957b3c8fabda1cfa1992fp+5), C_(0x1.7d1f138d16b9d31aa28298c6d585p+6), C_(-0x1.d6f4cad7bdd82bc575e84a0ae447p+6), C_(0x1.9fd808c31038fd9d9f9820868c69p+6), C_(-0x1.ecec6e1a57ab3b47a08d37ee9238p+5), C_(0x1.43fff7220eba3de58880aab6571cp+4), C_(0x1.5e941cd01c024910420637b6b61bp-2), C_(-0x1.d2a0789936f63c584facf37b3e67p+1), C_(0x1.940e89f9fbe3b90fa47d360fd472p+0), C_(-0x1.f62a7689777aabb4ab21abcf7e27p-3), C_(-0x1.2b3b3b35a204159ed02721cadaafp-6), C_(0x1.3de2ba1c1b05528a92ffeeb8fc2ep-7), C_(-0x1.21cbeea2dd955597cbff120c27ccp-11), C_(-0x1.2150f65158193f62d7d7f8ca1f69p-15), C_(0x1.159bf889454c6b38325ea0bd0aa7p-20), C_(0x1.b00f4f96ce85167dd0220db19d66p-30), C_(-0x1.21e8e13c855c01e5c446a0ad86p-37), C_(0x1.33590911079747fc32e0ebbb9924p-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3069c9b572d786eb96d929d90cddp+2), C_(-0x1.2e376983f6cb6b3abd68459b0db9p+5), C_(0x1.1366d92966ea16320047794482afp+7), C_(-0x1.37b9852173f06f1765e1fe9f84p+8), C_(0x1.ff3f2db6a15a3d87e9d7df5b42f3p+8), C_(-0x1.57d9383606e506f39f38563cb6bep+9), C_(0x1.9e8b97533b1eae6eef5ccc2c8b76p+9), C_(-0x1.c556790a27e1d4367bdf86d03f05p+9), C_(0x1.af9eb47abc08e08daae8af537da6p+9), C_(-0x1.5e3047bf51b54c2759154839c7dbp+9), C_(0x1.efd9329bb40ff6440883f8a40f82p+8), C_(-0x1.337ec090261a5db68ef9839a3fcp+8), C_(0x1.1dd7e09a266914bfb2df7819245bp+7), C_(-0x1.34f8d53391e95dda3b7a36e1f269p+4), C_(-0x1.1b6423ffa4134de5e81b13aa374dp+5), C_(0x1.038ecbdebefe39ca7724b2c5d6b5p+5), C_(-0x1.9f2073b507553852ed1a7122dc5cp+3), C_(0x1.0d3b2378aacf1f56c9dbd6033ed8p+1), C_(0x1.b93ffbdcbcfbcafb2828e4f8a1e6p-3), C_(-0x1.00284db90f95b583e4f9723dea4p-3), C_(0x1.5202609236b6be9cf16ae5695042p-7), C_(0x1.4b9320a57f2323116dd63291deebp-11), C_(-0x1.d3b085775602aad7427a1a128489p-16), C_(-0x1.e975304f420640f339ac1f2721b2p-25), C_(0x1.e5cecfa6ab7bb5421ef8c106f4f7p-32), C_(-0x1.0188e4a2f5a9df06f6875fecaac5p-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f579b17074e36836eacdf20b2124p+2), C_(-0x1.13b9cbe766166f25c9dace3616b1p+6), C_(0x1.0d0d0432bec134cd566f5783ca25p+8), C_(-0x1.309a86e68bfe9899fc0e86f2260fp+9), C_(0x1.b8e26231ea03e8ec859843dc6ce9p+9), C_(-0x1.b08b284517ec42e68106ca8a8bc1p+9), C_(0x1.3c7d2b26245024778e76cf716fbfp+9), C_(-0x1.7e7def0dd6c17f062ac5f280847p+8), C_(0x1.9c880448390e60397d83aacda54p+5), C_(0x1.dc1752cc2f2f84356ce375550f21p+8), C_(-0x1.e54a03fbbc2fa46a8399b07d254cp+9), C_(0x1.1a42e1dae56904bbcf3f8f7fa5c7p+10), C_(-0x1.f903f4a18c30e32dc6c260029f14p+9), C_(0x1.9d8db919083864fcc4e1ce713df3p+9), C_(-0x1.34173ffb143e1d9eed0dd73c6925p+9), C_(0x1.64eb3c27db564d469eb11c515c5dp+8), C_(-0x1.0b0c43171fee5929daa55b569994p+7), C_(0x1.5f0a5375d11c72dc55988338ff36p+4), C_(0x1.d8f6b9f1522f2e96a9e46aa5caf8p+1), C_(-0x1.1c75896d6d598c65080bd27d32aap+1), C_(0x1.f38ac1a749daef77915c1d44f9d7p-3), C_(0x1.f82700b4dc7274aa9bd956d7234cp-7), C_(-0x1.1306135d4672f12980f36c25a44ep-10), C_(-0x1.2dc514d6999140dbb2a21c1d56f1p-19), C_(0x1.1d494ae1d331f410d68f7a178351p-25), C_(-0x1.2e8464bcec8d40ffd77ac9bbd77ap-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e32cc25ea4da498425dfec2497a6p+2), C_(-0x1.1692ca6458ea9e38b45000f9e974p+6), C_(0x1.1fa09c1316dfb4b439ad2e78bb59p+8), C_(-0x1.615e67f0c1ccc897da6f2d005018p+9), C_(0x1.265c8c1b4b1aa4b3e36b99e4a1a9p+10), C_(-0x1.7569ed1c8210ca209e47f9d0511cp+10), C_(0x1.9e96bde5063d41cf09da3c270b93p+10), C_(-0x1.bbbe167a38d63287ecfeda29fbbep+10), C_(0x1.be080201e737d36f7e79bffa876fp+10), C_(-0x1.8f099bdabb21898e359857d34007p+10), C_(0x1.43b83815e15a62b284f0ee906572p+10), C_(-0x1.ee6ad68b3bda4ee4ba8bf16f4fabp+9), C_(0x1.58d561cb84d267ecaf633fb5a5d5p+9), C_(-0x1.a3b282a8407a310226d833dadcd5p+8), C_(0x1.c79d620ffafc0589079eea90279ap+7), C_(-0x1.bc78cb9447aa124d62b31a0a7f54p+6), C_(0x1.418e35902e32cdd0c2f21fb873ep+5), C_(-0x1.3abf360acc2f742d879127375bb2p+2), C_(-0x1.ad7bb3867b3c2b046f80e1cb0482p+1), C_(0x1.a655024ebf2fd4378622021ee814p+0), C_(-0x1.affdcd4718ba7f1a965455b89c8ep-3), C_(-0x1.8341cd6c6b0a9d48905a1ecfc91fp-7), C_(0x1.b55710d3ebf552b754ea432b16e1p-10), C_(0x1.e321738ab144873b6e4379081333p-19), C_(-0x1.c53c1373c88584f948dc39838bd8p-24), C_(0x1.e0c270acb15c5fb50466c4df9e1p-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8d1f8a32797636f661365be0e3e6p+2), C_(-0x1.d4881995a0c1ea2393ff422e453fp+5), C_(0x1.e86d414a78e33b3180b306c7fb52p+7), C_(-0x1.280027c9b087591ad85db337ae83p+9), C_(0x1.d3eb5f0b0594c2750ef02a700404p+9), C_(-0x1.0b82a55c2799ede8dec1e33e1dcdp+10), C_(0x1.07ce9f70ddb2869a658274b505f1p+10), C_(-0x1.0d7822536789d9033e70cbead7bap+10), C_(0x1.0df61d2a506b1f8fcfe72d1ca4cdp+10), C_(-0x1.c6893ac6cda6b55a4941f5e57261p+9), C_(0x1.45ac9e808978822ff4ad1899b3b8p+9), C_(-0x1.c9d686e237043dec7c04f88fd885p+8), C_(0x1.35c4c3819b30f9b6fdd5c67ec132p+8), C_(-0x1.4a58be360f4f421d89e83ecf3267p+7), C_(0x1.017559c35f7610aa1b72e5e5a83p+6), C_(-0x1.5d1ba7f13474232b92fdf4e5cb84p+4), C_(0x1.dadd49a935c8394385d3a3bdf6d5p+1), C_(0x1.87b01fd4326a3668ccbb1eed227dp+2), C_(-0x1.9ab15d247f90f9fe7c9b6b3dd567p+2), C_(0x1.46cd6a0d33a48aafbbc221eb1f48p+1), C_(-0x1.8955d7defe0d5217296739d07f07p-2), C_(-0x1.85244f4e65bbc4ccef7883bc8ba1p-7), C_(0x1.6f86d3c43106164aba39dbfe0b2fp-8), C_(0x1.1b4e3c12a74dff21568f59de83f3p-16), C_(-0x1.7914d82d3193f580c3335f167104p-21), C_(0x1.903b4b44dd8c7c0a4e702124dc3fp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.041a0a897aa28eb3a0ccade17e3cp+1), C_(-0x1.3658b5d77609e7977d3641db3a11p+4), C_(0x1.5194af04e2f848c21930873e900ap+6), C_(-0x1.c3df81f0aaf28bccb5fed61687cfp+7), C_(0x1.ad183e8db3dabe867a1b1e1d7e93p+8), C_(-0x1.3d9c782d7007715e1144e807f092p+9), C_(0x1.852da35362a6d4101e229e2b5077p+9), C_(-0x1.9cca18f6947dd0d5bed4aff692d8p+9), C_(0x1.9a6efa498935e2e3d82e1fd52122p+9), C_(-0x1.a300c2ebdd39d26204b2e2ccd8bdp+9), C_(0x1.a735477cbff1b966c8a20eaae97p+9), C_(-0x1.7a384b1c312fbe2a2f45b3550037p+9), C_(0x1.2afd886ee72d716fc638e75f48b8p+9), C_(-0x1.d0f63946d275b18c0f5c2756f025p+8), C_(0x1.6384c4a13f54dc153d90136891aap+8), C_(-0x1.d6c269ce8bf34e1953164b65a3d5p+7), C_(0x1.08982647617ff8ae60bccefbfe0fp+7), C_(-0x1.1f7e83a0711235a83bc8e025bd62p+6), C_(0x1.2a5701b5bea0dde347ec02073e97p+5), C_(-0x1.c18aa4ec1159b6d22d740e4f35cdp+3), C_(0x1.4dc13861658a8dd406eb1a845d5ap+1), C_(0x1.bd5ac19033244ca1c006b305a421p-5), C_(-0x1.1aa94170fffad7174e8899965ff8p-4), C_(-0x1.97678bd8dc9fa54b7e4c01f3ba2ap-14), C_(0x1.25b3fc23ddcf5fe31ea2281e4301p-16), C_(-0x1.381fef501218e9cc3e0863bb3cadp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.456a1d2a45d0d4e9e18e4013bda3p+0), C_(-0x1.86731e38f2c9e9bd245a6d7f6e86p+3), C_(0x1.99ddae9b5957da8932fc9013b15ep+5), C_(-0x1.ebccc1d5d759a0cf4adc92beb271p+6), C_(0x1.74f85dd906948af50c229b89c98dp+7), C_(-0x1.8426225b26443b4ef3c972f9489bp+7), C_(0x1.4fbcc1bdf3f1963c49a88c06aa08p+7), C_(-0x1.4776c0e99319f61e68a41fbe42b3p+7), C_(0x1.573bef3fda7eadeaaa4191468e3p+7), C_(-0x1.2b0c271bd883e242fdd8d9725e0bp+7), C_(0x1.bb5bca80b624fa5bb278816db9f3p+6), C_(-0x1.5808025c93fa4e6af5a7ad436556p+6), C_(0x1.0c1df40cf5e4c4ea4441c80693a5p+6), C_(-0x1.5dea01151a3e197eb05317c268edp+5), C_(0x1.997fc95198573b5277250e908707p+4), C_(-0x1.f5c4140f2a03e036d15c57dbb36p+3), C_(0x1.1578f4041624b0e3ebbbb44abecfp+3), C_(-0x1.e11a4c47848258b137f885157e3p+1), C_(0x1.8c2f5a8cae553e89ef1e861ef5b3p+0), C_(-0x1.42cdddde9b71e8354b8c2fb7c09ep-1), C_(0x1.1b37523680cd9a16c0e5dc3ebd03p-3), C_(0x1.61bca3fd3effb1c3f5807afcb9adp-7), C_(-0x1.eeca78cc1dd9a8d407a9b1f6577bp-8), C_(0x1.427b3775515b64598a140f609c8fp-14), C_(0x1.1c6c30fb5472c91c3ee2a25808b3p-18), C_(-0x1.2f056506ce5e619914ce605b0524p-29), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.45a484f799a722e4cd950a09d5fbp-2), C_(-0x1.87cf9eab4f40073db99e6a0fb481p+1), C_(0x1.99aecd437634b1af52fbd40a01bcp+3), C_(-0x1.e335dd2c6e9de306d05cc358c6bp+4), C_(0x1.5e3841e2195098fae8b77b691b21p+5), C_(-0x1.48839e048b83d3127ebe74020885p+5), C_(0x1.e11a7f30735e301f0eb2ede8063fp+4), C_(-0x1.bff27724d4103b12e92a64b54c9dp+4), C_(0x1.f68b6fe2ccc3168c1a15db6eeebdp+4), C_(-0x1.a9c89c30bca221a764ae454bfb09p+4), C_(0x1.147ddad811d2b11feabea5bba8adp+4), C_(-0x1.a10ee0eb1ccb64a80033704ddb98p+3), C_(0x1.5d8b9ffe3cdb891325e9bfc9fb55p+3), C_(-0x1.b0eebf69279efaf954dd166c21dep+2), C_(0x1.b180929e1a69b7ef5328a0cfd4a4p+1), C_(-0x1.11a2d370771ca7d9ba7c7444df33p+1), C_(0x1.45b0d998cab377e10ef3a92e12dfp+0), C_(-0x1.d74083eaced416102c8dd2af61fp-2), C_(0x1.27c1113b5bdb7975242772f43479p-3), C_(-0x1.2ee6a8512694e4da2e5b07f1c606p-4), C_(0x1.0ad11030da22955532f0e66e0c83p-6), C_(0x1.b719ad4ae715fb13a424d63fb241p-8), C_(-0x1.7b5726cd7507b577ab874fe8a876p-9), C_(0x1.efe0e7fbce7f41797c67293a0937p-14), C_(0x1.116839f7247ae044e8dfdefe7163p-18), C_(-0x1.24c158fd367df5563093507c0edcp-28), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.439a95b32a47eb5722e3cd7fe3cap-5), C_(-0x1.85e5f8ce20b701780e2029b7ff55p-2), C_(0x1.959ab595a2ea47cca93fdec47d03p+0), C_(-0x1.d591277dff53d8dcf59277336155p+1), C_(0x1.43a6564933b3f0805a5a899c5bb9p+2), C_(-0x1.0a2c05cc597aaccc032de2cc831fp+2), C_(0x1.273950f6ffd17ee92b32456caf9bp+1), C_(-0x1.050c8b9cb84b7c5048bc5cd2f92ep+1), C_(0x1.600ea820111d062fdf2a6acf661cp+1), C_(-0x1.21f61a844a104f06b392bde6725p+1), C_(0x1.19f0e6ef31a0d26707b436c0ada9p+0), C_(-0x1.8e2103144a726110a565e981ea79p-1), C_(0x1.a07f2894f970eb1bd26c4012674ap-1), C_(-0x1.ccce8527cee5c45450edf8973a9cp-2), C_(0x1.e56137866a8254327c313c62b4d6p-4), C_(-0x1.5df48c0c87cd72cb9ba6c6b9ceadp-4), C_(0x1.19d3f039c46cde096e59d4adaef2p-4), C_(-0x1.9e6cd0f61f4caa9b0d4bb0b897fp-9), C_(-0x1.b966bdf45728a5a5bb304f91c5cp-7), C_(0x1.8240771a20727b5953c676de8a9p-9), C_(-0x1.1b05a2f57f924748a24f50e9e6eep-9), C_(0x1.7f8554959f4a532982e2ba397a2fp-9), C_(-0x1.23710df832eb1845bb5316dc1abfp-10), C_(0x1.cc575afdf3f3ce7d0de6ac81f14p-14), C_(0x1.1f238196ae22e33d86876e9e195ep-18), C_(-0x1.3697e9bf43069ef0c328d37a1aebp-27), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d99d611c0465d7fca87092137394p-12), C_(0x1.0d2f985427a1dc1f62afa99d998fp-4), C_(0x1.4a539266aac6de6ff0ee136fe6aap-1), C_(0x1.1fc50d04f7f07a49e55f06b78355p-1), C_(-0x1.d497750272bfa28f3f1990b740bdp-2), C_(0x1.3575a87d9c1633de9f0ee95125a2p-2), C_(-0x1.7e644ab11888684db8a7b8d90489p-3), C_(0x1.a1785765bb948d52e0838b0df196p-4), C_(-0x1.7135a6ada8b52155f89869cf22c7p-5), C_(0x1.d8cfdcbb1618899a1617de65e071p-7), C_(-0x1.57e157b5bcea7fac037e4b9b62aap-9), C_(-0x1.5f633204e959fc32c151ba987165p-15), C_(0x1.10a4589d9f87d6dc51e36837ed0bp-13), C_(-0x1.592264d16e621b5275bdd9d12d3ep-16), C_(0x1.89979784d7185338d2badb26cabcp-18), C_(-0x1.4f841169a1bad189406e2832bc2dp-18), C_(0x1.74953d3967ccd8cc322dbf252946p-20), C_(-0x1.f7cb1acefcf435a3d287cb8094c6p-26), C_(-0x1.c92be21aef0c9ac0fb550ddd5f87p-26), C_(-0x1.3b9a57c4ce7e7a8e7b0e1df188abp-35), C_(-0x1.6a58cec0fa224ca49741d5041713p-35), C_(0x1.4bf1eb8cd4c9c2273508a8b73f46p-37), C_(0x1.697067f1715a141417bb7553b3a7p-44), C_(-0x1.513d790bd242fdd412e02eaf3fd9p-49), C_(-0x1.b3943c02986a6636aaf05d95d84p-57), C_(0x1.54d330be5783db7123cd1333ac9cp-67), C_(-0x1.3f6e1e631364c64c65f6b5a7fe23p-80), C_(-0x1.d0d882f8587b498d8efb759e05fp-104), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.af673717274af370272903c1fa7cp-9), C_(0x1.c7ad45d086ea4c5ed9ed7e340defp-3), C_(0x1.9756cb092ee06f6ac1eb577b96f6p-1), C_(-0x1.51916657c183447d0774789d6344p+0), C_(0x1.6cc6e8f0624052b2c0fdcc8950d3p-2), C_(-0x1.8cf37d6182ca0b170d0a042e4192p-4), C_(0x1.9a3fa2f41d4953051b0c6d4a1b03p-4), C_(-0x1.0a50be22f2b86dd755f1bb101decp-3), C_(0x1.df3f4f6c19d45193b61450be39f8p-4), C_(-0x1.2d4b7e715db6bf84cb93e1a16129p-4), C_(0x1.0681e4c20b9fce41d5b4e56756a7p-5), C_(-0x1.1b50d689cbed8df146901e68b6b4p-7), C_(0x1.49acd134a254ba0136bf2c9ddd8p-11), C_(0x1.16651955943e391787562b852142p-11), C_(-0x1.c26d1f2c70c86f0644644cef75b6p-13), C_(0x1.3002118e762a111c6bcee4aaae9bp-16), C_(0x1.49fbecfd7d9c6cba55cd30ac067dp-17), C_(-0x1.8781a4a6a5f7c8daadd9ede249c3p-19), C_(0x1.5ed0ad164acd249f0f9d827483fep-24), C_(0x1.da4a7558674addd03b35614f7a6dp-25), C_(-0x1.7e23c7237f3f9358779e22d38d23p-29), C_(-0x1.bd8f2cef8c9f03d137232e9e498bp-35), C_(0x1.1c61501fa10480730673344e3608p-37), C_(-0x1.c1b8b33989e0245e7c861b898f54p-44), C_(-0x1.95156f39cb33a3cd95db28e3bb11p-52), C_(0x1.d1f8ddb7d01989509bfbf0327d67p-60), C_(-0x1.34635de67ce8bb9a35ccd2f4bcc3p-74), C_(-0x1.c0c6d283f741e5d8d9e1ced44ca2p-97), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.52aa167437ed3a97a2d16e2e7e71p-6), C_(0x1.2f386450cd3603452775e405daacp-1), C_(-0x1.92da3e0f4795f52ddad307073cb1p-2), C_(-0x1.010e6c23362c2f5a0189ea0fe7f3p+1), C_(0x1.ba5e5707337cefc73943a8303bc5p+1), C_(-0x1.6efa1a351e68942304e8e68b7bacp+1), C_(0x1.e2efff792ca6cd2456dfdb721f76p+0), C_(-0x1.e9e84815ce29a5578b4bc0477acbp-1), C_(0x1.3e7bcfc83dd34f0d929299013451p-2), C_(-0x1.3f21e5e83db9b76a1e6a21ec3442p-6), C_(-0x1.00e091b8310d7c425038e08dacbfp-5), C_(0x1.93252ea5d40edb85ff0ddad301dp-8), C_(0x1.0cb53bda124f4c4d4c0ae3af4779p-7), C_(-0x1.6ecc6596fdeb97786cd08cbbbaedp-8), C_(0x1.1da3c88de4593a0d10cc249b83cep-10), C_(0x1.0f705c9109b88bc792c8e251c3f5p-12), C_(-0x1.687f176415b5a1410c9f394cb959p-13), C_(0x1.03bf749271ea0dc9bfa9a81f4245p-15), C_(-0x1.0a570c997b8f6bb3aa2b6fc454e1p-20), C_(-0x1.b60c856b75c6f8f8db3b0f76f67dp-22), C_(0x1.2f36c8024d47853b1fc5abd2c569p-24), C_(-0x1.ab6b4d2a0c9eb0fb78406697468ap-30), C_(-0x1.b77dbd4d624bb182ce2a8088a4c2p-33), C_(0x1.02e06a0b5252899742121667393ep-39), C_(0x1.f900db818405bc4cfc19c190531fp-46), C_(-0x1.5cc6aba4a366fbfbcb9e7e9b2b91p-54), C_(0x1.79a9be1badaf05e53c8d4ae211e7p-67), C_(0x1.12cb1c6610cf5a5ca8d9bf45819bp-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bde47de89537efcc2943722b907bp-4), C_(0x1.ff6e39e05bc1960ac6a7468afb9ep-1), C_(-0x1.0edf7812c7e6f7d06a00b362ef27p+2), C_(0x1.788eafbfef56fcdc50a685d1f90ep+2), C_(-0x1.0b9e58d049e2b1cb9469b014878dp+2), C_(0x1.57d72a54d9b7d9046e3ca22b5dccp+1), C_(-0x1.5aec59993d64c03ae451f5fb822ap+1), C_(0x1.66be004fbc25830ff3a497ea74efp+1), C_(-0x1.257b730e2148d4f4b3feb863502dp+1), C_(0x1.61e6a248fa765db41939b126fafep+0), C_(-0x1.1d661708485736ce63b6c04b417fp-1), C_(0x1.7634ae9385e7d28433590ede5d72p-4), C_(0x1.aae5eb36cf2339bb1da3727f92c7p-5), C_(-0x1.66a2dd81189a5724bb1062f0dfebp-5), C_(0x1.9ee5c38dff3c5ada29575f743d87p-7), C_(0x1.cee452b55c630166e1f1c650af12p-12), C_(-0x1.7d0e63753adf810a13b7946ecd6fp-10), C_(0x1.95a9bb14ccec080a6175688009ap-12), C_(-0x1.ac68b8496deea7093d3eaa37178ap-17), C_(-0x1.4a3e531dccd5a7c88df667aa9928p-17), C_(0x1.45a5b2adacfee470f99a3f9acab4p-20), C_(-0x1.a0585e72874e51a270db9477829dp-28), C_(-0x1.4a4aaf36fdaec2c3a3e857f50877p-28), C_(0x1.818dc3c36642c77c4040a75f3899p-34), C_(0x1.bc8ec635290e455c58f05f4aae9ap-41), C_(-0x1.1c50f4adb4d48c39b492719c193cp-48), C_(0x1.541ee5efeba27ec1d6332fa4f538p-61), C_(0x1.eef3c669427ba33d298eab6d070cp-82), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.da9efb84cd101b891a55bf085a33p-2), C_(-0x1.0a963523c780f95520ba62e1635dp-2), C_(-0x1.6ead78b2a7f870bae850968c013ap+2), C_(0x1.1fb0b7ee7fe9b42077abdaf556e2p+4), C_(-0x1.a26b20f9bdeeff0cd0b5e878c8cap+4), C_(0x1.5a362701692b5d54a80faabe0329p+4), C_(-0x1.c3b93743ed5e1f4aae7ff96667ep+2), C_(-0x1.0393f54066e2a86d4f5766fcec98p+3), C_(0x1.ce0e335b9b5cfd8737f6de07dc86p+3), C_(-0x1.3371f4378fc25cdcbf584ed9698fp+3), C_(0x1.04744c732a8970957ba707eb759dp-2), C_(0x1.5d5bbaac2d3dd399541ae8c8527cp+2), C_(-0x1.56903abc9d372d08f72cf8f9b7f6p+2), C_(0x1.4f367450bb0294accf5c9a7e742cp+1), C_(-0x1.16f1bf1e47dd7b33b29f107a7717p-1), C_(-0x1.0ca6089fc41ee660907b2bb584cap-3), C_(0x1.fd1e6437298de912355a40f30818p-4), C_(-0x1.127569c6d3d201e096a74c3e92a3p-5), C_(0x1.031ce43d6f2a9b28afac205ca3a5p-9), C_(0x1.dbc5a12350173dc4ceb0edd40202p-11), C_(-0x1.6e57586c99db2a8af6576e5d9fc9p-13), C_(0x1.338c12c9a95b47e57d454a7c66e9p-19), C_(0x1.ec833bdc8d6ab1cf492647696452p-21), C_(-0x1.31ee1e222a82fe6e397b0f1ab0a7p-26), C_(-0x1.068cce25031d061c7d5229b85c51p-32), C_(0x1.ab486d191520d8a9aefca6d39becp-40), C_(-0x1.971ac61147c4bd5f21d58d94dd2bp-52), C_(-0x1.28365b5992261cb91d89a4a61c9dp-71), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a28bf1f4baf0256370de9e50cdfp+0), C_(-0x1.0b8ecb513e670e46e8b61ff5e5a2p+3), C_(0x1.301d17ac5e1c6daeb2bb903493bbp+4), C_(-0x1.80a5fd5ebbea4cbe232c3d8a57f1p+4), C_(0x1.4a39e3e1048d62539834148e9e34p+4), C_(-0x1.1148278e9d9a1304c4d27a6289e7p+4), C_(0x1.18e244d79a0328c7ff6eaa1380dep+4), C_(-0x1.3908669ba07796469d9944fd1af2p+4), C_(0x1.80446c71adb1488769cf4e603a7ap+4), C_(-0x1.0a40794798e411ebd23986dcd959p+5), C_(0x1.52509dd04c4f6aeb9cbf4fd2a65ep+5), C_(-0x1.4b468531c5b19f58ba9821140c9p+5), C_(0x1.c80f1430e334a07768f1a5bc676fp+4), C_(-0x1.82ded3c89e7e9fa329e76277e5cep+3), C_(0x1.7610a167089f1959ecdad2bfe856p+0), C_(0x1.b0a89a8818c0677d48d7304191d3p+0), C_(-0x1.2b516da5d080fbac57ead9c2cab4p+0), C_(0x1.488189c0e63233e310386fe21bdep-2), C_(-0x1.16dd91fce8d2f3a24746d48a1c72p-6), C_(-0x1.957d5757f4d581e1eb81397c4cedp-7), C_(0x1.613bcf2c2fc6a53ed2c91b207503p-9), C_(-0x1.0adbc024da55152d1e362e31540ap-14), C_(-0x1.44905597a89087a3899ef1de6ff1p-16), C_(0x1.238bd55115863b967f9591633549p-21), C_(0x1.0b863bc593a1d515b8c451bf0e45p-27), C_(-0x1.2dac52b5d35bb8e11505ea96f44p-34), C_(0x1.a8ab5a61388b1db01ad925c31a8cp-46), C_(0x1.34fcf88bcfb3fdd3eace81ef29a8p-64), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e156f58145aba7d0b30fa35cff6p+1), C_(-0x1.d9350b2238c2b904f5fdfc3f59d8p+4), C_(0x1.b03e3957ecd6a002d130922f2289p+6), C_(-0x1.f51dfa789d878832ad001b3c3bbap+7), C_(0x1.b1d9ee3321d942364cb8258ac548p+8), C_(-0x1.3c90b7e3ca1db82e1a61d1d6988cp+9), C_(0x1.a1025f9df5665ef6d6390bf76e1p+9), C_(-0x1.ee82dbab6ab103949b52c0e24238p+9), C_(0x1.fcf169933904c38827bff6f06e1ap+9), C_(-0x1.beee0dc0c8ddb1ba16139309e6dap+9), C_(0x1.545f49e00f495f369a9c2bc574c5p+9), C_(-0x1.c39ca355bd5d296f37962bd729eep+8), C_(0x1.d17e6e268802ca2d8ab4ba84d645p+7), C_(-0x1.8d05e2b81cf726b84ae7be04d2f8p+5), C_(-0x1.a57ddae4deced8b3bcbf57c78c0cp+5), C_(0x1.065bfb9cfed103880a47e8cebd5dp+6), C_(-0x1.1a783beefce87b0115cd7f827bd2p+5), C_(0x1.2e9f2c1581a696ea729509934246p+3), C_(-0x1.3cad9a2427051e071bf1f9b27c09p-2), C_(-0x1.1b4b3a7aa70e82673e69d678de04p-1), C_(0x1.15a31469a9ce01c4f9e606bc0537p-3), C_(-0x1.5c66a63c9347469ce6f66ff5c6a6p-8), C_(-0x1.5db560cc8a8d9420c2df7533732ep-10), C_(0x1.c57be52a95f9a3c03fb08957c434p-15), C_(0x1.c9738067c5909d91761fe08abd47p-21), C_(-0x1.63f652c47225898a139ddd320614p-27), C_(0x1.769767db4423b6439ddbe400214ap-38), C_(0x1.108b386e39e95695575892a5277bp-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d870debcc05c458cb431fd983345p+2), C_(-0x1.0c2b8b0b28193dcd228c0a0c405bp+6), C_(0x1.10bd374d63550b983999c56c677ap+8), C_(-0x1.4441daef321d4016bb9b2c10ec43p+9), C_(0x1.eaed48222cc9b9253ebb102b9831p+9), C_(-0x1.dea055aad4ecaefb97c3b4138e1fp+9), C_(0x1.0ea6de87556ea6a2de81d408b23ep+9), C_(0x1.3bb921604519d1ae88e6a7fa3786p+5), C_(-0x1.7c03d4dcf551472cf7483533c9dbp+9), C_(0x1.b77df6c77230b9a06a324d910941p+10), C_(-0x1.59dd45c186fb11c5ad121467058cp+11), C_(0x1.92ad5ee85458cf75ddc7493a06c7p+11), C_(-0x1.7716e9b298971ca51bace1729b0ap+11), C_(0x1.34cd942cd473a5a7100d811101f7p+11), C_(-0x1.d2108687fa36ec88dd6bfb56d5c3p+10), C_(0x1.27e2041912517aaa65b2132e4553p+10), C_(-0x1.0ee0131c1b04ee634d1b07d2c971p+9), C_(0x1.13ffc016f56ca3a3bb78dd1c64f4p+7), C_(0x1.9021a9dd4e12af18897a92604f62p+1), C_(-0x1.cb9505a70965b7f9ec7314ae6da2p+3), C_(0x1.f11cd618c3358a67a8f728986e77p+1), C_(-0x1.a3fefe1a942d41c95d66abeb0178p-3), C_(-0x1.a953da883746e1eb5fc521fbad44p-5), C_(0x1.9718bee3af728b9e4c2d8088bafdp-9), C_(0x1.ad4249f39958d903ac018ed0138fp-15), C_(-0x1.eb70cd1aa40511f5c12a3ada0131p-21), C_(0x1.72006a07a097f617e889edbdb056p-31), C_(0x1.0d30627e6a2ad3489cda0318f0edp-47), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.155158ac6ea984ad1f3ad98465a9p+3), C_(-0x1.4fec3a6a32c1ef2818fdbca7bd5fp+6), C_(0x1.70dec41eaf97d263c2e4504b0b21p+8), C_(-0x1.e94cfecb1efa1478b22094cf32b8p+9), C_(0x1.bf0b100d34d0405ff7a1094810ecp+10), C_(-0x1.39291803fcf47b5c26824c7c465ep+11), C_(0x1.79ccf50afb46dbd4b77400a63149p+11), C_(-0x1.ab6c90991611b280fa6243394583p+11), C_(0x1.c47ed9a17b9cc8042e779917f5f2p+11), C_(-0x1.af1005783c9c08a75d46ca645f35p+11), C_(0x1.72a859cabb471f7e1c8ba7bd2a6cp+11), C_(-0x1.2846e6b9b14f481005e402049827p+11), C_(0x1.b3d87dff6a954876ee30a3fd1e1p+10), C_(-0x1.1ae10527ae49437f7880589e6393p+10), C_(0x1.41e16e9c43532c08707a85b672ep+9), C_(-0x1.460030c5bf206e4d0618004a8fep+8), C_(0x1.0818e6dd9acdc76d8ca94db3b3b3p+7), C_(-0x1.8ef0b66c7662c653e53071c7fb7ep+4), C_(-0x1.6eb8ec2d2fcf0443ad7c1412d0d4p+3), C_(0x1.3aba0303f01c424453fb561d43b2p+3), C_(-0x1.588d6d239648dcf73cdacc19a23ap+1), C_(0x1.5ca063a2897a34772f3d9594be58p-3), C_(0x1.72c884e06d399a8e64ff05cdd7a2p-5), C_(-0x1.2b7b99da7239a8d08435e37194cp-8), C_(-0x1.359ad5ec914c5a48afa1ae580694p-14), C_(0x1.0cff089d4d592f01775a150c05eep-19), C_(-0x1.207535755ab2ee6fe496486e6edap-29), C_(-0x1.a3ad9d559345b904814003502ba2p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.174fb1d6730638307d1e4b445fc7p+3), C_(-0x1.5cf63b4072a084fdeb886ad661e9p+6), C_(0x1.859702b93091fc7e65868db7a8fbp+8), C_(-0x1.008e38c64d4049e94bd38a5f00e3p+10), C_(0x1.c03c1b8df613f180675faa2c200ap+10), C_(-0x1.1e0d30516cd0d5b6c1126d4bf14cp+11), C_(0x1.33504e2e62ab9029d44ee63bfb62p+11), C_(-0x1.4498a39b45dd2d15e6ecc8905aabp+11), C_(0x1.500c422b7e4d651447cfcdfc454bp+11), C_(-0x1.2d6f916f2f063d6cac6b467c2932p+11), C_(0x1.c5bd8b8beccdb3ef655c28cdfe75p+10), C_(-0x1.3b7208dc1850750db50ab0ef592ep+10), C_(0x1.a4b1819107c720e54775d3b0e2c4p+9), C_(-0x1.c03583e49298125db8e2fdf27d4ep+8), C_(0x1.1254d5dd1a3c865791d5348ec394p+7), C_(0x1.be19509979c252700bdddf4796f4p+2), C_(-0x1.6abf524121ea45d75b1ac598d945p+5), C_(0x1.bdfa9494723d3641f8f4e66eff1ap+5), C_(-0x1.7a9c102bdb495114d11be11a8205p+5), C_(0x1.86920d3d07ed23a9933ffc257d69p+4), C_(-0x1.a9adfb25c4f27469db3fea5dd201p+2), C_(0x1.1337641b89dbbf1427d95e0cc537p-1), C_(0x1.191c64622c1b13245bafd3429ab6p-3), C_(-0x1.88d18423866c243d7190f3f8f03dp-6), C_(-0x1.aee4f466bb96965b6a34b6c35598p-12), C_(0x1.15e5e9747fe1bbdbc08f26b48b4cp-16), C_(-0x1.bc4491eee0fdcc0c5c6a94682339p-26), C_(-0x1.431c03e754cd8a35cd8981f0bf35p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.57dd202e5e84ab856980df8a0abap+2), C_(-0x1.b426b94987908d499f3bffafa19ep+5), C_(0x1.ef50af36bc949ed3fa7cc19e8e96p+7), C_(-0x1.4da8e644667e6ac3b7b19c4c383dp+9), C_(0x1.2d889ab089910f7ad4219226878ep+10), C_(-0x1.9456ec86efc743d502abdf76eae3p+10), C_(0x1.ca1f75d29c1784a6a7a3af88a28cp+10), C_(-0x1.f2eaf24b48be90f886d98564f553p+10), C_(0x1.0a60e2fdcea779a991419059c46dp+11), C_(-0x1.07fe75c2d85392f12125b660934dp+11), C_(0x1.e2b37ed5f446198c3a6ab7d8b74fp+10), C_(-0x1.a28fcff6e684b5cca8e0268f1e92p+10), C_(0x1.5596d2be7c1f83852a4b17681f79p+10), C_(-0x1.02761175eccb4a7f32feddc56feep+10), C_(0x1.70f45a3e9b6c87dda520903f4aafp+9), C_(-0x1.edf5a5b354e128a66fada7d4bcf3p+8), C_(0x1.27b1e13298bb3ef65c7ced26ff2fp+8), C_(-0x1.3be69243ef2c31f0230131660198p+7), C_(0x1.3b71f0120f2a47ab2f14bf7b7d89p+6), C_(-0x1.11985d9404f45378f95059bc551ep+5), C_(0x1.3b5a9762f053ae040918d7979484p+3), C_(-0x1.c32c18767db723614ce78e339586p-1), C_(-0x1.5d8e89b8ba2f46a3386878a383e3p-2), C_(0x1.3b1b46a97c2fa9eb1545e9c9486p-4), C_(0x1.23706d03f6f7466fb42dcd72c19fp-10), C_(-0x1.9c26fc84f3ff5e0f45e88806fbbbp-14), C_(0x1.962939a138e2b376295550104948p-23), C_(0x1.27428a5934f9dbd8cb77b8eb93d8p-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.82ba18a2815549dbb583ba20e3a4p+1), C_(-0x1.ee321ac782e8103dfda5e2a50005p+4), C_(0x1.174e5f65a44a587e2370d6742aeep+7), C_(-0x1.6e81d57c4c979417ab1a67acd69dp+8), C_(0x1.368de3361fae4ae909df52a5836ap+9), C_(-0x1.7106731d7c870bc083e5fa51f617p+9), C_(0x1.661d220cefa0ffe013a28a70693fp+9), C_(-0x1.6833b778e773ab42be55fb8d5e31p+9), C_(0x1.833c1b7a24cc4442e638654d7d43p+9), C_(-0x1.704d0cf5b403f737ee51433c941bp+9), C_(0x1.2a287b4a8744be736369f360e45fp+9), C_(-0x1.d795731af32d4e2789960ef06165p+8), C_(0x1.7a6623bbe9af7bf6c822bfb77cd2p+8), C_(-0x1.0ddd9fa1ad021e162c6d71d17f6ap+8), C_(0x1.4f824182bb440977dbde7b407e9p+7), C_(-0x1.9b8d6efd833c3f31fdcf2bc0b9fap+6), C_(0x1.e6b9bfc912a60c385c4952c1112ep+5), C_(-0x1.d872a65489bc6c3914d51095ebc1p+4), C_(0x1.82e4e50171640b22bb8023c09d2ep+3), C_(-0x1.3c81b080d7c589f42c4b3bd2cdd6p+2), C_(0x1.87117e04fd822595de3e0b568ccp+0), C_(-0x1.f2d1dbd395098c995334374fed2ep-6), C_(-0x1.327c0d249413fa2745cbbd687d3ep-3), C_(0x1.13b8c9585145f7834dc70fb2de56p-5), C_(-0x1.094893076dab22e2cc6f5a93ce22p-13), C_(-0x1.784719262e6d99b5739a61a4981ap-14), C_(0x1.31d26875ab45ebb06f0484706cp-23), C_(0x1.bc3aef2e9698a9624f45add91d4dp-36), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.229017de89888d3b45e2c184d9bp+0), C_(-0x1.74b098d7b294230e1965426f3612p+3), C_(0x1.a3d6fe58853c1e5c5b0a3a09e40cp+5), C_(-0x1.0ee9fe2c639a74c7c045b3701c38p+7), C_(0x1.b7ec28edec4542d27f9646062fefp+7), C_(-0x1.dcbffedb3a507fa5c4f4218a69c2p+7), C_(0x1.8f9512e48d1c46e9aca0a2a1ffcap+7), C_(-0x1.7421b1a8804595d4b26746d9ca32p+7), C_(0x1.a17e1d21e73d1b2881053890e718p+7), C_(-0x1.8b13badbca1d886a8838c2c2e2e8p+7), C_(0x1.210062e92f4896d0f00a29c58cfbp+7), C_(-0x1.a9798d44da6c2035da535dfbec27p+6), C_(0x1.62f521d1972a85eb2c6f26f231b9p+6), C_(-0x1.f0d14679f69c06584d1c30d18738p+5), C_(0x1.0b0540b21cf0924f5546e5194d02p+5), C_(-0x1.2e7f81d7237507956599c3ca61c1p+4), C_(0x1.776b19bc1de7ac2a6f830edb0d24p+3), C_(-0x1.390aaca35a348d0447af0cac40bp+2), C_(0x1.0e68e9445701769efc7a68d035e5p+0), C_(-0x1.1d9e671612a45bff7deef6e6cc44p-2), C_(0x1.1e141f6f8381b1b9942811bfdb96p-5), C_(0x1.626281f06a565209b56968645fb1p-3), C_(-0x1.00510e27c6af9fccce7dab2661cp-3), C_(0x1.dda065aa933f3a25232d375fa99bp-6), C_(-0x1.397e42b4cc1c25443933189b9067p-10), C_(-0x1.5e2780fee3a224f5cbc2e8463206p-13), C_(0x1.93d63eaebefb797682d434c6108cp-23), C_(0x1.24c485651202d28a48b67967bbebp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2dba81606cdf44cd9f04d2f8bc14p-3), C_(-0x1.83ba9062dc10a95420ae8251630ap+0), C_(0x1.bc6ce42e9d3a21102e4fdf0d4671p+2), C_(-0x1.2c97bd817af94b6452b764a95107p+4), C_(0x1.0e06914d9315537516f107f294e6p+5), C_(-0x1.5f4706680d4ada71d3fe8928e941p+5), C_(0x1.6ea3fbf492340b1a8746b11d0c42p+5), C_(-0x1.5a777ed4931f215f8e0a373e4b9fp+5), C_(0x1.424978021982d2d37f62990dfb19p+5), C_(-0x1.3090ff3d7fed662537bbff91030bp+5), C_(0x1.23e4419ddb640edbe25a71aaad29p+5), C_(-0x1.07fd356f7673b92c13a9d66edf4fp+5), C_(0x1.a8f488a3b6e4b2eef60c68cd2c1fp+4), C_(-0x1.49932384ed8b4cc7bb541dede413p+4), C_(0x1.0a96d421140fecc2982baba8b026p+4), C_(-0x1.8f60cd9c056028206308e7df4429p+3), C_(0x1.003bcbf26a5db032107ad008618cp+3), C_(-0x1.433ef046d9ed13921cc6b579a83ap+2), C_(0x1.a65b7dff9352096da27547ffc3e7p+1), C_(-0x1.d36032adf2dbd6f014bd3f02cf6dp+0), C_(0x1.a4a1ad470bd0ddc88c1710fd49dcp-1), C_(-0x1.88e9f63513ce060ad42735911b82p-2), C_(0x1.6764f965c95116ec3ca5a4be4d2fp-3), C_(-0x1.91c36b23af1d7e93ac71caa65612p-5), C_(0x1.07d03d7a1adc182d361556de1e4bp-8), C_(0x1.362d3e37ff6cd230a2a77cad24c8p-11), C_(-0x1.92dbfdbfa8197afc834aaea734e3p-20), C_(-0x1.22ff804507dbe78851ce06e1d7fp-30), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8dd6e1684e11d5d1ba3be6ea3c1dp-6), C_(-0x1.ffb4de00653d36e2054de2d9b35cp-3), C_(0x1.1f8df89dea983b6a6839c59e1daap+0), C_(-0x1.6eae32a3a790681f248ae47d8bf4p+1), C_(0x1.200cfdab0a8887ae485a3302d7acp+2), C_(-0x1.1f287662480ab738cbe219de6228p+2), C_(0x1.90990b7ee9dd1f94866d2e2c98f7p+1), C_(-0x1.3d166b62b6085e29fb936a0976f7p+1), C_(0x1.74d60ae1a8ceaa71b4a74664e6fcp+1), C_(-0x1.68026579c2213b7f75e6c5dc86c1p+1), C_(0x1.e76ba8ae988d51e5857ecafcf58dp+0), C_(-0x1.60830949d4c82da954f5df283712p+0), C_(0x1.48f2a8ad7050c9588f35978df03dp+0), C_(-0x1.e7d09d1d5c76d8ae64a80dc22b4p-1), C_(0x1.1252ee85de9250052c51460801d2p-1), C_(-0x1.6e9d007e3ce50ac7539c0411656fp-2), C_(0x1.0a88fbec92db255ff329ff3310a4p-2), C_(-0x1.16ea71f276b00e5a14dad4f88487p-3), C_(0x1.018afa9348367b971e98c4cc0c2cp-4), C_(-0x1.2fa053de7510dd5de40051b25ee8p-5), C_(0x1.2375ee2696f86cd08bc27b41fb5bp-6), C_(-0x1.73b10c938e4b6609ab6cf8acbfb8p-8), C_(0x1.1decc8370b2354d839f55dfbd7ebp-9), C_(-0x1.b8713a4dd74a971b693427cc738fp-11), C_(0x1.732711f764c017456161af308333p-14), C_(0x1.5deb76c540b6c1414e8c8011ad5bp-16), C_(-0x1.9271259f104138f720ca0ebaa72bp-23), C_(-0x1.2099915b9335422a7d16c948a51bp-32), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.674708c20fd278e13cb308fbf6b6p-13), C_(0x1.27cdb30a789a9a4cba57381b80dfp-5), C_(0x1.f3f9a4213a58e15fea805c6fce03p-2), C_(0x1.8a1b0e63e768effc8742d136ac6ep-1), C_(-0x1.d0008134e7b24ce7a0bdb2d5e177p-2), C_(0x1.06c9817f611e98379b152a389fafp-2), C_(-0x1.4ec109006f3ab5eb9ef4b4145d24p-3), C_(0x1.b93c322324f48f0734b615fc9893p-4), C_(-0x1.09f5f4083e296fb6c1df50020f51p-4), C_(0x1.0b6a75dfa25cd5d117e10197333bp-5), C_(-0x1.a17eb803ff745c2b927f4b56bb55p-7), C_(0x1.cda18d3f662aa65f684ad290727fp-9), C_(-0x1.1815693b1e509dbfebb4547eb7c2p-11), C_(-0x1.547c4d557ee7eea60970ca463eb3p-15), C_(0x1.a1d518779619a935a6506c218d6ap-15), C_(-0x1.fb90c559a340a6d74429771a650ap-17), C_(0x1.085bbb58c3dc5e159337591d11c5p-19), C_(0x1.4a16ea18a78a9255137a36b6eeb6p-22), C_(-0x1.3b0f83cef7c9cd6e4992ef7a8e0ap-23), C_(0x1.426950d9b6bca7a253eba2c282ddp-28), C_(0x1.acf5cc83787c76964322f9b1343dp-29), C_(0x1.c7dfc1cbcd560059e1fa3bbb0da4p-37), C_(-0x1.99a4987142751268f68b0c6ed2ep-37), C_(0x1.0c54f6dbbd52aba64c70d9892a56p-42), C_(0x1.60b6215484a1c96af7151c51425dp-49), C_(-0x1.6360709f9f94bbe775bd0ffbeceep-54), C_(0x1.f308a7934d0993ea019328882821p-62), C_(-0x1.dcd83ccd7b40e72afa7a2bb7cfap-74), C_(-0x1.f4c81d09055a8112f9a8f0e29d58p-87), C_(0x1.f541a7bafa4019158f37f50aca47p-112), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5e2be3ffc02e5cb63d505e4d42d9p-10), C_(0x1.115596e3350ec9cfc7fd8b282c15p-3), C_(0x1.8e066ec21fc6a13efd57c0a1a8d5p-1), C_(-0x1.9a3ae9a2a692b7d6fe0312f42fd2p-1), C_(-0x1.b4e823397cf87b829664fcfb615p-2), C_(0x1.24d79baf908bbde12d97a94a7f11p-1), C_(-0x1.96ff08990aa1ff2b3a6156b3a6f7p-2), C_(0x1.7cff079859d44a97134acb0b3815p-3), C_(-0x1.3b2f6fbc125eff4f9e00971a8041p-5), C_(-0x1.8c439625af31faef37a9ac49e57fp-6), C_(0x1.d82f61038e0e00ad9adf7940901dp-6), C_(-0x1.d308486caa607d54998083598bc8p-7), C_(0x1.b8ca6f1e525d8fc1aecc191249d8p-9), C_(0x1.4ea26d28d30874cd6f1bece4d0cdp-13), C_(-0x1.4455094b3efac9d3c28631c94fc4p-12), C_(0x1.116fb5095b299dc0400b6814e296p-15), C_(0x1.e6f46905743cf29b32a5a94efd0bp-16), C_(-0x1.73244b56511394e5623a6c13b582p-17), C_(0x1.105e30d7ecb45c8d929e54615ad8p-20), C_(0x1.85ee598e5c772af7b4423f5e4908p-23), C_(-0x1.5ac9f1c76ae72306c6963aa9eb6ap-25), C_(0x1.d789f3d703adce6fceeb7470ebe2p-30), C_(0x1.8d5e3e20027e865e92d2141a2b73p-35), C_(-0x1.c8b3833c3b76938050c849f3c902p-37), C_(0x1.38fe40b99904e82fbd88d14cb331p-43), C_(0x1.f524d19d8420a05a730c8d14369dp-49), C_(-0x1.a73b7d5e557e750b97979bfe8e3ep-57), C_(-0x1.c5320460bba019effc9564690ea4p-68), C_(0x1.a5354de9b5e4be0a26cfffd8bdbp-81), C_(-0x1.a59b918cf087f7e28a66eadc80bbp-105), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.295efeac152d79633d42d6d916dap-7), C_(0x1.9d61cc47e5de2628b18136c91ea6p-2), C_(0x1.161d416b67637e8de5329814dbadp-2), C_(-0x1.5b7a45663376a9aa5f95ed877064p+1), C_(0x1.d1174d09edd0e5a9b8dec824cf43p+1), C_(-0x1.64fd520a66219e33ceb19171c931p+1), C_(0x1.05168da96484602e8bf4113ac4e7p+1), C_(-0x1.6575089c4586c8407b43149ab11bp+0), C_(0x1.a38bf0b53f437316576c7b5f77a6p-1), C_(-0x1.889b16ed752f17512574ee20842fp-2), C_(0x1.152c76b8c5aa61f7d1f86545cf96p-3), C_(-0x1.1b4c99876d201e8bbadda8305eebp-5), C_(0x1.907f1e8b42628bd87c6dfaa42428p-8), C_(-0x1.48b152205d27ec7322d3d940da05p-13), C_(-0x1.a3276d4b1b41ee0d43115b5aa81dp-11), C_(0x1.19008ab2bad0e78321ce13187a8p-11), C_(-0x1.4a0f2fc3a3fe6743d3250b9f0687p-13), C_(0x1.b16d8531bcd974ffcfcfb275888ap-17), C_(0x1.3c9bc919e0e49ac8c1ec9b7c72d7p-19), C_(0x1.899254d74191895a0ee7c7e368dfp-24), C_(-0x1.e003adff466a6871b6189e153009p-24), C_(-0x1.b118f867cd64dc8214de14f22a3dp-27), C_(0x1.a8e81cf9b2bf4ed6a7f80b7fee49p-30), C_(0x1.472047d4ce812177c28860710d42p-36), C_(0x1.0bc546f1206b056c51ef6c4e3c73p-41), C_(-0x1.5b78778ec812c1a8126f0f855511p-47), C_(-0x1.75c5773026aebf48665648526e47p-53), C_(-0x1.4450e0ff79233cb66d7ae0406fdfp-64), C_(0x1.74639b34e9729d879c349c60a705p-76), C_(-0x1.74be14820bd545c3f1e6ecce41eap-99), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ade0c67a6df62bfb0e80195f4993p-5), C_(0x1.c28b430a75f298c1d73bb81e4353p-1), C_(-0x1.5f4ccfba427cea15c66f4a5c12bbp+1), C_(0x1.cdb8f607de72e596ea568a034c8fp+0), C_(0x1.f77743196657a78ad5bf74425543p+0), C_(-0x1.dd879ba809267a9d7904ab437cc5p+1), C_(0x1.37053c10bce28d1022d31ac1246dp+1), C_(-0x1.1bfa76c0a943a24b6df5bb2abebdp-2), C_(-0x1.2b5034c5e7cec27aa44e7ea3a878p+0), C_(0x1.63e2260baa9fdeb5f048ba37a04bp+0), C_(-0x1.a29913a0c0f2ddeebb2bd3c275b3p-1), C_(0x1.852867c8ceb35a88f788b40857cap-3), C_(0x1.9a9664fc9e678ca180654356c297p-4), C_(-0x1.c29f78e2de8f527b7cd8a08d24efp-4), C_(0x1.54d634445fcf6eedbc5dccf04eadp-5), C_(-0x1.41b2a5a54a66286808252915b865p-9), C_(-0x1.225d9fec5c6e8c447caf2b42ced4p-8), C_(0x1.f9019974a7ddb631ebee782869d1p-10), C_(-0x1.2c283714217e754b55528b628588p-12), C_(-0x1.8e8742bbbfb2111f9226dbaea15fp-16), C_(0x1.c9f58c62dd5d38676514b49c9e2ep-17), C_(-0x1.61f6495ed1b8ece209fc78f1d085p-20), C_(-0x1.96b8b0f8a15e32028c8ee0076679p-25), C_(0x1.71f48c99d030adfe377a7056701dp-27), C_(-0x1.b5fc8d66ab6cfd5a83337a0cc9b9p-34), C_(-0x1.c5963ee2273d2d13e0940bb125cdp-38), C_(0x1.6b4e6ce52480a98b4ad64082a237p-45), C_(0x1.e67135f42b49adad00310559fa39p-58), C_(-0x1.6aff40a6dd5b409b62d44964fcf6p-67), C_(0x1.6b5790e714dd812f487575d04214p-89), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.002833198203bf56e8fbb6905c21p-2), C_(0x1.74f145f5180b48bf2521976daf68p-1), C_(-0x1.d40722c67b8b2c63d49b5a9b6cadp+2), C_(0x1.2af6f0f464bc571c8b763a8383eap+4), C_(-0x1.a43135145799a27dfd1fadf6761p+4), C_(0x1.9a15ae0412710439a9b40c2dd4dbp+4), C_(-0x1.38d1bd49e9af291f59c9f34bcde4p+4), C_(0x1.6c6cdb14d7fe107edc16c4953b35p+3), C_(-0x1.13619aaa119f97b37d6d1c2c4585p+2), C_(0x1.d56ce1ec874a0c5dd634fb59d6d1p-1), C_(-0x1.e42907ae7a26468d6ecb1d9e3f24p-1), C_(0x1.e52911f9f656640a2404f83a2b4fp+0), C_(-0x1.ee224ef8eb13d4b961d19b7d1c3bp+0), C_(0x1.1f26d6223d44cb481a2910c6eba2p+0), C_(-0x1.5888435f5783628967f9baa03f79p-2), C_(-0x1.9e45fc4e6f7c960ebee0a7c398e8p-7), C_(0x1.dcd2d2ebfb6e400bbcf752c0bf7fp-5), C_(-0x1.93116bc1ac6b7200b82ddbf8d638p-6), C_(0x1.0e01783e342a4693e98c9edbf33cp-8), C_(0x1.31f3faa90de9ede16d914789626ap-12), C_(-0x1.f6b0df77a54401ad9bab438557ddp-13), C_(0x1.f05077a02c3aba8741da9769ad4ep-16), C_(0x1.2ec5b9d224e6bceb5db9ee6cff1dp-20), C_(-0x1.47f2b0eb68eda8ce48926b156c9bp-22), C_(0x1.bcb021bf883a1f92a78fc9df6525p-29), C_(0x1.1bcefd6cfba520ba047378483637p-32), C_(-0x1.34d97adc52a38a676a55a692601cp-39), C_(-0x1.6f2c8c9ca394fbdec6dda2487026p-53), C_(0x1.34e43d9253e6e8975e6c8e7aefefp-60), C_(-0x1.352f98f0f2e48db2a203fb32a0f2p-81), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e5d8b15d3664d52108fae09a8e52p-1), C_(-0x1.e7e4ae8313c9841f6b4ba59501e9p+1), C_(0x1.643947f56174ee22b35084254df8p+1), C_(0x1.8bf77730624fb34f058dbb215e6ap+3), C_(-0x1.39575fcf961c0f3da45ce2cb7fb1p+5), C_(0x1.f6657cd6c7e299b7cc89d7d3daa3p+5), C_(-0x1.2981aaa66ca36b3a94f8297750dp+6), C_(0x1.0cf300079688d85d6be476057064p+6), C_(-0x1.71528cd9cab137a39829bbec9ca2p+4), C_(-0x1.13658826409b41720bd51a0f2d32p+6), C_(0x1.5ecf135e336b7c201cd13f9f1c7bp+7), C_(-0x1.ca8fbd8754dc1920d78e0ace3c5ep+7), C_(0x1.83a96558c6c07294f0fd718cdf26p+7), C_(-0x1.9d91182e0786a78e2338c8bf2ff2p+6), C_(0x1.818f5ca05f023837d630b257f2ffp+4), C_(0x1.4e782cc994094deb153537dfc8d9p+3), C_(-0x1.7fba734a377970e0ae8d82bc8b81p+3), C_(0x1.361d7d826bb5b3b3a1616de586bdp+2), C_(-0x1.85fee8307d590ead49f8c992534dp-1), C_(-0x1.fcc3205624ce56be678cf9a5a7bcp-4), C_(0x1.30d54b861144b0080c77fb2ef955p-4), C_(-0x1.4236c7ccc62df6904f1792b21926p-7), C_(-0x1.6b6d4bcc089eed67f90762e3bff2p-12), C_(0x1.251cb75a77a65027fa18c49d6fe7p-13), C_(-0x1.7df627db3ed37f55c551bdd12823p-19), C_(-0x1.6d7ba0319a17f9c5347fd4ebc07ap-23), C_(0x1.047350b843565161f3ac671e5f76p-29), C_(0x1.ecabd0f857c5126fafed07e8e831p-41), C_(-0x1.035ef08b1273d485ae68801933a9p-49), C_(0x1.039e900e7fa12bdd9aa0b500dd5fp-69), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5c435b4994699430de1f0bf0f96ep+1), C_(-0x1.45ad88073e6251792d84638c28d6p+4), C_(0x1.1ac643e9c99f8dff42b4b5f9e976p+6), C_(-0x1.3bcd24e1c22f08a7330d952db5cp+7), C_(0x1.1132bead650e64e0cc6250fd5a4cp+8), C_(-0x1.a3321607e359615c22640184890cp+8), C_(0x1.2bec4ce73b524de840d2af975fb7p+9), C_(-0x1.83ddd4224b9abfb64ecabd8660acp+9), C_(0x1.b1ad4241d86bedd378c0238858cbp+9), C_(-0x1.9d7a3218170b28b67328a4e4a6f8p+9), C_(0x1.5526f87e8214f36e89fc59fbe6b5p+9), C_(-0x1.e996857ebd3fd865f8b8b57715d2p+8), C_(0x1.186a9a24f3387e74b22113290d4ap+8), C_(-0x1.4f804f76b6d5b86a618f6e232bp+6), C_(-0x1.84954fc1821007c0fd22bc06ae8ep+5), C_(0x1.59efa11d2ec6f964630b6fd432d3p+6), C_(-0x1.dac7ad3b33c95d5f07d90297e68ap+5), C_(0x1.62078796373e73b5598b78c1554p+4), C_(-0x1.88bb023e9f2f98b9b7a5caf3d0d1p+1), C_(-0x1.04b9160269b89d57d0a515a32ad5p+0), C_(0x1.18c6982acbd2cd140bf32d2822bbp-1), C_(-0x1.508ddc9d3ccb43c37b8bf661b39ap-4), C_(-0x1.539386e1415cf5772194fa5cb789p-9), C_(0x1.9eab992a4b9ab37998a4782656d7p-10), C_(-0x1.980b92ff814cc556c4aeda05445fp-15), C_(-0x1.761c29381edd29e5680cf5367b41p-19), C_(0x1.64e7e2ec4af2d5325d3b1ebf7038p-25), C_(0x1.1823b743e4c412fe2e1a1caf98aep-35), C_(-0x1.623923d3ddbaeed10b04fa360d62p-44), C_(0x1.6290fa803758e40f0b825bbc6f28p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.891443770e9f5b58ca0bdbd939d6p+2), C_(-0x1.c4b28f7dbecf38e874d3b242d4fbp+5), C_(0x1.d994c46f08417c9c24a3de260d39p+7), C_(-0x1.26defe09eb9e312242e62017ceb2p+9), C_(0x1.ddf577c4250f78c0132ae5d7d1cep+9), C_(-0x1.fd2079b0f3ddb297d557ffac7fap+9), C_(0x1.36152a2e286cfeac434a875affb8p+9), C_(0x1.d8616a51db368c3df9bbb5de82cep+6), C_(-0x1.190b42892374c709dd8c148043fep+10), C_(0x1.36219b396179567cea600ef5a5e7p+11), C_(-0x1.eed74001662f7e761e907ef9b166p+11), C_(0x1.31c149450a5e9832b2fbd7c32f38p+12), C_(-0x1.31807a4d8f7d8b9ec23e94e23c9ap+12), C_(0x1.07e37f0875c28ba98c5df12ea151p+12), C_(-0x1.9ca0e06fa4e40e6ba9a2f070a627p+11), C_(0x1.192392a49659f5be4afa683922a3p+11), C_(-0x1.28f7ef65a911c2242d4a04d3586cp+10), C_(0x1.8ef1182eeb70c3b810afe07ad9aep+8), C_(-0x1.076216da5c43b27292cd22bcb978p+5), C_(-0x1.3734a9c9c5014b6b42b155a6abedp+5), C_(0x1.2e313dce4fbf11c25ec52c766e83p+4), C_(-0x1.913ecda1e3436af7caac068805f8p+1), C_(-0x1.aba4e0591b35ef78388396d8949ap-4), C_(0x1.5578ca229685f75ec4dbb7fb72b6p-4), C_(-0x1.f3ff47839e58d032a1a624c1f604p-9), C_(-0x1.bd3a12076a4f509f06e99bb28599p-13), C_(0x1.29ffe91412a29d368ce7b0895443p-18), C_(0x1.5e7711914b058b73ae8c4ed370dp-28), C_(-0x1.267e3f1ece05182094aa29382cf7p-36), C_(0x1.26c8d9be624c3d09b42c989d403cp-54), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1c06072fbf26f358c9f078f98565p+3), C_(-0x1.65d998749f19f3f52787d2ac7bd1p+6), C_(0x1.9d8978b96f57f154ef9ce52c7bdfp+8), C_(-0x1.24c8d76a7f36d7089e3f4940c827p+10), C_(0x1.21d479bc00697b14d91a6dd4bcabp+11), C_(-0x1.bbc006c9393532c76b5d7283eb2fp+11), C_(0x1.2211c4425df9c2e46c401315e702p+12), C_(-0x1.5c64ff1d8bf677ab09ac8c8005b4p+12), C_(0x1.845a35a3158347c96beac73413ep+12), C_(-0x1.87e6df0fbf8ef42fd538df2c44e6p+12), C_(0x1.6504110de640c4682cba264cf46ap+12), C_(-0x1.2b9aa02be2b35409ccae86a8991fp+12), C_(0x1.cebcfb329a57eadc95a6866f02e1p+11), C_(-0x1.3e375c669dabfd4de916796f2023p+11), C_(0x1.7d70c67fe8973e080c2a8eb7f182p+10), C_(-0x1.8fd6874952e8a903dace07633bccp+9), C_(0x1.57b6f4096f1cf0152662dc88de7ap+8), C_(-0x1.3e2c004c73161017d1fe47d49586p+6), C_(-0x1.f1e0f66437531ffa287a43716481p+4), C_(0x1.39f676c7227564daf7244ac826e7p+5), C_(-0x1.07f7de36ead717df75674d143f33p+4), C_(0x1.6eaf02b444bc4ce4684168c04e9ap+1), C_(0x1.f8896c7b27aea8a0c13b638bec5cp-4), C_(-0x1.b78e4a3636f77d36045fd051d0a7p-4), C_(0x1.faf293c65fc88bb39eaf07f0c833p-8), C_(0x1.a6b604defe6a94f42a0056ad171bp-12), C_(-0x1.9886be2865e4c650159b7d4d95b1p-17), C_(-0x1.7c0bde2d4dd50659d8e873b48d0ap-26), C_(0x1.90aca39ea2e8ac3870ca13b1a564p-34), C_(-0x1.91166efa6d0a92bc7a2e9704d452p-51), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.58e7df6732419db59e9ac42f9ab1p+3), C_(-0x1.c53a29616fa380817d7f5e347aefp+6), C_(0x1.0cc18d57a1a1fb48e108cac3a066p+9), C_(-0x1.7c92fc1b6ca3895680c38212861fp+10), C_(0x1.6a1945d20b68d8baff4381a817e2p+11), C_(-0x1.fab771c0e1baf24e2c8f95c4199fp+11), C_(0x1.254298acbb2d449a7b3bb526f729p+12), C_(-0x1.407f9dc95f9b1203f980178aa4a8p+12), C_(0x1.53233c63dd8a7f18f0a2b3af5ccep+12), C_(-0x1.3b528b34539979362d8c0e80e80ep+12), C_(0x1.e2ea2797d25e54507eb78c335f71p+11), C_(-0x1.3d6169dd11c9bca3212058149b0bp+11), C_(0x1.75fce5d641404560c1229131d8bdp+10), C_(-0x1.2b5b50127f9f56d44ea4f01f61c9p+9), C_(-0x1.18e0518b142ec5c99d05ce213217p+7), C_(0x1.ed1ee257a974ab35fe81e878de48p+8), C_(-0x1.f5a5a8d8a9b3c073ca67ee8615b8p+8), C_(0x1.920c943e9e1a266133bfad52e46dp+8), C_(-0x1.22c1385412c45fef72454e0ef403p+8), C_(0x1.4b1ba13f6628b1dd44be57f24352p+7), C_(-0x1.ec876f34dee07503da6a5d0e4af4p+5), C_(0x1.641261f15a2bc3d54eada0d94bc5p+3), C_(0x1.3bac7fcb6881fd2d747aef7d1cc5p-1), C_(-0x1.3ae0db5ff49e0fda9ef09cfb9b34p-1), C_(0x1.0ba445bef297ba3c0905b698e9c6p-4), C_(0x1.c3804abda5b0efa9daece8d22468p-9), C_(-0x1.3c78fba89f7e4dd2da5d2b0f1ab2p-13), C_(-0x1.6e90a45b17e11834e30d4035587ep-22), C_(0x1.34c398a5dd4857b9fcc2b9b3ec09p-29), C_(-0x1.351bbccd566d5b56e0d110fac029p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0cfd9304e9d0e9e89a508d967352p+3), C_(-0x1.68c00ea69764cc01a573447ef7eep+6), C_(0x1.b4a63a85c6a121d6db6758f94115p+8), C_(-0x1.3c4fcf304828edf08897e340df25p+10), C_(0x1.35efe9ab816f6ad2ce3b95243287p+11), C_(-0x1.c3872b5b6dcd2512d759e390543cp+11), C_(0x1.1261ac83f506bff0f38c31198cefp+12), C_(-0x1.39e1fa3f00833a2dd6c432f2edcep+12), C_(0x1.5e4c9d364466ef749b8d0d88979bp+12), C_(-0x1.6b72e41a84905cceda3e7fc6c066p+12), C_(0x1.578fd4c404248dabc968b7c529b9p+12), C_(-0x1.30faf3648505cdf5f671e0ae34fdp+12), C_(0x1.0174ad7c898217c903f8f07741efp+12), C_(-0x1.942bc49f2f52a22fa3eae80252dcp+11), C_(0x1.25cbc7992fd63cf31740b115daf5p+11), C_(-0x1.914caac5676309ecc6f6c550d8ebp+10), C_(0x1.f93f030387c4d019b6838cf24389p+9), C_(-0x1.1b4f5dfc787bbc32262ca3f167bep+9), C_(0x1.1df01b8a36a8b0e740af0c5b60a7p+8), C_(-0x1.048db6f3ab7c1cc8ce49930b812dp+7), C_(0x1.730bcb9c58bfc20d60bef0471523p+5), C_(-0x1.09b56b87c1c7fb7baeed74ce6cdbp+3), C_(-0x1.4fb833b30fa7eeef6a7358348b92p+0), C_(0x1.e38e1048601a60cbceead8c786b8p-1), C_(-0x1.ee07e572041f738c256c5953b0d7p-4), C_(-0x1.913ced3c0164b56d323de7f36c57p-8), C_(0x1.0726b83c4032bf81b9ad0141e709p-11), C_(0x1.2751c6763466bbc5b359801c4ca6p-20), C_(-0x1.00ceb77e39cabc22cbab1770a0b7p-26), C_(0x1.0123085a8910152fac9990b7a672p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6ddd33f198eb3c96ba1c54f670fdp+2), C_(-0x1.ef9ef6f596ce44132c5dde1777d4p+5), C_(0x1.2bec86422c72fb4a905555a96936p+8), C_(-0x1.ab3138ae63b3c1e29f1c692c8b8ep+9), C_(0x1.90171accf1ae92cfd9c146fd2557p+10), C_(-0x1.0b8279e6381aa2b741cb2d9796cbp+11), C_(0x1.21c7cbc3a51f50320f21aa56334ap+11), C_(-0x1.3291c6bd3630cafeef14937244cfp+11), C_(0x1.52187d4f278255d90661622e17d1p+11), C_(-0x1.5764b21031af003ebeca03a2b0b9p+11), C_(0x1.2d82b77758b7aad296e73eef7d7bp+11), C_(-0x1.efcf6fd97e7509c927b7122c5c13p+10), C_(0x1.96b834131566dc9e06167e63c7d4p+10), C_(-0x1.34d67cf0a39ad9453edbb75a25c5p+10), C_(0x1.9aafba6f0ff85ebebfb694ebd422p+9), C_(-0x1.002f1ef9723b265f846b3c2332f6p+9), C_(0x1.378956144d5be0ceae60b1a0aa28p+8), C_(-0x1.48f6827b3eeb52ea5b3fa287d164p+7), C_(0x1.17de886be7cb3ac887cff35422aap+6), C_(-0x1.abd1c377daaf4123bc47a29397f4p+4), C_(0x1.18836fa0aedf116ff47c167f808p+3), C_(-0x1.72b11631904f6bd3fd5a823e34cp-2), C_(-0x1.93c736e0c44c0da3f45cfa30760fp+0), C_(0x1.74105b4ecfea6c16423bc348f8fp-1), C_(-0x1.a9382883de207a4dbe62c7de34c2p-4), C_(-0x1.8ee02bc822713114de66688f8544p-9), C_(0x1.b89c5ecf7a7b773088c639b3a53ap-11), C_(0x1.5051009d42a4549b60dc1a4ffdc1p-19), C_(-0x1.a9ba33acc416babe2777385baddfp-25), C_(0x1.aa6a7d0ba81031b3c9971794d3cep-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7e688b7526a774b76724ba13a96cp+1), C_(-0x1.044f66dd0bb355e9e82c72d5eaffp+5), C_(0x1.39d2780b0ad2f5c130250e42d893p+7), C_(-0x1.b63bb8898df0968b0e5291c5adf1p+8), C_(0x1.86b367123a2139a59288ccfca3dfp+9), C_(-0x1.d8001c1817ddf23795b1149354dfp+9), C_(0x1.b397f071da3115c284e47fbefa66p+9), C_(-0x1.9ca191acc971e01d76f080b3e85ap+9), C_(0x1.d28d7edb2db091286a502e3d1491p+9), C_(-0x1.daeab5bf793f0a5db198f7c1b01p+9), C_(0x1.738e37d47cc21d48d3f57dfe7cfep+9), C_(-0x1.0785a3e74df59d20286619983999p+9), C_(0x1.a556a97ba734840eab5a765f294cp+8), C_(-0x1.320671c41025d2eac683ee371196p+8), C_(0x1.33661041ead74be914f62376ca64p+7), C_(-0x1.d86506577d5080199e51f7260b6fp+5), C_(0x1.9ebe0657238551a24ab6c6c0e20bp+4), C_(-0x1.ec9ee904293324442bcbed481925p-1), C_(-0x1.1034340999c868fff5238312a8aap+4), C_(0x1.04d7524f6a9fff23ceab9523e19cp+4), C_(-0x1.2fcc89fd04e88d59c75667d7c4bbp+3), C_(0x1.7c24bc012bffc7d1e21de0348c52p+2), C_(-0x1.c84c145900f77b34a4876818624fp+1), C_(0x1.57bccbd9e4fcea0faae4ccf7a2f9p+0), C_(-0x1.d81daf1af068d1091e32e8f2fcc9p-3), C_(-0x1.20f9f72def1de8f22a005f73e8a4p-13), C_(0x1.c2f2ad7e016f5272ff115101365p-9), C_(0x1.baf6705e59cac3284164d29d2adfp-17), C_(-0x1.ae94eeab2dbd4d40eac4360abe26p-22), C_(0x1.af91281d9938911a63573a1c8a3ap-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a308ef1d16805759614e47ced45fp-1), C_(-0x1.1df37cb20ef6cd526bae886688ccp+3), C_(0x1.5a47cc2daffcb2cf20f8cbe23f9dp+5), C_(-0x1.e7cc32d4c7f05cc178a92423af38p+6), C_(0x1.ba5aa6f58d154790fde87c08c1abp+7), C_(-0x1.137ebe2556bb5c31390bfbcc3555p+8), C_(0x1.07f96c27b79ba1c76a48900fad0dp+8), C_(-0x1.f176d6c3151d8ca65c2069cc8ba9p+7), C_(0x1.0c09a0e0bcb9ff8d7d5ef1548dd1p+8), C_(-0x1.12bf0f34a9a5500b54ae9f341239p+8), C_(0x1.de16d55d65d2bb62ec7f100c7235p+7), C_(-0x1.8c7b496d3d3fd8274eb146a1b265p+7), C_(0x1.56592506626bc28d37aec7a2a08bp+7), C_(-0x1.13d919c9693b2e85ee4209bf711ep+7), C_(0x1.8b69de5718a09e2e84e51d955579p+6), C_(-0x1.15b78c90e783729339c94d803f63p+6), C_(0x1.8188b8db550fea38899d2489ef66p+5), C_(-0x1.e03c011f666ac66011b7609652a9p+4), C_(0x1.12ed8b36e986458009c8fb08c63dp+4), C_(-0x1.36a5b057bc26ecf6312ef4c8aa89p+3), C_(0x1.3d2641cf67e8fbde6d24a0c08316p+2), C_(-0x1.11ef148707dfa11f55a9bad8158fp+1), C_(0x1.c294da23fe29fd37f9c13ab439f3p-1), C_(-0x1.4f57e7e05e818e7ff02709327119p-2), C_(0x1.1ebd9964081cf6e9a360b8a8d058p-4), C_(0x1.367917f76eee2f0773ffda2dee7cp-14), C_(-0x1.fdd37749c94d91b95e5811e014fcp-10), C_(-0x1.0fc0733cbc7d657bb2812f3ed59dp-22), C_(0x1.f945fb653cfda9182e6054d0438ep-22), C_(-0x1.fb1bcfae6e46d13bafafa99aa27p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.74ef139ad4e11f00f65daa8820cdp-3), C_(-0x1.fd9d32fdef73fc52b4caeb648516p+0), C_(0x1.3320f17be8b7073381e865362afep+3), C_(-0x1.a9e31dbd98dd09635b0d379485c8p+4), C_(0x1.73dbdd38a87f5064433a350c721dp+5), C_(-0x1.aa50f206f25c72a99cb7b1dfa7d2p+5), C_(0x1.5e48ac9c2f1f1eff350b14cb6a0cp+5), C_(-0x1.20d7a78e95ecf57e7add31db3fd2p+5), C_(0x1.4350b94e5aa2da50e61a74e27b2cp+5), C_(-0x1.5499ff05228ddd2807c95d8259cp+5), C_(0x1.0d8c7214ffee0a1235b3874b3a3ap+5), C_(-0x1.8fe88996cfa9a55157f19af30b98p+4), C_(0x1.63da6bffb7322ee61e908c187b83p+4), C_(-0x1.24223f5c1b9d9506d6b401adee8dp+4), C_(0x1.7851e19176715ec2bb3ef2e77d74p+3), C_(-0x1.e4fd178fcd0ef2f7354c8299da37p+2), C_(0x1.610a439acb28979c58f2b0d330cdp+2), C_(-0x1.ae4c3e147b71c294863ea12a0857p+1), C_(0x1.a6fe28ab7ffa991086c47e322a6dp+0), C_(-0x1.ccc920f98175dd5797f1c22d8029p-1), C_(0x1.f9389387bff6b354c93278385205p-2), C_(-0x1.8612de961fd0228a7f5532d1edd2p-3), C_(0x1.fd43fc0e7883ee43ba7f30ad9465p-5), C_(-0x1.aafa1e0c4a86f88db60d4f1fa17bp-6), C_(0x1.b638737fa8e8eebd498a75e7c49cp-8), C_(0x1.071682a1f5057e2143b4d72fc7c5p-11), C_(-0x1.a84c3f530239b63f7da26929d4ffp-12), C_(0x1.a20c2374a0f6700016084886c2a8p-18), C_(0x1.e7f1c0adda0f62adb67917e7d654p-23), C_(-0x1.eb089a4058efe658e6efa5db9e34p-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.31c729360063e0149d619e7c5659p-6), C_(-0x1.a21aa8a66a6833da5818bdb00dc4p-3), C_(0x1.f656a46fa2a9169e56e0e1915e67p-1), C_(-0x1.589b4fca92a9f10523379245a6fbp+1), C_(0x1.25049558932c1a7bf94dfb345bd9p+2), C_(-0x1.3b0f087615a26809432e1d6e01c8p+2), C_(0x1.bed87f332745bf792baa46fb22d3p+1), C_(-0x1.37fe75fa2aa3b693bb533ebc90ap+1), C_(0x1.75c34ae38a11fc31440e21813692p+1), C_(-0x1.9f32b219f201f09e83858382dcccp+1), C_(0x1.2a50b5ebe798e437ef2503085768p+1), C_(-0x1.80aff2523d4b3342a833db6031p+0), C_(0x1.71f9af43c19f0952a4e07472578p+0), C_(-0x1.40d21595459cbd897728656ded6bp+0), C_(0x1.6edc3b8de7cbccef39ac5c5b8452p-1), C_(-0x1.abb5cf29e076b1f30f36686df3b2p-2), C_(0x1.5fdcb9c5e1f87c285b04c2fd8053p-2), C_(-0x1.af4e9b9242255620df4c3ab9bf57p-3), C_(0x1.57b33e4d63cb5298c7100384e3b2p-4), C_(-0x1.736294d370dec79efb4014a700a8p-5), C_(0x1.e1a61d7964668ec603cb9aadd499p-6), C_(-0x1.38138139d6cd8275f0059b0302fbp-7), C_(0x1.a99b874715d59140bd445bce9797p-10), C_(-0x1.191ada841d111d8ae1875d5194c5p-10), C_(0x1.44a23a1750afa85a30082caf581dp-12), C_(0x1.4db128e094987961ef4278d6a462p-13), C_(-0x1.2cad37f3dbf9e7a235442f3e067dp-14), C_(0x1.f38c667f694821291da674a42ae8p-19), C_(0x1.c870773604d02f72b6568dfdd8eep-24), C_(-0x1.cdd01a024c710ef11bdc57da89cfp-34), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.086b758f2eb28fd921eab56a11edp-14), C_(0x1.39d1d9b6240962e535ae21b2376ap-6), C_(0x1.6586cdc7bb445ac141a0312b8103p-2), C_(0x1.b9d577601dcdb0dcb740f8b98373p-1), C_(-0x1.29ed86125a029803c293e63e1f67p-2), C_(0x1.35228579cf169af0c995d4c52ae4p-4), C_(-0x1.d940ea5a753eace5078cc210d381p-6), C_(0x1.eb66212482f668b8fcf8d3b919cbp-6), C_(-0x1.11e395c55e411390d39b33c12486p-5), C_(0x1.cac8225b45414be4173b8eab4ac8p-6), C_(-0x1.1c2e36898d63a7284aba1b17de4dp-6), C_(0x1.01459f9607ee130b7061d5eb1498p-7), C_(-0x1.3f705b6c01172b34ae01036bd601p-9), C_(0x1.aa4226008e468554c7236a5aa13dp-12), C_(0x1.a227b89277165ccd7a008b2025e9p-16), C_(-0x1.df4876fdde2706ccc1065c683114p-16), C_(0x1.a3348c487531e3e6d511223fa2f3p-19), C_(0x1.bc3886b839cf7c209eee289f6c48p-20), C_(-0x1.3c3d3ef190e94974e0b46a471d0ep-21), C_(0x1.fe10f39c7db3f74fc941d5c89993p-26), C_(0x1.28b87cd51d74b7827dcb3f76ba15p-26), C_(-0x1.5145c4e025139affe8138cf7767p-29), C_(-0x1.c7ef81e91e695e468ea8a5c582b5p-34), C_(0x1.74462d4702c982a79ea8a83c2f8bp-37), C_(-0x1.2eb21459dd6235173db20b5350d7p-41), C_(-0x1.802cada0cd8903e4e2cc5b09958dp-49), C_(0x1.f4dc3c81c07b2740f80e7509651ap-52), C_(-0x1.790641c0d0b7b530c5f3ea46fd8ap-59), C_(-0x1.7be9575142225928d5569ad8cee9p-68), C_(0x1.70d851342e8d54c091b220a3045ap-78), C_(-0x1.08ea9c21a48ad423ef299cf99255p-94), C_(-0x1.6d7121dda4d1a467dfa9e3b22e7bp-121), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1287f0812571ced1e1d4f218f2e4p-11), C_(0x1.3963c1ea0712ddb1fe38bd9c9b8p-4), C_(0x1.56352993b88d1ab506ab53972cdp-1), C_(-0x1.f6edcab194e1f1b63bcde69f40efp-3), C_(-0x1.17b7ccfaac21f6709bae8571c345p+0), C_(0x1.0e886b0af5f1b1856a755304e662p+0), C_(-0x1.8ecc3f557378e15602e7822e181ep-1), C_(0x1.fc587a34e0e0edbbd49047b2d639p-2), C_(-0x1.0d307d8a24ec475046eaa126ebfbp-2), C_(0x1.aea667b7c25e2cfd5f86bd0180b7p-4), C_(-0x1.9d42bc92105fbc1675af424ec92cp-6), C_(-0x1.84840a8e18b0614ca4eaeb216151p-11), C_(0x1.a3a969f351753a208cd3e5a8f168p-9), C_(-0x1.2b9d22453328eaf6cc00ab2ce255p-10), C_(0x1.95e4d7f634c66f1127081eca4c12p-13), C_(-0x1.348b4478275cac4e09ed00491749p-14), C_(0x1.d3098c771ac4dfa090c0edef58f9p-15), C_(-0x1.49cdbb7d5d852bdcaa3c1cea09bfp-16), C_(0x1.12cb123d22d84321bf94a9d64f4p-19), C_(0x1.ee369d60388e0cdc7a4cb2173367p-22), C_(-0x1.fe1ef00c018375d62e92ff3458b4p-24), C_(0x1.a7341d99c255c94d652d9d8f033dp-28), C_(-0x1.530b27430376f235ffb52485dd26p-31), C_(0x1.baba95d77648bbe90c5142dc80f9p-36), C_(0x1.4f068520e819c6ced35b43d3471ap-37), C_(-0x1.57c84bc8729954adbcf1854852e1p-43), C_(-0x1.4644a16a824bfa62197420e08c45p-48), C_(-0x1.8db806597a9c3e694cd52ef5d34cp-57), C_(0x1.0d894936ca76f0f900d3760154afp-62), C_(-0x1.b4baf18dcac141cf35421e01ae8ap-74), C_(0x1.758520ee5d32f0284861059680c8p-88), C_(0x1.01a0cdf0066867c0900e21808ebp-113), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f55ef3437afefacc7be18bbe98cep-9), C_(0x1.0777b4e7fcce2c0e40744ca54978p-2), C_(0x1.3f1d6fcf2ecbd47e40d3c1703896p-1), C_(-0x1.504b43d516f52267cd7e5fe7d16dp+1), C_(0x1.4eaade935c6e2740942fa58ebd6dp+1), C_(-0x1.5ad808042149f417dbd58af6b00dp+0), C_(0x1.cab544fbb7d4b4c60e5f5aaacf98p-1), C_(-0x1.9ef87caf9226b19c3d44c512bce3p-1), C_(0x1.71fed5bcb893256d48b5662cb1dbp-1), C_(-0x1.0f0d57adf520b2ff7dc518f39f1bp-1), C_(0x1.30c75d43e61143b20925258c8b83p-2), C_(-0x1.e86b0f7372ef580e2a548027c15bp-4), C_(0x1.b73425fd2a98ccd833576427e8eep-6), C_(0x1.4682acb561a50d1c8642601cd7d1p-9), C_(-0x1.2eacc75c57cd93079a89b775a2e9p-8), C_(0x1.a21a6f510bbe181a8681692c18eap-10), C_(-0x1.147cb459e63791d570da7fd30181p-14), C_(-0x1.28e19a4afa00bfea3a7c1b8c9b43p-13), C_(0x1.931858e53ca4936f19114cad31b8p-15), C_(-0x1.62eadbc9e95863c36c22bbc42279p-19), C_(-0x1.de496f2e6fedcba7342c1d21ed73p-20), C_(0x1.70387d4ff6ccbebda63c71a99d37p-22), C_(-0x1.75a0d535dc76533ec0cb363c4ecp-32), C_(-0x1.a0b3effc1d4a9bf1824673d2a6ap-29), C_(0x1.b9e3fb75297f14c235645de65301p-33), C_(0x1.a8bed9eb35249e37507da13a3226p-41), C_(-0x1.16b3429b615b32018d7a07c98618p-42), C_(0x1.ff8673e3757ca4761f1167047725p-50), C_(0x1.145878dae073bba8c6a0fb3960bap-57), C_(-0x1.9feee550a5c8e58e5b4245c07331p-67), C_(0x1.83b415f1b1f54454e6745eb4b4d9p-82), C_(0x1.0b692b789332c1658c8a24d9733ap-106), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8aac090c80a048b0460ec2d7badbp-6), C_(0x1.5750bdc83f394eb3b8faccf4d05p-1), C_(-0x1.50c8f6f54e2cc9e3e11af9656bf6p+0), C_(-0x1.8a451969aae1b985b829fad06526p+0), C_(0x1.a2b7eb3937eee939c776f8d31095p+2), C_(-0x1.118e064b4695a7f92c4b4501fcb4p+3), C_(0x1.c7bf87fc63cf93f68f74e5e7c825p+2), C_(-0x1.1d8d78044ee8ee6d6d812a1942fep+2), C_(0x1.e73d8bee7689f31a0590abd75fdap+0), C_(-0x1.2add7b6319082ca3c2efcadae5afp-2), C_(-0x1.d3adb45266b9c9f4635ae6e3441ap-3), C_(0x1.033a83600934f9863377b693a726p-3), C_(0x1.b5451b19e5929d480505b5a86b0ep-5), C_(-0x1.7b8dd6246eb29127a889717ed76ep-4), C_(0x1.791fa45e84d145e6dc4c1510b4b6p-5), C_(-0x1.7c0beae24c83b65b5de7467eb78fp-8), C_(-0x1.5782b21d6af61f4f7dba20838e5fp-8), C_(0x1.a840c3e83eb503c78b20b8a28b62p-9), C_(-0x1.986e55de09433017be901893ecf5p-11), C_(0x1.26705b8c8ad65b55b61c41f75588p-15), C_(0x1.d3d83a9fdf1319302a3787bdd6a4p-16), C_(-0x1.d82fd865aa4582e2885f825ad846p-18), C_(0x1.f5b54c9c1896a94bf7ab1ebbd585p-22), C_(0x1.fdc61d80cbe3fa72384c0df210aep-25), C_(-0x1.0fd59d78e582bd5f0e263192f5d2p-27), C_(-0x1.b2380e734b4f9e20f629d35cee8ep-35), C_(0x1.88e8ce1bbad67bfa806d6889ad1bp-37), C_(-0x1.9888eae4a10ce8dbd9f3a51b6ca7p-45), C_(-0x1.466525261ac31d726b6464754be8p-51), C_(0x1.1b33afe3275e0f5266344c60d67dp-60), C_(-0x1.cb1864e2c62c6b93f97126fa2abep-75), C_(-0x1.3ca6dac99711dbeeb8df3656a48ap-98), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.0491b50257a217948037c313c632p-3), C_(0x1.088e085a415b940e86ec5f53c805p+0), C_(-0x1.9cc2273fe20fe221de7ca14dc50ap+2), C_(0x1.b3ef626d8f7b0512e777dbab2038p+3), C_(-0x1.fbdaa71ed3446ae9d3eb57fb2edp+3), C_(0x1.ba80f6fc4d07a16a8240d21d3427p+3), C_(-0x1.97b8947186ea82517ff8170fe92bp+3), C_(0x1.9ec07cc028783871c266a993e177p+3), C_(-0x1.7db26c06ff96156fee69f60a32a6p+3), C_(0x1.1910e3936c71e0698749e0100bd9p+3), C_(-0x1.2af49c29492fb4bebe4ea4c0492ep+2), C_(0x1.4fef94a557c4567b7c45f05c21cdp+0), C_(0x1.8759880e99b2b3b19fcf3cb856f9p-2), C_(-0x1.52e5ecb25ff9114988afe0915415p-1), C_(0x1.5f17262b3d7f451babb3a37c2f6bp-2), C_(-0x1.a7f494de47ba1f8ccefd1a48b767p-5), C_(-0x1.5dc2bf7dbd1d10649dd1efeed2ebp-5), C_(0x1.fa52c9fe27d631a55490bc5d6453p-6), C_(-0x1.0edbce8cbb631c85810ceb7afb83p-7), C_(0x1.51bdedea6ecf9aa291d741d5449p-13), C_(0x1.03e8c53050207786cbf7a98773ebp-11), C_(-0x1.fbae0e996b24eb9e7412c53365a6p-14), C_(0x1.a5405fbd60ce14b0ebcc8751154bp-18), C_(0x1.8401a133e3997a7f15f86f10443dp-20), C_(-0x1.9620d8180585bbc8bcc656387216p-23), C_(0x1.59175b5517be80fcdb2badddc5c9p-32), C_(0x1.a5d4ddd28a790634117b9f52ee98p-32), C_(-0x1.a9e2125d31a3c8bd4449e4b094e8p-39), C_(-0x1.068a399565e004f3cf609f3513f9p-45), C_(0x1.3ca73a6f9a6a05c209544433b8c6p-54), C_(-0x1.740e2252efb089d1ae6c93a1b5fp-68), C_(-0x1.009e0cb9ab19e5360f5dcaede516p-90), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.12eabbc13ae4184543451253a593p-1), C_(-0x1.dcd48a30309a985e66770059ddf6p-1), C_(-0x1.61bd6ca0b74ea8c2e61c8e522049p+2), C_(0x1.4b16a330057a9a464e1afd029265p+4), C_(-0x1.6645126fb9e4a4d9cdaf8add299bp+3), C_(-0x1.746a9ef1dde16ed58e0b432bfa77p+6), C_(0x1.49df58a6d0bb202b69c6e445a50dp+8), C_(-0x1.2844a2ebcc53c8df614ae3957cc5p+9), C_(0x1.2e42267f64054a81e12f7b2ff462p+9), C_(-0x1.0225a1d4c62f4d7b402b42538ffp+7), C_(-0x1.601645627c56a1dba4f1a59caa2dp+9), C_(0x1.58f8de6f258472f30e4dedd3b403p+10), C_(-0x1.693ca7a1da62866e49185596166ep+10), C_(0x1.d8c8ec24a42109f71622d8b3d887p+9), C_(-0x1.46d08ddd7ae2544339cc13f918fp+8), C_(-0x1.3b3b035293fc39a231fe7419868fp+5), C_(0x1.d12d6fce626a721298fd94ab886ap+6), C_(-0x1.06b1d4ca392cd5c4bed1c5482646p+6), C_(0x1.11a1d31e54e9ef311bda0933730cp+4), C_(-0x1.40c7309469440a4e5541e2e4c29cp-4), C_(-0x1.5ca50bfd4e3e4aa86ac8722ac5aep+0), C_(0x1.83af684fffb5b293cdc91cda7503p-2), C_(-0x1.9e6da0de05c76e1cd2d553753824p-6), C_(-0x1.7858ef153620d7c30fc31cf56a03p-8), C_(0x1.dbde29a936a150c27f696a66c4f8p-11), C_(-0x1.7bcec5a7e8c292f303bfbe3660adp-19), C_(-0x1.4f2043d7bc5e1f3a3aca5e8c6039p-19), C_(0x1.c2215a9e7432391b90e0fdc7be76p-26), C_(0x1.2faa97edde49cab9c4399ff18db1p-32), C_(-0x1.023988307e2875f374e798bb263p-40), C_(0x1.b307ce337f9f1788bff0e23a47f6p-54), C_(0x1.2c0d7e12bcbb5186b064f5495d76p-75), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d53d20f76b4eb49c1b6330a595f1p+0), C_(-0x1.86cf243ed21bd08659834822cd59p+3), C_(0x1.17b81677ed649599a4d3595e967cp+5), C_(-0x1.abb0b3868d1ea2ff8d47921a5292p+5), C_(0x1.f121a0540b3049d09ec7e5551764p+4), C_(0x1.17380aa83335c1ea7599d28ad525p+6), C_(-0x1.0c95dd1e4ca7caa2bd6deac65cdcp+8), C_(0x1.0b7efc300b3c27dde71e697ba35dp+9), C_(-0x1.826ec4b2204db57bfd19486982e8p+9), C_(0x1.b8a41eb5a39bd8486cfb324fe223p+9), C_(-0x1.a1f5e828547f7c5b2bcb67af2fb7p+9), C_(0x1.5201c70981a0b03733b9e6dd6e09p+9), C_(-0x1.b80f281da59c5918dfb2c054585bp+8), C_(0x1.5562f5403383fa55297b9a337231p+7), C_(0x1.90f51962a56d70bb1b983c1ee4e5p+5), C_(-0x1.24ca65a640b01ad09d88f66dbd3cp+7), C_(0x1.f2553461b931355eaf34d3576431p+6), C_(-0x1.dd44638d13da936b6e3a63722e62p+5), C_(0x1.c0ad57b9e59f4a68dc33ce587da3p+3), C_(0x1.4256b15254b23391d079094819dbp+0), C_(-0x1.fef8071c6ce2bcb3957ad8d4d2e8p+0), C_(0x1.22e6dade4ecd5ba17bba3803612ep-1), C_(-0x1.5b42b69e978a5317df9091ce52d4p-5), C_(-0x1.642c165a0dc2d5830f0c68cef691p-7), C_(0x1.1410f766f54ec568508253190fd5p-9), C_(-0x1.866a34dd716a310ea2f7f87ada3fp-16), C_(-0x1.0b5a3f31f6ca3105091deb1b111dp-17), C_(0x1.e9e690f2d2cdcc9f8d2e274aa38ap-24), C_(0x1.73aa86e33bd9c22c0a03f2815f8fp-30), C_(-0x1.ab771b8e4149cc3a675cc4898a01p-38), C_(0x1.0db4d80a1d5dee01c7237b2562edp-50), C_(0x1.740bf5a4533bf10d9f87491f9f4bp-71), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.295ff3e65734f855f39c88490c77p+2), C_(-0x1.53451cd19bffc6de5e35716507fdp+5), C_(0x1.6528da0fe333f438d196bece2469p+7), C_(-0x1.cbdb85c1ecbc284c645d00a79bf9p+8), C_(0x1.932ea82ba595876f9e544cf675e8p+9), C_(-0x1.f84307101d81872f84fc73fbdae3p+9), C_(0x1.bf6854697aae94bb46e7b0542bd4p+9), C_(-0x1.bf12de658509da0b644cd695e0b7p+8), C_(-0x1.4368651bd726f170cb68d94b4efp+8), C_(0x1.6e6644c0e40c6d361a9bc94d8ca8p+10), C_(-0x1.63936602c4e494fb5778af823485p+11), C_(0x1.effe4a55a204acd95799b1a3ca8fp+11), C_(-0x1.113fec7086061d5415319b0c5f72p+12), C_(0x1.fcb0d58a8410175cda764e2c75f6p+11), C_(-0x1.a4bb9f060dab410fe3bd526fda39p+11), C_(0x1.329610ee0fa8084fbb618f8b1294p+11), C_(-0x1.6a3f2ab2a8a1738b723263aa7f2ap+10), C_(0x1.28b90043770072e85c55c758b4e2p+9), C_(-0x1.98095b9a0fe58b99d4dbb49d1d1ep+6), C_(-0x1.7e9c13fb873c76fdf7051d8da9ep+5), C_(0x1.38a8e96bcb8fab70b383bca5ab41p+5), C_(-0x1.67764003f2db50e6202ef878e23p+3), C_(0x1.be87d29fcd9eaf1da18ad636de29p-1), C_(0x1.281bdec2a7f8db103e09703f13fp-2), C_(-0x1.0bb48c6ffbbe8bdda51c03bcdddep-4), C_(0x1.77235116b4238df6f725d274e118p-10), C_(0x1.6675983c9f507c163e6782c7703ap-12), C_(-0x1.d3d6efe237ab3413c9e890035877p-18), C_(-0x1.81b8689afa6e0c7916f7a3885678p-24), C_(0x1.2f0e5249c6fc36ea9c04c196c326p-31), C_(-0x1.1cfcb984a013a5a7bc95cb9320e8p-43), C_(-0x1.891f706028ea406f88faa50dd1c9p-63), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.06fc2ba8e79eb72495307bac6ae7p+3), C_(-0x1.5489cef9cc78f65236603d4cf5b6p+6), C_(0x1.9903c6b2ba02d6090a910755f61cp+8), C_(-0x1.312486b078b78cd8f1a70419307dp+10), C_(0x1.4302b86058a5a1292888fa9ca885p+11), C_(-0x1.0b2ccf4526b8c244af343cdb508bp+12), C_(0x1.789932548bf931d92c8e1c8fdaeap+12), C_(-0x1.e12b9567cda5d69eb9d09a4087d7p+12), C_(0x1.1abf23f09fbf8f276f484c29af9dp+13), C_(-0x1.2d5cd803da680fe5c48016ca91a5p+13), C_(0x1.2251ae99e408a20ab182f4722d14p+13), C_(-0x1.003d36dfd5a7feaa6fd4657cd76ep+13), C_(0x1.9f286327797df00b01373e3a21a7p+12), C_(-0x1.2d0f0d917a1ccdeca67d314f4298p+12), C_(0x1.7c4b637f2390259cb36649bf5cadp+11), C_(-0x1.9dc666df2eb31fd9d525e80a61c4p+10), C_(0x1.706ff6209d6f31fbb17a3cac3d1cp+9), C_(-0x1.76b515afa4c5f086db4f0c0e11f9p+7), C_(-0x1.24480d16a6ef2cbf187e850a3c68p+6), C_(0x1.d48700b685d23247b608b5cfdb9bp+6), C_(-0x1.05a23476b2f21c52a72aaf8a7e1cp+6), C_(0x1.24935371deb2ec43e23d888eb93dp+4), C_(-0x1.4ca6dde02f223d08bbf5ac28bf78p+0), C_(-0x1.58615b018cee75761c906455ba3p-1), C_(0x1.608c7993e060e80a3ede46931d7cp-3), C_(-0x1.b69ce98ab84f025bb8e299cdad9p-8), C_(-0x1.4823967168edf829557ae3a04f84p-10), C_(0x1.35d91ac6fb610d89a9ca12ef88e9p-15), C_(0x1.1a7bfc97dc33f6885878a1ae185cp-21), C_(-0x1.2be69d6aba0faabdfc72f4f8d745p-28), C_(0x1.ab2f7726c736fed01e244eeb7278p-40), C_(0x1.26a24576b891cedff10c341592ecp-58), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7d326037dd59f04b93695dea64a2p+3), C_(-0x1.057b7f9e150cfea8b7f60a37452p+7), C_(0x1.46966635c034e3d077a23a34c32dp+9), C_(-0x1.ebce82ab1e29c2e7e1d24be27a9dp+10), C_(0x1.f63288a008a00b0de93e3b52ce8cp+11), C_(-0x1.7a1dba3b5d1c5c524569d9d8ab6fp+12), C_(0x1.cf6c2665a1ce80b761f29f92f584p+12), C_(-0x1.02e9d9c7c198539a0401a9ab1cc4p+13), C_(0x1.126ddfd818acd4152500102b2dd1p+13), C_(-0x1.fbbfeeed9e84aef44a32d1cdc74ep+12), C_(0x1.6dd45600e62e38c3d8b7dfec1df4p+12), C_(-0x1.70d3cf8b17a54f73f23ea7c9008bp+11), C_(0x1.116e22f7a2135c32a071c68e4c4bp+9), C_(0x1.45e19d7a9f76f8d3600c21c7d961p+10), C_(-0x1.541801f00ec703cee53ee38cf9d1p+11), C_(0x1.9d27adde86cc9d38961105f8f3abp+11), C_(-0x1.718955043c8aaad595f50f39f434p+11), C_(0x1.13d222dd6eb22f7f0b910b51dfcbp+11), C_(-0x1.75dd9fab7780dd812eb2ca0b6548p+10), C_(0x1.b95889cd4ba403f3d771bad22aefp+9), C_(-0x1.880fb1002a98d978d68c5c6d01b8p+8), C_(0x1.a3c6bfae2048432d988090525bccp+6), C_(-0x1.6af0f7c1089720fadea20b94dfd9p+2), C_(-0x1.7dda27580f4d6fe605e5e2098125p+2), C_(0x1.bb56918206273622bbbf209a8389p+0), C_(-0x1.95410e4d3fa90c79d49021063b4ep-4), C_(-0x1.1e3dcf4406fb03d054399893d4cp-6), C_(0x1.863de856b0c02544096765b7d0aap-11), C_(0x1.82e7abd79b3d018087088704fa41p-17), C_(-0x1.21b01c6eb2b87dca0186448dc932p-23), C_(0x1.2f1ce1bb4e63e9b48ca04ddd06b5p-34), C_(0x1.a21b5c9a00d44d929d9e41311f24p-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6636de936afdb6694c4ffaed6a31p+3), C_(-0x1.f93a40edfceae00ae68e29b08ccap+6), C_(0x1.446da371d76c83e79d3a084840a1p+9), C_(-0x1.f81b7969b6241ca8af219aea83e3p+10), C_(0x1.0bf59cc8ab3644f7ca5bdfe6f82cp+12), C_(-0x1.aac9a227eb351b4f5d24fbc72641p+12), C_(0x1.1995306c55b12646bead2c38ad5ep+13), C_(-0x1.558e777f304785d9e9d3bf74bb24p+13), C_(0x1.8e256f3ea2d2e1b7bb373067b872p+13), C_(-0x1.b16f217fc65b857f8f6c9d68eed5p+13), C_(0x1.ae7e2aa7eb75bb88db9f2bedf708p+13), C_(-0x1.8d7f6b89b7d82de8cbcb8a91aep+13), C_(0x1.5bc0c9e9bcdde01e3a5bcbdf7ae2p+13), C_(-0x1.1c9a0c6fad5ae4a6fdea1b4bf6cap+13), C_(0x1.ae2f95c3b0ec2e40af37580cdc26p+12), C_(-0x1.2f129053ebc24ed7fe6fd750dd19p+12), C_(0x1.8d5b23e080443674d13b71f54d14p+11), C_(-0x1.d627dd21f8491dafe966ff60514ap+10), C_(0x1.ed8f9f756f065170266103952acap+9), C_(-0x1.cf7165a4ea829414cafd158d5c4ep+8), C_(0x1.6d33ddb7ad7e8017c0cb0ef30276p+7), C_(-0x1.65b4962a79c56602e9794ee156bdp+5), C_(-0x1.4d3b8e7db26f275e39c95bf13c09p+1), C_(0x1.950dbe3d7aca2e2a683f470bff22p+2), C_(-0x1.dbafbd443f803e2caf8c9757690fp+0), C_(0x1.04861e6b2202e3d3d031b9ec9cb4p-3), C_(0x1.7fe12c9629eace47e413a0b6403dp-6), C_(-0x1.c081b52017ebd837349a62b66ef9p-10), C_(-0x1.adbded066f7794fda23e0774673bp-16), C_(0x1.dd5025fbe71cc3a7e8141de53daap-22), C_(-0x1.642f3973aefae4a4f6422168ecd6p-32), C_(-0x1.eb48617a106cce90559379e40303p-49), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.24754790ab93df0d2355b8c8a1d6p+3), C_(-0x1.a21d6a4e4d9eb295ee53b44586fdp+6), C_(0x1.0d7a54376cc0558116461ff0ad85p+9), C_(-0x1.9dbd2fa0800f2f31e9998fd08c87p+10), C_(0x1.a81b276d71be81d44423e8d7940ap+11), C_(-0x1.3af0559f33f06e14389580e81a29p+12), C_(0x1.79904c76e9a060ec8e465cd0f64ep+12), C_(-0x1.a8514199bacb20e9109b77f293abp+12), C_(0x1.e26f534b2b2fd591e9ff3ecf4696p+12), C_(-0x1.01e02902687a04ca65f96e6a8b68p+13), C_(0x1.e5294c43a413c0653234e7f1aa09p+12), C_(-0x1.a1b883ef12d1d5472469dd56bc1fp+12), C_(0x1.5e76af85cca307f1a26352596c69p+12), C_(-0x1.15aa3e69a2aa9b29daeedbfe44dep+12), C_(0x1.86a5a2358b24b67c01514a96d3ebp+11), C_(-0x1.f3289b5523f3f49f9c93e10ff537p+10), C_(0x1.313866068b105f8069b31bb16bf3p+10), C_(-0x1.4f6a48ce8e3698f8a03194833bbfp+9), C_(0x1.23a63c6ead8e0e6aa15fe6f45702p+8), C_(-0x1.8310a2cf199a480eca2c2b3394c8p+6), C_(0x1.66b7a5ffb79e9dc036820a3ad358p+4), C_(0x1.9e1737848ca25244943790e11b0ap+2), C_(-0x1.b5673299d6c08937871359b74265p+3), C_(0x1.06e8de128ea18c685f5f56cec9c2p+3), C_(-0x1.231b2877825a92418fa8440891fep+1), C_(0x1.8ab9028a51e09357bf81bd620a6dp-3), C_(0x1.fe0af766377cd4e6799421dcabc8p-6), C_(-0x1.2be854453bc6da5ab705ba515333p-8), C_(-0x1.2ae4048d20f92820dcdbdae1afdp-14), C_(0x1.cba1e05e755f67b92b6effedbc08p-20), C_(-0x1.07cc113fc2e535393592fd575de3p-29), C_(-0x1.6bcf254ca2da0ef6aaa6b7f61e81p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.6734f40a39a9f749d116c99eb0b2p+3), C_(-0x1.02800bdef42eee8e9cbe8c5b799cp+7), C_(0x1.46b9a7fb0659b383f2e6ccc2bfdp+9), C_(-0x1.d4653513846d8b632e3ab00ec6aep+10), C_(0x1.960cff14f27e9f5b5c924a5e31a6p+11), C_(-0x1.978ccec6aa50557b75045abb874cp+11), C_(0x1.65f6a7cb1b6c9a8b6c858f9858eap+10), C_(0x1.c444279391a3fe3940190e9b0d42p+7), C_(-0x1.743641ef137ce3dda68a9d7a6a5ep+7), C_(0x1.b0d221397077b61aaac6990656bfp+8), C_(-0x1.789f01238bd736d3d165c526de34p+11), C_(0x1.78076d93e8b2a21b1e57f1d51e32p+12), C_(-0x1.b80f30dfff7c8968576fe93ef454p+12), C_(0x1.bb7e92e14a551f987f2cb928af9ep+12), C_(-0x1.d7e88c840d9e4cc3ea2da57543cp+12), C_(0x1.d2485f20f81231778ef5c3fde98cp+12), C_(-0x1.8196b31f2aea3e18b21270e4dab8p+12), C_(0x1.2207d34a8263912f9c133abdb819p+12), C_(-0x1.b1c880d8d5a9e0a75d42bdbef999p+11), C_(0x1.2ab917d5ba30fbe55897a0ecf4f1p+11), C_(-0x1.5bfb47d78d5c9aa6b7b3ea1583e5p+10), C_(0x1.6b044d9f20d2a049f5f6d532822ap+9), C_(-0x1.6ef48eab0e23a150ac4817c103f4p+8), C_(0x1.3c86344d962287236a63845979d3p+7), C_(-0x1.62bb42947746334cf9768602ee2bp+5), C_(0x1.302845e71cb15c4d9c86c4ce6c69p+2), C_(0x1.8f631724d133592549dc9efdce6cp-1), C_(-0x1.82b35bd32ad297d37e7e03fdd8d4p-3), C_(-0x1.957cf95e09e20118e411d55e99c2p-9), C_(0x1.f6dae900f0dfcd786a2b2d830063p-14), C_(-0x1.960194a81c1ce1e7d634227c61f3p-23), C_(-0x1.17e5f78c653c49cc8a92fdb4f4c1p-37), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.206cbb79429c2414ff0c64aec8d3p+1), C_(-0x1.a083553e4e5a13a3aa202924b202p+4), C_(0x1.0cf208fc3d0318bce33d11bbf4eep+7), C_(-0x1.98490e95032010181534884dfc77p+8), C_(0x1.94a218c65bbc9e721912af119136p+9), C_(-0x1.17c83af6fa175ec696cff584b399p+10), C_(0x1.2a2038ecd41ce99e3b7c57bb1465p+10), C_(-0x1.2a77ab7e6edd3ce02f308ffb22c9p+10), C_(0x1.48a4ad0a80d290f172a8699dd903p+10), C_(-0x1.63c7a0fcade974b2571bdc4dbe83p+10), C_(0x1.4db14cb7e55e4fa2d6df561d81b8p+10), C_(-0x1.1f7d1042db45f9c24caed3674305p+10), C_(0x1.f7c955767cdfe40b013173464e47p+9), C_(-0x1.aa68a77f455100ba1716b7e81665p+9), C_(0x1.42df44997682f8bbd8705c8237fap+9), C_(-0x1.cc3c8a0b1406c4cb1854f7f475a5p+8), C_(0x1.4691261a687538ac5d74074129f3p+8), C_(-0x1.af8b6d718425edc744dded4be2d2p+7), C_(0x1.fddec0373e9c198b0187bcd05338p+6), C_(-0x1.206dca918e07679e17977c9e643dp+6), C_(0x1.394f1079b1d1bab9757ca4be3df6p+5), C_(-0x1.259c4ffdb02b3840be66495f597dp+4), C_(0x1.dbd0529d14d06481a401f7d28924p+2), C_(-0x1.6f7d774b2017e6812c50c53f3953p+1), C_(0x1.bf296d0152554d98043114f06ab7p-1), C_(-0x1.7c872eb94aac4434f1f1ee90200cp-4), C_(-0x1.14b95c5b19212b4fc03cbfb78471p-5), C_(0x1.194e2e645655459aae5fe3cd821dp-7), C_(0x1.3531940b1823b632efb391ef6f52p-14), C_(-0x1.7166e830bc1e3944c924058c6f08p-17), C_(0x1.2436b817dcb001ed9c4696c6c208p-26), C_(0x1.92b45b9b9529b7ad46fa43bf2077p-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.74cc6314dd173590f359217811bfp-1), C_(-0x1.0da07c63bf5b57427067a74fa654p+3), C_(0x1.5af5b4b6a40764cc3bad47672c18p+5), C_(-0x1.03fb3e545cdf8287d11ea7aeca93p+7), C_(0x1.f3ca921092c121957e2f18e268fcp+7), C_(-0x1.44047871dcef9850bbedf1b419e5p+8), C_(0x1.3358182c099a552dc3876c2274b9p+8), C_(-0x1.10bd53f78b9c50f9a6e08d98e9a7p+8), C_(0x1.29eb9e1a3472cf232a6709ddfbd2p+8), C_(-0x1.4a2468b639e365dc0b3fd125eb7cp+8), C_(0x1.26dfa9c8f6c029f4753dc36c664p+8), C_(-0x1.d2f1acef4b4ba3b7e608497ba6a3p+7), C_(0x1.9597a28faf38ab1c2b429a5dd79dp+7), C_(-0x1.5e8348f17beed687dbbf25dfed75p+7), C_(0x1.f9613319a9e146e700ffce02e1bbp+6), C_(-0x1.4ea47fc45e78dfd9cd4f69ce75a7p+6), C_(0x1.dde07d45fce1683ab6993808e07bp+5), C_(-0x1.3e0ca7abd11c2d7cf0bb1fa5493p+5), C_(0x1.599232ab9283f8d2a3c47d198eb2p+4), C_(-0x1.6ac8188fba9f38deb15c420eb1d6p+3), C_(0x1.96eff61828d979e9be81958fbf3p+2), C_(-0x1.7071f5cc1d4694972d2c2c65d04cp+1), C_(0x1.e12484c6688efee796e8769de364p-1), C_(-0x1.4f89eb4be752a44a4402c23fb27ep-2), C_(0x1.c393c8a6167f5e45bd4990217d8dp-4), C_(0x1.7dd147fa057e0b50125bcfcb63a2p-9), C_(-0x1.13f7fd7ac3a280d730a2c002774bp-6), C_(0x1.03548ce92b6649d84ccad32bfb61p-8), C_(-0x1.2341881399bbc4b237f436539e91p-14), C_(-0x1.74f214490ba0ea1723d42cc72a56p-17), C_(0x1.5a01bfbda2f04b0c7709f4c8e447p-27), C_(0x1.dc5f89a7304e8e2e4721be65411cp-40), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3c25010b60fb3674740b05f24332p-3), C_(-0x1.c9af2c3ccca23c68e09fc2f7dc65p+0), C_(0x1.254de8cf13856aa803ccd66fd125p+3), C_(-0x1.b1e5eadb5abe7e897564be3e19b7p+4), C_(0x1.9450c60bf67cdef9bb4416994ee8p+5), C_(-0x1.e89b5b0fb80bdea3060e89b3c3b1p+5), C_(0x1.8f3eff015290335d6c5ba8db3ba6p+5), C_(-0x1.26718b161a212a6473dfb26ae75ep+5), C_(0x1.4a6ff4d30582a729b53c09473635p+5), C_(-0x1.8a12303f1194f457265cb9c94d2ap+5), C_(0x1.48e1a80801a27ea5d6b8c09eef2ap+5), C_(-0x1.bb6e89adbb91b4400c7c8bacc9f2p+4), C_(0x1.826bb857299c08edd527360dc4c6p+4), C_(-0x1.66d59bbc1beb521a1822adef1e5ap+4), C_(0x1.d762d94bf79addacd550a56af00dp+3), C_(-0x1.017df19c95ab47cf0b3801bfa83ep+3), C_(0x1.7ce4baf9290af712ae0b872e1a1ap+2), C_(-0x1.076985c84651e1c5e5388d3ed212p+2), C_(0x1.a91f1aca1f4d85453f0f9c33299ap+0), C_(-0x1.19588e1d9e17bce2cb6d81a29cf5p-1), C_(0x1.70b50254db487528bd3d29d3be35p-2), C_(-0x1.a1a5a33d385d5b812d62c1b7093dp-4), C_(-0x1.4244fca3bc21ee34636ecc1caae2p-4), C_(0x1.e957c08844afbfd050ce104aed32p-5), C_(-0x1.7d54f6f8e016b5cc4d2c805b197dp-6), C_(0x1.293a2e4267dc81d9d07b602eb6d4p-6), C_(-0x1.5d4d2a8021a073e46a46ee79612ap-7), C_(0x1.5b4fecdba5f9087fe95645ea7106p-9), C_(-0x1.4ed9a3f4a9afdf2f3236e61b6585p-13), C_(-0x1.125ce08dc9b661014740f9362c84p-16), C_(0x1.5ea5b19f4ff29c7baf0a16f9257p-27), C_(0x1.e1d2c8108c65a8cd4dea742f8f7p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.78f50d65c4a16421841e3f303dcap-7), C_(-0x1.10f9973c2a07331ce0ccac35cccap-3), C_(0x1.5ea80ed1cf2f2dbfa0cb00aff04ep-1), C_(-0x1.04e32caec7824fdd8feada2c4721p+1), C_(0x1.ec7b02aa786ba97d52a304f12e4cp+1), C_(-0x1.3174e658f8076784a24459fccb68p+2), C_(0x1.04af0495e940fb1a0934ba937e55p+2), C_(-0x1.82d9ce4c80e7862d53bd54f737b2p+1), C_(0x1.8562e843b948818ab7543f47aa8ep+1), C_(-0x1.b4475da1bb05033056b650854fbcp+1), C_(0x1.773ee8a0b6e167fb7d5268d067eep+1), C_(-0x1.162bbf2e87d9ef969863945cc2b1p+1), C_(0x1.ed70fea486a4beb02761cf722ef7p+0), C_(-0x1.be0a12832787fdeed784930ccda8p+0), C_(0x1.43344776804460a755e69c9fe27dp+0), C_(-0x1.bc193640146ea4b82ef2e3c4b7fp-1), C_(0x1.59f9f9e4cd9a370cf83a45b3405fp-1), C_(-0x1.ea19fd7c2dc2c5db9794b9225413p-2), C_(0x1.24cb1e377b41a9dc8bcbafd5c9e4p-2), C_(-0x1.6d1685ae383191436a11192a6015p-3), C_(0x1.ce23289a0d5c025951ea09936714p-4), C_(-0x1.e968908c7474ea2a6b493052c12ep-5), C_(0x1.e76f4d23e3441d0b7efbafd90df3p-6), C_(-0x1.fe92310a812ac1b17c748db28b34p-7), C_(0x1.bcfa77e534eadd2bde270b26117bp-8), C_(-0x1.3fde2d0e55306e2cc04a5e77181ep-9), C_(0x1.f9933c512b48e3277e9a4bb4b19p-11), C_(-0x1.3cde4b0a8d6703babab6ae1d57aep-12), C_(0x1.055b9666e46160de479c93713a7fp-15), C_(0x1.0afdd4a80e426c9edced22de6763p-18), C_(-0x1.63fa7644baff156719997e19782bp-27), C_(-0x1.e7410ee7b8c80f0f9fbb1245ff4ep-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7a4ce6ed992bb75d1922e250e291p-16), C_(0x1.42671fb0211a4a998d3a999cbba9p-7), C_(0x1.e6ee175fb834c8b714c01feffa11p-3), C_(0x1.b4d3dfe055a7b7209d9d957ea39fp-1), C_(-0x1.7d14720c62ef81c88eaa2934ef9ap-6), C_(-0x1.5a94efaefa077beed21f8e31afdfp-3), C_(0x1.42098eebb591e34e8dce26f5d9fdp-3), C_(-0x1.9b7dc4f9c2feaee194cc6094b673p-4), C_(0x1.80316f876ff22302ae3ab2cc5942p-5), C_(-0x1.8b13757e5a833cb7be38d086bf07p-7), C_(-0x1.9d8e278701564e508cebafcfb133p-9), C_(0x1.712f899035a27c983c908b6bba6cp-8), C_(-0x1.bedf3b9dd86feef8439cad4de336p-9), C_(0x1.4240f2118e493251bd8d9317b7d6p-10), C_(-0x1.0ae82fa70b020b05eaa57d2e86fcp-12), C_(0x1.5d87bb3a4b0411a199a2bbfb04acp-16), C_(-0x1.2d8c3a0a0933f834dfa752e731e6p-19), C_(0x1.e1643353d40db172275bb94c8db6p-19), C_(-0x1.66348482b32035f68245e91af884p-20), C_(0x1.38acac17e89fa0162b376bbd5bb2p-24), C_(0x1.00e7697e09dd627363f277ae5d0cp-24), C_(-0x1.a8f56e9d3a1cc00e461420464983p-27), C_(0x1.5a1ead033f0e454a9963da3438ap-33), C_(0x1.d4875150adea6366dba9b099b588p-34), C_(-0x1.cfdee2a4d421dce1ed3eb1824eb8p-39), C_(0x1.4ba806282cb55638c336fa42513ap-41), C_(-0x1.af632a71f0a85982bb61e8403dafp-51), C_(-0x1.cbdd4d28c6b8d8568783fc7a0356p-51), C_(0x1.4fd0be68bf175912b8e24547698ep-58), C_(0x1.61ffe57672ff2f1dc3af03a0658ep-65), C_(-0x1.3c884f70db98bc38107c463d9e95p-75), C_(-0x1.1f64d25df3ed3d5bb564497f042ep-86), C_(0x1.2bba4936fe9662bf3eb13c8582ep-103), C_(-0x1.1d5cf90ee87504b468831a41ae1ep-131), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a0c37edf06a8f94f636662aa39bbp-13), C_(0x1.5938ebddd04e210d6e15ff1b97b9p-5), C_(0x1.0ce81716630c1f9cc4b07a770d1bp-1), C_(0x1.bad54d5c0a788c931739cae743bdp-3), C_(-0x1.734c9748f4ffbe66b4e75bb9c043p+0), C_(0x1.219848201b9a0b52ec9b8191e5b3p+0), C_(-0x1.967b651c15d3ab20c349ccf7a27fp-1), C_(0x1.1dd39ecf7d040d13482ae3416703p-1), C_(-0x1.7d233595983848fd2834ed2571cap-2), C_(0x1.bdf22d0e95afab2bb96e5bd19c6ep-3), C_(-0x1.ab4ab3ea2f36e1559b9c3420ec0fp-4), C_(0x1.361512fce1c67582139ca256de4fp-5), C_(-0x1.2052c9fd431d75170cd08f266eddp-7), C_(0x1.0fc840c4a9b1a2b7d29c508eb6d3p-12), C_(0x1.b1c90fbb8951feffd58470c9d80ep-11), C_(-0x1.c8b87ff5be380a38841f22318f52p-12), C_(0x1.11b72f5c2ab5d1894363c9e7ab05p-13), C_(-0x1.44fd9e718f23deb8dfb254ca9d3p-16), C_(-0x1.801763632cca8db4265fd9b7171p-19), C_(0x1.09096d92c04b504ace3e77b64297p-19), C_(-0x1.d590c9308d6d05c5021dabbaa32ep-23), C_(-0x1.b408b4e946eb9006560416ae94d7p-25), C_(0x1.26b8d9536f33f7963391a473b488p-27), C_(0x1.21ba41de7becb667214c3ca5d913p-30), C_(-0x1.005e15e86c4a56785a4a0f6ab3f1p-33), C_(-0x1.892c108c5e8de79fc1617882908ap-39), C_(0x1.5e2035f63580023798eda85d3d21p-42), C_(-0x1.d491970f7aaa6c617e7d1c311941p-48), C_(0x1.4a6b89912129028f7fea4136c808p-54), C_(0x1.1d009ad5392248132b10cca6afdep-61), C_(-0x1.a642a25e87ebcab18086a8e2fc06p-69), C_(-0x1.2011c2ce8690d9b9656d986e92cap-81), C_(0x1.9134326520639372add0f822994cp-96), C_(-0x1.7df9e44e24a4ebd5669f58093dafp-123), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.971a55e8255470a8e87397205afep-10), C_(0x1.3dc2c8dbfcf7f93df2e2e770167bp-3), C_(0x1.7546e57d9721df0ee0f4226116f4p-1), C_(-0x1.037adcec0657ef37e8f5501826c9p+1), C_(0x1.f0f2562cfec47ba3b00526650a7ep-1), C_(0x1.6c9838c4962e4af4c25ecbc468b7p-1), C_(-0x1.ebd5569ff73f2f877d55e4233979p-1), C_(0x1.2915d00cfaaa51da1d3b22bc1b91p-1), C_(-0x1.e34c46891f72dbbcd8a73f99bdap-4), C_(-0x1.5072010dc85e733fe3c06054204ap-3), C_(0x1.c67306010de8b6a212c8a67869b3p-3), C_(-0x1.2fa98054a2107feaebe98c8fc435p-3), C_(0x1.df7d703c2f7ab707c9106e495b0fp-5), C_(-0x1.28e5dcad2172c449a1b7dca486f3p-7), C_(-0x1.dc7a4c4cd9eeea5517aa806e57aap-9), C_(0x1.18e996b43138b67ddc3e006638c8p-9), C_(0x1.b32438920580e922f03409f3eb6p-18), C_(-0x1.9037acbcd4ec345580dcc6ddb006p-12), C_(0x1.44eb457dfe491144a6a8147f8c33p-13), C_(-0x1.4321ac67acfe448897274bc08792p-16), C_(-0x1.256fe0790910edb7d614dee4ba24p-18), C_(0x1.ed8efd908e26dfcaf46a03ca2c55p-20), C_(-0x1.a7d2bd14ff6144489ccdef55f7a8p-23), C_(-0x1.037133591bd1adccd684e0184c22p-27), C_(0x1.ab74edd3244b37270e37d649fe31p-29), C_(-0x1.fc9e38e19ebe258bd42cc39b8e13p-33), C_(-0x1.8084026dbca3fcd810e0eb658b42p-38), C_(0x1.368fe30917847fa68db0002b6cdap-41), C_(-0x1.39e30293b3af2c4949eb4a178d03p-51), C_(-0x1.7503d7779e458b1aa1fdddbe3326p-54), C_(0x1.9a1da2379c2a990ef23e5cbc6726p-63), C_(-0x1.f1aa7d24b3e7cf365e425fbf9856p-78), C_(-0x1.86a335fc44a9a2d537ec8158da4p-89), C_(0x1.73ea8d0ad818e245ff5b1e9884a2p-115), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.5a9454bfce16a0a0dcc504f76122p-7), C_(0x1.dac670f07b3810cfe0200e30b836p-2), C_(-0x1.07048222529da273b75a32ca582bp-2), C_(-0x1.b83c3b0926524121fff53826cc44p+1), C_(0x1.0676df488b1e4ed89c22050c7595p+3), C_(-0x1.30179a3f4da7316ca0c075836a81p+3), C_(0x1.05ba4eee5e31141776d12d72864ep+3), C_(-0x1.93e9c8737c9db916fd3aeb9dbbf9p+2), C_(0x1.11f35b97811e1392b7e5f33b18aep+2), C_(-0x1.34f47b568e89b7ecbfe83a3f3f92p+1), C_(0x1.13cb0f11e8118c8728dc07b4f30bp+0), C_(-0x1.7b2819c00008e638df3a1f667154p-2), C_(0x1.a1284251ac1c9a380e6762cf2045p-4), C_(-0x1.9462a198000c99e2d17bdaf7509fp-6), C_(0x1.98cbd04cf38d0b88fffaebdc2248p-10), C_(0x1.790fb9b4e1079fdb7c7f3de53909p-8), C_(-0x1.44467a122c6f0b3c619500e4be8cp-8), C_(0x1.0c81b81e9a914d549de9a5603fbfp-9), C_(-0x1.cac8f340d2aa3b68b219b85c015dp-12), C_(0x1.056344fb5f7fa4c5bdacd495990dp-15), C_(0x1.64dbcddfce7247b526ac9d7e0ccfp-18), C_(-0x1.2ea8218d9b8d1d441244fcd4b66ap-19), C_(0x1.ae941e74a568c6bb01832f906cd8p-21), C_(-0x1.1e524786cf0a95db795410244806p-23), C_(-0x1.2a97ea36eab85a08d496990ea5bdp-28), C_(0x1.91a720541503c3aab6c0537ffaf4p-30), C_(0x1.61eee7e526616835f0ba9666b29dp-35), C_(-0x1.1df0b9e54c56a105bc6728365e2fp-39), C_(-0x1.1ea73fd30a1b3871739285e4eb76p-44), C_(0x1.4cef49ba65ab3a484daa2106a09ap-51), C_(-0x1.042acc29aba7ca20f707f59b4985p-59), C_(0x1.2f927288a9fec8bba637277e07b5p-69), C_(0x1.f64dd565d432a80474f09d7042aap-85), C_(-0x1.de3b2de560b19ad42b01407d7ddfp-110), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.f65b07bf823cec483c39d5a11448p-5), C_(0x1.f0133093951f37f6a896ead34da4p-1), C_(-0x1.2157210d40dee8bdad6501ac0ec8p+2), C_(0x1.a490d9720df43c568fadfc931407p+2), C_(-0x1.0a37608588b0a4119bc76eb25c95p+1), C_(-0x1.166e49a8a0cc2b9e02e97716b213p+2), C_(0x1.47f9043ce81ccaeaa7b51a7192a1p+2), C_(-0x1.51650f8f0f7bc2a8e1c87a310a8ep-2), C_(-0x1.4a651a2d2c8b208523a548f223d3p+2), C_(0x1.daa4090446b0d279d1861aa53d55p+2), C_(-0x1.69495e8e6d87591bdc3892f6f8c5p+2), C_(0x1.0277af1839af3f779c7cdb3ae641p+1), C_(0x1.6b6419616b5982af3302995b743bp-1), C_(-0x1.731cf8395e4c8d5b88b93305475p+0), C_(0x1.d1e75297f2041df9c5f5bf256a3fp-1), C_(-0x1.d49cf0590577e4f277c27934579cp-3), C_(-0x1.397f17a4194e8ce372c9e426fbfbp-4), C_(0x1.7a21cbbedfbe11f0454df42e4775p-4), C_(-0x1.2988578b3adabc4b1512d4cbb6abp-5), C_(0x1.545144ccc581a21bd7cff42729e5p-8), C_(0x1.55e4a8c66e27b9cd3f291e5b6a18p-10), C_(-0x1.82c0f91d9bec49c90d6f1f27054cp-11), C_(0x1.ed2cd19280a89d42a9f703b9d37bp-14), C_(0x1.348863e0c3862c00204ef5c290d7p-19), C_(-0x1.8699ea90dfea228ea4870e9888cp-19), C_(0x1.03f81160244ea4e0561d2796396ap-22), C_(0x1.2dc9e87ced5d3e0075d1b0f48214p-27), C_(-0x1.1e0055531ecb5b5480ebd74d3d13p-30), C_(0x1.78b61664e5a70e15a0ed3d839b88p-39), C_(0x1.5f0c636dbd6bd39cd760ce07545p-42), C_(-0x1.6221e33afdbcbb6531e539a33b88p-50), C_(0x1.408f5ecc984b11ae43df9f32fee6p-64), C_(0x1.516335d80f8b3330068bd15b7661p-74), C_(-0x1.4137e85d31ab926f05f01bb46b99p-98), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2c1ae6823399b2cb435cac91e1b4p-2), C_(0x1.0b5a4c7a50e393bc298a68b8c54ep-1), C_(-0x1.35e6d8721b448f3219c2ebf797cep+3), C_(0x1.08056d18cc3abfd158e32f385712p+5), C_(-0x1.e443d0b2f1917ce5a7864d3c4f97p+5), C_(0x1.26e95184621c1fe6c94f3f1e55c1p+6), C_(-0x1.027c3db720fc8465d08ef051f852p+6), C_(0x1.39b53e5c17e2d98c6d1b6a224a1p+5), C_(-0x1.a2ef9908e5f3063d5f6a67d79ad9p+3), C_(0x1.3c1856843b6ed43e69173ec9beb8p+2), C_(-0x1.50a61279deff7a9f95e9f5b1ffb7p+4), C_(0x1.7005437ea7f364b02fc7783b2745p+5), C_(-0x1.c35972d3e17999223e53468e37e1p+5), C_(0x1.5e3ef093f504f098160dfa010bc8p+5), C_(-0x1.3ec57fe40125d739e37516f7731fp+4), C_(0x1.8f87e8ce4ea1f97c1a2b6959d92ap+0), C_(0x1.3ebb2932b57e51e04c3ab524c19ep+2), C_(-0x1.f8f19a2160e20da38a2d0ba656dp+1), C_(0x1.767cc5a51bc973a84dbcca58047p+0), C_(-0x1.713b4eb249abff794f2872f24925p-3), C_(-0x1.57f96e30ddfd9bc4477fb05a13ecp-4), C_(0x1.6d3c7dfd75dd9d13bacd85402f0bp-5), C_(-0x1.f364307632fcaaf5a516d1734575p-8), C_(-0x1.a69b8516a1ae027062e6cc44b942p-13), C_(0x1.037145bb4087ace803c84d0a5bfcp-12), C_(-0x1.900324bb445222e2af610e0c858ap-16), C_(-0x1.c39b875e9ce90c4599df73f3cdd4p-21), C_(0x1.257ca20db0247e060d265d852efcp-23), C_(-0x1.94fc591b19bf8737ee11ebdb8608p-31), C_(-0x1.f784210bc45a0c13791f8d01e395p-35), C_(0x1.45da31c732197dc55fbe5cc58e5bp-42), C_(0x1.7b22a9fcf8e8894af17ff0c96d4ap-59), C_(-0x1.36334f22553eac1c5efc112842bap-65), C_(0x1.27559bf46283fc4563833952d7p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.1b6522cefc386094703a1b940b9dp+0), C_(-0x1.725aa82bb56b65b988671eeb4df9p+2), C_(0x1.352392d274a5a82ecc23fa33228p+3), C_(0x1.0932fb369d6b1d42ff49967acb97p-1), C_(-0x1.879358a7154c8fe38abb0596bfcdp+3), C_(-0x1.7bc58b3667a9b25269bdd7a77a0cp+5), C_(0x1.0b13ecb8bf57a95468d44bdf0495p+8), C_(-0x1.43c9c4bcfe445dc8af77035b453p+9), C_(0x1.09ee5b9c8e5bb60028ced9f338a6p+10), C_(-0x1.51e18f7652afc8e422b14381c4bfp+10), C_(0x1.644767119a752b7a9c6636fe4ba3p+10), C_(-0x1.410473daba291fd610d9e089e60fp+10), C_(0x1.da130c42857b78f659a1d6303558p+9), C_(-0x1.d701d7e9133134b0f0d4fc7eec0bp+8), C_(0x1.63319398a8ba44714204cc51ebfap+1), C_(0x1.103c991a3daa09809634b6cd54c5p+8), C_(-0x1.27d3d6e7fd9bf2dd1ee7850f5b25p+8), C_(0x1.603f483ab97e5aeba0d81de20a75p+7), C_(-0x1.d0777f2eb89143bc896dcbff61bbp+5), C_(0x1.7a787d5d8610ba8dcf36333d8bcdp+1), C_(0x1.ac67a9959292f75e5874c7846e26p+2), C_(-0x1.90d4180a252c7e521492da4437e6p+1), C_(0x1.1a35f9399ae687cbbdc99928434bp-1), C_(0x1.6227b50ba315edc16940995bb21fp-6), C_(-0x1.88f3b956f9d0dbc770c981dd72f9p-6), C_(0x1.6aef03d1b7b80f64bb2a7833284p-9), C_(0x1.578d75e3a79566687a46c7635dbbp-14), C_(-0x1.6111d8865be635c9573ceef437cap-16), C_(0x1.98ae70f64468f801509511411944p-23), C_(0x1.ab515975e313ab940af4e8bf9f79p-27), C_(-0x1.5c32c92bf479e396733399534bacp-34), C_(-0x1.1971da66bec91c38c535f903a2a2p-47), C_(0x1.4b1b6c4a0c92ce2876a63b480607p-56), C_(-0x1.3b3d574a043e2a3cf8b53ffa3decp-78), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a2b24d1ab719647b6a1c2ecf4af6p+1), C_(-0x1.c90129239b0561ac21474fdc1f01p+4), C_(0x1.cf2e00eaf4f0becc29975ebbb3d9p+6), C_(-0x1.2500bd3d88164480cc94fa086f38p+8), C_(0x1.077598d26b6930fe825f3677222p+9), C_(-0x1.6c0faa52dddafef24a3684f97c95p+9), C_(0x1.958eaac6820db16ee26374b84f58p+9), C_(-0x1.6c2fe2006b51236b8cd28d2a3376p+9), C_(0x1.b8f7517f01d05ad3f5b4ba6c9b6ap+8), C_(0x1.7e41eac4aec61876fb9933392dbp+6), C_(-0x1.a414506f1749a1c58305f0247915p+9), C_(0x1.8a42dc8d7e0c984036d44acf6da6p+10), C_(-0x1.fc70c5eb750631dda8bffa5c2966p+10), C_(0x1.078cc6f7751312b231c8496978c6p+11), C_(-0x1.d83a569460166e52313ff6ef2cdap+10), C_(0x1.72db6cb15cd72ceb44fc1391ca0ap+10), C_(-0x1.e3a6df319fa13f73a1becc99c1bp+9), C_(0x1.cf3b0d7df18f715bb39783adf96p+8), C_(-0x1.d51428e901c215eaaca0f201c961p+6), C_(-0x1.8c56c880ec38034e39c62c6aaf1ep+4), C_(0x1.2c380f5e865da81b223aaf9ba893p+5), C_(-0x1.fc04081d34cedd56a87f6a93c47p+3), C_(0x1.67cfd3a1ef5c6955d5156ad19fdfp+1), C_(0x1.9005cc81fa0dd8ddcb0ef2e368cap-3), C_(-0x1.6895dc001e228c4142a65a949d43p-3), C_(0x1.82652a80425786d395286ed1c874p-6), C_(0x1.2598eb52540c582b66a388a574c1p-11), C_(-0x1.f931a276c55e6702f13f4d2ec79cp-13), C_(0x1.dc668b4d899394715f65f547aa0ap-19), C_(0x1.b4c7dcafec63006d515f9533babdp-23), C_(-0x1.cb6cdde84a22b96a4fc307092c49p-30), C_(-0x1.f612f7790e7dfcfca6facf9edd4ep-42), C_(0x1.b3f84ae9c3a1d3983026d3d5d97bp-51), C_(-0x1.9f1407c19decc2d85cd5ba63de83p-72), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.bc1bbb932352fd4db217186d8038p+2), C_(-0x1.230220e94a6286e3ccf38d4bfcecp+6), C_(0x1.65729881a37a4e3a6ec39c0b03abp+8), C_(-0x1.146d11d32151befbe03f1861632dp+10), C_(0x1.34072da363b055ea4712dedb9e79p+11), C_(-0x1.0fba655ec8815d599296c7fe289ep+12), C_(0x1.9a1825ab277513bb221db58c408ep+12), C_(-0x1.16b4a3d0368f557cee02ea790ba7p+13), C_(0x1.59fb20e260f209444967e6c1a575p+13), C_(-0x1.8532af6245b8a37a5135bb9a8819p+13), C_(0x1.8c055ef648911dec2e20ac309451p+13), C_(-0x1.70169a3124976f7442e92622f30cp+13), C_(0x1.392792bc1a4318354c951213b5c5p+13), C_(-0x1.de2062219056d64d01622237bf5fp+12), C_(0x1.3e37823e9c9169638076f5c7aaebp+12), C_(-0x1.691be2f943c22d4422f81e97a65cp+11), C_(0x1.4b463c6bd400a0ecfedd95ba90c8p+10), C_(-0x1.5fc2af1919c21f21f19a7f30b116p+8), C_(-0x1.286e81ad3c5d4bb15d987b1d1575p+7), C_(0x1.11137fdb9735b4b7b7c77d4bdac5p+8), C_(-0x1.749f8e79c1414c37972b9280e062p+7), C_(0x1.1b06a540d8bf3d4241ae8a187538p+6), C_(-0x1.7a50c04170b90bf05ecb290f9376p+3), C_(-0x1.b0c80bbf87c7b0afb3614e48c05fp+0), C_(0x1.32db8166dd6bf259ffbc02129a89p+0), C_(-0x1.78bbab19bbfce1e222ea4ae4ebc1p-3), C_(-0x1.6be3931ec3a0a0f934055bd32184p-9), C_(0x1.4cb7ceaf89c2bc6ca23b4de198adp-9), C_(-0x1.ec1ff5f12b99a0b5484713b8896bp-15), C_(-0x1.a28eed0313308b4187f5c957721p-19), C_(0x1.1e4d1afc4f213777086c26ac990fp-25), C_(0x1.2e933ece77f3d4f12785b9380e9bp-36), C_(-0x1.0ed8efcca12869c8a8420946c2ebp-45), C_(0x1.01deae8b7334485f38756e42ddc9p-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.7d01eebdfe55fe3c6ed21587d92p+3), C_(-0x1.0e862c8ffe7ff18db1f4d0d89561p+7), C_(0x1.6068e5f78cc3a3034b49cf000d6fp+9), C_(-0x1.16e27e80bfe67c3ab640b5e1ecffp+11), C_(0x1.2cfcdcdcf07c3d87dcfc36a512dcp+12), C_(-0x1.de03a2d7212d303b5f3943016437p+12), C_(0x1.2ec8864cafb19603887a2d7c4703p+13), C_(-0x1.500683f99e667a964beb950c1258p+13), C_(0x1.545745c7955e4cdf07cc034c2854p+13), C_(-0x1.1c5400071f26b6f894c12a7b3f37p+13), C_(0x1.16dc653d8bc1d4bb36f214e1e20ep+12), C_(0x1.b4ea0cf6f0a6b2f781cf9163eadfp+10), C_(-0x1.c11dd36c4cf2a48e63345a744925p+12), C_(0x1.5827531f986387c8025c0b0f20cep+13), C_(-0x1.a3de245f7e97f4c57daf304b115p+13), C_(0x1.b4f7e9a0a0606952656f83a68277p+13), C_(-0x1.7f2cf0b4269dd38dde070b5f0cdep+13), C_(0x1.2042e1dec45f6d9e8ecdde4d30dp+13), C_(-0x1.84b7d120c9be3df99a52bbd8cee1p+12), C_(0x1.d5a3bb45a7db2c787108d4dd50f2p+11), C_(-0x1.d06f9035faa5ec088975f115cd7bp+10), C_(0x1.3bba5a0006ab829f47d96569222bp+9), C_(-0x1.633fc40d33ceb334ddc3416213edp+6), C_(-0x1.ea064cf26a80ac52af3e7edffe55p+4), C_(0x1.228bc38d7faa44c44536bc6e393bp+4), C_(-0x1.94763b8fc894319c6a4baa13397fp+1), C_(-0x1.d3df039dfc19a1e9d51d6ee6175fp-6), C_(0x1.e63bf96d77b58d48a45fb3200bfap-5), C_(-0x1.0df6f4a0b44ee3edfa91f00b193cp-9), C_(-0x1.be80af96687fddc94510e8ade719p-14), C_(0x1.a12b7b548061ec0aec1afee7ffb3p-20), C_(0x1.557c0a8693ccc679320f886d948dp-30), C_(-0x1.894221980c4b8d10bc7e6d5fc51ap-39), C_(0x1.766b6e3ec237c8c757492e2c2a6dp-58), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a6f23ff482d2a8534d18ee2bd813p+3), C_(-0x1.37e1afb1392b3f40934da3d558f9p+7), C_(0x1.a686ad1a0ba3db778ce2719b5c95p+9), C_(-0x1.5df1b3980b353a49181f807fa276p+11), C_(0x1.912604b6b386163aa8a2a506984fp+12), C_(-0x1.5b61ddc6ff3217136a743b9c2999p+13), C_(0x1.f0e6d62d6c3adad4499f950bdba8p+13), C_(-0x1.40b6eb16bb3fcf7bbb403448e39fp+14), C_(0x1.87585fcb881fe424c96217849318p+14), C_(-0x1.be1e3f54a4c6e6b54ffcceb8221cp+14), C_(0x1.d1d8cfaa9552876a45180bcc50b2p+14), C_(-0x1.c1cad55e0d499c75b90a8681896dp+14), C_(0x1.98c3ae43fe1125e958f8e677c61fp+14), C_(-0x1.5c4d34f8b772415210663ccb0834p+14), C_(0x1.12a3aa37e5fd016d4163c33ef0a7p+14), C_(-0x1.9192f9cf12c8db367f3be99603f7p+13), C_(0x1.1122d052f1ea79533169d18075p+13), C_(-0x1.52bae1043f73d75aa63286049566p+12), C_(0x1.74a03155cefa742f49e86547448dp+11), C_(-0x1.690be5335ae783047d5d4ded6084p+10), C_(0x1.2aa92592f4ea4eab6ee72559722bp+9), C_(-0x1.54e703590f43bf9834fd6d7c3fcp+7), C_(-0x1.eedaac4f8962ad088ff79f7ab717p-1), C_(0x1.de050411f7cd568eda13f525f9dap+4), C_(-0x1.c148def3b49e232ee4958ee9fafep+3), C_(0x1.48e1be6a547f7c0d38d3ce51af9ep+1), C_(0x1.ccb6f2024dedfd3e23939d6e234ep-6), C_(-0x1.0b11a0ddf9bc2847e1d232a914d5p-4), C_(0x1.f0397fd92ef550872efcf8d934adp-9), C_(0x1.723cd3b01432ce7970852fde484dp-13), C_(-0x1.ed12536f5e4f2788058dfbdeb7b6p-19), C_(-0x1.6aaf317d39b56dc9439410fb90dbp-28), C_(0x1.cd1c2594785771509fd29eba3b57p-37), C_(-0x1.b707d969a42cbded13543076b42ap-55), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.9908fd0ce831f3487747d933d748p+3), C_(-0x1.3339176496abd2cc6f353a6e44a9p+7), C_(0x1.a399ad0400dbc9e71dafc101d1e1p+9), C_(-0x1.58f242d223982437163d99490d3fp+11), C_(0x1.7f8e29aa27ab125f24d2fcb7cf63p+12), C_(-0x1.38a61979e2b2ffe2ae4d4e65fc71p+13), C_(0x1.9add7b4a18f5c8300bd029e80d54p+13), C_(-0x1.ebee387c8e0aff52186a751f53cp+13), C_(0x1.219cbd1b2da3c7319d2594cddc32p+14), C_(-0x1.42ee71a32a848700929a8801a23fp+14), C_(0x1.4162f4284633fd1e7fba1bb3800ep+14), C_(-0x1.21467722a3c16c9f70c4e0f39397p+14), C_(0x1.f02472a8506fd3b8d32f77a4b8f9p+13), C_(-0x1.93ab7dcd5a6c14300ddac86b8dd8p+13), C_(0x1.26e6ca1326b3694ec43b05b1dfbbp+13), C_(-0x1.7e6f2ae54bf7f66077fef1175708p+12), C_(0x1.ca344102205561eaf28babf9b0b3p+11), C_(-0x1.ec7742f47fb3351081ba5a5968b7p+10), C_(0x1.8bd38bdf87a320af9a5418399e9fp+9), C_(-0x1.1acd500cc5943718da806ac7add3p+7), C_(-0x1.4d85442446456020706cd509b723p+6), C_(0x1.ed6ad17e0f78e02531c1a4770ad4p+6), C_(-0x1.b2f4089457d680f06bec3c3dd972p+6), C_(0x1.0c247d783695e3ffa9b901ecf60ap+6), C_(-0x1.9870dc8b45a9f4e303e8e8311b4ap+4), C_(0x1.3338d9a06d3fea3c6e122fc7de4bp+2), C_(0x1.0f6ca08ad5fae6b6177d3fc4323bp-5), C_(-0x1.4c4e08354cb7e3eae0ddb198440bp-3), C_(0x1.02d3a75dac8a719338fdc8517e15p-6), C_(0x1.7509581763d127e7d21fa4b754b1p-11), C_(-0x1.54ad634865cc13ff2aa8e2b2e8acp-16), C_(-0x1.7ef1d65121e030d70caf398558e9p-25), C_(0x1.3b877c4e5003312e2d376dc10e97p-33), C_(-0x1.2c6f23660e48f98694d796524bep-50), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.e6c2b226df78c279af13845051c3p+2), C_(-0x1.70ef0a94afa59b1a6aa8d2343645p+6), C_(0x1.fe115e7fdadc37c38b9e6da89457p+8), C_(-0x1.ab2ae85d8df6a5fa4cff025ed87bp+10), C_(0x1.e9076c74293a400016225b9ca839p+11), C_(-0x1.9fe839f33e758faf5bf246ffdc45p+12), C_(0x1.1ec83a83d597d7f150637077f9b7p+13), C_(-0x1.61f4e1f4fcae3d0d387b625dac79p+13), C_(0x1.a34037eb93edf57ca17d98f692cbp+13), C_(-0x1.df1d808eb7eddd0fc723f047f0e5p+13), C_(0x1.03261bb811b49bff52d5b3bd37b4p+14), C_(-0x1.08bec2cb9bb5325c84c6514f4d44p+14), C_(0x1.000c9dcb7996cb96b43e3d1c9772p+14), C_(-0x1.d42c4b6e482399636855cedb1712p+13), C_(0x1.9723de14cea5319a6860bbd3c799p+13), C_(-0x1.524bda96018d06eb97a9a94efd6ep+13), C_(0x1.08b8d63f8a5e0d7a39871bf89f73p+13), C_(-0x1.81d1060b61d0d3635b17f5b8f829p+12), C_(0x1.09630f3565a574b943c123a6bfa7p+12), C_(-0x1.59ea297354d075bf6b0a4b01f032p+11), C_(0x1.9c7ad6ace2b3cf85fb948aa7bdadp+10), C_(-0x1.b6b7705751739945f7c51d7dcccap+9), C_(0x1.aa6416006d3250b9dcdb9d2790c7p+8), C_(-0x1.7918296878e4f9853df6b6e8ae14p+7), C_(0x1.07145b6ad1daf57366d1625ece2dp+6), C_(-0x1.a108d75d6bbaf0652587e828bd3cp+3), C_(-0x1.33d485acc9655e7d88b74e802f9ap-2), C_(0x1.6d6fa9e91b92d2703b87421f247fp-1), C_(-0x1.78a5b635c316b5bfc318d4eea976p-4), C_(-0x1.16db8d9d41de38829032ed627d9fp-8), C_(0x1.9ed47b91da7177bda1e64cfb1175p-13), C_(0x1.dd448a5da4eed2af5748439dae43p-22), C_(-0x1.7fd3f33da284c2945eb532e858d6p-29), C_(0x1.6d7f73f5c3ea6d60bfb8d1a80ec8p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.34875227fc78d9ef7ed7ac6e0f82p+2), C_(-0x1.d5cd5efb52a9ef14597d82d198bcp+5), C_(0x1.425dfad9b492e41845300927f3b1p+8), C_(-0x1.06c373fbafad1222f880762e04cp+10), C_(0x1.1b9bff7a51e187819c73161a78e1p+11), C_(-0x1.b244eac1fdcf0d5091a23ea449c8p+11), C_(0x1.01eb21ca101f022e5418621b2a9ep+12), C_(-0x1.166548c799cafbaa88fc763d8453p+12), C_(0x1.3b0ce98f7e34e32ea84135429657p+12), C_(-0x1.6362301a242eb8214208b870faaep+12), C_(0x1.65cf7c0d7f65c5008737a94a5fecp+12), C_(-0x1.4657f8cbcbde3d6a4e18c8e9c05ep+12), C_(0x1.24d7d2cdfa25a491f828221544bcp+12), C_(-0x1.010708097c75d2ac6e322278d08bp+12), C_(0x1.9d020a4459bdeb50b979470ee77dp+11), C_(-0x1.328cca6ef194279a5bb009ec9338p+11), C_(0x1.bc083519c657836208142c7eb836p+10), C_(-0x1.32ef111f54699b431e478036157dp+10), C_(0x1.7f8dca23d339c29569ea2ec801c2p+9), C_(-0x1.bc6a63cb2fc0846b3e6af0f884aep+8), C_(0x1.f09b702a78c4dd679fe395dd6a7dp+7), C_(-0x1.f532dbb546bbac5b183e2380610fp+6), C_(0x1.ab4ca1b61588ca9a0a6f9d915ea4p+5), C_(-0x1.463ffdaa1065322e64ac74f7fa8bp+4), C_(0x1.ba4ea70cee33c38b2b0e8b20a1aap+2), C_(-0x1.3f8f23678b563eb9630f6042805dp+0), C_(-0x1.2f5a76f330866b9d02c88ed42bb5p-2), C_(0x1.a0cbd7080604e3774928fed42dbdp-3), C_(-0x1.d523cae4ae400c2fe3e190e83e84p-6), C_(-0x1.01b8eb0a5cba7579162a23c9063cp-10), C_(0x1.02b9e23339b17453717d89dae4c9p-13), C_(0x1.5122002fcd3e4c50886af50f4453p-22), C_(-0x1.dca9566b2b5e33d63760b950eda2p-29), C_(0x1.c5fa90ac19cdbed6fcc50c677b98p-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.095a4630f25b345edb3a033429c7p+1), C_(-0x1.94f72d60a79651db24efb743df14p+4), C_(0x1.14fec0291d4b12e7113f25067be9p+7), C_(-0x1.bdfa0b6be593ce00570a7078fca5p+8), C_(0x1.d39577b7cad7e7c4fd5dbf90540fp+9), C_(-0x1.5193ad0b12f066b4cb0fcaacb204p+10), C_(0x1.6a2e0f056a38f1473da552dd4715p+10), C_(-0x1.5d0e503eeaf62b38a4d6937112eep+10), C_(0x1.7e6b7f3178684900694f3b8c2fp+10), C_(-0x1.b6360679ec82c511bf5718cad79ep+10), C_(0x1.ac545c0c739641a55bb4e4c80843p+10), C_(-0x1.6be3874eef6d1f1a32235a12525ap+10), C_(0x1.3c4c888cb63122525397dd653d36p+10), C_(-0x1.1879194795ebee18032f4a91a091p+10), C_(0x1.b5e083426b3c7c6a910b26a6198p+9), C_(-0x1.2f24fbf8b03f0944b0e6672a17c2p+9), C_(0x1.aab5115e884dc181977e8353a09cp+8), C_(-0x1.2726385d133e4a16d05b604abddfp+8), C_(0x1.59979df7b75e1cc96562d4bd910ep+7), C_(-0x1.65732078d27eb27f5ae5d7879665p+6), C_(0x1.7f6def467b5364cd233fba2c5a55p+5), C_(-0x1.704ee2b3997739837bc58d39a41p+4), C_(0x1.cc5ee35ab0ad93a46168320cb92ep+2), C_(-0x1.50976171160a6dd2e2a17268b2e6p+0), C_(0x1.f9c57fa6a287f2b26fe11e313d13p-4), C_(0x1.64b2a171f9a1261fcd30fc5b5dfep-2), C_(-0x1.998a031a0009070455c3c0080416p-2), C_(0x1.57c1f71aec6cd09bc7ae16b02e75p-3), C_(-0x1.b25ef4a8ceef29ad7df2d5db7234p-6), C_(-0x1.808f4aaa023730c43464ce0d9251p-14), C_(0x1.d605bd7dd6adec51bc920eb90a32p-13), C_(0x1.cf1c89541af51d642527681f35ep-21), C_(-0x1.a94329286bdc4b6164f134153d1ap-27), C_(0x1.952b6e764f688e496b665b4266b4p-41), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.42660039f1e4ab1b56c2e8881a0bp-6), C_(0x1.ec93c1aa5b61c9b6d5696151fd09p-3), C_(-0x1.97ce26c5b170acf42f1f93361a05p-2), C_(-0x1.c01099aa543ca8b825e143b557bap+2), C_(0x1.a4014de9af920ed4c9ee54928ddep+5), C_(-0x1.6ded0cd4cc8b853b87bfbfacc025p+7), C_(0x1.8330f0dbb0c28dbf63333311ac1cp+8), C_(-0x1.0c893c9ed1485a74e7f7800e12b6p+9), C_(0x1.052ccc4345d2df5a1dbe6873e028p+9), C_(-0x1.c1974852375e5b099cd67d213452p+8), C_(0x1.fad23c454fb6519a66669891ce2dp+8), C_(-0x1.3ffe274228465c9afdc401f4f0f8p+9), C_(0x1.4635deb84c3cfd97dc985dd6672ep+9), C_(-0x1.19ba20aba1a1dc6b33ade2534e4dp+9), C_(0x1.065bcb209e9694669a116f8f1c4fp+9), C_(-0x1.015ece212696c91b2da16a54aabdp+9), C_(0x1.b4c17c7bd409b3d1eb496cf9d8c2p+8), C_(-0x1.48c8d9ca7f31bb244453a83bed84p+8), C_(0x1.008b40131779b22fe5ee591e5e55p+8), C_(-0x1.8c6185bde00310328e2d72cc1f71p+7), C_(0x1.08d51505255015c001174081c04ap+7), C_(-0x1.42df3db9c4b2e8aa91c152e2460ep+6), C_(0x1.93d8682a099131f2e30d1893505ep+5), C_(-0x1.d72aacc75787dddd2538f4cd11fbp+4), C_(0x1.c56cd8c23773878de5456aa0988fp+3), C_(-0x1.8c843e6f10e078b693975b9ceec3p+2), C_(0x1.620f8bdb46e5d416d1abe187fae9p+1), C_(-0x1.ff5dc9ffbca3cebcb086bd21ec14p-1), C_(0x1.8dbab0e6a8c888a4a8c14551861fp-3), C_(-0x1.14fd9c124f34ee1806a1877b89eep-8), C_(-0x1.8d698e7a70351fb6b69fe98cc8ecp-9), C_(-0x1.922f4b831ef6074ab73b0f88d222p-17), C_(0x1.661caab697dee3a1ab3a4d24609cp-22), C_(-0x1.556f58a6ea91cacbb7f565948433p-35), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.a102d4874492bf0c3f8abe5216a6p-4), C_(-0x1.3ebe78df84aaa4d0f4b794efc132p+0), C_(0x1.b2f7cb5502cda6c9d230fef5216p+2), C_(-0x1.5ac9e38bb117840228ea5f0969e6p+4), C_(0x1.63176aeb8932d6ab994905b6314fp+5), C_(-0x1.e61b7010df60cf6c4ad892eedae1p+5), C_(0x1.d104bdea5563bcce7c191c344f3p+5), C_(-0x1.7544f2a572dd637b67c83e625741p+5), C_(0x1.737d5aa77938e2318fbe4c3f84c8p+5), C_(-0x1.b1c6edf1bb3236287638385af6a1p+5), C_(0x1.9f0c5397c3faff6479945ec39ad4p+5), C_(-0x1.47ca4941183ccf73d74cc2ab091p+5), C_(0x1.1a93e6543e9f9a411108443c7824p+5), C_(-0x1.0927206f45006f2abe266610514dp+5), C_(0x1.a5f0e2f2d0b54c0cfa24d939192fp+4), C_(-0x1.2685107a4162e669c1fad19a69ebp+4), C_(0x1.bed6d3109a358fcb040f5e21b4d9p+3), C_(-0x1.52c12c07acc0e1d274e7d45ba9eap+3), C_(0x1.af31110ee1468e10bf21a15fab4p+2), C_(-0x1.02817ffcabad7fa52399e99ae606p+2), C_(0x1.4e0f916d4e048c57bf43251d9d88p+1), C_(-0x1.864c4e83e1764ac0ffdca7b484d8p+0), C_(0x1.7f1784ea638898f647b4e2787299p-1), C_(-0x1.8002ee89d7986397c24beb3e4ecfp-2), C_(0x1.7fc7499a09e8924504cfc808759p-3), C_(-0x1.2bfa08732bf79ef113f03ba38535p-4), C_(0x1.957da4e89baa41a793f6e28cc5c7p-6), C_(-0x1.2aec3447b7aecf379d17702dfbdp-7), C_(0x1.266385cc4f62510ab31310cb9e9ep-9), C_(-0x1.c0dfb99a8ea4dbba7703d245fd43p-16), C_(-0x1.1928369b116813aa42a010ac694dp-14), C_(0x1.2017f1a37d1405b50e30d1eabd65p-23), C_(0x1.0f4800b7b0a184fe6ec7608004b6p-26), C_(-0x1.03044a0f4ec3952e4f859c26c44fp-38), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.302549bcac16a07480ffb58950a4p-7), C_(-0x1.d1147836a22995451a237d2c571ep-4), C_(0x1.3c7951e94efea5a01e74ac179967p-1), C_(-0x1.f485b5137068e2de7e3ecadb998fp+0), C_(0x1.f6c9c4f20d2e109d726d9bfa2ad3p+1), C_(-0x1.498acbc4ea72d090f910303e1e3ap+2), C_(0x1.1d9755d014c869b79bc13e22f12fp+2), C_(-0x1.81525835d067c01df39c6d7268f2p+1), C_(0x1.6d720e347fb567a21392b49f69f3p+1), C_(-0x1.cedd19de5af2aa41ce8142ac49bdp+1), C_(0x1.b162c910bfde4ce0f673ec48bfa7p+1), C_(-0x1.2aa74c52348af8100314f0e62e0cp+1), C_(0x1.eda3d295893e868bfb35ec305bap+0), C_(-0x1.f7973b0f803ffd6ba7bc4f61d739p+0), C_(0x1.87d55f9f1654529cea30f503f524p+0), C_(-0x1.e3314a61cec2d1ec8852d0dbcec9p-1), C_(0x1.712067be057e009feff90d8198e8p-1), C_(-0x1.2d407bbb0b0ac1aee45b8cabc16p-1), C_(0x1.675f9e5eb7de518e9bb7430a57b9p-2), C_(-0x1.80b747814ba27c7cd05f743f5455p-3), C_(0x1.0a57b0f3cb83001cac6acade9288p-3), C_(-0x1.43510035a93ea4e9f4f0330f9b63p-4), C_(0x1.135c54f340512b998224396e7637p-5), C_(-0x1.042576d3101c9bfa2c3ee11498b6p-6), C_(0x1.28e7b29b5a905feb407256a997a8p-7), C_(-0x1.b45ff7bd1d15c0d666ce33e8722ep-9), C_(0x1.b09f4241d30f170ec83bd736891ep-11), C_(-0x1.7633994bcb363452031c0be60442p-12), C_(0x1.d2f415013436fa877d9f51f3a238p-14), C_(0x1.16fcce8bf9664ffcec318d033322p-17), C_(-0x1.f9a19b157868fe73cb52d3d8f794p-18), C_(0x1.555633d592e52d8c981188aedf8fp-23), C_(0x1.285fe2167b5b4b96d89f7083a8a9p-28), C_(-0x1.1bc8f87104551fb246bfa29e3c89p-39), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.bd717b66e1d1d4d95ba3c08947dep-7), C_(-0x1.7b9fec6bb92af42e63e2e68ecca4p+2), C_(-0x1.1ead339bb1d44833388375e63d59p+7), C_(-0x1.012ddbc7bca1e6101aa1cf5d564ep+9), C_(0x1.c0b75070f83e37ada47fd8928c98p+3), C_(0x1.981856bff215b594a8e4e5f86ceep+6), C_(-0x1.7b31c06193f3e30ac8e863c6933ap+6), C_(0x1.e4866be11fb72b736fa85f578e21p+5), C_(-0x1.c461c239dff802f2348bdb864e24p+4), C_(0x1.d13242d9fb5ff5fac5479a566994p+2), C_(0x1.e6f4964d6a03d0f8158833051b6ap+0), C_(-0x1.b2b5fa84ed5bf72597a5eb232c95p+1), C_(0x1.0717ba30154525a4b9eaa944e41bp+1), C_(-0x1.7b72f81fcc526babbc7b68ad5d28p-1), C_(0x1.3a477558616d24c10f1dd99cb0c4p-3), C_(-0x1.9b911968d13ed312bc38bac2906ep-7), C_(0x1.631172e87e301114011b41a3b8a9p-10), C_(-0x1.1b6a6db603dde402c2223c4221d9p-9), C_(0x1.a5c80b0f2bc5bc3b3f1a94740a37p-11), C_(-0x1.702b73dc1bf286d5e095a7a0f5a4p-15), C_(-0x1.2e802f058eb73ef9b14848780ecp-15), C_(0x1.f461fea3bf76e5a0a5716d49933cp-18), C_(-0x1.978d16c26c68ef616764f83e76c8p-24), C_(-0x1.13d7c474d8cbc6770c364afcd753p-24), C_(0x1.1119bb3fe775e15526c923b289ap-29), C_(-0x1.8685450351316156519237add64dp-32), C_(0x1.fbf3d2901e1ab81addb9d152dd5p-42), C_(0x1.0ebded1ffbce50e958913e490b72p-41), C_(-0x1.8b6af637a9f31fc837c7aa02d1f6p-49), C_(-0x1.a0d4564bf2dc66611a174850c89ep-56), C_(0x1.74b661da2714cde7309e3860bc9fp-66), C_(0x1.5266f1077241c8b5ce693870559cp-77), C_(-0x1.60eccf731ce43024be7a209a4a5bp-94), C_(0x1.5002d3b2c3d4cf65f716a68d3eb6p-122), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.640d0cbfb34edc433e3c265970b3p-9), C_(-0x1.26ee7a9fef2f3cd66764d9f94d81p-1), C_(-0x1.cb77692ba61f4bed97023b434896p+2), C_(-0x1.7a52a3b4a77c5125cf118ae57d54p+1), C_(0x1.3d35a908c4d29476ad845269a92ap+4), C_(-0x1.eed0bb7ffc728b5021c0dd7f402dp+3), C_(0x1.5b446269f85399ef36e0a8f67578p+3), C_(-0x1.e860777819bbb58c5f71ba40875fp+2), C_(0x1.459d6005ddfc2d02a2fae3fd310dp+2), C_(-0x1.7cfb6d6fe6c7981796f3f294d796p+1), C_(0x1.6d0ba0eba8694d88a64c51b8f50ap+0), C_(-0x1.08e91d938b8389f5f0add295cdbap-1), C_(0x1.eca4948d0008e456bc9d67c81d75p-4), C_(-0x1.d06140d0577a1b263782da58dca4p-9), C_(-0x1.7297d215124a9ff8bc7627391918p-7), C_(0x1.862feda5c0e0ac9dd17f1152635dp-8), C_(-0x1.d3aeeacfe9c70326d1fac582acbcp-10), C_(0x1.15a5ade831e782a4ffc3bed5638p-12), C_(0x1.48236580a81473ae0d83a7ad5bf2p-15), C_(-0x1.c4dab80b872dfd428813332137cfp-16), C_(0x1.912930341a4fc5b6071d5bc9b09dp-19), C_(0x1.74839b9d5596fba97dd8392c7187p-21), C_(-0x1.f7937244a115a288dc7cde59188p-24), C_(-0x1.ef0ac8df8a590687cfdcc193b466p-27), C_(0x1.b60aa56de0f8813393124e0f539p-30), C_(0x1.4fe56c11057c7023ec8d56f2bd84p-35), C_(-0x1.2b1ee6f947a6f09f111f53e08b99p-38), C_(0x1.904f2b23e480ded5004c9a3b2081p-44), C_(-0x1.1a491e89e84c1ae1ad605792ed65p-50), C_(-0x1.e6f7ea660d39c7595d9913c47738p-58), C_(0x1.68bf338efe90278676de17896db9p-65), C_(0x1.ec3578649519ba8d72287ee8e375p-78), C_(-0x1.56c2062f8a091fe577e9571b2417p-92), C_(0x1.4654c88c71974e3c9f8fffc52861p-119), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.07725ffa38e9ced625cca68f3f21p-17), C_(0x1.418c13eff61cbb3a021569097a1cp-8), C_(0x1.3da46890dd9a0a4b666b663d4aa3p-3), C_(0x1.8a2b52a78c79acb029ea1b6db9aep-1), C_(0x1.1a351fcd80743de548c177ab2074p-2), C_(-0x1.854589d6ffe0f67b9ae39f8edb13p-2), C_(0x1.33e4c9737dbaaadf26763db4b5edp-2), C_(-0x1.aa815b6478cdd9f02d23c8d18fc1p-3), C_(0x1.087553137f3f92720c562745af4bp-3), C_(-0x1.1923520d0b86878b50e3a0765033p-4), C_(0x1.dbed9e8e6653062b736fe52ecb07p-6), C_(-0x1.13641cf1379f43fd1c7ac3bc71edp-7), C_(0x1.6875bc1af4453d3d4e0df0f5de38p-11), C_(0x1.a947dfa3688a3625b782cb79509ep-11), C_(-0x1.10b3493092979555022e5756e4f3p-11), C_(0x1.739af28e775c2a9c036cd7599ca6p-13), C_(-0x1.6cbb4a08c7eb5fe8237038a25da7p-15), C_(0x1.409e1bccbf4ef7d2793c14591929p-17), C_(-0x1.b4b5ec00d923dbc2091331f8dd78p-20), C_(-0x1.0bf29985eecde4627b6e6f4c0369p-23), C_(0x1.687a642b13ec01d769b15bc617e8p-23), C_(-0x1.137b64e3f44e9fdac7b535f30d85p-25), C_(-0x1.07f0606fa0dbad766d3197dd19cap-30), C_(0x1.6c85ed37d47e7b904cfd46760581p-31), C_(0x1.e0b71b0ad278ef564d1fcf1e88a3p-37), C_(-0x1.c7f3c451c06bde44cba8b0964cfp-39), C_(-0x1.3e734cfafd184d570a4dc2808fb9p-41), C_(0x1.ce28f04bbb94c603b91b46462315p-47), C_(0x1.70c276923dc2ecdd8f158e1477f7p-51), C_(-0x1.79a58db93f5236bb350459a10815p-57), C_(0x1.1f5027aac86b8e122cbfaf41ee62p-65), C_(-0x1.02276c5db8038c6bd4e95867d18dp-70), C_(0x1.254876c157537023d202fc646803p-80), C_(0x1.01c1badc280ce855150f875fe27fp-94), C_(0x1.81b6379c836e2bab36a7efba81e2p-110), C_(0x1.fb9eccd49ecd0870d19d3ffd447bp-140), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.32ea938ba90f99b6837f5af63be2p-14), C_(0x1.6ee1bf4cf707539d522967930e11p-6), C_(0x1.8a481c471691e9b156b25ff57636p-2), C_(0x1.0b4f5688ae00b19fc1e160cf6648p-1), C_(-0x1.73e1ddbd7901f6383d61c3a6ac0ap+0), C_(0x1.8b33bb402f96e0732af30db90eddp-1), C_(-0x1.9843e3061a5286745b1a22aa34f6p-2), C_(0x1.174b1b1b9671399a52d81cce6671p-2), C_(-0x1.d5ed9bfb0b3eacb0609851530eccp-3), C_(0x1.7f42427dbd66dd7c640694ddac63p-3), C_(-0x1.08eb5567536606f98b744fb38775p-3), C_(0x1.23d363b3776e341b922f685a5527p-4), C_(-0x1.e3311fba2b6786652a72b9017675p-6), C_(0x1.080310d541cbc7b415408ff9e9e9p-7), C_(-0x1.70478a76493e219892885c932ab3p-11), C_(-0x1.0307c808a4ebd5856963c5fffbdfp-11), C_(0x1.dee4ac1d99b73074451ae5f38c64p-13), C_(-0x1.44f6514c266093c947d073730317p-16), C_(-0x1.25e4b5de72eb99eebb1451b05b03p-16), C_(0x1.d4b5838001d90ed04674ba339f05p-18), C_(-0x1.0c63aca94f3b9788d5e3d0094dfdp-21), C_(-0x1.5d75636e21f07d7a3381c79d0362p-22), C_(0x1.731d5b5d003f55b6876fe0044ec6p-24), C_(-0x1.0c3e8c9e77afbdab5c815392ec9ep-29), C_(-0x1.add3791299db3c378e9de40e8a64p-30), C_(0x1.06fadabb3956eae25696a4f51f5cp-33), C_(-0x1.f4ce18079dfc9d6929b9dda1612cp-42), C_(-0x1.2eaa27d46e548153d91731a7ee6ap-41), C_(0x1.ae2bef5a0c85a05297e337e77b0ep-46), C_(0x1.4bfd5bd67de9ea53ad7c40089635p-54), C_(-0x1.1d671c704d7fca69eb029e029b5ap-57), C_(0x1.67963d56e9a972fedce141425dcep-66), C_(0x1.0b2bba52e426ee86c81ee87efd7fp-74), C_(-0x1.835ebfbafcc994f81e5e17cf300cp-86), C_(0x1.613768a516da5440f559a8b7229fp-103), C_(0x1.d0dabcbcf214e8044829d82792bcp-132), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.3f4897070d099352fef182a2ce17p-11), C_(0x1.6d998ddc083bb79599bbcdbf5aabp-4), C_(0x1.5cdfd95e7a29056f595ea6b04d0dp-1), C_(-0x1.3be70bab67dce74ec0a3fcb7068ep+0), C_(-0x1.4f0043bcb070f4a9035f0cb75f46p-1), C_(0x1.3f5cc039811e2b5b41e1339ce191p+1), C_(-0x1.435a201615b7649bde7e6bdcd35cp+1), C_(0x1.edddf036bb21e05065a4314b8003p+0), C_(-0x1.339bd26a01d7b24e4a113345801p+0), C_(0x1.26ea186703fa7b37f25c2df1ffcep-1), C_(-0x1.62a5bd05e71620f3397b8b55cadcp-3), C_(-0x1.8157fc40373b6ffb1b755d5d64ddp-9), C_(0x1.2626bd14128e3600ff5e4ef117ddp-5), C_(-0x1.458d354bc66bca085d03a73908bp-6), C_(0x1.60eb38bd6dcb5883ff977a13b631p-8), C_(-0x1.11a579a9f60ad1f4e34335fca023p-10), C_(0x1.8521f25159bae6c124f05e0aa6c8p-11), C_(-0x1.2e7cbaa1495260ee131d264b7fcbp-11), C_(0x1.d8a73116e5170bf766c62902d5cp-13), C_(-0x1.14baffbb5f3fc7cd4417451de38p-15), C_(-0x1.bc76b1b7765f460d127ed8109cb6p-18), C_(0x1.eb62162b875e74ac3ffbad741aedp-19), C_(-0x1.3ec5df1234a119b292d63f400f4fp-21), C_(0x1.0bd69df0fe817c3f4ec6f9220c7ep-25), C_(0x1.06532665f4ae126a371a91623062p-28), C_(-0x1.7b6b83afc0194421f9c689981f49p-30), C_(0x1.34507b73be114caacaacc09786fp-33), C_(0x1.3e99e3a60acfbc311476e151da98p-38), C_(-0x1.f151e40b836b8f8aaa3a3f0ced37p-42), C_(-0x1.448cc1196d194e9baa30923d08e2p-48), C_(0x1.4daf1830022e2a424c8ef6ce75a5p-53), C_(0x1.5011fa2f598d1104ecc45344c209p-62), C_(-0x1.1686e4fad9ced67d1bdbae1c9b3ep-69), C_(0x1.abb8cbb5d77c3d36c138309edcb2p-81), C_(-0x1.70542f5b2fe975bfb256d1ce4e9dp-97), C_(-0x1.e4be478d2f9719b08915aab446a4p-125), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.2434b5ba872d4c5808e71daa73f5p-8), C_(0x1.3130229eb7f3605b9b1b32cb9f97p-2), C_(0x1.7ae2dc23075619726157a440b0afp-2), C_(-0x1.f582a7e51625005d91ec63b814bap+1), C_(0x1.c7d08bb60552f4ce0a1dfeaea923p+2), C_(-0x1.a91c524d7a54ea689caba9ffde39p+2), C_(0x1.3c2342a582cf3f8debfc54cc85bap+2), C_(-0x1.088cd569576045a61a631e97afdcp+2), C_(0x1.d4e6f8f27b14576971c750ec5e9dp+1), C_(-0x1.7aa23dd152a396e3b62ff372d1d7p+1), C_(0x1.fadab4daf8f0e58f8d9d4ef01e97p+0), C_(-0x1.060b8820123e5eec7823aad8401ap+0), C_(0x1.6f3fb0d6ae2f90f1c572f1f9292fp-2), C_(-0x1.4c612316c2d6c3d361a3a87a8a95p-5), C_(-0x1.59b5936f0b00d23a57c7cb83dad9p-5), C_(0x1.f1cd6ac34748038c9618e97f54p-6), C_(-0x1.0815866d993d299c542a96e619ccp-7), C_(-0x1.33db5d2125a2859a2040c40794b8p-10), C_(0x1.bff774c7101082d480ffa7afad95p-10), C_(-0x1.14d1461893fe65443154fdd9ff78p-11), C_(0x1.60ee19b0b8b54d2e9cf10559c07ap-18), C_(0x1.6481008914d42c490ce92b7a443fp-15), C_(-0x1.79e8548e2225181445126279e5f6p-17), C_(0x1.0000883a713c85d37bfa6cb29923p-21), C_(0x1.0c4a52b19c7af0f6d1d88d405597p-22), C_(-0x1.51bfdb03a0cb4dfbccfaca10a1e4p-25), C_(0x1.2786225b5270b4ae5ce680be0a2p-30), C_(0x1.c2f3c31efae819fc824fc14e81e3p-33), C_(-0x1.e485fc83c20815b41344b0b5ebd8p-37), C_(-0x1.cdcc8478ab5ca320820b2bdaf727p-45), C_(0x1.248fa48f37bd758b38759e29a62cp-47), C_(-0x1.a1ed7efc74f0ddd5c3e7a26568ffp-56), C_(-0x1.257d232551abd9af4093fdff2e93p-63), C_(0x1.8e8d04aa5ac8d2663570e52c4402p-74), C_(-0x1.858c6aec0ddcc911f17d17aad5aap-90), C_(-0x1.0055b5f34554e57cc908df0fdeeep-116), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.cd2d34d1a42efd10b55402f678dcp-6), C_(0x1.84d83b63c2112e72eadf0e175b4dp-1), C_(-0x1.432ceae809a5e8ac576108008797p+1), C_(0x1.a0b9d38c7e490414c924ee603181p-2), C_(0x1.201a5e729e35c6b52d82081c697bp+3), C_(-0x1.2e113a8c2f74baddd86814ec6249p+4), C_(0x1.552ffbcbb449884fbffcd2fa1903p+4), C_(-0x1.094e929e449b6445010b66a63f08p+4), C_(0x1.1c13ef7eb64aa8ee0175687d62ffp+3), C_(-0x1.1af822f546327a2297be45973a7cp+1), C_(-0x1.f9d0cabdd71723c2b35a33ecead9p-1), C_(0x1.ddb0b49cb2203c31df0981557b5ep-1), C_(0x1.5318acd89fe65697aea31294c66ep-2), C_(-0x1.05b05a50c615d71587f066c9936dp+0), C_(0x1.9b5ab34637cfef44bfcb0657ebfap-1), C_(-0x1.1af795bed4913c5d4d0b7000d26bp-2), C_(-0x1.67451e2d12b8b1dce42c001cf264p-5), C_(0x1.99b155175f94ba8d3e0e29b8e60fp-4), C_(-0x1.ac7539c2e19ebed9f65c60048ba4p-5), C_(0x1.9ca72681ec9ea8c760a8f2a71fa1p-7), C_(0x1.34e3b1c23cb7d1aa00f8b981d763p-12), C_(-0x1.3a24c6f5381cdc3e9a0a2312b097p-10), C_(0x1.74fb460ba6a3c91ca053d755b7f7p-12), C_(-0x1.0b246714f1ffd71ceaf84df8a2f5p-15), C_(-0x1.ab7c59cb5e81411290eca69a51b1p-18), C_(0x1.dce3bc922f58f0b17196be55c2d5p-20), C_(-0x1.67697e8054a806243dffdcb105dap-24), C_(-0x1.9e416c1fd1c36255ecb5eed76efap-27), C_(0x1.c8b3d9029a8aec4464e3c0dd17ap-31), C_(0x1.5aaa4a43abfd9a111ae71704a9d5p-37), C_(-0x1.7db632c817eaeaef04d7671c292bp-41), C_(0x1.4a05d041f84f4639b3fa535ffbc5p-49), C_(0x1.e2fed86a51ad69aa2e1cca0d7a0cp-57), C_(-0x1.05d887c98f164a6efe9f254828cp-66), C_(0x1.42293c268faac3b8f9cecd0a784ap-82), C_(0x1.a7fbcc57e37f33cf909b7d2d16cep-108), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.31422db2538bc0a87b308ffa37p-3), C_(0x1.0d01250c1b0d06e5278d6357ef2dp+0), C_(-0x1.24921c6c7a3e4123721458dbf25dp+3), C_(0x1.a227c85b5e55bd2048d352a6c652p+4), C_(-0x1.524f50b139534832a4ee54d2fbecp+5), C_(0x1.8738d759012c36786ab70fb57053p+5), C_(-0x1.9323ab467eb529dc5b829fba165cp+5), C_(0x1.a42ab8b3ebb45f1751552cca4226p+5), C_(-0x1.a0b31f7eb9e57c7f0585d5e9fdbfp+5), C_(0x1.5b572ee0532df8736514c7068d41p+5), C_(-0x1.a65ce687fe55f007c4de98a4572ep+4), C_(0x1.d054e5f3566481470f5818319872p+2), C_(0x1.85d591edfc333f35ee49a560ad36p+2), C_(-0x1.3b9b5d3160df5b3c5b4fd29535fbp+3), C_(0x1.a0e3e2fe3af5aba2fa3cba939e51p+2), C_(-0x1.908502149e3126842af43ab5d7e1p+0), C_(-0x1.2fdcf4d1b74c11a7c8107dbf5a5dp+0), C_(0x1.71a344c5df788a37bb879332042cp+0), C_(-0x1.6f12d9a04f61757636a67705762bp-1), C_(0x1.40e9a8c631ed8f09035310ff998dp-3), C_(0x1.90c3dfa395147a7cc0c7676c3758p-6), C_(-0x1.cb2bc9edd20ef799e67ea0b4ad99p-6), C_(0x1.07343e2ee6832b57b8208a80d9e7p-7), C_(-0x1.49dfe7960ed68e24de4768224cf5p-11), C_(-0x1.b6e121c3001f0f7bec5598cab095p-13), C_(0x1.dcc996a9ecb3b5336d9759d46957p-15), C_(-0x1.a1bb03b6243b89e05627bbe8512bp-19), C_(-0x1.d9f622b803a645f37f52496ad03cp-22), C_(0x1.6819f189a7727ca3a62602f289abp-25), C_(0x1.4ca2954f6ae1a2e73667b4619ccfp-32), C_(-0x1.8c19531172f0aea0af3e91e143eep-35), C_(0x1.ad03ab6b6c0809d426ec9d64de28p-43), C_(0x1.92a5c80316f77784726d71e5f027p-50), C_(-0x1.126aebf2a41485b2605ffe0d6f2ep-59), C_(0x1.0d7f8030d9d60a694722396ad34fp-74), C_(0x1.62acfe05bfb1201e774235c1d27p-99), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.46ba9611fdf6c7a94d4f6d15ae64p-1), C_(-0x1.dc52978d552a4c87a8e0e11df878p+0), C_(-0x1.7fa540f99cfd7a53d485cc23b3dep+2), C_(0x1.5732b50df53b69d2559ff51a1e33p+5), C_(-0x1.b13b1bdb27ab101c396869bcc29bp+6), C_(0x1.33606cf67b649ff0c53d5daba4dp+7), C_(-0x1.bdcf241a98962a37ffef026534aep+6), C_(-0x1.6f03a4675ff5f681cbcdceb803f8p+5), C_(0x1.1808882b291db1c41b8c116f1fb3p+8), C_(-0x1.010ae854c8f06138d8c0149f09bcp+9), C_(0x1.53a4857a4441ea9cc9b274ab65a3p+9), C_(-0x1.6d4a26d83e33b0ac3dc870af21b4p+9), C_(0x1.3d6709439125c739fb2f5edfb5dcp+9), C_(-0x1.889b5e2f1c327048a556374f7da9p+8), C_(0x1.56fd4f6d97a60ae9928f3958a702p+6), C_(0x1.25b06390e20f015674e98cf0aeb5p+7), C_(-0x1.b399a1a2f22fe6161cb0e96be4a5p+7), C_(0x1.3df78e7e4d04373329461fc9ed72p+7), C_(-0x1.0ef9b79a3621238b48ca4f0954ap+6), C_(0x1.5f7982d2ac2abd1246025f08fe6fp+3), C_(0x1.6a625e6b6bab463f678abfc9f5a5p+2), C_(-0x1.198f31ed8cd901a93c9ab1bea14ep+2), C_(0x1.42ee7fc8a94768a05abd24f4f6ap+0), C_(-0x1.7d60037bbed413784256ebd48bcdp-4), C_(-0x1.6ff7a83ef962302af99cd8276389p-5), C_(0x1.ab35b35a042defdd50e378dee2cap-7), C_(-0x1.b332608ca1a847238ace5779c464p-11), C_(-0x1.021ab5a3bdbb30ee9a537ffac573p-13), C_(0x1.eac528756b7f5130df18318c4f94p-17), C_(0x1.0199b85d253f43e310c32a3ee23dp-24), C_(-0x1.6d0abfd965fbe6911b0989caac0cp-26), C_(0x1.0c61bef3e22c19990cf4042ba7e3p-33), C_(0x1.18cf50a4e4b4950ef758930ceb31p-40), C_(-0x1.0160d4507e328ccba58abe0174c2p-49), C_(0x1.7a161fd10bdebbba470322602b5ap-64), C_(0x1.f195998251a554e483f0c71a4471p-88), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.13189db507a58f44b230b3686764p+1), C_(-0x1.0f9b17b47559884eb516506b8576p+4), C_(0x1.e2750024accc2d74cdaf0e777dc5p+5), C_(-0x1.02e9517352f36c7e1cca5cdce0a3p+7), C_(0x1.84ea97af0478dfed161742a65f15p+7), C_(-0x1.cff7ea5e103622b218e35556d5c2p+7), C_(0x1.edfef34bb4dfb6181091bc4e1283p+7), C_(-0x1.f2fc15391d50c27f5075a6c8ff4bp+7), C_(0x1.eb246356ef9387175566a1e68a13p+7), C_(-0x1.02127d08179f9b70803e08887c21p+8), C_(0x1.3a1511b48828ca00655918525c18p+8), C_(-0x1.91c784aea677bcaa4677a1d92317p+8), C_(0x1.d755a30a6335088a6e9e8a634a61p+8), C_(-0x1.e5c19797a7c13f73162c80019235p+8), C_(0x1.be09360d2ab5d983638f05e968dcp+8), C_(-0x1.6e80a047a6bc49df58dac888c978p+8), C_(0x1.017887f1e05fdfd52e459afc793dp+8), C_(-0x1.16d045efd9fc23449024f4ef5b58p+7), C_(0x1.6f3c5a5aa270e946f4f0452290a4p+5), C_(0x1.00a0bb4260f4b86b22991895dfc7p+1), C_(-0x1.883af181a30c4b69a77ebd74a0cbp+3), C_(0x1.ca6f2d6266dac24630d5b0215037p+2), C_(-0x1.fb9354caf7469830d8b743a50504p+0), C_(0x1.c12f9fd42c0cff788f8d8a32aaf7p-4), C_(0x1.aa753c061078e6073623671f0cd1p-4), C_(-0x1.0149c0900041728b5dc19008c617p-5), C_(0x1.320d29d0ed46573ee176d2f36b8fp-9), C_(0x1.7569a3a8ad03ea55263aad4cfdap-12), C_(-0x1.c7142f2922eef32fe70a3d54296ap-15), C_(0x1.46d93383351fcdeef5e2617523b5p-25), C_(0x1.cc32d5d77364e5410b711a5b1237p-24), C_(-0x1.c3faa80be31a417c7ff07c960f74p-31), C_(-0x1.0e8f2f249697649bebd486ba2aa7p-37), C_(0x1.4b97e65c483067d885e78eb825fep-46), C_(-0x1.6f0e0ef20e7a06716a4c8ec9fe8dp-60), C_(-0x1.e310d5b8794443399cdd6ece490ap-83), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.580f506a271ceefdaa3463cf1629p+2), C_(-0x1.bed7dad0110afcce89ace888e88p+5), C_(0x1.122d5f16217b3e9bf4e80fdc4373p+8), C_(-0x1.ad0c5fd2ce7d97e26b1b63596f32p+9), C_(0x1.ebebc475930229b2000cf737b101p+10), C_(-0x1.c66859645ad39ff322d2fa4b454fp+11), C_(0x1.6b3c821d2c08e770e244c3fd9b4bp+12), C_(-0x1.05ed443c98660df7e825b62de19bp+13), C_(0x1.57df9f8d58ae967ab62cd9351becp+13), C_(-0x1.988852a4ddb8e2394c97f0e9d30bp+13), C_(0x1.b718499032f53cfb6791a553f164p+13), C_(-0x1.ae72afe9b5f0ce3d7715181f289ep+13), C_(0x1.817de8fd200b93d2fe94ab51ad77p+13), C_(-0x1.361e5f944923d3d5bdf35a20adffp+13), C_(0x1.b3a6d661a5e954603cd076722514p+12), C_(-0x1.036ff3829f5795f4ec64398489e6p+12), C_(0x1.edf47d39280a4d357e9e1781a39bp+10), C_(-0x1.10c036b4236268a93be68873acb9p+9), C_(-0x1.e0b697df7f002ac2801a14873b67p+7), C_(0x1.ecbda44c262ae523cdc868e322e1p+8), C_(-0x1.86f5d451d505eacfde5511850305p+8), C_(0x1.725c7f3a52e97d8a78a3843dfb9p+7), C_(-0x1.79d4729613fc7b35a032158d6205p+5), C_(0x1.fd7ee793312f8451ca67d9e92df2p-4), C_(0x1.0d01b8a4bb031f49626bbfdc2049p+2), C_(-0x1.47046f0d13d0e9edd2f830615f89p+0), C_(0x1.be74b29e56e9e7adf67a6938c90ep-4), C_(0x1.1bce9460eaf5c685ea35565b6408p-6), C_(-0x1.bea1c36d184dadae8028a6e3e14cp-9), C_(0x1.c87dd9f0e82f03f1f618a5e508a2p-16), C_(0x1.3736896d21eebb32c780ad16f33cp-17), C_(-0x1.9904cb4c4529ea63892483302a3cp-24), C_(-0x1.1964fba513e306ae2fe86b385614p-30), C_(0x1.cd54969392f7573024faf58e36bap-39), C_(-0x1.819d1aa8bbcb7dddef905812ef85p-52), C_(-0x1.fb7d3a090e0ab46eb1271ed833e8p-74), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.58fd39e3ea473b9c365112f9e5fdp+3), C_(-0x1.f5c4ea84a3bdf86fabc78b7ccf87p+6), C_(0x1.5132162ce5f74a25ac418aed5521p+9), C_(-0x1.153d0f08884aedd476baf2e683p+11), C_(0x1.382a3e583a8c4c9f1dbe11c15209p+12), C_(-0x1.01662d4c3e81ce469818c40b609cp+13), C_(0x1.4a1e803e16c3f08b00f992a85132p+13), C_(-0x1.5e4f1aa3047031adaa3ecd9f7d51p+13), C_(0x1.34f8d319cfee8ccaed9905f9568p+13), C_(-0x1.5037b2099231e17c790011360049p+12), C_(-0x1.c9d4325924514ceeece20c92f62cp+11), C_(0x1.ef1c5da047ca3c6636907219e698p+13), C_(-0x1.aa6460f62329021cc0a31061d8ffp+14), C_(0x1.1493ffefe577c924223ee91be135p+15), C_(-0x1.378dc9a8516802b7004a42d17ea6p+15), C_(0x1.3a895ef60ca292cbe80e485690b9p+15), C_(-0x1.17d3cdfce981563e49f923d38dc9p+15), C_(0x1.b32449a2a05e7c53387e3b5eab6ap+14), C_(-0x1.2d005b15e1ac660d6c6de2ac5d77p+14), C_(0x1.762585d24bf9c7735f9898961b24p+13), C_(-0x1.8db35bc09fe7ee5140a582ff984ep+12), C_(0x1.3cd0860a0aa20c2aa3d4d395b99bp+11), C_(-0x1.0eb312cd7109b3879fc433d5f57fp+9), C_(-0x1.439f55d9eae59605a3c39a59b84ep+6), C_(0x1.991df190f9945d0054430f51818fp+6), C_(-0x1.f474551766f4044e9817e92e973ap+4), C_(0x1.7b90022b6c4e7f168ce752888458p+1), C_(0x1.1453a51ab81ae063df6727985433p-1), C_(-0x1.0919f3da668fc601223376349f5bp-3), C_(0x1.2552ca2a72c78998c9ac373b5bbap-9), C_(0x1.0101dfee94cc5d7f60f2678fd0b1p-11), C_(-0x1.dade9b27d08cb19be2ad380c75a3p-18), C_(-0x1.64097fcb6571f6185210c51bbb62p-24), C_(0x1.8e12f1e504e13d786036befb6f25p-32), C_(-0x1.eef1afe29fcfbef2c0d8edeb2fdcp-45), C_(-0x1.45af8bce131ab3ac470aded6347bp-65), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.c2e57f37dba380a65ba9eda2079fp+3), C_(-0x1.59749d8525f12d8082256adb88ffp+7), C_(0x1.ea6ee085cc96e0d288f3be1b9ca2p+9), C_(-0x1.adf6c2874bed2b3f69d173f96a2fp+11), C_(0x1.07b4a22de335b119555a005db318p+13), C_(-0x1.ecd88a76ee3d3e922a5c04819366p+13), C_(0x1.7c29acad357038f41eb8b1dd0fc7p+14), C_(-0x1.052f5556b7e4a1a5c20ecd7e819fp+15), C_(0x1.4e46d551ac93ec5e56006a3de757p+15), C_(-0x1.8e77607cfd5ad57c6663b8875b37p+15), C_(0x1.b47447ef6b859ed13ace58a9a34dp+15), C_(-0x1.b911fbfaa77dec0071a250cc5fefp+15), C_(0x1.a115d6e8e14d04bc0db0286009bep+15), C_(-0x1.7187cfaf46cf0d5ed6f0095f890ep+15), C_(0x1.2fababdbdc3283e40c1d376f77f3p+15), C_(-0x1.cda4daf54c9cb2382843dcbe14cfp+14), C_(0x1.457825a36823f87f660fc5987cb3p+14), C_(-0x1.a46083210b99766804825ce7a718p+13), C_(0x1.e3885ee2753248f8df804c157d1cp+12), C_(-0x1.e49914e71496a8b65b2bc3b0a8d4p+11), C_(0x1.9ae829c152385eae9b1515bb5c36p+10), C_(-0x1.f191137e3badeb9e76f5cbed8cb2p+8), C_(0x1.57e65b068678833f27ed3ab74f4ep+1), C_(0x1.c2acc962d2fde80f4a40165a5fbdp+6), C_(-0x1.1b8eff5b124df721e99f0cb0e796p+6), C_(0x1.4ce0864f5bc843b2b9783951ecc5p+4), C_(-0x1.f98632e1903923d8655f653df191p+0), C_(-0x1.f614ca355bef0d83e7011b692c6bp-2), C_(0x1.105d05e210a04ac76f5004e82666p-3), C_(-0x1.2c35027764d106ecb7dcc0f035dp-8), C_(-0x1.76591805b151661a98c804b730dcp-11), C_(0x1.f83620ba68c2e3da4e964c603cc5p-17), C_(0x1.9ec84cf651d46727ce1b0a44d7ddp-23), C_(-0x1.358d783409c13e2404896fd5c7b4p-30), C_(0x1.257546b697ae8fd8394b22b0ae34p-42), C_(0x1.8233dd1d0686d57c137ec852b5d4p-62), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.ffa03a8700da7856451e869e7b5ap+3), C_(-0x1.91f11c60f20f4732595d765621bcp+7), C_(0x1.215104c7061731e391acb03d0135p+10), C_(-0x1.fa2000694cbffa8b68970bca9b4p+11), C_(0x1.2ea66d9c1c1c36281a4f053280ccp+13), C_(-0x1.0bde0020ff0122097ceed958162p+14), C_(0x1.7dfdf722720076bd662023e14b8fp+14), C_(-0x1.e6475940e8f80e3e0662171bf565p+14), C_(0x1.28fcf546d66430029dc0ae7f105p+15), C_(-0x1.570d2d144c0d85d5f33951d38d4dp+15), C_(0x1.64b992f501b16328e29ed09c3ca4p+15), C_(-0x1.4cdaed031e2e4abf8359db4b1506p+15), C_(0x1.21c4ffd20e63be71df3b6f2245d3p+15), C_(-0x1.db78c1b913f3be9244561a56f2ecp+14), C_(0x1.5e8fb02e9949d4c003e971dc8526p+14), C_(-0x1.bcf51c1ea8f31b04ed5d992397bap+13), C_(0x1.e583e17ea627e00530e2cb6f7d39p+12), C_(-0x1.aa4e81eafaf451b39ea0ddb0f57dp+11), C_(0x1.13f68d6d4da0d49f20c5505cdf9ep+9), C_(0x1.eda1ba36110bbecc88ad9ef4ce8cp+9), C_(-0x1.4fff2b926b6f5e6bcd2243e80004p+10), C_(0x1.12bce3e2f7931f11964e6bc3f549p+10), C_(-0x1.798d627cec26e7e1e4f53d7bdf9cp+9), C_(0x1.be6fc86ae4a8be5d77f2a1e9d57ap+8), C_(-0x1.8da2d6faf8e64c22dc4a043ad99dp+7), C_(0x1.b66a3015a1c5a11c948aaaf7cab3p+5), C_(-0x1.44429d9883de74d9c60a876b939p+2), C_(-0x1.c3e96613b6e5e2ff71adfacfda7fp+0), C_(0x1.1e57998dcfcf5d1648e257f8bf08p-1), C_(-0x1.07010d4834a6e7a67ce43acbf39ep-5), C_(-0x1.1b562f148b2fb64632b98ead9b7fp-8), C_(0x1.0af79c08ad78f06aac625b45eb1p-13), C_(0x1.f410b3bf125a82ae4c43c7624696p-20), C_(-0x1.f9be8616ca648419dbd80373acd5p-27), C_(0x1.6a9909c4a9f6ffff9ad70512f7b1p-38), C_(0x1.dd2f7b7aa9b821698f859b9d1a0fp-57), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.87fb22468465fb8a2934ce18ef16p+3), C_(-0x1.37c2f683aab22684a06e79a101a1p+7), C_(0x1.c5fd83f053f82dac4273a062a48dp+9), C_(-0x1.91b1e12dd60d97ec2e841dbfca05p+11), C_(0x1.e68387666347c07a316a9422b5b6p+12), C_(-0x1.b4dea0e7d579f84f7fb9d6c16bdcp+13), C_(0x1.3c269a772fa78e428d8f5044caa8p+14), C_(-0x1.97127ecaa2ab1915c1aae5c6fc8ap+14), C_(0x1.f6af289cce31c29a6ec330fbe9e1p+14), C_(-0x1.2a9f5b6b03ca5e9eb10038f1c5dbp+15), C_(0x1.4b10d6718988db4dba24714139cp+15), C_(-0x1.55a31577d419bbaf6e8ea53fe90dp+15), C_(0x1.4e7cdd5d8ea4ad7bd94b50975a01p+15), C_(-0x1.38022f772c0b4cce7e7232f4f9bap+15), C_(0x1.12be31f5fe34faa8426124a140c7p+15), C_(-0x1.c90c6d590473b7e23f50a6ff90abp+14), C_(0x1.68be09036d4b8e25079ad44a0fb5p+14), C_(-0x1.0c494e2492cb7350d7dea324e249p+14), C_(0x1.758345ee1ea103707e4fc5726b69p+13), C_(-0x1.e8a773cd517e44f45076f71519e1p+12), C_(0x1.2a474ea41676fa5a62a310e63587p+12), C_(-0x1.4af3fdfe318309e19b15b68fb972p+11), C_(0x1.49733b39a1c4ced0b1d897e0d8ecp+10), C_(-0x1.28058c9d809d32e67b550b8feec3p+9), C_(0x1.c739fb1ca38e254565961e77d1e7p+7), C_(-0x1.e2ee0f774ec3af6a1c1e4f7b17bcp+5), C_(0x1.f584835c1818f23dc08b323d98e5p+1), C_(0x1.dc8e84cc4afe7a2fb01ea8367041p+1), C_(-0x1.3b3a53bf8d0a53e1e10973253b98p+0), C_(0x1.6a83343080c3f8b48adb7f8a0fc4p-4), C_(0x1.952a26a6e4af59b3b26bda8c8609p-7), C_(-0x1.3a135cf1b710ef334411ec10d2fbp-11), C_(-0x1.208be3b61fd62740fba383db12cep-17), C_(0x1.a71d1df2466b06f953d67915b744p-24), C_(-0x1.b3e65dd0b550b982df6eefc5304bp-35), C_(-0x1.1ed120d152ef3b5a4475e78c15bcp-52), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.14760cca8b142294e79588592265p+3), C_(-0x1.ba74df47bf664ee2547385285e06p+6), C_(0x1.41711dcfaf9ae33ef5a42497cdccp+9), C_(-0x1.1818fad342f755601ec00141bb62p+11), C_(0x1.474e1b48df1603e34e0f10a63ce8p+12), C_(-0x1.1344c928a46119ef7f83bdf82b73p+13), C_(0x1.69c3448f5e9dbd2d90d955490598p+13), C_(-0x1.a6933630b28804e5fdf1db79e516p+13), C_(0x1.f096b7533884b484daabf2ec386p+13), C_(-0x1.22623e57fb5283c6330ad006e50dp+14), C_(0x1.3656cdaada5ee9f54e572471e7bep+14), C_(-0x1.2c112510224741f5281f55b6dc46p+14), C_(0x1.1649895fe753bac480e018c717a8p+14), C_(-0x1.f7bb2384208e05c66ecac730535dp+13), C_(0x1.a9475e44156e584ae36a2ec50f02p+13), C_(-0x1.4a8f9de0fe8b863882cf98bdc30ep+13), C_(0x1.eb5875381b21b266553a6296e0a5p+12), C_(-0x1.5ee64eec32c02ba06ecbd76a11b3p+12), C_(0x1.ccfb4d9d3a3fd43202c9da414974p+11), C_(-0x1.14a05b02023d93595fe14dff5f3bp+11), C_(0x1.3a9e21e52de90e0e25e5cf4ca63ap+10), C_(-0x1.4bc3a327f05f291344a38f901a5dp+9), C_(0x1.2adbd2de6a50340d8168b2783c01p+8), C_(-0x1.c3c2f4b5f88c5c0995d28d11b9ebp+6), C_(0x1.277a18d79f69dcf96944e2b0fcf5p+5), C_(-0x1.c9f8833026d5a408341117a30a92p+2), C_(-0x1.454631d4223dc7af67ef97ef1099p+1), C_(0x1.43b3c20fabe24e5d14333b1e0567p+1), C_(-0x1.7e2b7474504f09a810523ca07f92p-1), C_(0x1.0161c2b653dc5e969cd9fbd6d0edp-4), C_(0x1.00c51140e71642a9a41e83368bbdp-7), C_(-0x1.ae184c969f7530c56af21ca3a7a8p-11), C_(-0x1.8063c15ef2a25ff6da3cad34895fp-17), C_(0x1.7fa9f24707d3d7cbfa3e9820acf4p-23), C_(-0x1.2feaa75fa15b4cbbde0dc3686d2fp-33), C_(-0x1.8febd0375e4aae5f4479ef67c215p-50), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.309432a44a63023cd5d74f5bea55p+2), C_(-0x1.e8f069c87232260c91fa71890f2bp+5), C_(0x1.620bb6edc4428b1d5f4fa47a5ecep+8), C_(-0x1.30502125aeb77e95c45d9e43464ep+10), C_(0x1.5897d2f743a96869b1eb0ca13247p+11), C_(-0x1.10925ae24fc57451105c29bc2a9fp+12), C_(0x1.4362e4b63cec61ff21aac6b7ac6ep+12), C_(-0x1.4ffdb02cc70cfe03dbf6d475eb63p+12), C_(0x1.779b03f599f05e82b08d8b48f758p+12), C_(-0x1.baec7e0e55169b8140b39b8fb14bp+12), C_(0x1.ce2ff743f88370d5e72cb7988fbcp+12), C_(-0x1.9f067ce3296956a187e74bb12383p+12), C_(0x1.6abb1f9cef609047d528387a0ad9p+12), C_(-0x1.4450d5aabf62ce501c4c7a9271c2p+12), C_(0x1.08545f0a3187b9a2ec020313e51cp+12), C_(-0x1.7530230cd216d38656dfbf0553dap+11), C_(0x1.f952b436845ca1bafccd87887abfp+10), C_(-0x1.560fff419d2c2e711437c4013006p+10), C_(0x1.8c0d255b6e233d3a2cb91681d042p+9), C_(-0x1.5fdc3ca1d5db02eaba158929c246p+8), C_(0x1.0a97d5984be8315545f375086dccp+7), C_(-0x1.20a6202d36bbe9ea7b9fe18176b3p+5), C_(-0x1.5a7221251a0809c48fe9776bbed6p+4), C_(0x1.3634e4081412bfd6aa7ecc784b01p+5), C_(-0x1.bdda94264568de640cdd8fb6a91bp+4), C_(0x1.feb750a84a74f7d5dc8417586506p+3), C_(-0x1.275477518f18aa31553de78414f5p+3), C_(0x1.12ebd04f5867e9e6cd551be469c5p+2), C_(-0x1.30dbe403419efe34f764090a038fp+0), C_(0x1.058d7af30daa34c20339630ccaeap-3), C_(0x1.916084cd62258d7ea8b1535e2f8ep-7), C_(-0x1.732dce99f11c6f7cee7cd02c7701p-9), C_(-0x1.7126e2b2a55e5160267b465d584cp-15), C_(0x1.f42158d77d0c28962287129d0e59p-21), C_(-0x1.357be619f66df06ada13476a9641p-30), C_(-0x1.9731ccc0ad49712bbc19913bd785p-46), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.8a04267542fb82b6511fb8f206b7p+0), C_(-0x1.3cbc4bff9713202eddfb257134f3p+4), C_(0x1.cbebed769f041b8ff3b3ff336b7ep+6), C_(-0x1.8d408dd48e3feaaa0b268282946dp+8), C_(0x1.c5c362fe59a680f0eae654ab9d42p+9), C_(-0x1.6befff94df0fd5c1ea5963474048p+10), C_(0x1.b68e6a376222daa009bfb53e28dp+10), C_(-0x1.c650372cae06a09b58e507b0871ep+10), C_(0x1.e7dc6f316434651b61d954241667p+10), C_(-0x1.15cc9fcbffbdadb34e9d61d6c6eep+11), C_(0x1.25d8da27ae488c61183e3d71ffbcp+11), C_(-0x1.17ff07a3bf7e3928a0bec71f80dbp+11), C_(0x1.0475b26522c32263166cf14a852ap+11), C_(-0x1.e40da504c90b0dabfc10981e655cp+10), C_(0x1.a69e253ca704fe5504b2c83ebfdbp+10), C_(-0x1.57f0b96fa56496dc384c41ebdb2p+10), C_(0x1.11486c0ca46dc3a169a7bf688364p+10), C_(-0x1.a51b5b4b4c6e9a002c8fc1ca65e6p+9), C_(0x1.2ee508d88648873a9042e781e817p+9), C_(-0x1.9d3a15a142fb235220e5bdb7d581p+8), C_(0x1.11494e2078a35defd9005276ea95p+8), C_(-0x1.535f44eb08e29df270d509de713ep+7), C_(0x1.85e2cd196a74cb82559b30f986fdp+6), C_(-0x1.ab69cc5e56727978f17d430c4129p+5), C_(0x1.b6235da40abe2f3f3eea8ec9a5f6p+4), C_(-0x1.8b55be10b7592b154b2ba9939157p+3), C_(0x1.414892cca85f8967c379d65c1761p+2), C_(-0x1.e63611dc23584e97ec62af26dc25p+0), C_(0x1.1a15ef6adced3df1c6c0346a88a1p-1), C_(-0x1.2481c80f712590a8d277e551e4fep-4), C_(-0x1.27449cc156e8a2b8d79cdb23e19p-7), C_(0x1.70c363a504f9eefb5323d6beb984p-9), C_(0x1.513124306018b235441513a840aep-15), C_(-0x1.d1034c80bf12bfc41e39ee6d8817p-20), C_(0x1.59ccd407dcf5a9a7533ca67a560ap-29), C_(0x1.c6dbd9b6fbf34f8784ef66a9534dp-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.d374dc0cd29f78efae1c669adc98p-2), C_(-0x1.780e4d99b7126e1227fd8360470ep+2), C_(0x1.0fdf2439cdc107efd9b577f835a9p+5), C_(-0x1.cfa32c44d17cf6112a211a2ca37ap+6), C_(0x1.015959857901578ca504dacee669p+8), C_(-0x1.85bc6b66153fd1bea9b65cf18fa7p+8), C_(0x1.a64f0f8c995c4aa45de473272a55p+8), C_(-0x1.7a602a5238af6059f76503b7cbc2p+8), C_(0x1.7b654c5560678179ce7606e1eb5bp+8), C_(-0x1.bd48fca1124c5a0c87121a03cfe7p+8), C_(0x1.d04b583d66c5fddbbacf446d9c66p+8), C_(-0x1.9412225fd51522e93e47c93309f2p+8), C_(0x1.601c278c16ffe3bedc9949af1437p+8), C_(-0x1.4b7186886095601966984faa4acep+8), C_(0x1.1d01310f5613f772298e42534595p+8), C_(-0x1.abfcdefee09bf658999362e6f111p+7), C_(0x1.4372d34e52fa3409ae85e2a019f6p+7), C_(-0x1.f6105d4c84d999290c211733ed04p+6), C_(0x1.5bb1d872e66637325ce8f6aa17bep+6), C_(-0x1.b1d6456c69f76f04df5acebda739p+5), C_(0x1.15b4bfdbddb01fb2de3e2b574816p+5), C_(-0x1.5951b3080c61b9307228b6ed10bbp+4), C_(0x1.701e202aeccdeb8ac6b6b30bcacp+3), C_(-0x1.6ddc190753e3ea59a0862615508fp+2), C_(0x1.77099e572e056d9b063dba7e75c1p+1), C_(-0x1.4e4b25c08b76d3f35349a1737dcep+0), C_(0x1.d2b148f357c3f676caf89142fe6p-2), C_(-0x1.3f20a405e77bfa5f0c7b2c20c976p-3), C_(0x1.9e7b676edad2c438a7201cee715ap-5), C_(-0x1.868422c7d3c55e44cf7999291ce8p-8), C_(-0x1.3d8b8d9fd24906b21fe8a1d895d9p-9), C_(0x1.57f23d8a911c1c88e9f1808c31e4p-11), C_(0x1.21e64d9dcd8227de3458f3f5849cp-21), C_(-0x1.d450acc53a98cfc94056c9e9eb52p-21), C_(0x1.0524ac3af31035a21da55dd5b9a3p-30), C_(0x1.575344ae7025305d708f9f17a1a5p-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.515b9f63b7c8d9d621c7f83ca202p-4), C_(-0x1.0f7f6c187ccac0b76cfe6b463e44p+0), C_(0x1.8785c563b5897121211402b9f302p+2), C_(-0x1.4b2e4e52216e5851aba80d8bd8e5p+4), C_(0x1.6901cf579638d44ea9478cea01d4p+5), C_(-0x1.06c8002a381179d9f60f753114a4p+6), C_(0x1.05cb21187a0f4fd8449a14491a1ap+6), C_(-0x1.95b91f5bb17e01dfb0ac91c796f8p+5), C_(0x1.7701942190fc5f1e86a9d43b21f6p+5), C_(-0x1.ce78be0577929e543cbd7ad9b93bp+5), C_(0x1.e29898694f90f26ba0d29f50470ep+5), C_(-0x1.7f1203e71656f1392c2a5ed0ed1cp+5), C_(0x1.37e1b965edd32923f1ca90e8ee72p+5), C_(-0x1.32c7bde1b71fddd33a7396827f1p+5), C_(0x1.098dc7ef6c8b51bc5142e5eef069p+5), C_(-0x1.6fe8868cdb497ea274e3965b3923p+4), C_(0x1.0ba553b7e7f0be8b204b950f5ae8p+4), C_(-0x1.b42a38b735b9796714d4ff017726p+3), C_(0x1.28e9aca928974002f9a9710ee004p+3), C_(-0x1.515c3566a134d8fdf2749b107958p+2), C_(0x1.ae8a4319bcbc3c0849df1986eff8p+1), C_(-0x1.1895df589aea592ca4ae051262ecp+1), C_(0x1.14e9f7c12e2c99db92b3020068dbp+0), C_(-0x1.e47340b006f8809308435a5f94dcp-2), C_(0x1.062f736c8ea4db2c5025ce71eba6p-2), C_(-0x1.d4b69f6b077f6afaf5cbb7fe058ap-4), C_(0x1.ca34188e3ee232929967c28b9b2ep-6), C_(-0x1.abe68c068be60d047f0a28b8716cp-8), C_(0x1.690421cc61ef435baf7b95f1a52fp-9), C_(0x1.f0697cb773e3bc4b5c6f8da3552ap-12), C_(-0x1.c195d60892125cb3e4fc26494359p-11), C_(0x1.b812af9cf3a26f639a51b597d61cp-13), C_(-0x1.bff07c97b4e02892210bbfe57ccbp-18), C_(-0x1.52d29bd9004df24ead72772a383cp-21), C_(0x1.032cd4ca8cfc03e1481665c670fdp-32), C_(0x1.5462cc3c1b3950e1af932e243f9p-45), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.19f56cbab95bde76557badc0f4cfp-7), C_(-0x1.c5e9cb7948f398db235b0497713cp-4), C_(0x1.45ccfe221c0e9033121b0a870c75p-1), C_(-0x1.0ff7774a4970235ef0d0d38e3503p+1), C_(0x1.1f8e85bb37dc52e0187eb7a98e68p+2), C_(-0x1.86af502d50caccee8ec1f8fa9cd2p+2), C_(0x1.49bbefd2893ed26dde1f31860f1dp+2), C_(-0x1.6128a473d02d185e7eb02c402e5cp+1), C_(0x1.1828041581a25f5b721c3a717f02p+1), C_(-0x1.d956f1ddda30a36e6132710c578ep+1), C_(0x1.038faca047549c3c3be2f3f91741p+2), C_(-0x1.37b3d4e72913f8a1a7f18bf41b92p+1), C_(0x1.7db8d08d07a3f9e23e72ca58a9d9p+0), C_(-0x1.e8024d590281c76397a14742f7fep+0), C_(0x1.bf0c126480d51b8dd799512a9bbcp+0), C_(-0x1.9a6e24093a6a2e038548f4c21568p-1), C_(0x1.9d414904073073148ca53b09a0c9p-2), C_(-0x1.e94579a438133caa5c0cf94e7bc6p-2), C_(0x1.1fe0d75be11ddab72d3817a1df79p-2), C_(-0x1.138ce466125db8659c96547c9ecbp-7), C_(-0x1.34e623ad04da0418dc894a3d03adp-6), C_(-0x1.2fc16b0c0aa7163aea99c6e062f3p-7), C_(-0x1.d550ce5b878423f79b2e760869bbp-6), C_(0x1.5e3d43af8f8ddb8e3580c4af5d78p-5), C_(-0x1.6c1ef7a1d6e428cbd81df1c34e95p-6), C_(0x1.8a7d31fc8c9aee233f27827d8acap-7), C_(-0x1.52a8406945db2a229ecbdd1d3a6ap-7), C_(0x1.7e48f37194da1a9d35aebc50ef39p-8), C_(-0x1.157ac29aabe3ff0003550e84e639p-9), C_(0x1.ef1519ddac57eba8aaaa2d2f321ap-11), C_(-0x1.e9152bfae3a36641e3acf97f58dcp-12), C_(0x1.063d5981a1db32ae377107926c9ep-13), C_(-0x1.4c0cd023430cc482bd47183c0ef3p-17), C_(-0x1.c41b70da67df95d6233d9591b513p-21), C_(0x1.5615a8cb6d771ab8987aa2645074p-32), C_(0x1.c05941495cbd662c96cb64517d6bp-44), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.94435eb9af5275885daf683a6d65p-11), C_(0x1.ed6b4c3fc563bad856b7ff679708p-2), C_(0x1.e76d4a24be344d37fa2f63572709p+3), C_(0x1.2e6decff81b60c629b716c5e755bp+6), C_(0x1.b10d4368bfb547486b053181a892p+4), C_(-0x1.2aabf32fc96a83423162d2c816bp+5), C_(0x1.d877b83c63dd7e5e4cc6dd5d03a9p+4), C_(-0x1.473d4fc793666a7b844c67c60bd8p+4), C_(0x1.95d0bb71b70ebdc02338882a3446p+3), C_(-0x1.af691b75d1d83460cd380f784013p+2), C_(0x1.6d28dba75e1d6e3724ad5b4f87b2p+1), C_(-0x1.a6978440cef93cfbe48ab54a4883p-1), C_(0x1.1490ceb2bb752e576e6ab7934d2ap-4), C_(0x1.464cc9ffc1d7e4d14789afa29b8ap-4), C_(-0x1.a276802b30603b547d67dda28d1bp-5), C_(0x1.1d1df4fc9211fc9b42905d09c47cp-6), C_(-0x1.17d7d8739a0a8aedb047da85632p-8), C_(0x1.ebfe215a7af3d07469844cb63084p-11), C_(-0x1.4f11d28267254fe725cc5344d47fp-13), C_(-0x1.9b2b7a111f74e448315a5acfceb6p-17), C_(0x1.14946151574b1cc87019ae7e5eccp-16), C_(-0x1.a6bb3de2d570ec48084b02756991p-19), C_(-0x1.9504b8c2dfd49dc16ebf73767df5p-24), C_(0x1.17aee7159c99baf232751bad6bd3p-24), C_(0x1.70d51f32a8d959f82b22d341a23bp-30), C_(-0x1.5dd5370ddab610b2e6c646e6c17ap-32), C_(-0x1.e8aac4dbdf4eaec509688435a8c6p-35), C_(0x1.629884f91c42aa4b289bcdb69f39p-40), C_(0x1.1aef0590aab3b2864498ba08a331p-44), C_(-0x1.21c09a3e7d5c59641f5b485f413p-50), C_(0x1.b8e2ec16d3130e2d4b06e1e5ebcbp-59), C_(-0x1.8c242cff56d3b852843f6ec978c7p-64), C_(0x1.c20c22cff32a0ee7b7221886273ep-74), C_(0x1.8b88202dbba79e3009dedbb574b1p-88), C_(0x1.27f0bb4febe21c10d76a7232b49p-103), C_(0x1.8579c244925048746514bf00ae6dp-133), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(0x1.263966f58e93453d04e057c51a09p-10), C_(0x1.5fb5bf5017c5cbd580114bdb418p-2), C_(0x1.79fa0aa0ef4b1e94ae76e603830ep+2), C_(0x1.0041752577d99920a4756cf6dfd7p+3), C_(-0x1.6480edc11cb316f0df4191286f79p+4), C_(0x1.7adbeb32519375a4e9fc4f3e6a5bp+3), C_(-0x1.8761c804c949b74e319f96893292p+2), C_(0x1.0bbe5cbfe7fbfd16a26214b40cadp+2), C_(-0x1.c27eb52ff5df81afb96ebb8be06ap+1), C_(0x1.6f68e268413d3fe6c3a7fa4919f1p+1), C_(-0x1.fbed86051f0cd090a4eeebb3ba08p+0), C_(0x1.17c1f8ccfdcb9142f7ebab0435b5p+0), C_(-0x1.cf35ce446b0dbe81a8d8224d1015p-2), C_(0x1.fa3032b16e2ec1aa83ca0e93a41cp-4), C_(-0x1.610cbeafdcc29a63e60dfb78086p-7), C_(-0x1.f0a31aba969e59e1d540df6c7f09p-8), C_(0x1.cb16dc9a66c8c832a40588853909p-9), C_(-0x1.378619c057d6f59580d9bc18beb2p-12), C_(-0x1.19bd674de47d6898c22e3b3237e3p-12), C_(0x1.c15384b637285af63775101117b6p-14), C_(-0x1.014a5dd580db7e757daab9ece5fdp-17), C_(-0x1.4f01d7193ba039b859fe936d4da5p-18), C_(0x1.63c48bb9daaef9ef37d87bcf220dp-20), C_(-0x1.0126c6d159333aa9ffefda4ce01fp-25), C_(-0x1.9c0d1ce2d6bcfc30df35efd50ccbp-26), C_(0x1.f835a0a4ec39a7abf277183bd5afp-30), C_(-0x1.e018504ab9e4668fd6a8d7855266p-38), C_(-0x1.2225fdd38424d963076e1b05254fp-37), C_(0x1.9c61eaa91cf12e3330e482deddd5p-42), C_(0x1.3e42beb720a117dd0b00b4bdbe96p-50), C_(-0x1.1199b0b74da5aecc08a2c6ccc14ep-53), C_(0x1.58b777bfe6b1520fc88066b839f4p-62), C_(0x1.001f51ec932dbb77f103a0f7564dp-70), C_(-0x1.7359d9741f8ec2aef5430062a9fap-82), C_(0x1.529c13dec223da6d213dd3aa18cap-99), C_(0x1.bda18c791fe6b89a60c075d9dac4p-128), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.55c2dd92705ef29dacf510df5483p-9), C_(-0x1.875690159b946a743f6031d71359p-2), C_(-0x1.756f6cbad17a45f8fdca57537e0cp+1), C_(0x1.522462f959194685a62f604b7373p+2), C_(0x1.6695cecd8b44feab641f1eb716abp+1), C_(-0x1.55d8721e5e38fe7f6b6b27b70f1ap+3), C_(0x1.5a1db9a981431612f8d678081919p+3), C_(-0x1.0851517441a6e04a55b896ef99e1p+3), C_(0x1.4943b00084361d8656967cf91ea6p+2), C_(-0x1.3bad2deaede17c67f605a6915c1cp+1), C_(0x1.7b9d5b96164de0ffe09e1ad56182p-1), C_(0x1.9c78d3c486af6a9c43cd6d82014p-7), C_(-0x1.3adc11c8d3555c352fd89192cfdp-3), C_(0x1.5c787302c6a0e308908c5a566d12p-4), C_(-0x1.79c3b00ffbead0016b7d6948b83ep-6), C_(0x1.24e941b9401cdd0859a58e2c60b8p-8), C_(-0x1.a08712ec476e0f62559aaf166efp-9), C_(0x1.43c84b18b6bc1f9bc1ed4ace622fp-9), C_(-0x1.f9ed905ce1a3fabec727edc27bfdp-11), C_(0x1.28365cf3c20b9931191c65e395d2p-13), C_(0x1.dbc105f0dcd19a43895a2c14219bp-16), C_(-0x1.06fd02a0249f9985362be2e45162p-16), C_(0x1.5536f1beba49f3fa62573cb3aefap-19), C_(-0x1.1eb1b927a2367b6b71d37a3a0b16p-23), C_(-0x1.18cae380af7c0fb2b2883f2e7a9fp-26), C_(0x1.962198a9fb4f49acf27837af9e55p-28), C_(-0x1.4a0510fbc2258e2b740de37281f1p-31), C_(-0x1.5507dda80e4462056671b4ed9443p-36), C_(0x1.0a2a68de8dc560166b8fa1f0e29fp-39), C_(0x1.5b65f0e23da86c0f9732111de5a7p-46), C_(-0x1.652ce69e3233a8cdb2d672d4de9fp-51), C_(-0x1.67baca3a273431e8c1471458d539p-60), C_(0x1.2a22a2a629f6431996d0904b53cbp-67), C_(-0x1.c9d5657e9bda6dc8a405fc5c3a28p-79), C_(0x1.8a4260a0edd15c6744f3a072dd9cp-95), C_(0x1.036f45f65701ff403784f02b67ep-122), C_(0x0p+0) }; }; +template struct daubechies_scaling_integer_grid_imp { static inline constexpr std::array value = { C_(0x0p+0), C_(-0x1.bda79ab9326966a8373d34c403d5p-10), C_(-0x1.d1744a8423410c1cdbc92198fb2ep-4), C_(-0x1.20ed565d8344f24b447d5dad1a94p-3), C_(0x1.7e6fc4bdbfcb347e60be376cd8fcp+0), C_(-0x1.5b972509d68a9e778b59e41da454p+1), C_(0x1.442d2d17d149d7c8adb7128a4a5bp+1), C_(-0x1.e2277288714cc11d45fb77f46c4ap+0), C_(0x1.9379ce87585cf7e36c9df60dab88p+0), C_(-0x1.659214144828aeeba2e8c5e20a63p+0), C_(0x1.20bc0fb1d00715f9a829adb0ea43p+0), C_(-0x1.8283009ebbc1eb153c3ab896b77bp-1), C_(0x1.8fa7bb64ff9ab76d61906bd796f1p-2), C_(-0x1.180d836c3d15c7dc5dd02b639eccp-3), C_(0x1.faecc9e70faee2855b6fee69691fp-7), C_(0x1.07a09dde4a2beade229071da7cf2p-6), C_(-0x1.7b9be86674bb70da10cbd67f2dafp-7), C_(0x1.92c3d8394a5b35c0ac95d90e2cd5p-9), C_(0x1.d5864f4fa99910c57caa7bc9e471p-12), C_(-0x1.559b12ec6e892a72794bb66e37cep-11), C_(0x1.a62f6a612f39a18acf0803b47144p-13), C_(-0x1.0d223ecdbfff75a7fa9690777531p-19), C_(-0x1.0fdbebf048174e10984f842f14c4p-16), C_(0x1.202e4a843fcd49b1f3f621772e1ep-18), C_(-0x1.86705793870af2933b93c10e211p-23), C_(-0x1.992e1c88b7cd13dae9b8e491d4dap-24), C_(0x1.018eb6827a7049feef27c5ca32bcp-26), C_(-0x1.c2b71846e1645f5cc0f2480787d5p-32), C_(-0x1.57e1e9171e5bc5fcf45eafbaecf7p-34), C_(0x1.717b9ae9f68e605d4d193d54fc52p-38), C_(0x1.6027613ce51bde3efec97caba709p-46), C_(-0x1.be324a2f0323f8a5380cb0e8a1d4p-49), C_(0x1.3eb2f19289730e4086f2e07ef711p-57), C_(0x1.bf9c807f8fa727e8ceb75bf12aacp-65), C_(-0x1.2fec3bd7b3920aea071e434958e4p-75), C_(0x1.290ed0b71d4a892449c6c2ced6f5p-91), C_(0x1.86f240571d54c453fa3cc6af74bep-118), C_(0x0p+0) }; }; + + +template +constexpr inline std::array daubechies_scaling_integer_grid() +{ + static_assert(sizeof(Real) <= 16, "Integer grids only computed up to 128 bits of precision."); + static_assert(p <= 19, "Integer grids only implemented up to 19."); + static_assert(p > 1, "Integer grids only implemented for p >= 2."); + return daubechies_scaling_integer_grid_imp::value; +} + +} // namespaces +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/erf_inv.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/erf_inv.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/erf_inv.hpp @@ -0,0 +1,549 @@ +// (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_SF_ERF_INV_HPP +#define BOOST_MATH_SF_ERF_INV_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4127) // Conditional expression is constant +#pragma warning(disable:4702) // Unreachable code: optimization warning +#endif + +#include + +namespace boost{ namespace math{ + +namespace detail{ +// +// The inverse erf and erfc functions share a common implementation, +// this version is for 80-bit long double's and smaller: +// +template +T erf_inv_imp(const T& p, const T& q, const Policy&, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // for ADL of std names. + + T result = 0; + + if(p <= 0.5) + { + // + // Evaluate inverse erf using the rational approximation: + // + // x = p(p+10)(Y+R(p)) + // + // Where Y is a constant, and R(p) is optimised for a low + // absolute error compared to |Y|. + // + // double: Max error found: 2.001849e-18 + // long double: Max error found: 1.017064e-20 + // Maximum Deviation Found (actual error term at infinite precision) 8.030e-21 + // + static const float Y = 0.0891314744949340820313f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000508781949658280665617), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00836874819741736770379), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0334806625409744615033), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0126926147662974029034), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0365637971411762664006), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0219878681111168899165), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00822687874676915743155), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00538772965071242932965) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.970005043303290640362), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.56574558234175846809), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.56221558398423026363), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.662328840472002992063), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.71228902341542847553), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0527396382340099713954), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0795283687341571680018), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00233393759374190016776), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000886216390456424707504) + }; + T g = p * (p + 10); + T r = tools::evaluate_polynomial(P, p) / tools::evaluate_polynomial(Q, p); + result = g * Y + g * r; + } + else if(q >= 0.25) + { + // + // Rational approximation for 0.5 > q >= 0.25 + // + // x = sqrt(-2*log(q)) / (Y + R(q)) + // + // Where Y is a constant, and R(q) is optimised for a low + // absolute error compared to Y. + // + // double : Max error found: 7.403372e-17 + // long double : Max error found: 6.084616e-20 + // Maximum Deviation Found (error term) 4.811e-20 + // + static const float Y = 2.249481201171875f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.202433508355938759655), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.105264680699391713268), + BOOST_MATH_BIG_CONSTANT(T, 64, 8.37050328343119927838), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.6447298408374015486), + BOOST_MATH_BIG_CONSTANT(T, 64, -18.8510648058714251895), + BOOST_MATH_BIG_CONSTANT(T, 64, -44.6382324441786960818), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.445385985570866523), + BOOST_MATH_BIG_CONSTANT(T, 64, 21.1294655448340526258), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.67192254707729348546) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.24264124854247537712), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.9713437953343869095), + BOOST_MATH_BIG_CONSTANT(T, 64, -28.6608180499800029974), + BOOST_MATH_BIG_CONSTANT(T, 64, -20.1432634680485188801), + BOOST_MATH_BIG_CONSTANT(T, 64, 48.5609213108739935468), + BOOST_MATH_BIG_CONSTANT(T, 64, 10.8268667355460159008), + BOOST_MATH_BIG_CONSTANT(T, 64, -22.6436933413139721736), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.72114765761200282724) + }; + T g = sqrt(-2 * log(q)); + T xs = q - 0.25f; + T r = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = g / (Y + r); + } + else + { + // + // For q < 0.25 we have a series of rational approximations all + // of the general form: + // + // let: x = sqrt(-log(q)) + // + // Then the result is given by: + // + // x(Y+R(x-B)) + // + // where Y is a constant, B is the lowest value of x for which + // the approximation is valid, and R(x-B) is optimised for a low + // absolute error compared to Y. + // + // Note that almost all code will really go through the first + // or maybe second approximation. After than we're dealing with very + // small input values indeed: 80 and 128 bit long double's go all the + // way down to ~ 1e-5000 so the "tail" is rather long... + // + T x = sqrt(-log(q)); + if(x < 3) + { + // Max error found: 1.089051e-20 + static const float Y = 0.807220458984375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.131102781679951906451), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.163794047193317060787), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.117030156341995252019), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.387079738972604337464), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.337785538912035898924), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142869534408157156766), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0290157910005329060432), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00214558995388805277169), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.679465575181126350155e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.285225331782217055858e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.681149956853776992068e-9) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.46625407242567245975), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.38168345707006855425), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.77846592945843778382), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.59301921623620271374), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.848854343457902036425), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.152264338295331783612), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.01105924229346489121) + }; + T xs = x - 1.125f; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 6) + { + // Max error found: 8.389174e-21 + static const float Y = 0.93995571136474609375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0350353787183177984712), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00222426529213447927281), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0185573306514231072324), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00950804701325919603619), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00187123492819559223345), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000157544617424960554631), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.460469890584317994083e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.230404776911882601748e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.266339227425782031962e-11) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.3653349817554063097), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.762059164553623404043), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.220091105764131249824), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0341589143670947727934), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00263861676657015992959), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.764675292302794483503e-4) + }; + T xs = x - 3; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 18) + { + // Max error found: 1.481312e-19 + static const float Y = 0.98362827301025390625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0167431005076633737133), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00112951438745580278863), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00105628862152492910091), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000209386317487588078668), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.149624783758342370182e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.449696789927706453732e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.462596163522878599135e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.281128735628831791805e-13), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.99055709973310326855e-16) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.591429344886417493481), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.138151865749083321638), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0160746087093676504695), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000964011807005165528527), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.275335474764726041141e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.282243172016108031869e-6) + }; + T xs = x - 6; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else if(x < 44) + { + // Max error found: 5.697761e-20 + static const float Y = 0.99714565277099609375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0024978212791898131227), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.779190719229053954292e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.254723037413027451751e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.162397777342510920873e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.396341011304801168516e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.411632831190944208473e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.145596286718675035587e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.116765012397184275695e-17) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.207123112214422517181), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0169410838120975906478), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000690538265622684595676), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.145007359818232637924e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.144437756628144157666e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.509761276599778486139e-9) + }; + T xs = x - 18; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + else + { + // Max error found: 1.279746e-20 + static const float Y = 0.99941349029541015625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000539042911019078575891), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.28398759004727721098e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.899465114892291446442e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.229345859265920864296e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.225561444863500149219e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.947846627503022684216e-12), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.135880130108924861008e-14), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.348890393399948882918e-21) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0845746234001899436914), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00282092984726264681981), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.468292921940894236786e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.399968812193862100054e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.161809290887904476097e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.231558608310259605225e-11) + }; + T xs = x - 44; + T R = tools::evaluate_polynomial(P, xs) / tools::evaluate_polynomial(Q, xs); + result = Y * x + R * x; + } + } + return result; +} + +template +struct erf_roots +{ + boost::math::tuple operator()(const T& guess) + { + BOOST_MATH_STD_USING + T derivative = sign * (2 / sqrt(constants::pi())) * exp(-(guess * guess)); + T derivative2 = -2 * guess * derivative; + return boost::math::make_tuple(((sign > 0) ? static_cast(boost::math::erf(guess, Policy()) - target) : static_cast(boost::math::erfc(guess, Policy())) - target), derivative, derivative2); + } + erf_roots(T z, int s) : target(z), sign(s) {} +private: + T target; + int sign; +}; + +template +T erf_inv_imp(const T& p, const T& q, const Policy& pol, const std::integral_constant*) +{ + // + // Generic version, get a guess that's accurate to 64-bits (10^-19) + // + T guess = erf_inv_imp(p, q, pol, static_cast const*>(nullptr)); + T result; + // + // If T has more bit's than 64 in it's mantissa then we need to iterate, + // otherwise we can just return the result: + // + if(policies::digits() > 64) + { + std::uintmax_t max_iter = policies::get_max_root_iterations(); + if(p <= 0.5) + { + result = tools::halley_iterate(detail::erf_roots::type, Policy>(p, 1), guess, static_cast(0), tools::max_value(), (policies::digits() * 2) / 3, max_iter); + } + else + { + result = tools::halley_iterate(detail::erf_roots::type, Policy>(q, -1), guess, static_cast(0), tools::max_value(), (policies::digits() * 2) / 3, max_iter); + } + policies::check_root_iterations("boost::math::erf_inv<%1%>", max_iter, pol); + } + else + { + result = guess; + } + return result; +} + +template +struct erf_inv_initializer +{ + struct init + { + init() + { + do_init(); + } + static bool is_value_non_zero(T); + static void do_init() + { + // If std::numeric_limits::digits is zero, we must not call + // our initialization code here as the precision presumably + // varies at runtime, and will not have been set yet. + if(std::numeric_limits::digits) + { + boost::math::erf_inv(static_cast(0.25), Policy()); + boost::math::erf_inv(static_cast(0.55), Policy()); + boost::math::erf_inv(static_cast(0.95), Policy()); + boost::math::erfc_inv(static_cast(1e-15), Policy()); + // These following initializations must not be called if + // type T can not hold the relevant values without + // underflow to zero. We check this at runtime because + // some tools such as valgrind silently change the precision + // of T at runtime, and numeric_limits basically lies! + if(is_value_non_zero(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130)))) + boost::math::erfc_inv(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-130)), Policy()); + + // Some compilers choke on constants that would underflow, even in code that isn't instantiated + // so try and filter these cases out in the preprocessor: +#if LDBL_MAX_10_EXP >= 800 + if(is_value_non_zero(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)))) + boost::math::erfc_inv(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-800)), Policy()); + if(is_value_non_zero(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)))) + boost::math::erfc_inv(static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1e-900)), Policy()); +#else + if(is_value_non_zero(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)))) + boost::math::erfc_inv(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-800)), Policy()); + if(is_value_non_zero(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900)))) + boost::math::erfc_inv(static_cast(BOOST_MATH_HUGE_CONSTANT(T, 64, 1e-900)), Policy()); +#endif + } + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename erf_inv_initializer::init erf_inv_initializer::initializer; + +template +BOOST_NOINLINE bool erf_inv_initializer::init::is_value_non_zero(T v) +{ + // This needs to be non-inline to detect whether v is non zero at runtime + // rather than at compile time, only relevant when running under valgrind + // which changes long double's to double's on the fly. + return v != 0; +} + +} // namespace detail + +template +typename tools::promote_args::type erfc_inv(T z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + + // + // Begin by testing for domain errors, and other special cases: + // + static const char* function = "boost::math::erfc_inv<%1%>(%1%, %1%)"; + if((z < 0) || (z > 2)) + return policies::raise_domain_error(function, "Argument outside range [0,2] in inverse erfc function (got p=%1%).", z, pol); + if(z == 0) + return policies::raise_overflow_error(function, nullptr, pol); + if(z == 2) + return -policies::raise_overflow_error(function, nullptr, pol); + // + // Normalise the input, so it's in the range [0,1], we will + // negate the result if z is outside that range. This is a simple + // application of the erfc reflection formula: erfc(-z) = 2 - erfc(z) + // + result_type p, q, s; + if(z > 1) + { + q = 2 - z; + p = 1 - q; + s = -1; + } + else + { + p = 1 - z; + q = z; + s = 1; + } + // + // A bit of meta-programming to figure out which implementation + // to use, based on the number of bits in the mantissa of T: + // + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + detail::erf_inv_initializer::force_instantiate(); + + // + // And get the result, negating where required: + // + return s * policies::checked_narrowing_cast( + detail::erf_inv_imp(static_cast(p), static_cast(q), forwarding_policy(), static_cast(nullptr)), function); +} + +template +typename tools::promote_args::type erf_inv(T z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + + // + // Begin by testing for domain errors, and other special cases: + // + static const char* function = "boost::math::erf_inv<%1%>(%1%, %1%)"; + if((z < -1) || (z > 1)) + return policies::raise_domain_error(function, "Argument outside range [-1, 1] in inverse erf function (got p=%1%).", z, pol); + if(z == 1) + return policies::raise_overflow_error(function, nullptr, pol); + if(z == -1) + return -policies::raise_overflow_error(function, nullptr, pol); + if(z == 0) + return 0; + // + // Normalise the input, so it's in the range [0,1], we will + // negate the result if z is outside that range. This is a simple + // application of the erf reflection formula: erf(-z) = -erf(z) + // + result_type p, q, s; + if(z < 0) + { + p = -z; + q = 1 - p; + s = -1; + } + else + { + p = z; + q = 1 - z; + s = 1; + } + // + // A bit of meta-programming to figure out which implementation + // to use, based on the number of bits in the mantissa of T: + // + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + // + // Likewise use internal promotion, so we evaluate at a higher + // precision internally if it's appropriate: + // + typedef typename policies::evaluation::type eval_type; + + detail::erf_inv_initializer::force_instantiate(); + // + // And get the result, negating where required: + // + return s * policies::checked_narrowing_cast( + detail::erf_inv_imp(static_cast(p), static_cast(q), forwarding_policy(), static_cast(nullptr)), function); +} + +template +inline typename tools::promote_args::type erfc_inv(T z) +{ + return erfc_inv(z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type erf_inv(T z) +{ + return erf_inv(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_SF_ERF_INV_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/fp_traits.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/fp_traits.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/fp_traits.hpp @@ -0,0 +1,587 @@ +// fp_traits.hpp + +#ifndef BOOST_MATH_FP_TRAITS_HPP +#define BOOST_MATH_FP_TRAITS_HPP + +// Copyright (c) 2006 Johan Rade + +// Distributed under 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) + +/* +To support old compilers, care has been taken to avoid partial template +specialization and meta function forwarding. +With these techniques, the code could be simplified. +*/ + +#if defined(__vms) && defined(__DECCXX) && !__IEEE_FLOAT +// The VAX floating point formats are used (for float and double) +# define BOOST_FPCLASSIFY_VAX_FORMAT +#endif + +#include +#include +#include +#include +#include +#include + +// Determine endianness +#ifndef BOOST_MATH_STANDALONE + +#include +#define BOOST_MATH_ENDIAN_BIG_BYTE BOOST_ENDIAN_BIG_BYTE +#define BOOST_MATH_ENDIAN_LITTLE_BYTE BOOST_ENDIAN_LITTLE_BYTE + +#elif (__cplusplus >= 202002L || _MSVC_LANG >= 202002L) + +#if __has_include() +#include +#define BOOST_MATH_ENDIAN_BIG_BYTE (std::endian::native == std::endian::big) +#define BOOST_MATH_ENDIAN_LITTLE_BYTE (std::endian::native == std::endian::little) +#else +#error Missing header. Please disable standalone mode, and file an issue at https://github.com/boostorg/math +#endif + +#elif defined(_WIN32) + +#define BOOST_MATH_ENDIAN_BIG_BYTE 0 +#define BOOST_MATH_ENDIAN_LITTLE_BYTE 1 + +#elif defined(__BYTE_ORDER__) + +#define BOOST_MATH_ENDIAN_BIG_BYTE (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define BOOST_MATH_ENDIAN_LITTLE_BYTE (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) + +#else +#error Could not determine endian type. Please disable standalone mode, and file an issue at https://github.com/boostorg/math +#endif // Determine endianness + +static_assert((BOOST_MATH_ENDIAN_BIG_BYTE || BOOST_MATH_ENDIAN_LITTLE_BYTE) + && !(BOOST_MATH_ENDIAN_BIG_BYTE && BOOST_MATH_ENDIAN_LITTLE_BYTE), + "Inconsistent endianness detected. Please disable standalone mode, and file an issue at https://github.com/boostorg/math"); + +#ifdef BOOST_NO_STDC_NAMESPACE + namespace std{ using ::memcpy; } +#endif + +#ifndef FP_NORMAL + +#define FP_ZERO 0 +#define FP_NORMAL 1 +#define FP_INFINITE 2 +#define FP_NAN 3 +#define FP_SUBNORMAL 4 + +#else + +#define BOOST_HAS_FPCLASSIFY + +#ifndef fpclassify +# if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) \ + && defined(_GLIBCXX_USE_C99_MATH) \ + && !(defined(_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC) \ + && (_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC != 0)) +# ifdef _STLP_VENDOR_CSTD +# if _STLPORT_VERSION >= 0x520 +# define BOOST_FPCLASSIFY_PREFIX ::__std_alias:: +# else +# define BOOST_FPCLASSIFY_PREFIX ::_STLP_VENDOR_CSTD:: +# endif +# else +# define BOOST_FPCLASSIFY_PREFIX ::std:: +# endif +# else +# undef BOOST_HAS_FPCLASSIFY +# define BOOST_FPCLASSIFY_PREFIX +# endif +#elif (defined(__HP_aCC) && !defined(__hppa)) +// aCC 6 appears to do "#define fpclassify fpclassify" which messes us up a bit! +# define BOOST_FPCLASSIFY_PREFIX :: +#else +# define BOOST_FPCLASSIFY_PREFIX +#endif + +#ifdef __MINGW32__ +# undef BOOST_HAS_FPCLASSIFY +#endif + +#endif + + +//------------------------------------------------------------------------------ + +namespace boost { +namespace math { +namespace detail { + +//------------------------------------------------------------------------------ + +/* +The following classes are used to tag the different methods that are used +for floating point classification +*/ + +struct native_tag {}; +template +struct generic_tag {}; +struct ieee_tag {}; +struct ieee_copy_all_bits_tag : public ieee_tag {}; +struct ieee_copy_leading_bits_tag : public ieee_tag {}; + +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +// +// These helper functions are used only when numeric_limits<> +// members are not compile time constants: +// +inline bool is_generic_tag_false(const generic_tag*) +{ + return true; +} +inline bool is_generic_tag_false(const void*) +{ + return false; +} +#endif + +//------------------------------------------------------------------------------ + +/* +Most processors support three different floating point precisions: +single precision (32 bits), double precision (64 bits) +and extended double precision (80 - 128 bits, depending on the processor) + +Note that the C++ type long double can be implemented +both as double precision and extended double precision. +*/ + +struct unknown_precision{}; +struct single_precision {}; +struct double_precision {}; +struct extended_double_precision {}; + +// native_tag version -------------------------------------------------------------- + +template struct fp_traits_native +{ + typedef native_tag method; +}; + +// generic_tag version ------------------------------------------------------------- + +template struct fp_traits_non_native +{ +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + typedef generic_tag::is_specialized> method; +#else + typedef generic_tag method; +#endif +}; + +// ieee_tag versions --------------------------------------------------------------- + +/* +These specializations of fp_traits_non_native contain information needed +to "parse" the binary representation of a floating point number. + +Typedef members: + + bits -- the target type when copying the leading bytes of a floating + point number. It is a typedef for uint32_t or uint64_t. + + method -- tells us whether all bytes are copied or not. + It is a typedef for ieee_copy_all_bits_tag or ieee_copy_leading_bits_tag. + +Static data members: + + sign, exponent, flag, significand -- bit masks that give the meaning of the + bits in the leading bytes. + +Static function members: + + get_bits(), set_bits() -- provide access to the leading bytes. + +*/ + +// ieee_tag version, float (32 bits) ----------------------------------------------- + +#ifndef BOOST_FPCLASSIFY_VAX_FORMAT + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7f800000; + static constexpr uint32_t flag = 0x00000000; + static constexpr uint32_t significand = 0x007fffff; + + typedef uint32_t bits; + static void get_bits(float x, uint32_t& a) { std::memcpy(&a, &x, 4); } + static void set_bits(float& x, uint32_t a) { std::memcpy(&x, &a, 4); } +}; + +// ieee_tag version, double (64 bits) ---------------------------------------------- + +#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) \ + || defined(BOOST_BORLANDC) || defined(__CODEGEAR__) + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7ff00000; + static constexpr uint32_t flag = 0; + static constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 4; +}; + +//.............................................................................. + +#else + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + static constexpr uint64_t sign = static_cast(0x80000000u) << 32; + static constexpr uint64_t exponent = static_cast(0x7ff00000) << 32; + static constexpr uint64_t flag = 0; + static constexpr uint64_t significand + = (static_cast(0x000fffff) << 32) + static_cast(0xffffffffu); + + typedef uint64_t bits; + static void get_bits(double x, uint64_t& a) { std::memcpy(&a, &x, 8); } + static void set_bits(double& x, uint64_t a) { std::memcpy(&x, &a, 8); } +}; + +#endif + +#endif // #ifndef BOOST_FPCLASSIFY_VAX_FORMAT + +// long double (64 bits) ------------------------------------------------------- + +#if defined(BOOST_NO_INT64_T) || defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)\ + || defined(BOOST_BORLANDC) || defined(__CODEGEAR__) + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7ff00000; + static constexpr uint32_t flag = 0; + static constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 4; +}; + +//.............................................................................. + +#else + +template<> struct fp_traits_non_native +{ + typedef ieee_copy_all_bits_tag method; + + static const uint64_t sign = static_cast(0x80000000u) << 32; + static const uint64_t exponent = static_cast(0x7ff00000) << 32; + static const uint64_t flag = 0; + static const uint64_t significand + = (static_cast(0x000fffff) << 32) + static_cast(0xffffffffu); + + typedef uint64_t bits; + static void get_bits(long double x, uint64_t& a) { std::memcpy(&a, &x, 8); } + static void set_bits(long double& x, uint64_t a) { std::memcpy(&x, &a, 8); } +}; + +#endif + + +// long double (>64 bits), x86 and x64 ----------------------------------------- + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \ + || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \ + || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) + +// Intel extended double precision format (80 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7fff0000; + static constexpr uint32_t flag = 0x00008000; + static constexpr uint32_t significand = 0x00007fff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + 6, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + 6, &a, 4); + } +}; + + +// long double (>64 bits), Itanium --------------------------------------------- + +#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + +// The floating point format is unknown at compile time +// No template specialization is provided. +// The generic_tag definition is used. + +// The Itanium supports both +// the Intel extended double precision format (80 bits) and +// the IEEE extended double precision format with 15 exponent bits (128 bits). + +#elif defined(__GNUC__) && (LDBL_MANT_DIG == 106) + +// +// Define nothing here and fall though to generic_tag: +// We have GCC's "double double" in effect, and any attempt +// to handle it via bit-fiddling is pretty much doomed to fail... +// + +// long double (>64 bits), PowerPC --------------------------------------------- + +#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \ + || defined(__ppc) || defined(__ppc__) || defined(__PPC__) + +// PowerPC extended double precision format (128 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7ff00000; + static constexpr uint32_t flag = 0x00000000; + static constexpr uint32_t significand = 0x000fffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 12; +}; + + +// long double (>64 bits), Motorola 68K ---------------------------------------- + +#elif defined(__m68k) || defined(__m68k__) \ + || defined(__mc68000) || defined(__mc68000__) \ + +// Motorola extended double precision format (96 bits) + +// It is the same format as the Intel extended double precision format, +// except that 1) it is big-endian, 2) the 3rd and 4th byte are padding, and +// 3) the flag bit is not set for infinity + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7fff0000; + static constexpr uint32_t flag = 0x00008000; + static constexpr uint32_t significand = 0x00007fff; + + // copy 1st, 2nd, 5th and 6th byte. 3rd and 4th byte are padding. + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, &x, 2); + std::memcpy(reinterpret_cast(&a) + 2, + reinterpret_cast(&x) + 4, 2); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(&x, &a, 2); + std::memcpy(reinterpret_cast(&x) + 4, + reinterpret_cast(&a) + 2, 2); + } +}; + + +// long double (>64 bits), All other processors -------------------------------- + +#else + +// IEEE extended double precision format with 15 exponent bits (128 bits) + +template<> +struct fp_traits_non_native +{ + typedef ieee_copy_leading_bits_tag method; + + static constexpr uint32_t sign = 0x80000000u; + static constexpr uint32_t exponent = 0x7fff0000; + static constexpr uint32_t flag = 0x00000000; + static constexpr uint32_t significand = 0x0000ffff; + + typedef uint32_t bits; + + static void get_bits(long double x, uint32_t& a) + { + std::memcpy(&a, reinterpret_cast(&x) + offset_, 4); + } + + static void set_bits(long double& x, uint32_t a) + { + std::memcpy(reinterpret_cast(&x) + offset_, &a, 4); + } + +private: + static constexpr int offset_ = BOOST_MATH_ENDIAN_BIG_BYTE ? 0 : 12; +}; + +#endif + +//------------------------------------------------------------------------------ + +// size_to_precision is a type switch for converting a C++ floating point type +// to the corresponding precision type. + +template struct size_to_precision +{ + typedef unknown_precision type; +}; + +template<> struct size_to_precision<4, true> +{ + typedef single_precision type; +}; + +template<> struct size_to_precision<8, true> +{ + typedef double_precision type; +}; + +template<> struct size_to_precision<10, true> +{ + typedef extended_double_precision type; +}; + +template<> struct size_to_precision<12, true> +{ + typedef extended_double_precision type; +}; + +template<> struct size_to_precision<16, true> +{ + typedef extended_double_precision type; +}; + +//------------------------------------------------------------------------------ +// +// Figure out whether to use native classification functions based on +// whether T is a built in floating point type or not: +// +template +struct select_native +{ + typedef typename size_to_precision::value>::type precision; + typedef fp_traits_non_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; +template<> +struct select_native +{ + typedef fp_traits_native type; +}; + +//------------------------------------------------------------------------------ + +// fp_traits is a type switch that selects the right fp_traits_non_native + +#if (defined(BOOST_MATH_USE_C99) && !(defined(__GNUC__) && (__GNUC__ < 4))) \ + && !defined(__hpux) \ + && !defined(__DECCXX)\ + && !defined(__osf__) \ + && !defined(__SGI_STL_PORT) && !defined(_STLPORT_VERSION)\ + && !defined(__FAST_MATH__)\ + && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY)\ + && !defined(__INTEL_COMPILER)\ + && !defined(sun)\ + && !defined(__VXWORKS__) +# define BOOST_MATH_USE_STD_FPCLASSIFY +#endif + +template struct fp_traits +{ + typedef typename size_to_precision::value>::type precision; +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) + typedef typename select_native::type type; +#else + typedef fp_traits_non_native type; +#endif + typedef fp_traits_non_native sign_change_type; +}; + +//------------------------------------------------------------------------------ + +} // namespace detail +} // namespace math +} // namespace boost + +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/gamma_inva.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/gamma_inva.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/gamma_inva.hpp @@ -0,0 +1,233 @@ +// (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) + +// +// This is not a complete header file, it is included by gamma.hpp +// after it has defined it's definitions. This inverts the incomplete +// gamma functions P and Q on the first parameter "a" using a generic +// root finding algorithm (TOMS Algorithm 748). +// + +#ifndef BOOST_MATH_SP_DETAIL_GAMMA_INVA +#define BOOST_MATH_SP_DETAIL_GAMMA_INVA + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct gamma_inva_t +{ + gamma_inva_t(T z_, T p_, bool invert_) : z(z_), p(p_), invert(invert_) {} + T operator()(T a) + { + return invert ? p - boost::math::gamma_q(a, z, Policy()) : boost::math::gamma_p(a, z, Policy()) - p; + } +private: + T z, p; + bool invert; +}; + +template +T inverse_poisson_cornish_fisher(T lambda, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING + // mean: + T m = lambda; + // standard deviation: + T sigma = sqrt(lambda); + // skewness + T sk = 1 / sigma; + // kurtosis: + // T k = 1/lambda; + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + /* + // Add on correction due to kurtosis. + // Disabled for now, seems to make things worse? + // + if(lambda >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + */ + w = m + sigma * w; + return w > tools::min_value() ? w : tools::min_value(); +} + +template +T gamma_inva_imp(const T& z, const T& p, const T& q, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std lib math functions + // + // Special cases first: + // + if(p == 0) + { + return policies::raise_overflow_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + // + // Function object, this is the functor whose root + // we have to solve: + // + gamma_inva_t f(z, (p < q) ? p : q, (p < q) ? false : true); + // + // Tolerance: full precision. + // + tools::eps_tolerance tol(policies::digits()); + // + // Now figure out a starting guess for what a may be, + // we'll start out with a value that'll put p or q + // right bang in the middle of their range, the functions + // are quite sensitive so we should need too many steps + // to bracket the root from there: + // + T guess; + T factor = 8; + if(z >= 1) + { + // + // We can use the relationship between the incomplete + // gamma function and the poisson distribution to + // calculate an approximate inverse, for large z + // this is actually pretty accurate, but it fails badly + // when z is very small. Also set our step-factor according + // to how accurate we think the result is likely to be: + // + guess = 1 + inverse_poisson_cornish_fisher(z, q, p, pol); + if(z > 5) + { + if(z > 1000) + factor = 1.01f; + else if(z > 50) + factor = 1.1f; + else if(guess > 10) + factor = 1.25f; + else + factor = 2; + if(guess < 1.1) + factor = 8; + } + } + else if(z > 0.5) + { + guess = z * 1.2f; + } + else + { + guess = -0.4f / log(z); + } + // + // Max iterations permitted: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + // + // Use our generic derivative-free root finding procedure. + // We could use Newton steps here, taking the PDF of the + // Poisson distribution as our derivative, but that's + // even worse performance-wise than the generic method :-( + // + std::pair r = bracket_and_solve_root(f, guess, factor, false, tol, max_iter, pol); + if(max_iter >= policies::get_max_root_iterations()) + return policies::raise_evaluation_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol); + return (r.first + r.second) / 2; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + gamma_p_inva(T1 x, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(p == 0) + { + policies::raise_overflow_error("boost::math::gamma_p_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(p == 1) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::gamma_inva_imp( + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + pol), "boost::math::gamma_p_inva<%1%>(%1%, %1%)"); +} + +template +inline typename tools::promote_args::type + gamma_q_inva(T1 x, T2 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(q == 1) + { + policies::raise_overflow_error("boost::math::gamma_q_inva<%1%>(%1%, %1%)", nullptr, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::gamma_inva_imp( + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + pol), "boost::math::gamma_q_inva<%1%>(%1%, %1%)"); +} + +template +inline typename tools::promote_args::type + gamma_p_inva(T1 x, T2 p) +{ + return boost::math::gamma_p_inva(x, p, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + gamma_q_inva(T1 x, T2 q) +{ + return boost::math::gamma_q_inva(x, q, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_DETAIL_GAMMA_INVA + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_0F1_bessel.hpp @@ -0,0 +1,47 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_0F1_BESSEL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_0F1_BESSEL_HPP + +#include +#include + + namespace boost { namespace math { namespace detail { + + template + inline T hypergeometric_0F1_bessel(const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING + + const bool is_z_nonpositive = z <= 0; + + const T sqrt_z = is_z_nonpositive ? T(sqrt(-z)) : T(sqrt(z)); + const T bessel_mult = is_z_nonpositive ? + boost::math::cyl_bessel_j(b - 1, 2 * sqrt_z, pol) : + boost::math::cyl_bessel_i(b - 1, 2 * sqrt_z, pol) ; + + if (b > boost::math::max_factorial::value) + { + const T lsqrt_z = log(sqrt_z); + const T lsqrt_z_pow_b = (b - 1) * lsqrt_z; + T lg = (boost::math::lgamma(b, pol) - lsqrt_z_pow_b); + lg = exp(lg); + return lg * bessel_mult; + } + else + { + const T sqrt_z_pow_b = pow(sqrt_z, b - 1); + return (boost::math::tgamma(b, pol) / sqrt_z_pow_b) * bessel_mult; + } + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_0F1_BESSEL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp @@ -0,0 +1,293 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP + +#include + +// +// This file implements the addition theorems for 1F1 on z, specifically +// each function returns 1F1[a, b, z + k] for some integer k - there's +// no particular reason why k needs to be an integer, but no reason why +// it shouldn't be either. +// +// The functions are named hypergeometric_1f1_recurrence_on_z_[plus|minus|zero]_[plus|minus|zero] +// where a "plus" indicates forward recurrence, minus backwards recurrence, and zero no recurrence. +// So for example hypergeometric_1f1_recurrence_on_z_zero_plus uses forward recurrence on b and +// hypergeometric_1f1_recurrence_on_z_minus_minus uses backwards recurrence on both a and b. +// +// See https://dlmf.nist.gov/13.13 +// + + namespace boost { namespace math { namespace detail { + + // + // This works moderately well for a < 0, but has some very strange behaviour with + // strings of values of the same sign followed by a sign switch then another + // series all the same sign and so on.... doesn't converge smoothly either + // but rises and falls in wave-like behaviour.... very slow to converge... + // + template + struct hypergeometric_1f1_recurrence_on_z_minus_zero_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_minus_zero_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_minus_a_plus_n(b - a), a_(a), b_(b), z_(z), n(0), k(k_) + { + BOOST_MATH_STD_USING + long long scale1(0), scale2(0); + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol, scale1); + M_next = boost::math::detail::hypergeometric_1F1_imp(T(a - 1), b, z, pol, scale2); + if (scale1 != scale2) + M_next *= exp(T(scale2 - scale1)); + if (M > 1e10f) + { + // rescale: + long long rescale = lltrunc(log(fabs(M))); + M *= exp(T(-rescale)); + M_next *= exp(T(-rescale)); + scale1 += rescale; + } + scaling = scale1; + } + T operator()() + { + T result = term * M; + term *= b_minus_a_plus_n * k / ((z_ + k) * ++n); + b_minus_a_plus_n += 1; + T M2 = -((2 * (a_ - n) - b_ + z_) * M_next - (a_ - n) * M) / (b_ - (a_ - n)); + M = M_next; + M_next = M2; + + return result; + } + long long scale()const { return scaling; } + private: + T term, b_minus_a_plus_n, M, M_next, a_, b_, z_; + int n, k; + long long scaling; + }; + + template + T hypergeometric_1f1_recurrence_on_z_minus_zero(const T& a, const T& b, const T& z, int k, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT((z + k) / z > 0.5f); + hypergeometric_1f1_recurrence_on_z_minus_zero_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + log_scaling += s.scale(); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)) * pow(z / (z + k), b - a); + } + +#if 0 + + // + // These are commented out as they are currently unused, but may find use in the future: + // + + template + struct hypergeometric_1f1_recurrence_on_z_plus_plus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_plus_plus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), a_plus_n(a), b_plus_n(b), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a + 1, b + 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= a_plus_n * k / (b_plus_n * ++n); + a_plus_n += 1; + b_plus_n += 1; + // The a_plus_n == 0 case below isn't actually correct, but doesn't matter as that term will be zero + // anyway, we just need to not divide by zero and end up with a NaN in the result. + T M2 = (a_plus_n == -1) ? 1 : (a_plus_n == 0) ? 0 : (M_next * b_plus_n * (1 - b_plus_n + z_) + b_plus_n * (b_plus_n - 1) * M) / (a_plus_n * z_); + M = M_next; + M_next = M2; + return result; + } + T term, a_plus_n, b_plus_n, M, M_next, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_plus_plus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + hypergeometric_1f1_recurrence_on_z_plus_plus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result; + } + + template + struct hypergeometric_1f1_recurrence_on_z_zero_minus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_zero_minus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_pochhammer(1 - b), x_k_power(-k_ / z), b_minus_n(b), a_(a), z_(z), b_(b), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a, b - 1, z, pol); + } + T operator()() + { + BOOST_MATH_STD_USING + T result = term * M; + term *= b_pochhammer * x_k_power / ++n; + b_pochhammer += 1; + b_minus_n -= 1; + T M2 = (M_next * b_minus_n * (1 - b_minus_n - z_) + z_ * (b_minus_n - a_) * M) / (-b_minus_n * (b_minus_n - 1)); + M = M_next; + M_next = M2; + return result; + } + T term, b_pochhammer, x_k_power, M, M_next, b_minus_n, a_, z_, b_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_zero_minus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(abs(k) < fabs(z)); + hypergeometric_1f1_recurrence_on_z_zero_minus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * pow((z + k) / z, 1 - b); + } + + template + struct hypergeometric_1f1_recurrence_on_z_plus_zero_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_plus_zero_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), a_pochhammer(a), z_plus_k(z + k_), b_(b), a_(a), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a + 1, b, z, pol); + } + T operator()() + { + T result = term * M; + term *= a_pochhammer * k / (++n * z_plus_k); + a_pochhammer += 1; + T M2 = (a_pochhammer == -1) ? 1 : (a_pochhammer == 0) ? 0 : (M_next * (2 * a_pochhammer - b_ + z_) + (b_ - a_pochhammer) * M) / a_pochhammer; + M = M_next; + M_next = M2; + + return result; + } + T term, a_pochhammer, z_plus_k, M, M_next, b_minus_n, a_, b_, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_plus_zero(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(k / z > -0.5f); + //BOOST_MATH_ASSERT(floor(a) != a || a > 0); + hypergeometric_1f1_recurrence_on_z_plus_zero_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * pow(z / (z + k), a); + } + + template + struct hypergeometric_1f1_recurrence_on_z_zero_plus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_zero_plus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), b_minus_a_plus_n(b - a), b_plus_n(b), a_(a), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a, b + 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= b_minus_a_plus_n * -k / (b_plus_n * ++n); + b_minus_a_plus_n += 1; + b_plus_n += 1; + T M2 = (b_plus_n * (b_plus_n - 1) * M + b_plus_n * (1 - b_plus_n - z_) * M_next) / (-z_ * b_minus_a_plus_n); + M = M_next; + M_next = M2; + + return result; + } + T term, b_minus_a_plus_n, M, M_next, b_minus_n, a_, b_plus_n, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_zero_plus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + hypergeometric_1f1_recurrence_on_z_zero_plus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)); + } + // + // I'm unable to find any situation where this series isn't divergent and therefore + // is probably quite useless: + // + template + struct hypergeometric_1f1_recurrence_on_z_minus_minus_series + { + typedef T result_type; + + hypergeometric_1f1_recurrence_on_z_minus_minus_series(const T& a, const T& b, const T& z, int k_, const Policy& pol) + : term(1), one_minus_b_plus_n(1 - b), a_(a), b_(b), z_(z), n(0), k(k_) + { + M = boost::math::detail::hypergeometric_1F1_imp(a, b, z, pol); + M_next = boost::math::detail::hypergeometric_1F1_imp(a - 1, b - 1, z, pol); + } + T operator()() + { + T result = term * M; + term *= one_minus_b_plus_n * k / (z_ * ++n); + one_minus_b_plus_n += 1; + T M2 = -((b_ - n) * (1 - b_ + n + z_) * M_next - (a_ - n) * z_ * M) / ((b_ - n) * (b_ - n - 1)); + M = M_next; + M_next = M2; + + return result; + } + T term, one_minus_b_plus_n, M, M_next, a_, b_, z_; + int n, k; + }; + + template + T hypergeometric_1f1_recurrence_on_z_minus_minus(const T& a, const T& b, const T& z, int k, const Policy& pol) + { + BOOST_MATH_STD_USING + hypergeometric_1f1_recurrence_on_z_minus_minus_series s(a, b, z, k, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_recurrence_on_z_plus_plus<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result * exp(T(k)) * pow((z + k) / z, 1 - b); + } +#endif + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_ADDITION_THEOREMS_ON_Z_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp @@ -0,0 +1,735 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_1F1_BESSEL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP + +#include +#include +#include +#include +#include + + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_divergent_fallback(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + bool hypergeometric_1F1_is_tricomi_viable_positive_b(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if ((z < b) && (a > -50)) + return false; // might as well fall through to recursion + if (b <= 100) + return true; + // Even though we're in a reasonable domain for Tricomi's approximation, + // the arguments to the Bessel functions may be so large that we can't + // actually evaluate them: + T x = sqrt(fabs(2 * z * b - 4 * a * z)); + T v = b - 1; + return log(boost::math::constants::e() * x / (2 * v)) * v > tools::log_min_value(); + } + + // + // Returns an arbitrarily small value compared to "target" for use as a seed + // value for Bessel recurrences. Note that we'd better not make it too small + // or underflow may occur resulting in either one of the terms in the + // recurrence being zero, or else the result being zero. Using 1/epsilon + // as a safety factor ensures that if we do underflow to zero, all of the digits + // will have been cancelled out anyway: + // + template + T arbitrary_small_value(const T& target) + { + using std::fabs; + return (tools::min_value() / tools::epsilon()) * (fabs(target) > 1 ? target : 1); + } + + + template + struct hypergeometric_1F1_AS_13_3_7_tricomi_series + { + typedef T result_type; + + enum { cache_size = 64 }; + + hypergeometric_1F1_AS_13_3_7_tricomi_series(const T& a, const T& b, const T& z, const Policy& pol_) + : A_minus_2(1), A_minus_1(0), A(b / 2), mult(z / 2), term(1), b_minus_1_plus_n(b - 1), + bessel_arg((b / 2 - a) * z), + two_a_minus_b(2 * a - b), pol(pol_), n(2) + { + BOOST_MATH_STD_USING + term /= pow(fabs(bessel_arg), b_minus_1_plus_n / 2); + mult /= sqrt(fabs(bessel_arg)); + bessel_cache[cache_size - 1] = bessel_arg > 0 ? boost::math::cyl_bessel_j(b_minus_1_plus_n - 1, 2 * sqrt(bessel_arg), pol) : boost::math::cyl_bessel_i(b_minus_1_plus_n - 1, 2 * sqrt(-bessel_arg), pol); + if (fabs(bessel_cache[cache_size - 1]) < tools::min_value() / tools::epsilon()) + { + // We get very limited precision due to rapid denormalisation/underflow of the Bessel values, raise an exception and try something else: + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Underflow in Bessel functions", bessel_cache[cache_size - 1], pol); + } + if ((term * bessel_cache[cache_size - 1] < tools::min_value() / (tools::epsilon() * tools::epsilon())) || !(boost::math::isfinite)(term) || (!std::numeric_limits::has_infinity && (fabs(term) > tools::max_value()))) + { + term = -log(fabs(bessel_arg)) * b_minus_1_plus_n / 2; + log_scale = lltrunc(term); + term -= log_scale; + term = exp(term); + } + else + log_scale = 0; +#ifndef BOOST_NO_CXX17_IF_CONSTEXPR + if constexpr (std::numeric_limits::has_infinity) + { + if (!(boost::math::isfinite)(bessel_cache[cache_size - 1])) + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); + } + else + if ((boost::math::isnan)(bessel_cache[cache_size - 1]) || (fabs(bessel_cache[cache_size - 1]) >= tools::max_value())) + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); +#else + if ((std::numeric_limits::has_infinity && !(boost::math::isfinite)(bessel_cache[cache_size - 1])) + || (!std::numeric_limits::has_infinity && ((boost::math::isnan)(bessel_cache[cache_size - 1]) || (fabs(bessel_cache[cache_size - 1]) >= tools::max_value())))) + policies::raise_evaluation_error("hypergeometric_1F1_AS_13_3_7_tricomi_series<%1%>", "Expected finite Bessel function result but got %1%", bessel_cache[cache_size - 1], pol); +#endif + cache_offset = -cache_size; + refill_cache(); + } + T operator()() + { + // + // We return the n-2 term, and do 2 terms at once as every other term can be + // very small (or zero) when b == 2a: + // + BOOST_MATH_STD_USING + if(n - 2 - cache_offset >= cache_size) + refill_cache(); + T result = A_minus_2 * term * bessel_cache[n - 2 - cache_offset]; + term *= mult; + ++n; + T A_next = ((b_minus_1_plus_n + 2) * A_minus_1 + two_a_minus_b * A_minus_2) / n; + b_minus_1_plus_n += 1; + A_minus_2 = A_minus_1; + A_minus_1 = A; + A = A_next; + + if (A_minus_2 != 0) + { + if (n - 2 - cache_offset >= cache_size) + refill_cache(); + result += A_minus_2 * term * bessel_cache[n - 2 - cache_offset]; + } + term *= mult; + ++n; + A_next = ((b_minus_1_plus_n + 2) * A_minus_1 + two_a_minus_b * A_minus_2) / n; + b_minus_1_plus_n += 1; + A_minus_2 = A_minus_1; + A_minus_1 = A; + A = A_next; + + return result; + } + + long long scale()const + { + return log_scale; + } + + private: + T A_minus_2, A_minus_1, A, mult, term, b_minus_1_plus_n, bessel_arg, two_a_minus_b; + std::array bessel_cache; + const Policy& pol; + int n, cache_offset; + long long log_scale; + + hypergeometric_1F1_AS_13_3_7_tricomi_series operator=(const hypergeometric_1F1_AS_13_3_7_tricomi_series&) = delete; + + void refill_cache() + { + BOOST_MATH_STD_USING + // + // We don't calculate a new bessel I/J value: instead start our iterator off + // with an arbitrary small value, then when we get back to the last value in the previous cache + // calculate the ratio and use it to renormalise all the new values. This is more efficient, but + // also avoids problems with J_v(x) or I_v(x) underflowing to zero. + // + cache_offset += cache_size; + T last_value = bessel_cache.back(); + T ratio; + if (bessel_arg > 0) + { + // + // We will be calculating Bessel J. + // We need a different recurrence strategy for positive and negative orders: + // + if (b_minus_1_plus_n > 0) + { + bessel_j_backwards_iterator i(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(bessel_arg), arbitrary_small_value(last_value)); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_cache[j] = *i; + // + // Depending on the value of bessel_arg, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) + { + T rescale = pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2; + if (!((boost::math::isfinite)(rescale))) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_cache[k] /= rescale; + bessel_j_backwards_iterator ti(b_minus_1_plus_n + j, 2 * sqrt(bessel_arg), bessel_cache[j + 1], bessel_cache[j]); + i = ti; + } + } + ratio = last_value / *i; + } + else + { + // + // Negative order is difficult: the J_v(x) recurrence relations are unstable + // *in both directions* for v < 0, except as v -> -INF when we have + // J_-v(x) ~= -sin(pi.v)Y_v(x). + // For small v what we can do is compute every other Bessel function and + // then fill in the gaps using the recurrence relation. This *is* stable + // provided that v is not so negative that the above approximation holds. + // + bessel_cache[1] = cyl_bessel_j(b_minus_1_plus_n + 1, 2 * sqrt(bessel_arg), pol); + bessel_cache[0] = (last_value + bessel_cache[1]) / (b_minus_1_plus_n / sqrt(bessel_arg)); + int pos = 2; + while ((pos < cache_size - 1) && (b_minus_1_plus_n + pos < 0)) + { + bessel_cache[pos + 1] = cyl_bessel_j(b_minus_1_plus_n + pos + 1, 2 * sqrt(bessel_arg), pol); + bessel_cache[pos] = (bessel_cache[pos-1] + bessel_cache[pos+1]) / ((b_minus_1_plus_n + pos) / sqrt(bessel_arg)); + pos += 2; + } + if (pos < cache_size) + { + // + // We have crossed over into the region where backward recursion is the stable direction + // start from arbitrary value and recurse down to "pos" and normalise: + // + bessel_j_backwards_iterator i2(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(bessel_arg), arbitrary_small_value(bessel_cache[pos-1])); + for (int loc = cache_size - 1; loc >= pos; --loc) + bessel_cache[loc] = *i2++; + ratio = bessel_cache[pos - 1] / *i2; + // + // Sanity check, if we normalised to an unusually small value then it was likely + // to be near a root and the calculated ratio is garbage, if so perform one + // more J_v(x) evaluation at position and normalise again: + // + if (fabs(bessel_cache[pos] * ratio / bessel_cache[pos - 1]) > 5) + ratio = cyl_bessel_j(b_minus_1_plus_n + pos, 2 * sqrt(bessel_arg), pol) / bessel_cache[pos]; + while (pos < cache_size) + bessel_cache[pos++] *= ratio; + } + ratio = 1; + } + } + else + { + // + // Bessel I. + // We need a different recurrence strategy for positive and negative orders: + // + if (b_minus_1_plus_n > 0) + { + bessel_i_backwards_iterator i(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(-bessel_arg), arbitrary_small_value(last_value)); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_cache[j] = *i; + // + // Depending on the value of bessel_arg, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if ((j < cache_size - 2) && (tools::max_value() / fabs(64 * bessel_cache[j] / bessel_cache[j + 1]) < fabs(bessel_cache[j]))) + { + T rescale = pow(fabs(bessel_cache[j] / bessel_cache[j + 1]), j + 1) * 2; + if (!((boost::math::isfinite)(rescale))) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_cache[k] /= rescale; + i = bessel_i_backwards_iterator(b_minus_1_plus_n + j, 2 * sqrt(-bessel_arg), bessel_cache[j + 1], bessel_cache[j]); + } + } + ratio = last_value / *i; + } + else + { + // + // Forwards iteration is stable: + // + bessel_i_forwards_iterator i(b_minus_1_plus_n, 2 * sqrt(-bessel_arg)); + int pos = 0; + while ((pos < cache_size) && (b_minus_1_plus_n + pos < 0.5)) + { + bessel_cache[pos++] = *i++; + } + if (pos < cache_size) + { + // + // We have crossed over into the region where backward recursion is the stable direction + // start from arbitrary value and recurse down to "pos" and normalise: + // + bessel_i_backwards_iterator i2(b_minus_1_plus_n + (int)cache_size - 1, 2 * sqrt(-bessel_arg), arbitrary_small_value(last_value)); + for (int loc = cache_size - 1; loc >= pos; --loc) + bessel_cache[loc] = *i2++; + ratio = bessel_cache[pos - 1] / *i2; + while (pos < cache_size) + bessel_cache[pos++] *= ratio; + } + ratio = 1; + } + } + if(ratio != 1) + for (auto j = bessel_cache.begin(); j != bessel_cache.end(); ++j) + *j *= ratio; + // + // Very occasionally our normalisation fails because the normalisztion value + // is sitting right on top of a root (or very close to it). When that happens + // best to calculate a fresh Bessel evaluation and normalise again. + // + if (fabs(bessel_cache[0] / last_value) > 5) + { + ratio = (bessel_arg < 0 ? cyl_bessel_i(b_minus_1_plus_n, 2 * sqrt(-bessel_arg), pol) : cyl_bessel_j(b_minus_1_plus_n, 2 * sqrt(bessel_arg), pol)) / bessel_cache[0]; + if (ratio != 1) + for (auto j = bessel_cache.begin(); j != bessel_cache.end(); ++j) + *j *= ratio; + } + } + }; + + template + T hypergeometric_1F1_AS_13_3_7_tricomi(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scale) + { + BOOST_MATH_STD_USING + // + // Works for a < 0, b < 0, z > 0. + // + // For convergence we require A * term to be converging otherwise we get + // a divergent alternating series. It's actually really hard to analyse this + // and the best purely heuristic policy we've found is + // z < fabs((2 * a - b) / (sqrt(fabs(a)))) ; b > 0 or: + // z < fabs((2 * a - b) / (sqrt(fabs(ab)))) ; b < 0 + // + T prefix(0); + int prefix_sgn(0); + bool use_logs = false; + long long scale = 0; + // + // We can actually support the b == 2a case within here, but we haven't + // as we appear never to get here in practice. Which means this get out + // clause is a bit of defensive programming.... + // + if(b == 2 * a) + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + + try + { + prefix = boost::math::tgamma(b, pol); + prefix *= exp(z / 2); + } + catch (const std::runtime_error&) + { + use_logs = true; + } + if (use_logs || (prefix == 0) || !(boost::math::isfinite)(prefix) || (!std::numeric_limits::has_infinity && (fabs(prefix) >= tools::max_value()))) + { + use_logs = true; + prefix = boost::math::lgamma(b, &prefix_sgn, pol) + z / 2; + scale = lltrunc(prefix); + log_scale += scale; + prefix -= scale; + } + T result(0); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + bool retry = false; + long long series_scale = 0; + try + { + hypergeometric_1F1_AS_13_3_7_tricomi_series s(a, b, z, pol); + series_scale = s.scale(); + log_scale += s.scale(); + try + { + T norm = 0; + result = 0; + if((a < 0) && (b < 0)) + result = boost::math::tools::checked_sum_series(s, boost::math::policies::get_epsilon(), max_iter, result, norm); + else + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, result); + if (!(boost::math::isfinite)(result) || (result == 0) || (!std::numeric_limits::has_infinity && (fabs(result) >= tools::max_value()))) + retry = true; + if (norm / fabs(result) > 1 / boost::math::tools::root_epsilon()) + retry = true; // fatal cancellation + } + catch (const std::overflow_error&) + { + retry = true; + } + catch (const boost::math::evaluation_error&) + { + retry = true; + } + } + catch (const std::overflow_error&) + { + log_scale -= scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } + catch (const boost::math::evaluation_error&) + { + log_scale -= scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } + if (retry) + { + log_scale -= scale; + log_scale -= series_scale; + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scale); + } + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_7<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (use_logs) + { + int sgn = boost::math::sign(result); + prefix += log(fabs(result)); + result = sgn * prefix_sgn * exp(prefix); + } + else + { + if ((fabs(result) > 1) && (fabs(prefix) > 1) && (tools::max_value() / fabs(result) < fabs(prefix))) + { + // Overflow: + scale = lltrunc(tools::log_max_value()) - 10; + log_scale += scale; + result /= exp(T(scale)); + } + result *= prefix; + } + return result; + } + + + template + struct cyl_bessel_i_large_x_sum + { + typedef T result_type; + + cyl_bessel_i_large_x_sum(const T& v, const T& x) : v(v), z(x), term(1), k(0) {} + + T operator()() + { + T result = term; + ++k; + term *= -(4 * v * v - (2 * k - 1) * (2 * k - 1)) / (8 * k * z); + return result; + } + T v, z, term; + int k; + }; + + template + T cyl_bessel_i_large_x_scaled(const T& v, const T& x, long long& log_scaling, const Policy& pol) + { + BOOST_MATH_STD_USING + cyl_bessel_i_large_x_sum s(v, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::cyl_bessel_i_large_x<%1%>(%1%,%1%)", max_iter, pol); + long long scale = boost::math::lltrunc(x); + log_scaling += scale; + return result * exp(x - scale) / sqrt(boost::math::constants::two_pi() * x); + } + + + + template + struct hypergeometric_1F1_AS_13_3_6_series + { + typedef T result_type; + + enum { cache_size = 64 }; + // + // This series is only convergent/useful for a and b approximately equal + // (ideally |a-b| < 1). The series can also go divergent after a while + // when b < 0, which limits precision to around that of double. In that + // situation we return 0 to terminate the series as otherwise the divergent + // terms will destroy all the bits in our result before they do eventually + // converge again. One important use case for this series is for z < 0 + // and |a| << |b| so that either b-a == b or at least most of the digits in a + // are lost in the subtraction. Note that while you can easily convince yourself + // that the result should be unity when b-a == b, in fact this is not (quite) + // the case for large z. + // + hypergeometric_1F1_AS_13_3_6_series(const T& a, const T& b, const T& z, const T& b_minus_a, const Policy& pol_) + : b_minus_a(b_minus_a), half_z(z / 2), poch_1(2 * b_minus_a - 1), poch_2(b_minus_a - a), b_poch(b), term(1), last_result(1), sign(1), n(0), cache_offset(-cache_size), scale(0), pol(pol_) + { + bessel_i_cache[cache_size - 1] = half_z > tools::log_max_value() ? + cyl_bessel_i_large_x_scaled(T(b_minus_a - 1.5f), half_z, scale, pol) : boost::math::cyl_bessel_i(b_minus_a - 1.5f, half_z, pol); + refill_cache(); + } + T operator()() + { + BOOST_MATH_STD_USING + if(n - cache_offset >= cache_size) + refill_cache(); + + T result = term * (b_minus_a - 0.5f + n) * sign * bessel_i_cache[n - cache_offset]; + ++n; + term *= poch_1; + poch_1 = (n == 1) ? T(2 * b_minus_a) : T(poch_1 + 1); + term *= poch_2; + poch_2 += 1; + term /= n; + term /= b_poch; + b_poch += 1; + sign = -sign; + + if ((fabs(result) > fabs(last_result)) && (n > 100)) + return 0; // series has gone divergent! + + last_result = result; + + return result; + } + + long long scaling()const + { + return scale; + } + + private: + T b_minus_a, half_z, poch_1, poch_2, b_poch, term, last_result; + int sign; + int n, cache_offset; + long long scale; + const Policy& pol; + std::array bessel_i_cache; + + void refill_cache() + { + BOOST_MATH_STD_USING + // + // We don't calculate a new bessel I value: instead start our iterator off + // with an arbitrary small value, then when we get back to the last value in the previous cache + // calculate the ratio and use it to renormalise all the values. This is more efficient, but + // also avoids problems with I_v(x) underflowing to zero. + // + cache_offset += cache_size; + T last_value = bessel_i_cache.back(); + bessel_i_backwards_iterator i(b_minus_a + cache_offset + (int)cache_size - 1.5f, half_z, tools::min_value() * (fabs(last_value) > 1 ? last_value : 1) / tools::epsilon()); + + for (int j = cache_size - 1; j >= 0; --j, ++i) + { + bessel_i_cache[j] = *i; + // + // Depending on the value of half_z, the values stored in the cache can grow so + // large as to overflow, if that looks likely then we need to rescale all the + // existing terms (most of which will then underflow to zero). In this situation + // it's likely that our series will only need 1 or 2 terms of the series but we + // can't be sure of that: + // + if((j < cache_size - 2) && (bessel_i_cache[j + 1] != 0) && (tools::max_value() / fabs(64 * bessel_i_cache[j] / bessel_i_cache[j + 1]) < fabs(bessel_i_cache[j]))) + { + T rescale = pow(fabs(bessel_i_cache[j] / bessel_i_cache[j + 1]), j + 1) * 2; + if (rescale > tools::max_value()) + rescale = tools::max_value(); + for (int k = j; k < cache_size; ++k) + bessel_i_cache[k] /= rescale; + i = bessel_i_backwards_iterator(b_minus_a -0.5f + cache_offset + j, half_z, bessel_i_cache[j + 1], bessel_i_cache[j]); + } + } + T ratio = last_value / *i; + for (auto j = bessel_i_cache.begin(); j != bessel_i_cache.end(); ++j) + *j *= ratio; + } + + hypergeometric_1F1_AS_13_3_6_series() = delete; + hypergeometric_1F1_AS_13_3_6_series(const hypergeometric_1F1_AS_13_3_6_series&) = delete; + hypergeometric_1F1_AS_13_3_6_series& operator=(const hypergeometric_1F1_AS_13_3_6_series&) = delete; + }; + + template + T hypergeometric_1F1_AS_13_3_6(const T& a, const T& b, const T& z, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + if(b_minus_a == 0) + { + // special case: M(a,a,z) == exp(z) + long long scale = lltrunc(z, pol); + log_scaling += scale; + return exp(z - scale); + } + hypergeometric_1F1_AS_13_3_6_series s(a, b, z, b_minus_a, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_6<%1%>(%1%,%1%,%1%)", max_iter, pol); + result *= boost::math::tgamma(b_minus_a - 0.5f, pol) * pow(z / 4, -b_minus_a + 0.5f); + long long scale = lltrunc(z / 2); + log_scaling += scale; + log_scaling += s.scaling(); + result *= exp(z / 2 - scale); + return result; + } + + /****************************************************************************************************************/ + // + // The following are not used at present and are commented out for that reason: + // + /****************************************************************************************************************/ + +#if 0 + + template + struct hypergeometric_1F1_AS_13_3_8_series + { + // + // TODO: store and cache Bessel function evaluations via backwards recurrence. + // + // The C term grows by at least an order of magnitude with each iteration, and + // rate of growth is largely independent of the arguments. Free parameter h + // seems to give accurate results for small values (almost zero) or h=1. + // Convergence and accuracy, only when -a/z > 100, this appears to have no + // or little benefit over 13.3.7 as it generally requires more iterations? + // + hypergeometric_1F1_AS_13_3_8_series(const T& a, const T& b, const T& z, const T& h, const Policy& pol_) + : C_minus_2(1), C_minus_1(-b * h), C(b * (b + 1) * h * h / 2 - (2 * h - 1) * a / 2), + bessel_arg(2 * sqrt(-a * z)), bessel_order(b - 1), power_term(std::pow(-a * z, (1 - b) / 2)), mult(z / std::sqrt(-a * z)), + a_(a), b_(b), z_(z), h_(h), n(2), pol(pol_) + { + } + T operator()() + { + // we actually return the n-2 term: + T result = C_minus_2 * power_term * boost::math::cyl_bessel_j(bessel_order, bessel_arg, pol); + bessel_order += 1; + power_term *= mult; + ++n; + T C_next = ((1 - 2 * h_) * (n - 1) - b_ * h_) * C + + ((1 - 2 * h_) * a_ - h_ * (h_ - 1) *(b_ + n - 2)) * C_minus_1 + - h_ * (h_ - 1) * a_ * C_minus_2; + C_next /= n; + C_minus_2 = C_minus_1; + C_minus_1 = C; + C = C_next; + return result; + } + T C, C_minus_1, C_minus_2, bessel_arg, bessel_order, power_term, mult, a_, b_, z_, h_; + const Policy& pol; + int n; + + typedef T result_type; + }; + + template + T hypergeometric_1F1_AS_13_3_8(const T& a, const T& b, const T& z, const T& h, const Policy& pol) + { + BOOST_MATH_STD_USING + T prefix = exp(h * z) * boost::math::tgamma(b); + hypergeometric_1F1_AS_13_3_8_series s(a, b, z, h, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_AS_13_3_8<%1%>(%1%,%1%,%1%)", max_iter, pol); + result *= prefix; + return result; + } + + // + // This is the series from https://dlmf.nist.gov/13.11 + // It appears to be unusable for a,z < 0, and for + // b < 0 appears to never be better than the defining series + // for 1F1. + // + template + struct hypergeometric_1f1_13_11_1_series + { + typedef T result_type; + + hypergeometric_1f1_13_11_1_series(const T& a, const T& b, const T& z, const Policy& pol_) + : term(1), two_a_minus_1_plus_s(2 * a - 1), two_a_minus_b_plus_s(2 * a - b), b_plus_s(b), a_minus_half_plus_s(a - 0.5f), half_z(z / 2), s(0), pol(pol_) + { + } + T operator()() + { + T result = term * a_minus_half_plus_s * boost::math::cyl_bessel_i(a_minus_half_plus_s, half_z, pol); + + term *= two_a_minus_1_plus_s * two_a_minus_b_plus_s / (b_plus_s * ++s); + two_a_minus_1_plus_s += 1; + a_minus_half_plus_s += 1; + two_a_minus_b_plus_s += 1; + b_plus_s += 1; + + return result; + } + T term, two_a_minus_1_plus_s, two_a_minus_b_plus_s, b_plus_s, a_minus_half_plus_s, half_z; + long long s; + const Policy& pol; + }; + + template + T hypergeometric_1f1_13_11_1(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + bool use_logs = false; + T prefix; + int prefix_sgn = 1; + if (true/*(a < boost::math::max_factorial::value) && (a > 0)*/) + prefix = boost::math::tgamma(a - 0.5f, pol); + else + { + prefix = boost::math::lgamma(a - 0.5f, &prefix_sgn, pol); + use_logs = true; + } + if (use_logs) + { + prefix += z / 2; + prefix += log(z / 4) * (0.5f - a); + } + else if (z > 0) + { + prefix *= pow(z / 4, 0.5f - a); + prefix *= exp(z / 2); + } + else + { + prefix *= exp(z / 2); + prefix *= pow(z / 4, 0.5f - a); + } + + hypergeometric_1f1_13_11_1_series s(a, b, z, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1f1_13_11_1<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (use_logs) + { + long long scaling = lltrunc(prefix); + log_scaling += scaling; + prefix -= scaling; + result *= exp(prefix) * prefix_sgn; + } + else + result *= prefix; + + return result; + } + +#endif + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp @@ -0,0 +1,678 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ + +#include +#include + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + /* + Evaluation by method of ratios for domain b < 0 < a,z + + We first convert the recurrence relation into a ratio + of M(a+1, b+1, z) / M(a, b, z) using Shintan's equivalence + between solving a recurrence relation using Miller's method + and continued fractions. The continued fraction is VERY rapid + to converge (typically < 10 terms), but may converge to entirely + the wrong value if we're in a bad part of the domain. Strangely + it seems to matter not whether we use recurrence on a, b or a and b + they all work or not work about the same, so we might as well make + life easy for ourselves and use the a and b recurrence to avoid + having to apply one extra recurrence to convert from an a or b + recurrence to an a+b one. + + See: H. Shintan, Note on Miller's recurrence algorithm, J. Sci. Hiroshima Univ. Ser. A-I Math., 29 (1965), pp. 121-133. + Also: Computational Aspects of Three Term Recurrence Relations, SIAM Review, January 1967. + + The following table lists by experiment, how large z can be in order to + ensure the continued fraction converges to the correct value: + + a b max z + 13, -130, 22 + 13, -1300, 335 + 13, -13000, 3585 + 130, -130, 8 + 130, -1300, 263 + 130, - 13000, 3420 + 1300, -130, 1 + 1300, -1300, 90 + 1300, -13000, 2650 + 13000, -13, - + 13000, -130, - + 13000, -1300, 13 + 13000, -13000, 750 + + So try z_limit = -b / (4 - 5 * sqrt(log(a)) * a / b); + or z_limit = -b / (4 - 5 * (log(a)) * a / b) for a < 100 + + This still isn't quite right for both a and b small, but we'll be using a Bessel approximation + in that region anyway. + + Normalization using wronksian {1,2} from A&S 13.1.20 (also 13.1.12, 13.1.13): + + W{ M(a,b,z), z^(1-b)M(1+a-b, 2-b, z) } = (1-b)z^-b e^z + + = M(a,b,z) M2'(a,b,z) - M'(a,b,z) M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z)] - a/b M(a+1,b+1,z) z^(1-b)M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z)] - a/b R(a,b,z) M(a,b,z) z^(1-b)M2(a,b,z) + = M(a,b,z) [(a-b+1)z^(1-b)/(2-b) M2(a+1,b+1,z) + (1-b)z^-b M2(a,b,z) - a/b R(a,b,z) z^(1-b)M2(a,b,z) ] + so: + (1-b)e^z = M(a,b,z) [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z R(a,b,z) M2(a,b,z) ] + + */ + + template + inline bool is_in_hypergeometric_1F1_from_function_ratio_negative_b_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if (a < 100) + return z < -b / (4 - 5 * (log(a)) * a / b); + else + return z < -b / (4 - 5 * sqrt(log(a)) * a / b); + } + + template + T hypergeometric_1F1_from_function_ratio_negative_b(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling, const T& ratio) + { + BOOST_MATH_STD_USING + // + // Let M2 = M(1+a-b, 2-b, z) + // This is going to be a mighty big number: + // + long long local_scaling = 0; + T M2 = boost::math::detail::hypergeometric_1F1_imp(T(1 + a - b), T(2 - b), z, pol, local_scaling); + log_scaling -= local_scaling; // all the M2 terms are in the denominator + // + // Since a, b and z are all likely to be large we need the Wronksian + // calculation below to not overflow, so scale everything right down: + // + if (fabs(M2) > 1) + { + long long s = lltrunc(log(fabs(M2))); + log_scaling -= s; // M2 will be in the denominator, so subtract the scaling! + local_scaling += s; + M2 *= exp(T(-s)); + } + // + // Let M3 = M(1+a-b + 1, 2-b + 1, z) + // we can get to this from the ratio which is cheaper to calculate: + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef2(1 + a - b + 1, 2 - b + 1, z); + T M3 = boost::math::tools::function_ratio_from_backwards_recurrence(coef2, boost::math::policies::get_epsilon(), max_iter) * M2; + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Get the RHS of the Wronksian: + // + long long fz = lltrunc(z); + log_scaling += fz; + T rhs = (1 - b) * exp(z - fz); + // + // We need to divide that by: + // [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z^b R(a,b,z) M2(a,b,z) ] + // Note that at this stage, both M3 and M2 are scaled by exp(local_scaling). + // + T lhs = (a - b + 1) * z * M3 / (2 - b) + (1 - b) * M2 - a * z * ratio * M2 / b; + + return rhs / lhs; + } + + template + T hypergeometric_1F1_from_function_ratio_negative_b(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef(a + 1, b + 1, z); + T ratio = boost::math::tools::function_ratio_from_backwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + return hypergeometric_1F1_from_function_ratio_negative_b(a, b, z, pol, log_scaling, ratio); + } + // + // And over again, this time via forwards recurrence when z is large enough: + // + template + bool hypergeometric_1F1_is_in_forwards_recurence_for_negative_b_region(const T& a, const T& b, const T& z) + { + // + // There's no easy relation between a, b and z that tells us whether we're in the region + // where forwards recursion is stable, so use a lookup table, note that the minimum + // permissible z-value is decreasing with a, and increasing with |b|: + // + static const float data[][3] = { + {7.500e+00f, -7.500e+00f, 8.409e+00f }, + {7.500e+00f, -1.125e+01f, 8.409e+00f }, + {7.500e+00f, -1.688e+01f, 9.250e+00f }, + {7.500e+00f, -2.531e+01f, 1.119e+01f }, + {7.500e+00f, -3.797e+01f, 1.354e+01f }, + {7.500e+00f, -5.695e+01f, 1.983e+01f }, + {7.500e+00f, -8.543e+01f, 2.639e+01f }, + {7.500e+00f, -1.281e+02f, 3.864e+01f }, + {7.500e+00f, -1.922e+02f, 5.657e+01f }, + {7.500e+00f, -2.883e+02f, 8.283e+01f }, + {7.500e+00f, -4.325e+02f, 1.213e+02f }, + {7.500e+00f, -6.487e+02f, 1.953e+02f }, + {7.500e+00f, -9.731e+02f, 2.860e+02f }, + {7.500e+00f, -1.460e+03f, 4.187e+02f }, + {7.500e+00f, -2.189e+03f, 6.130e+02f }, + {7.500e+00f, -3.284e+03f, 9.872e+02f }, + {7.500e+00f, -4.926e+03f, 1.445e+03f }, + {7.500e+00f, -7.389e+03f, 2.116e+03f }, + {7.500e+00f, -1.108e+04f, 3.098e+03f }, + {7.500e+00f, -1.663e+04f, 4.990e+03f }, + {1.125e+01f, -7.500e+00f, 6.318e+00f }, + {1.125e+01f, -1.125e+01f, 6.950e+00f }, + {1.125e+01f, -1.688e+01f, 7.645e+00f }, + {1.125e+01f, -2.531e+01f, 9.250e+00f }, + {1.125e+01f, -3.797e+01f, 1.231e+01f }, + {1.125e+01f, -5.695e+01f, 1.639e+01f }, + {1.125e+01f, -8.543e+01f, 2.399e+01f }, + {1.125e+01f, -1.281e+02f, 3.513e+01f }, + {1.125e+01f, -1.922e+02f, 5.657e+01f }, + {1.125e+01f, -2.883e+02f, 8.283e+01f }, + {1.125e+01f, -4.325e+02f, 1.213e+02f }, + {1.125e+01f, -6.487e+02f, 1.776e+02f }, + {1.125e+01f, -9.731e+02f, 2.860e+02f }, + {1.125e+01f, -1.460e+03f, 4.187e+02f }, + {1.125e+01f, -2.189e+03f, 6.130e+02f }, + {1.125e+01f, -3.284e+03f, 9.872e+02f }, + {1.125e+01f, -4.926e+03f, 1.445e+03f }, + {1.125e+01f, -7.389e+03f, 2.116e+03f }, + {1.125e+01f, -1.108e+04f, 3.098e+03f }, + {1.125e+01f, -1.663e+04f, 4.990e+03f }, + {1.688e+01f, -7.500e+00f, 4.747e+00f }, + {1.688e+01f, -1.125e+01f, 5.222e+00f }, + {1.688e+01f, -1.688e+01f, 5.744e+00f }, + {1.688e+01f, -2.531e+01f, 7.645e+00f }, + {1.688e+01f, -3.797e+01f, 1.018e+01f }, + {1.688e+01f, -5.695e+01f, 1.490e+01f }, + {1.688e+01f, -8.543e+01f, 2.181e+01f }, + {1.688e+01f, -1.281e+02f, 3.193e+01f }, + {1.688e+01f, -1.922e+02f, 5.143e+01f }, + {1.688e+01f, -2.883e+02f, 7.530e+01f }, + {1.688e+01f, -4.325e+02f, 1.213e+02f }, + {1.688e+01f, -6.487e+02f, 1.776e+02f }, + {1.688e+01f, -9.731e+02f, 2.600e+02f }, + {1.688e+01f, -1.460e+03f, 4.187e+02f }, + {1.688e+01f, -2.189e+03f, 6.130e+02f }, + {1.688e+01f, -3.284e+03f, 9.872e+02f }, + {1.688e+01f, -4.926e+03f, 1.445e+03f }, + {1.688e+01f, -7.389e+03f, 2.116e+03f }, + {1.688e+01f, -1.108e+04f, 3.098e+03f }, + {1.688e+01f, -1.663e+04f, 4.990e+03f }, + {2.531e+01f, -7.500e+00f, 3.242e+00f }, + {2.531e+01f, -1.125e+01f, 3.566e+00f }, + {2.531e+01f, -1.688e+01f, 4.315e+00f }, + {2.531e+01f, -2.531e+01f, 5.744e+00f }, + {2.531e+01f, -3.797e+01f, 7.645e+00f }, + {2.531e+01f, -5.695e+01f, 1.231e+01f }, + {2.531e+01f, -8.543e+01f, 1.803e+01f }, + {2.531e+01f, -1.281e+02f, 2.903e+01f }, + {2.531e+01f, -1.922e+02f, 4.676e+01f }, + {2.531e+01f, -2.883e+02f, 6.845e+01f }, + {2.531e+01f, -4.325e+02f, 1.102e+02f }, + {2.531e+01f, -6.487e+02f, 1.776e+02f }, + {2.531e+01f, -9.731e+02f, 2.600e+02f }, + {2.531e+01f, -1.460e+03f, 4.187e+02f }, + {2.531e+01f, -2.189e+03f, 6.130e+02f }, + {2.531e+01f, -3.284e+03f, 8.974e+02f }, + {2.531e+01f, -4.926e+03f, 1.445e+03f }, + {2.531e+01f, -7.389e+03f, 2.116e+03f }, + {2.531e+01f, -1.108e+04f, 3.098e+03f }, + {2.531e+01f, -1.663e+04f, 4.990e+03f }, + {3.797e+01f, -7.500e+00f, 2.214e+00f }, + {3.797e+01f, -1.125e+01f, 2.679e+00f }, + {3.797e+01f, -1.688e+01f, 3.242e+00f }, + {3.797e+01f, -2.531e+01f, 4.315e+00f }, + {3.797e+01f, -3.797e+01f, 6.318e+00f }, + {3.797e+01f, -5.695e+01f, 9.250e+00f }, + {3.797e+01f, -8.543e+01f, 1.490e+01f }, + {3.797e+01f, -1.281e+02f, 2.399e+01f }, + {3.797e+01f, -1.922e+02f, 3.864e+01f }, + {3.797e+01f, -2.883e+02f, 6.223e+01f }, + {3.797e+01f, -4.325e+02f, 1.002e+02f }, + {3.797e+01f, -6.487e+02f, 1.614e+02f }, + {3.797e+01f, -9.731e+02f, 2.600e+02f }, + {3.797e+01f, -1.460e+03f, 3.806e+02f }, + {3.797e+01f, -2.189e+03f, 6.130e+02f }, + {3.797e+01f, -3.284e+03f, 8.974e+02f }, + {3.797e+01f, -4.926e+03f, 1.445e+03f }, + {3.797e+01f, -7.389e+03f, 2.116e+03f }, + {3.797e+01f, -1.108e+04f, 3.098e+03f }, + {3.797e+01f, -1.663e+04f, 4.990e+03f }, + {5.695e+01f, -7.500e+00f, 1.513e+00f }, + {5.695e+01f, -1.125e+01f, 1.830e+00f }, + {5.695e+01f, -1.688e+01f, 2.214e+00f }, + {5.695e+01f, -2.531e+01f, 3.242e+00f }, + {5.695e+01f, -3.797e+01f, 4.315e+00f }, + {5.695e+01f, -5.695e+01f, 7.645e+00f }, + {5.695e+01f, -8.543e+01f, 1.231e+01f }, + {5.695e+01f, -1.281e+02f, 1.983e+01f }, + {5.695e+01f, -1.922e+02f, 3.513e+01f }, + {5.695e+01f, -2.883e+02f, 5.657e+01f }, + {5.695e+01f, -4.325e+02f, 9.111e+01f }, + {5.695e+01f, -6.487e+02f, 1.467e+02f }, + {5.695e+01f, -9.731e+02f, 2.363e+02f }, + {5.695e+01f, -1.460e+03f, 3.806e+02f }, + {5.695e+01f, -2.189e+03f, 5.572e+02f }, + {5.695e+01f, -3.284e+03f, 8.974e+02f }, + {5.695e+01f, -4.926e+03f, 1.314e+03f }, + {5.695e+01f, -7.389e+03f, 2.116e+03f }, + {5.695e+01f, -1.108e+04f, 3.098e+03f }, + {5.695e+01f, -1.663e+04f, 4.990e+03f }, + {8.543e+01f, -7.500e+00f, 1.250e+00f }, + {8.543e+01f, -1.125e+01f, 1.250e+00f }, + {8.543e+01f, -1.688e+01f, 1.513e+00f }, + {8.543e+01f, -2.531e+01f, 2.214e+00f }, + {8.543e+01f, -3.797e+01f, 3.242e+00f }, + {8.543e+01f, -5.695e+01f, 5.222e+00f }, + {8.543e+01f, -8.543e+01f, 9.250e+00f }, + {8.543e+01f, -1.281e+02f, 1.639e+01f }, + {8.543e+01f, -1.922e+02f, 2.903e+01f }, + {8.543e+01f, -2.883e+02f, 5.143e+01f }, + {8.543e+01f, -4.325e+02f, 8.283e+01f }, + {8.543e+01f, -6.487e+02f, 1.334e+02f }, + {8.543e+01f, -9.731e+02f, 2.148e+02f }, + {8.543e+01f, -1.460e+03f, 3.460e+02f }, + {8.543e+01f, -2.189e+03f, 5.572e+02f }, + {8.543e+01f, -3.284e+03f, 8.974e+02f }, + {8.543e+01f, -4.926e+03f, 1.314e+03f }, + {8.543e+01f, -7.389e+03f, 2.116e+03f }, + {8.543e+01f, -1.108e+04f, 3.098e+03f }, + {8.543e+01f, -1.663e+04f, 4.536e+03f }, + {1.281e+02f, -7.500e+00f, 1.250e+00f }, + {1.281e+02f, -1.125e+01f, 1.250e+00f }, + {1.281e+02f, -1.688e+01f, 1.250e+00f }, + {1.281e+02f, -2.531e+01f, 1.513e+00f }, + {1.281e+02f, -3.797e+01f, 2.214e+00f }, + {1.281e+02f, -5.695e+01f, 3.923e+00f }, + {1.281e+02f, -8.543e+01f, 6.950e+00f }, + {1.281e+02f, -1.281e+02f, 1.231e+01f }, + {1.281e+02f, -1.922e+02f, 2.181e+01f }, + {1.281e+02f, -2.883e+02f, 4.250e+01f }, + {1.281e+02f, -4.325e+02f, 6.845e+01f }, + {1.281e+02f, -6.487e+02f, 1.213e+02f }, + {1.281e+02f, -9.731e+02f, 1.953e+02f }, + {1.281e+02f, -1.460e+03f, 3.460e+02f }, + {1.281e+02f, -2.189e+03f, 5.572e+02f }, + {1.281e+02f, -3.284e+03f, 8.159e+02f }, + {1.281e+02f, -4.926e+03f, 1.314e+03f }, + {1.281e+02f, -7.389e+03f, 1.924e+03f }, + {1.281e+02f, -1.108e+04f, 3.098e+03f }, + {1.281e+02f, -1.663e+04f, 4.536e+03f }, + {1.922e+02f, -7.500e+00f, 1.250e+00f }, + {1.922e+02f, -1.125e+01f, 1.250e+00f }, + {1.922e+02f, -1.688e+01f, 1.250e+00f }, + {1.922e+02f, -2.531e+01f, 1.250e+00f }, + {1.922e+02f, -3.797e+01f, 1.664e+00f }, + {1.922e+02f, -5.695e+01f, 2.679e+00f }, + {1.922e+02f, -8.543e+01f, 5.222e+00f }, + {1.922e+02f, -1.281e+02f, 9.250e+00f }, + {1.922e+02f, -1.922e+02f, 1.803e+01f }, + {1.922e+02f, -2.883e+02f, 3.193e+01f }, + {1.922e+02f, -4.325e+02f, 5.657e+01f }, + {1.922e+02f, -6.487e+02f, 1.002e+02f }, + {1.922e+02f, -9.731e+02f, 1.776e+02f }, + {1.922e+02f, -1.460e+03f, 3.145e+02f }, + {1.922e+02f, -2.189e+03f, 5.066e+02f }, + {1.922e+02f, -3.284e+03f, 8.159e+02f }, + {1.922e+02f, -4.926e+03f, 1.194e+03f }, + {1.922e+02f, -7.389e+03f, 1.924e+03f }, + {1.922e+02f, -1.108e+04f, 3.098e+03f }, + {1.922e+02f, -1.663e+04f, 4.536e+03f }, + {2.883e+02f, -7.500e+00f, 1.250e+00f }, + {2.883e+02f, -1.125e+01f, 1.250e+00f }, + {2.883e+02f, -1.688e+01f, 1.250e+00f }, + {2.883e+02f, -2.531e+01f, 1.250e+00f }, + {2.883e+02f, -3.797e+01f, 1.250e+00f }, + {2.883e+02f, -5.695e+01f, 2.013e+00f }, + {2.883e+02f, -8.543e+01f, 3.566e+00f }, + {2.883e+02f, -1.281e+02f, 6.950e+00f }, + {2.883e+02f, -1.922e+02f, 1.354e+01f }, + {2.883e+02f, -2.883e+02f, 2.399e+01f }, + {2.883e+02f, -4.325e+02f, 4.676e+01f }, + {2.883e+02f, -6.487e+02f, 8.283e+01f }, + {2.883e+02f, -9.731e+02f, 1.614e+02f }, + {2.883e+02f, -1.460e+03f, 2.600e+02f }, + {2.883e+02f, -2.189e+03f, 4.605e+02f }, + {2.883e+02f, -3.284e+03f, 7.417e+02f }, + {2.883e+02f, -4.926e+03f, 1.194e+03f }, + {2.883e+02f, -7.389e+03f, 1.924e+03f }, + {2.883e+02f, -1.108e+04f, 2.817e+03f }, + {2.883e+02f, -1.663e+04f, 4.536e+03f }, + {4.325e+02f, -7.500e+00f, 1.250e+00f }, + {4.325e+02f, -1.125e+01f, 1.250e+00f }, + {4.325e+02f, -1.688e+01f, 1.250e+00f }, + {4.325e+02f, -2.531e+01f, 1.250e+00f }, + {4.325e+02f, -3.797e+01f, 1.250e+00f }, + {4.325e+02f, -5.695e+01f, 1.375e+00f }, + {4.325e+02f, -8.543e+01f, 2.436e+00f }, + {4.325e+02f, -1.281e+02f, 4.747e+00f }, + {4.325e+02f, -1.922e+02f, 9.250e+00f }, + {4.325e+02f, -2.883e+02f, 1.803e+01f }, + {4.325e+02f, -4.325e+02f, 3.513e+01f }, + {4.325e+02f, -6.487e+02f, 6.845e+01f }, + {4.325e+02f, -9.731e+02f, 1.334e+02f }, + {4.325e+02f, -1.460e+03f, 2.363e+02f }, + {4.325e+02f, -2.189e+03f, 3.806e+02f }, + {4.325e+02f, -3.284e+03f, 6.743e+02f }, + {4.325e+02f, -4.926e+03f, 1.086e+03f }, + {4.325e+02f, -7.389e+03f, 1.749e+03f }, + {4.325e+02f, -1.108e+04f, 2.817e+03f }, + {4.325e+02f, -1.663e+04f, 4.536e+03f }, + {6.487e+02f, -7.500e+00f, 1.250e+00f }, + {6.487e+02f, -1.125e+01f, 1.250e+00f }, + {6.487e+02f, -1.688e+01f, 1.250e+00f }, + {6.487e+02f, -2.531e+01f, 1.250e+00f }, + {6.487e+02f, -3.797e+01f, 1.250e+00f }, + {6.487e+02f, -5.695e+01f, 1.250e+00f }, + {6.487e+02f, -8.543e+01f, 1.664e+00f }, + {6.487e+02f, -1.281e+02f, 3.242e+00f }, + {6.487e+02f, -1.922e+02f, 6.950e+00f }, + {6.487e+02f, -2.883e+02f, 1.354e+01f }, + {6.487e+02f, -4.325e+02f, 2.639e+01f }, + {6.487e+02f, -6.487e+02f, 5.143e+01f }, + {6.487e+02f, -9.731e+02f, 1.002e+02f }, + {6.487e+02f, -1.460e+03f, 1.953e+02f }, + {6.487e+02f, -2.189e+03f, 3.460e+02f }, + {6.487e+02f, -3.284e+03f, 6.130e+02f }, + {6.487e+02f, -4.926e+03f, 9.872e+02f }, + {6.487e+02f, -7.389e+03f, 1.590e+03f }, + {6.487e+02f, -1.108e+04f, 2.561e+03f }, + {6.487e+02f, -1.663e+04f, 4.124e+03f }, + {9.731e+02f, -7.500e+00f, 1.250e+00f }, + {9.731e+02f, -1.125e+01f, 1.250e+00f }, + {9.731e+02f, -1.688e+01f, 1.250e+00f }, + {9.731e+02f, -2.531e+01f, 1.250e+00f }, + {9.731e+02f, -3.797e+01f, 1.250e+00f }, + {9.731e+02f, -5.695e+01f, 1.250e+00f }, + {9.731e+02f, -8.543e+01f, 1.250e+00f }, + {9.731e+02f, -1.281e+02f, 2.214e+00f }, + {9.731e+02f, -1.922e+02f, 4.747e+00f }, + {9.731e+02f, -2.883e+02f, 9.250e+00f }, + {9.731e+02f, -4.325e+02f, 1.983e+01f }, + {9.731e+02f, -6.487e+02f, 3.864e+01f }, + {9.731e+02f, -9.731e+02f, 7.530e+01f }, + {9.731e+02f, -1.460e+03f, 1.467e+02f }, + {9.731e+02f, -2.189e+03f, 2.860e+02f }, + {9.731e+02f, -3.284e+03f, 5.066e+02f }, + {9.731e+02f, -4.926e+03f, 8.974e+02f }, + {9.731e+02f, -7.389e+03f, 1.445e+03f }, + {9.731e+02f, -1.108e+04f, 2.561e+03f }, + {9.731e+02f, -1.663e+04f, 4.124e+03f }, + {1.460e+03f, -7.500e+00f, 1.250e+00f }, + {1.460e+03f, -1.125e+01f, 1.250e+00f }, + {1.460e+03f, -1.688e+01f, 1.250e+00f }, + {1.460e+03f, -2.531e+01f, 1.250e+00f }, + {1.460e+03f, -3.797e+01f, 1.250e+00f }, + {1.460e+03f, -5.695e+01f, 1.250e+00f }, + {1.460e+03f, -8.543e+01f, 1.250e+00f }, + {1.460e+03f, -1.281e+02f, 1.513e+00f }, + {1.460e+03f, -1.922e+02f, 3.242e+00f }, + {1.460e+03f, -2.883e+02f, 6.950e+00f }, + {1.460e+03f, -4.325e+02f, 1.354e+01f }, + {1.460e+03f, -6.487e+02f, 2.903e+01f }, + {1.460e+03f, -9.731e+02f, 5.657e+01f }, + {1.460e+03f, -1.460e+03f, 1.213e+02f }, + {1.460e+03f, -2.189e+03f, 2.148e+02f }, + {1.460e+03f, -3.284e+03f, 4.187e+02f }, + {1.460e+03f, -4.926e+03f, 7.417e+02f }, + {1.460e+03f, -7.389e+03f, 1.314e+03f }, + {1.460e+03f, -1.108e+04f, 2.328e+03f }, + {1.460e+03f, -1.663e+04f, 3.749e+03f }, + {2.189e+03f, -7.500e+00f, 1.250e+00f }, + {2.189e+03f, -1.125e+01f, 1.250e+00f }, + {2.189e+03f, -1.688e+01f, 1.250e+00f }, + {2.189e+03f, -2.531e+01f, 1.250e+00f }, + {2.189e+03f, -3.797e+01f, 1.250e+00f }, + {2.189e+03f, -5.695e+01f, 1.250e+00f }, + {2.189e+03f, -8.543e+01f, 1.250e+00f }, + {2.189e+03f, -1.281e+02f, 1.250e+00f }, + {2.189e+03f, -1.922e+02f, 2.214e+00f }, + {2.189e+03f, -2.883e+02f, 4.747e+00f }, + {2.189e+03f, -4.325e+02f, 9.250e+00f }, + {2.189e+03f, -6.487e+02f, 1.983e+01f }, + {2.189e+03f, -9.731e+02f, 4.250e+01f }, + {2.189e+03f, -1.460e+03f, 8.283e+01f }, + {2.189e+03f, -2.189e+03f, 1.776e+02f }, + {2.189e+03f, -3.284e+03f, 3.460e+02f }, + {2.189e+03f, -4.926e+03f, 6.130e+02f }, + {2.189e+03f, -7.389e+03f, 1.086e+03f }, + {2.189e+03f, -1.108e+04f, 1.924e+03f }, + {2.189e+03f, -1.663e+04f, 3.408e+03f }, + {3.284e+03f, -7.500e+00f, 1.250e+00f }, + {3.284e+03f, -1.125e+01f, 1.250e+00f }, + {3.284e+03f, -1.688e+01f, 1.250e+00f }, + {3.284e+03f, -2.531e+01f, 1.250e+00f }, + {3.284e+03f, -3.797e+01f, 1.250e+00f }, + {3.284e+03f, -5.695e+01f, 1.250e+00f }, + {3.284e+03f, -8.543e+01f, 1.250e+00f }, + {3.284e+03f, -1.281e+02f, 1.250e+00f }, + {3.284e+03f, -1.922e+02f, 1.513e+00f }, + {3.284e+03f, -2.883e+02f, 3.242e+00f }, + {3.284e+03f, -4.325e+02f, 6.318e+00f }, + {3.284e+03f, -6.487e+02f, 1.354e+01f }, + {3.284e+03f, -9.731e+02f, 2.903e+01f }, + {3.284e+03f, -1.460e+03f, 6.223e+01f }, + {3.284e+03f, -2.189e+03f, 1.334e+02f }, + {3.284e+03f, -3.284e+03f, 2.600e+02f }, + {3.284e+03f, -4.926e+03f, 5.066e+02f }, + {3.284e+03f, -7.389e+03f, 9.872e+02f }, + {3.284e+03f, -1.108e+04f, 1.749e+03f }, + {3.284e+03f, -1.663e+04f, 3.098e+03f }, + {4.926e+03f, -7.500e+00f, 1.250e+00f }, + {4.926e+03f, -1.125e+01f, 1.250e+00f }, + {4.926e+03f, -1.688e+01f, 1.250e+00f }, + {4.926e+03f, -2.531e+01f, 1.250e+00f }, + {4.926e+03f, -3.797e+01f, 1.250e+00f }, + {4.926e+03f, -5.695e+01f, 1.250e+00f }, + {4.926e+03f, -8.543e+01f, 1.250e+00f }, + {4.926e+03f, -1.281e+02f, 1.250e+00f }, + {4.926e+03f, -1.922e+02f, 1.250e+00f }, + {4.926e+03f, -2.883e+02f, 2.013e+00f }, + {4.926e+03f, -4.325e+02f, 4.315e+00f }, + {4.926e+03f, -6.487e+02f, 9.250e+00f }, + {4.926e+03f, -9.731e+02f, 2.181e+01f }, + {4.926e+03f, -1.460e+03f, 4.250e+01f }, + {4.926e+03f, -2.189e+03f, 9.111e+01f }, + {4.926e+03f, -3.284e+03f, 1.953e+02f }, + {4.926e+03f, -4.926e+03f, 3.806e+02f }, + {4.926e+03f, -7.389e+03f, 7.417e+02f }, + {4.926e+03f, -1.108e+04f, 1.445e+03f }, + {4.926e+03f, -1.663e+04f, 2.561e+03f }, + {7.389e+03f, -7.500e+00f, 1.250e+00f }, + {7.389e+03f, -1.125e+01f, 1.250e+00f }, + {7.389e+03f, -1.688e+01f, 1.250e+00f }, + {7.389e+03f, -2.531e+01f, 1.250e+00f }, + {7.389e+03f, -3.797e+01f, 1.250e+00f }, + {7.389e+03f, -5.695e+01f, 1.250e+00f }, + {7.389e+03f, -8.543e+01f, 1.250e+00f }, + {7.389e+03f, -1.281e+02f, 1.250e+00f }, + {7.389e+03f, -1.922e+02f, 1.250e+00f }, + {7.389e+03f, -2.883e+02f, 1.375e+00f }, + {7.389e+03f, -4.325e+02f, 2.947e+00f }, + {7.389e+03f, -6.487e+02f, 6.318e+00f }, + {7.389e+03f, -9.731e+02f, 1.490e+01f }, + {7.389e+03f, -1.460e+03f, 3.193e+01f }, + {7.389e+03f, -2.189e+03f, 6.845e+01f }, + {7.389e+03f, -3.284e+03f, 1.334e+02f }, + {7.389e+03f, -4.926e+03f, 2.860e+02f }, + {7.389e+03f, -7.389e+03f, 5.572e+02f }, + {7.389e+03f, -1.108e+04f, 1.086e+03f }, + {7.389e+03f, -1.663e+04f, 2.116e+03f }, + {1.108e+04f, -7.500e+00f, 1.250e+00f }, + {1.108e+04f, -1.125e+01f, 1.250e+00f }, + {1.108e+04f, -1.688e+01f, 1.250e+00f }, + {1.108e+04f, -2.531e+01f, 1.250e+00f }, + {1.108e+04f, -3.797e+01f, 1.250e+00f }, + {1.108e+04f, -5.695e+01f, 1.250e+00f }, + {1.108e+04f, -8.543e+01f, 1.250e+00f }, + {1.108e+04f, -1.281e+02f, 1.250e+00f }, + {1.108e+04f, -1.922e+02f, 1.250e+00f }, + {1.108e+04f, -2.883e+02f, 1.250e+00f }, + {1.108e+04f, -4.325e+02f, 2.013e+00f }, + {1.108e+04f, -6.487e+02f, 4.315e+00f }, + {1.108e+04f, -9.731e+02f, 1.018e+01f }, + {1.108e+04f, -1.460e+03f, 2.181e+01f }, + {1.108e+04f, -2.189e+03f, 4.676e+01f }, + {1.108e+04f, -3.284e+03f, 1.002e+02f }, + {1.108e+04f, -4.926e+03f, 2.148e+02f }, + {1.108e+04f, -7.389e+03f, 4.187e+02f }, + {1.108e+04f, -1.108e+04f, 8.974e+02f }, + {1.108e+04f, -1.663e+04f, 1.749e+03f }, + {1.663e+04f, -7.500e+00f, 1.250e+00f }, + {1.663e+04f, -1.125e+01f, 1.250e+00f }, + {1.663e+04f, -1.688e+01f, 1.250e+00f }, + {1.663e+04f, -2.531e+01f, 1.250e+00f }, + {1.663e+04f, -3.797e+01f, 1.250e+00f }, + {1.663e+04f, -5.695e+01f, 1.250e+00f }, + {1.663e+04f, -8.543e+01f, 1.250e+00f }, + {1.663e+04f, -1.281e+02f, 1.250e+00f }, + {1.663e+04f, -1.922e+02f, 1.250e+00f }, + {1.663e+04f, -2.883e+02f, 1.250e+00f }, + {1.663e+04f, -4.325e+02f, 1.375e+00f }, + {1.663e+04f, -6.487e+02f, 2.947e+00f }, + {1.663e+04f, -9.731e+02f, 6.318e+00f }, + {1.663e+04f, -1.460e+03f, 1.490e+01f }, + {1.663e+04f, -2.189e+03f, 3.193e+01f }, + {1.663e+04f, -3.284e+03f, 6.845e+01f }, + {1.663e+04f, -4.926e+03f, 1.467e+02f }, + {1.663e+04f, -7.389e+03f, 3.145e+02f }, + {1.663e+04f, -1.108e+04f, 6.743e+02f }, + {1.663e+04f, -1.663e+04f, 1.314e+03f }, + }; + if ((a > 1.663e+04) || (-b > 1.663e+04)) + return z > -b; // Way overly conservative? + if (a < data[0][0]) + return false; + int index = 0; + while (data[index][0] < a) + ++index; + if(a != data[index][0]) + --index; + while ((data[index][1] < b) && (data[index][2] > 1.25)) + --index; + ++index; + BOOST_MATH_ASSERT(a > data[index][0]); + BOOST_MATH_ASSERT(-b < -data[index][1]); + return z > data[index][2]; + } + template + T hypergeometric_1F1_from_function_ratio_negative_b_forwards(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients coef(a, b, z); + T ratio = 1 / boost::math::tools::function_ratio_from_forwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // We can't normalise via the Wronksian as the subtraction in the Wronksian will suffer an exquisite amount of cancellation - + // potentially many hundreds of digits in this region. However, if forwards iteration is stable at this point + // it will also be stable for M(a, b+1, z) etc all the way up to the origin, and hopefully one step beyond. So + // use a reference value just over the origin to normalise: + // + long long scale = 0; + int steps = itrunc(ceil(-b)); + T reference_value = hypergeometric_1F1_imp(T(a + steps), T(b + steps), z, pol, log_scaling); + T found = boost::math::tools::apply_recurrence_relation_forward(boost::math::detail::hypergeometric_1F1_recurrence_a_and_b_coefficients(a + 1, b + 1, z), steps - 1, T(1), ratio, &scale); + log_scaling -= scale; + if ((fabs(reference_value) < 1) && (fabs(reference_value) < tools::min_value() * fabs(found))) + { + // Possible underflow, rescale + long long s = lltrunc(tools::log_max_value()); + log_scaling -= s; + reference_value *= exp(T(s)); + } + else if ((fabs(found) < 1) && (fabs(reference_value) > tools::max_value() * fabs(found))) + { + // Overflow, rescale: + long long s = lltrunc(tools::log_max_value()); + log_scaling += s; + reference_value /= exp(T(s)); + } + return reference_value / found; + } + + + + // + // This next version is largely the same as above, but calculates the ratio for the b recurrence relation + // which has a larger area of stability than the ab recurrence when a,b < 0. We can then use a single + // recurrence step to convert this to the ratio for the ab recursion and proceed largely as before. + // The routine is quite insensitive to the size of z, but requires |a| < |5b| for accuracy. + // Fortunately the accuracy outside this domain falls off steadily rather than suddenly switching + // to a different behaviour. + // + template + T hypergeometric_1F1_from_function_ratio_negative_ab(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // Get the function ratio, M(a+1, b+1, z)/M(a,b,z): + // + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients coef(a, b + 1, z); + T ratio = boost::math::tools::function_ratio_from_backwards_recurrence(coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_from_function_ratio_negative_b_positive_a<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // We need to use A&S 13.4.3 to convert a ratio for M(a, b + 1, z) / M(a, b, z) + // to M(a+1, b+1, z) / M(a, b, z) + // + // We have: (a-b)M(a, b+1, z) - aM(a+1, b+1, z) + bM(a, b, z) = 0 + // and therefore: M(a + 1, b + 1, z) / M(a, b, z) = ((a - b)M(a, b + 1, z) / M(a, b, z) + b) / a + // + ratio = ((a - b) * ratio + b) / a; + // + // Let M2 = M(1+a-b, 2-b, z) + // This is going to be a mighty big number: + // + long long local_scaling = 0; + T M2 = boost::math::detail::hypergeometric_1F1_imp(T(1 + a - b), T(2 - b), z, pol, local_scaling); + log_scaling -= local_scaling; // all the M2 terms are in the denominator + // + // Let M3 = M(1+a-b + 1, 2-b + 1, z) + // We don't use the ratio to get this as it's not clear that it's reliable: + // + long long local_scaling2 = 0; + T M3 = boost::math::detail::hypergeometric_1F1_imp(T(2 + a - b), T(3 - b), z, pol, local_scaling2); + // + // M2 and M3 must be identically scaled: + // + if (local_scaling != local_scaling2) + { + M3 *= exp(T(local_scaling2 - local_scaling)); + } + // + // Get the RHS of the Wronksian: + // + long long fz = lltrunc(z); + log_scaling += fz; + T rhs = (1 - b) * exp(z - fz); + // + // We need to divide that by: + // [(a-b+1)z/(2-b) M2(a+1,b+1,z) + (1-b) M2(a,b,z) - a/b z^b R(a,b,z) M2(a,b,z) ] + // Note that at this stage, both M3 and M2 are scaled by exp(local_scaling). + // + T lhs = (a - b + 1) * z * M3 / (2 - b) + (1 - b) * M2 - a * z * ratio * M2 / b; + + return rhs / lhs; + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_BY_RATIOS_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_cf.hpp @@ -0,0 +1,50 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_CF_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP + +#include + +// +// Evaluation of 1F1 by continued fraction +// see http://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/10/0002/ +// +// This is not terribly useful, as like the series we're adding a something to 1, +// so only really useful when we know that the result will be > 1. +// + + + namespace boost { namespace math { namespace detail { + + template + struct hypergeometric_1F1_cf_func + { + typedef std::pair result_type; + hypergeometric_1F1_cf_func(T a_, T b_, T z_) : a(a_), b(b_), z(z_), k(0) {} + std::pair operator()() + { + ++k; + return std::make_pair(-(((a + k) * z) / ((k + 1) * (b + k))), 1 + ((a + k) * z) / ((k + 1) * (b + k))); + } + T a, b, z; + unsigned k; + }; + + template + T hypergeometric_1F1_cf(const T& a, const T& b, const T& z, const Policy& pol, const char* function) + { + hypergeometric_1F1_cf_func func(a, b, z); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::continued_fraction_a(func, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations(function, max_iter, pol); + return 1 + a * z / (b * (1 + result)); + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_a.hpp @@ -0,0 +1,35 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_CF_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_CF_HPP +// +// Evaluation of 1F1 by continued fraction +// by asymptotic approximation for large a, +// see https://dlmf.nist.gov/13.8#E9 +// +// This is not terribly useful, as it only gets a few digits correct even for very +// large a, also needs b and z small: +// + + + namespace boost { namespace math { namespace detail { + + template + T hypergeometric_1F1_large_neg_a_asymtotic_dlmf_13_8_9(T a, T b, T z, const Policy& pol) + { + T result = boost::math::cyl_bessel_j(b - 1, sqrt(2 * z * (b - 2 * a)), pol); + result *= boost::math::tgamma(b, pol) * exp(z / 2); + T p = pow((b / 2 - a) * z, (1 - b) / 4); + result *= p; + result *= p; + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_BESSEL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp @@ -0,0 +1,484 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ + +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + template + inline bool is_negative_integer(const T& x) + { + using std::floor; + return (x <= 0) && (floor(x) == x); + } + + + template + struct hypergeometric_1F1_igamma_series + { + enum{ cache_size = 64 }; + + typedef T result_type; + hypergeometric_1F1_igamma_series(const T& alpha, const T& delta, const T& x, const Policy& pol) + : delta_poch(-delta), alpha_poch(alpha), x(x), k(0), cache_offset(0), pol(pol) + { + BOOST_MATH_STD_USING + T log_term = log(x) * -alpha; + log_scaling = lltrunc(log_term - 3 - boost::math::tools::log_min_value() / 50); + term = exp(log_term - log_scaling); + refill_cache(); + } + T operator()() + { + if (k - cache_offset >= cache_size) + { + cache_offset += cache_size; + refill_cache(); + } + T result = term * gamma_cache[k - cache_offset]; + term *= delta_poch * alpha_poch / (++k * x); + delta_poch += 1; + alpha_poch += 1; + return result; + } + void refill_cache() + { + typedef typename lanczos::lanczos::type lanczos_type; + + gamma_cache[cache_size - 1] = boost::math::gamma_p(alpha_poch + ((int)cache_size - 1), x, pol); + for (int i = cache_size - 1; i > 0; --i) + { + gamma_cache[i - 1] = gamma_cache[i] >= 1 ? T(1) : T(gamma_cache[i] + regularised_gamma_prefix(T(alpha_poch + (i - 1)), x, pol, lanczos_type()) / (alpha_poch + (i - 1))); + } + } + T delta_poch, alpha_poch, x, term; + T gamma_cache[cache_size]; + int k; + long long log_scaling; + int cache_offset; + Policy pol; + }; + + template + T hypergeometric_1F1_igamma(const T& a, const T& b, const T& x, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + if (b_minus_a == 0) + { + // special case: M(a,a,z) == exp(z) + long long scale = lltrunc(x, pol); + log_scaling += scale; + return exp(x - scale); + } + hypergeometric_1F1_igamma_series s(b_minus_a, a - 1, x, pol); + log_scaling += s.log_scaling; + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol); + T log_prefix = x + boost::math::lgamma(b, pol) - boost::math::lgamma(a, pol); + long long scale = lltrunc(log_prefix); + log_scaling += scale; + return result * exp(log_prefix - scale); + } + + template + T hypergeometric_1F1_shift_on_a(T h, const T& a_local, const T& b_local, const T& x, int a_shift, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + T a = a_local + a_shift; + if (a_shift == 0) + return h; + else if (a_shift > 0) + { + // + // Forward recursion on a is stable as long as 2a-b+z > 0. + // If 2a-b+z < 0 then backwards recursion is stable even though + // the function may be strictly increasing with a. Potentially + // we may need to split the recurrence in 2 sections - one using + // forward recursion, and one backwards. + // + // We will get the next seed value from the ratio + // on b as that's stable and quick to compute. + // + + T crossover_a = (b_local - x) / 2; + int crossover_shift = itrunc(crossover_a - a_local); + + if (crossover_shift > 1) + { + // + // Forwards recursion will start off unstable, but may switch to the stable direction later. + // Start in the middle and go in both directions: + // + if (crossover_shift > a_shift) + crossover_shift = a_shift; + crossover_a = a_local + crossover_shift; + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(crossover_a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = ((1+a-b) / a) M(a,b,z) + ((b-1) / a) M(a,b,z)/b_ratio + // + T first = 1; + T second = ((1 + crossover_a - b_local) / crossover_a) + ((b_local - 1) / crossover_a) / b_ratio; + // + // Recurse down to a_local, compare values and re-normalise first and second: + // + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(crossover_a, b_local, x); + long long backwards_scale = 0; + T comparitor = boost::math::tools::apply_recurrence_relation_backward(a_coef, crossover_shift, second, first, &backwards_scale); + log_scaling -= backwards_scale; + if ((h < 1) && (tools::max_value() * h > comparitor)) + { + // Need to rescale! + long long scale = lltrunc(log(h), pol) + 1; + h *= exp(T(-scale)); + log_scaling += scale; + } + comparitor /= h; + first /= comparitor; + second /= comparitor; + // + // Now we can recurse forwards for the rest of the range: + // + if (crossover_shift < a_shift) + { + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef_2(crossover_a + 1, b_local, x); + h = boost::math::tools::apply_recurrence_relation_forward(a_coef_2, a_shift - crossover_shift - 1, first, second, &log_scaling); + } + else + h = first; + } + else + { + // + // Regular case where forwards iteration is stable right from the start: + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a_local, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = ((1+a-b) / a) M(a,b,z) + ((b-1) / a) M(a,b,z)/b_ratio + // + T second = ((1 + a_local - b_local) / a_local) * h + ((b_local - 1) / a_local) * h / b_ratio; + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(a_local + 1, b_local, x); + h = boost::math::tools::apply_recurrence_relation_forward(a_coef, --a_shift, h, second, &log_scaling); + } + } + else + { + // + // We've calculated h for a larger value of a than we want, and need to recurse down. + // However, only forward iteration is stable, so calculate the ratio, compare values, + // and normalise. Note that we calculate the ratio on b and convert to a since the + // direction is the minimal solution for N->+INF. + // + // IMPORTANT: this is only currently called for a > b and therefore forwards iteration + // is the only stable direction as we will only iterate down until a ~ b, but we + // will check this with an assert: + // + BOOST_MATH_ASSERT(2 * a - b_local + x > 0); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T b_ratio = boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + // + // Convert to a ratio: + // (1+a-b)M(a, b, z) - aM(a+1, b, z) + (b-1)M(a, b-1, z) = 0 + // + // hence: M(a+1,b,z) = (1+a-b) / a M(a,b,z) + (b-1) / a M(a,b,z)/ (M(a,b,z)/M(a,b-1,z)) + // + T first = 1; // arbitrary value; + T second = ((1 + a - b_local) / a) + ((b_local - 1) / a) * (1 / b_ratio); + + if (a_shift == -1) + h = h / second; + else + { + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients a_coef(a + 1, b_local, x); + T comparitor = boost::math::tools::apply_recurrence_relation_forward(a_coef, -(a_shift + 1), first, second); + if (boost::math::tools::min_value() * comparitor > h) + { + // Ooops, need to rescale h: + long long rescale = lltrunc(log(fabs(h))); + T scale = exp(T(-rescale)); + h *= scale; + log_scaling += rescale; + } + h = h / comparitor; + } + } + return h; + } + + template + T hypergeometric_1F1_shift_on_b(T h, const T& a, const T& b_local, const T& x, int b_shift, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + + T b = b_local + b_shift; + if (b_shift == 0) + return h; + else if (b_shift > 0) + { + // + // We get here for b_shift > 0 when b > z. We can't use forward recursion on b - it's unstable, + // so grab the ratio and work backwards to b - b_shift and normalise. + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + + T first = 1; // arbitrary value; + T second = 1 / boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + if (b_shift == 1) + h = h / second; + else + { + // + // Reset coefficients and recurse: + // + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef_2(a, b - 1, x); + long long local_scale = 0; + T comparitor = boost::math::tools::apply_recurrence_relation_backward(b_coef_2, --b_shift, first, second, &local_scale); + log_scaling -= local_scale; + if (boost::math::tools::min_value() * comparitor > h) + { + // Ooops, need to rescale h: + long long rescale = lltrunc(log(fabs(h))); + T scale = exp(T(-rescale)); + h *= scale; + log_scaling += rescale; + } + h = h / comparitor; + } + } + else + { + T second; + if (a == b_local) + { + // recurrence is trivial for a == b and method of ratios fails as the c-term goes to zero: + second = -b_local * (1 - b_local - x) * h / (b_local * (b_local - 1)); + } + else + { + BOOST_MATH_ASSERT(!is_negative_integer(b - a)); + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef(a, b_local, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + second = h / boost::math::tools::function_ratio_from_backwards_recurrence(b_coef, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_large_abz<%1%>(%1%,%1%,%1%)", max_iter, pol); + } + if (b_shift == -1) + h = second; + else + { + boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients b_coef_2(a, b_local - 1, x); + h = boost::math::tools::apply_recurrence_relation_backward(b_coef_2, -(++b_shift), h, second, &log_scaling); + } + } + return h; + } + + + template + T hypergeometric_1F1_large_igamma(const T& a, const T& b, const T& x, const T& b_minus_a, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We need a < b < z in order to ensure there's at least a chance of convergence, + // we can use recurrence relations to shift forwards on a+b or just a to achieve this, + // for decent accuracy, try to keep 2b - 1 < a < 2b < z + // + int b_shift = b * 2 < x ? 0 : itrunc(b - x / 2); + int a_shift = a > b - b_shift ? -itrunc(b - b_shift - a - 1) : -itrunc(b - b_shift - a); + + if (a_shift < 0) + { + // Might as well do all the shifting on b as scale a downwards: + b_shift -= a_shift; + a_shift = 0; + } + + T a_local = a - a_shift; + T b_local = b - b_shift; + T b_minus_a_local = (a_shift == 0) && (b_shift == 0) ? b_minus_a : b_local - a_local; + long long local_scaling = 0; + T h = hypergeometric_1F1_igamma(a_local, b_local, x, b_minus_a_local, pol, local_scaling); + log_scaling += local_scaling; + + // + // Apply shifts on a and b as required: + // + h = hypergeometric_1F1_shift_on_a(h, a_local, b_local, x, a_shift, pol, log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, x, b_shift, pol, log_scaling); + + return h; + } + + template + T hypergeometric_1F1_large_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We make a small, and b > z: + // + int a_shift(0), b_shift(0); + if (a * z > b) + { + a_shift = itrunc(a) - 5; + b_shift = b < z ? itrunc(b - z - 1) : 0; + } + // + // If a_shift is trivially small, there's really not much point in losing + // accuracy to save a couple of iterations: + // + if (a_shift < 5) + a_shift = 0; + T a_local = a - a_shift; + T b_local = b - b_shift; + T h = boost::math::detail::hypergeometric_1F1_generic_series(a_local, b_local, z, pol, log_scaling, "hypergeometric_1F1_large_series<%1%>(a,b,z)"); + // + // Apply shifts on a and b as required: + // + if (a_shift && (a_local == 0)) + { + // + // Shifting on a via method of ratios in hypergeometric_1F1_shift_on_a fails when + // a_local == 0. However, the value of h calculated was trivial (unity), so + // calculate a second 1F1 for a == 1 and recurse as normal: + // + long long scale = 0; + T h2 = boost::math::detail::hypergeometric_1F1_generic_series(T(a_local + 1), b_local, z, pol, scale, "hypergeometric_1F1_large_series<%1%>(a,b,z)"); + if (scale != log_scaling) + { + h2 *= exp(T(scale - log_scaling)); + } + boost::math::detail::hypergeometric_1F1_recurrence_a_coefficients coef(a_local + 1, b_local, z); + h = boost::math::tools::apply_recurrence_relation_forward(coef, a_shift - 1, h, h2, &log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + else + { + h = hypergeometric_1F1_shift_on_a(h, a_local, b_local, z, a_shift, pol, log_scaling); + h = hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + return h; + } + + template + T hypergeometric_1F1_large_13_3_6_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // A&S 13.3.6 is good only when a ~ b, but isn't too fussy on the size of z. + // So shift b to match a (b shifting seems to be more stable via method of ratios). + // + int b_shift = itrunc(b - a); + T b_local = b - b_shift; + T h = boost::math::detail::hypergeometric_1F1_AS_13_3_6(a, b_local, z, T(b_local - a), pol, log_scaling); + return hypergeometric_1F1_shift_on_b(h, a, b_local, z, b_shift, pol, log_scaling); + } + + template + T hypergeometric_1F1_large_abz(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // This is the selection logic to pick the "best" method. + // We have a,b,z >> 0 and need to compute the approximate cost of each method + // and then select whichever wins out. + // + enum method + { + method_series = 0, + method_shifted_series, + method_gamma, + method_bessel + }; + // + // Cost of direct series, is the approx number of terms required until we hit convergence: + // + T current_cost = (sqrt(16 * z * (3 * a + z) + 9 * b * b - 24 * b * z) - 3 * b + 4 * z) / 6; + method current_method = method_series; + // + // Cost of shifted series, is the number of recurrences required to move to a zone where + // the series is convergent right from the start. + // Note that recurrence relations fail for very small b, and too many recurrences on a + // will completely destroy all our digits. + // Also note that the method fails when b-a is a negative integer unless b is already + // larger than z and thus does not need shifting. + // + T cost = a + ((b < z) ? T(z - b) : T(0)); + if((b > 1) && (cost < current_cost) && ((b > z) || !is_negative_integer(b-a))) + { + current_method = method_shifted_series; + current_cost = cost; + } + // + // Cost for gamma function method is the number of recurrences required to move it + // into a convergent zone, note that recurrence relations fail for very small b. + // Also add on a fudge factor to account for the fact that this method is both + // more expensive to compute (requires gamma functions), and less accurate than the + // methods above: + // + T b_shift = fabs(b * 2 < z ? T(0) : T(b - z / 2)); + T a_shift = fabs(a > b - b_shift ? T(-(b - b_shift - a - 1)) : T(-(b - b_shift - a))); + cost = 1000 + b_shift + a_shift; + if((b > 1) && (cost <= current_cost)) + { + current_method = method_gamma; + current_cost = cost; + } + // + // Cost for bessel approximation is the number of recurrences required to make a ~ b, + // Note that recurrence relations fail for very small b. We also have issue with large + // z: either overflow/numeric instability or else the series goes divergent. We seem to be + // OK for z smaller than log_max_value though, maybe we can stretch a little further + // but that's not clear... + // Also need to add on a fudge factor to the cost to account for the fact that we need + // to calculate the Bessel functions, this is not quite as high as the gamma function + // method above as this is generally more accurate and so preferred if the methods are close: + // + cost = 50 + fabs(b - a); + if((b > 1) && (cost <= current_cost) && (z < tools::log_max_value()) && (z < 11356) && (b - a != 0.5f)) + { + current_method = method_bessel; + current_cost = cost; + } + + switch (current_method) + { + case method_series: + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, "hypergeometric_1f1_large_abz<%1%>(a,b,z)"); + case method_shifted_series: + return detail::hypergeometric_1F1_large_series(a, b, z, pol, log_scaling); + case method_gamma: + return detail::hypergeometric_1F1_large_igamma(a, b, z, T(b - a), pol, log_scaling); + case method_bessel: + return detail::hypergeometric_1F1_large_13_3_6_series(a, b, z, pol, log_scaling); + } + return 0; // We don't get here! + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_LARGE_ABZ_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp @@ -0,0 +1,521 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2019 John Maddock +// Distributed under 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_DETIAL_1F1_MAP_NEG_B_HPP +#define BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP + +namespace boost { + namespace math { + namespace detail { + // + // hypergeometric_1F1_negative_b_recurrence_region maps out the domains over which + // forward and backwards recurrences are stable when b < 0. + // Returns -1, 0, or 1: + // -1: Backwards recurrence is stable. + // +1: Forwards recurrence is stable. + // 0: Neither recurrence is stable. + // + template + int hypergeometric_1F1_negative_b_recurrence_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + static const double domain[][4] = { + { 1e-300, -1000000.1, 278609.88983674475, 465687}, + { 1e-300, -400000.03999999998, 111530.83622048119, 111544}, + { 1e-300, -160000.016, 44699.113858309654, 44712}, + { 1e-300, -64000.006399999998, 17966.035866477272, 17980}, + { 1e-300, -25600.002560000001, 7273.793013139204, 7287}, + { 1e-300, -10240.001024000001, 2998.0791015625, 3012}, + { 1e-300, -4096.0004096000002, 1291.0461647727273, 1306}, + { 1e-300, -1638.40016384, 619.421875, 636}, + { 1e-300, -655.36006553599998, 374.62926136363637, 397}, + { 1e-300, -262.14402621440001, 335.29958677685943, 370}, + { 1e-300, -104.85761048576001, 412.83057851239664, 462}, + { 1e-300, -41.943044194304001, 513.00603693181824, 570}, + { 1e-300, -16.777217677721602, 584.14449896694214, 644}, + { 1e-300, -6.7108870710886404, 623.30417097107443, 684}, + { 1e-300, -2.6843548284354561, 642.31960227272725, 704}, + { 1e-300, -1.0737419313741825, 650.20738636363626, 711}, + { 1.0000000000000001e-275, -1000000.1, 278597.3203069513, 448872}, + { 1.0000000000000001e-275, -400000.03999999998, 111518.14741654831, 111531}, + { 1.0000000000000001e-275, -160000.016, 44686.621781782669, 44700}, + { 1.0000000000000001e-275, -64000.006399999998, 17953.944740988994, 17967}, + { 1.0000000000000001e-275, -25600.002560000001, 7261.1431107954559, 7274}, + { 1.0000000000000001e-275, -10240.001024000001, 2985.014559659091, 2999}, + { 1.0000000000000001e-275, -4096.0004096000002, 1277.4573863636363, 1292}, + { 1.0000000000000001e-275, -1638.40016384, 603.88778409090912, 620}, + { 1.0000000000000001e-275, -655.36006553599998, 354.10653409090912, 376}, + { 1.0000000000000001e-275, -262.14402621440001, 303.91367510330571, 337}, + { 1.0000000000000001e-275, -104.85761048576001, 367.0454545454545, 416}, + { 1.0000000000000001e-275, -41.943044194304001, 460.06028861053716, 516}, + { 1.0000000000000001e-275, -16.777217677721602, 528.36389462809916, 588}, + { 1.0000000000000001e-275, -6.7108870710886404, 566.33555010330565, 627}, + { 1.0000000000000001e-275, -2.6843548284354561, 585.32541322314046, 646}, + { 1.0000000000000001e-275, -1.0737419313741825, 593.0082967458676, 654}, + { 1.0000000000000002e-250, -1000000.1, 278584.75303113955, 431059}, + { 1.0000000000000002e-250, -400000.03999999998, 111505.53022349965, 111519}, + { 1.0000000000000002e-250, -160000.016, 44674.060190374199, 44687}, + { 1.0000000000000002e-250, -64000.006399999998, 17941.25452769886, 17954}, + { 1.0000000000000002e-250, -25600.002560000001, 7248.2002840909081, 7262}, + { 1.0000000000000002e-250, -10240.001024000001, 2972.017267400568, 2985}, + { 1.0000000000000002e-250, -4096.0004096000002, 1263.6363636363637, 1278}, + { 1.0000000000000002e-250, -1638.40016384, 588.35369318181824, 604}, + { 1.0000000000000002e-250, -655.36006553599998, 334.18039772727275, 355}, + { 1.0000000000000002e-250, -262.14402621440001, 273.7357954545455, 306}, + { 1.0000000000000002e-250, -104.85761048576001, 323.05010330578506, 370}, + { 1.0000000000000002e-250, -41.943044194304001, 407.41541838842977, 463}, + { 1.0000000000000002e-250, -16.777217677721602, 472.78376807851242, 532}, + { 1.0000000000000002e-250, -6.7108870710886404, 509.47443181818176, 570}, + { 1.0000000000000002e-250, -2.6843548284354561, 528.11466942148763, 589}, + { 1.0000000000000002e-250, -1.0737419313741825, 535.52815082644634, 596}, + { 1.0000000000000003e-225, -1000000.1, 278572.12184906006, 278585}, + { 1.0000000000000003e-225, -400000.03999999998, 111493.21068649805, 551165}, + { 1.0000000000000003e-225, -160000.016, 44661.126509232956, 44674}, + { 1.0000000000000003e-225, -64000.006399999998, 17928.069602272728, 17942}, + { 1.0000000000000003e-225, -25600.002560000001, 7235.550426136364, 7249}, + { 1.0000000000000003e-225, -10240.001024000001, 2959.153053977273, 2973}, + { 1.0000000000000003e-225, -4096.0004096000002, 1250.2649147727275, 1264}, + { 1.0000000000000003e-225, -1638.40016384, 573.37073863636363, 589}, + { 1.0000000000000003e-225, -655.36006553599998, 315.21946022727275, 335}, + { 1.0000000000000003e-225, -262.14402621440001, 245.11137654958674, 275}, + { 1.0000000000000003e-225, -104.85761048576001, 280.71022727272725, 326}, + { 1.0000000000000003e-225, -41.943044194304001, 355.45519111570246, 411}, + { 1.0000000000000003e-225, -16.777217677721602, 417.41670971074382, 476}, + { 1.0000000000000003e-225, -6.7108870710886404, 452.71984762396687, 513}, + { 1.0000000000000003e-225, -2.6843548284354561, 470.45648243801656, 532}, + { 1.0000000000000003e-225, -1.0737419313741825, 478.06438855888422, 539}, + { 1.0000000000000004e-200, -1000000.1, 278559.54284667969, 278573}, + { 1.0000000000000004e-200, -400000.03999999998, 111480.15247691762, 111493}, + { 1.0000000000000004e-200, -160000.016, 44648.944635564636, 44662}, + { 1.0000000000000004e-200, -64000.006399999998, 17916.076071999294, 17929}, + { 1.0000000000000004e-200, -25600.002560000001, 7223.06005859375, 7236}, + { 1.0000000000000004e-200, -10240.001024000001, 2946.222301136364, 2960}, + { 1.0000000000000004e-200, -4096.0004096000002, 1236.0916193181818, 1251}, + { 1.0000000000000004e-200, -1638.40016384, 558.40909090909076, 574}, + { 1.0000000000000004e-200, -655.36006553599998, 297.05220170454544, 316}, + { 1.0000000000000004e-200, -262.14402621440001, 218.16438533057845, 247}, + { 1.0000000000000004e-200, -104.85761048576001, 239.76949896694211, 283}, + { 1.0000000000000004e-200, -41.943044194304001, 304.40728305785115, 359}, + { 1.0000000000000004e-200, -16.777217677721602, 362.01349431818181, 421}, + { 1.0000000000000004e-200, -6.7108870710886404, 396.18123708677683, 456}, + { 1.0000000000000004e-200, -2.6843548284354561, 413.36518595041321, 474}, + { 1.0000000000000004e-200, -1.0737419313741825, 420.31249999999994, 482}, + { 1.0000000000000006e-175, -1000000.1, 278547.12638697342, 465687}, + { 1.0000000000000006e-175, -400000.03999999998, 111468.15407492899, 111481}, + { 1.0000000000000006e-175, -160000.016, 44636.134832208802, 44649}, + { 1.0000000000000006e-175, -64000.006399999998, 17903.091796875, 17917}, + { 1.0000000000000006e-175, -25600.002560000001, 7210.247247869318, 7223}, + { 1.0000000000000006e-175, -10240.001024000001, 2933.2915482954545, 2947}, + { 1.0000000000000006e-175, -4096.0004096000002, 1223.600497159091, 1237}, + { 1.0000000000000006e-175, -1638.40016384, 544.06640625, 559}, + { 1.0000000000000006e-175, -655.36006553599998, 279.11931818181813, 298}, + { 1.0000000000000006e-175, -262.14402621440001, 192.94921875, 220}, + { 1.0000000000000006e-175, -104.85761048576001, 200.78641528925618, 242}, + { 1.0000000000000006e-175, -41.943044194304001, 254.19679752066114, 308}, + { 1.0000000000000006e-175, -16.777217677721602, 307.10227272727263, 366}, + { 1.0000000000000006e-175, -6.7108870710886404, 339.36918904958679, 400}, + { 1.0000000000000006e-175, -2.6843548284354561, 356.1554106404958, 417}, + { 1.0000000000000006e-175, -1.0737419313741825, 363.13694473140492, 424}, + { 1.0000000000000007e-150, -1000000.1, 278534.48812689661, 448872}, + { 1.0000000000000007e-150, -400000.03999999998, 111455.15580610794, 111468}, + { 1.0000000000000007e-150, -160000.016, 44623.643454811798, 44637}, + { 1.0000000000000007e-150, -64000.006399999998, 17891.00373493541, 17904}, + { 1.0000000000000007e-150, -25600.002560000001, 7197.631392045454, 7211}, + { 1.0000000000000007e-150, -10240.001024000001, 2920.3607954545455, 2934}, + { 1.0000000000000007e-150, -4096.0004096000002, 1210.3267045454545, 1224}, + { 1.0000000000000007e-150, -1638.40016384, 530.0033735795455, 545}, + { 1.0000000000000007e-150, -655.36006553599998, 262.37215909090907, 280}, + { 1.0000000000000007e-150, -262.14402621440001, 169.07024793388427, 194}, + { 1.0000000000000007e-150, -104.85761048576001, 164.12706611570246, 203}, + { 1.0000000000000007e-150, -41.943044194304001, 206.02079028925615, 258}, + { 1.0000000000000007e-150, -16.777217677721602, 253.0191115702479, 311}, + { 1.0000000000000007e-150, -6.7108870710886404, 283.23056559917353, 343}, + { 1.0000000000000007e-150, -2.6843548284354561, 299.29041838842977, 360}, + { 1.0000000000000007e-150, -1.0737419313741825, 305.7925490702479, 367}, + { 1.0000000000000008e-125, -1000000.1, 278522.04145396838, 285024}, + { 1.0000000000000008e-125, -400000.03999999998, 111443.00279374557, 111456}, + { 1.0000000000000008e-125, -160000.016, 44611.143155184654, 44624}, + { 1.0000000000000008e-125, -64000.006399999998, 17878.306263316765, 17891}, + { 1.0000000000000008e-125, -25600.002560000001, 7185.1384943181802, 7198}, + { 1.0000000000000008e-125, -10240.001024000001, 2907.430042613636, 2921}, + { 1.0000000000000008e-125, -4096.0004096000002, 1197.0621448863635, 1211}, + { 1.0000000000000008e-125, -1638.40016384, 516.05983664772725, 531}, + { 1.0000000000000008e-125, -655.36006553599998, 246.17897727272725, 263}, + { 1.0000000000000008e-125, -262.14402621440001, 147.2197830578512, 171}, + { 1.0000000000000008e-125, -104.85761048576001, 130.599173553719, 166}, + { 1.0000000000000008e-125, -41.943044194304001, 159.12190082644628, 209}, + { 1.0000000000000008e-125, -16.777217677721602, 199.5635330578512, 256}, + { 1.0000000000000008e-125, -6.7108870710886404, 227.1807205578512, 287}, + { 1.0000000000000008e-125, -2.6843548284354561, 242.41670971074376, 303}, + { 1.0000000000000008e-125, -1.0737419313741825, 248.39036673553716, 309}, + { 1.0000000000000009e-100, -1000000.1, 278509.36086203833, 278546}, + { 1.0000000000000009e-100, -400000.03999999998, 111430.10303574696, 551165}, + { 1.0000000000000009e-100, -160000.016, 44598.652055220169, 44612}, + { 1.0000000000000009e-100, -64000.006399999998, 17865.125532670456, 17879}, + { 1.0000000000000009e-100, -25600.002560000001, 7172.046519886364, 7186}, + { 1.0000000000000009e-100, -10240.001024000001, 2895.015980113636, 2908}, + { 1.0000000000000009e-100, -4096.0004096000002, 1184.2329545454545, 1198}, + { 1.0000000000000009e-100, -1638.40016384, 502.04403409090901, 517}, + { 1.0000000000000009e-100, -655.36006553599998, 231.13849431818178, 247}, + { 1.0000000000000009e-100, -262.14402621440001, 128.02290482954544, 149}, + { 1.0000000000000009e-100, -104.85761048576001, 100.76188016528923, 133}, + { 1.0000000000000009e-100, -41.943044194304001, 115.10072314049584, 162}, + { 1.0000000000000009e-100, -16.777217677721602, 147.05255681818178, 203}, + { 1.0000000000000009e-100, -6.7108870710886404, 171.19963842975204, 231}, + { 1.0000000000000009e-100, -2.6843548284354561, 185.58367768595039, 246}, + { 1.0000000000000009e-100, -1.0737419313741825, 191.0575929752066, 252}, + { 1.0000000000000009e-75, -1000000.1, 278497.00512279174, 278510}, + { 1.0000000000000009e-75, -400000.03999999998, 111417.96751369131, 111431}, + { 1.0000000000000009e-75, -160000.016, 44586.151478160507, 44599}, + { 1.0000000000000009e-75, -64000.006399999998, 17853.128506747154, 17866}, + { 1.0000000000000009e-75, -25600.002560000001, 7160.0009918212891, 7173}, + { 1.0000000000000009e-75, -10240.001024000001, 2882.563210227273, 2896}, + { 1.0000000000000009e-75, -4096.0004096000002, 1171.4037642045455, 1185}, + { 1.0000000000000009e-75, -1638.40016384, 489.03941761363637, 503}, + { 1.0000000000000009e-75, -655.36006553599998, 216.05113636363637, 232}, + { 1.0000000000000009e-75, -262.14402621440001, 110.08296745867767, 129}, + { 1.0000000000000009e-75, -104.85761048576001, 74.400826446280988, 102}, + { 1.0000000000000009e-75, -41.943044194304001, 75.619834710743788, 118}, + { 1.0000000000000009e-75, -16.777217677721602, 96.373966942148741, 150}, + { 1.0000000000000009e-75, -6.7108870710886404, 116.33910123966942, 175}, + { 1.0000000000000009e-75, -2.6843548284354561, 129.00947507747935, 189}, + { 1.0000000000000009e-75, -1.0737419313741825, 134.06379132231399, 195}, + { 1.0000000000000011e-50, -1000000.1, 278484.14271457132, 465687}, + { 1.0000000000000011e-50, -400000.03999999998, 111405.16246448863, 111418}, + { 1.0000000000000011e-50, -160000.016, 44573.165838068184, 44587}, + { 1.0000000000000011e-50, -64000.006399999998, 17840.147727272728, 17854}, + { 1.0000000000000011e-50, -25600.002560000001, 7147.375887784091, 7160}, + { 1.0000000000000011e-50, -10240.001024000001, 2869.888583096591, 2883}, + { 1.0000000000000011e-50, -4096.0004096000002, 1158.1576704545455, 1172}, + { 1.0000000000000011e-50, -1638.40016384, 476.00257457386363, 490}, + { 1.0000000000000011e-50, -655.36006553599998, 202.20170454545453, 217}, + { 1.0000000000000011e-50, -262.14402621440001, 94.02682722107437, 111}, + { 1.0000000000000011e-50, -104.85761048576001, 53.0810950413223, 76}, + { 1.0000000000000011e-50, -41.943044194304001, 42.355371900826441, 78}, + { 1.0000000000000011e-50, -16.777217677721602, 50.051652892561975, 100}, + { 1.0000000000000011e-50, -6.7108870710886404, 63.174070247933884, 120}, + { 1.0000000000000011e-50, -2.6843548284354561, 72.956805268595033, 132}, + { 1.0000000000000011e-50, -1.0737419313741825, 77.104855371900811, 138}, + { 1.0000000000000012e-25, -1000000.1, 278471.90274041548, 448844}, + { 1.0000000000000012e-25, -400000.03999999998, 111392.85056374289, 111423}, + { 1.0000000000000012e-25, -160000.016, 44561.0361328125, 44574}, + { 1.0000000000000012e-25, -64000.006399999998, 17828.149314186794, 17841}, + { 1.0000000000000012e-25, -25600.002560000001, 7134.765625, 7148}, + { 1.0000000000000012e-25, -10240.001024000001, 2857.211647727273, 2870}, + { 1.0000000000000012e-25, -4096.0004096000002, 1146.1576704545453, 1159}, + { 1.0000000000000012e-25, -1638.40016384, 463.0625, 476}, + { 1.0000000000000012e-25, -655.36006553599998, 189.27556818181819, 203}, + { 1.0000000000000012e-25, -262.14402621440001, 79.163223140495859, 95}, + { 1.0000000000000012e-25, -104.85761048576001, 36.15702479338843, 54}, + { 1.0000000000000012e-25, -41.943044194304001, 19.008264462809912, 44}, + { 1.0000000000000012e-25, -16.777217677721602, 14.220686983471072, 53}, + { 1.0000000000000012e-25, -6.7108870710886404, 15.207081141998497, 66}, + { 1.0000000000000012e-25, -2.6843548284354561, 19.000046957175051, 76}, + { 1.0000000000000012e-25, -1.0737419313741825, 21.00738364892468, 81}, + { 1, -1000000.1, 278455, 285026}, + { 1, -400000.03999999998, 111376, 111392}, + { 1, -160000.016, 44544, 44561}, + { 1, -64000.006399999998, 17812, 17828}, + { 1, -25600.002560000001, 7119, 7135}, + { 1, -10240.001024000001, 2841, 2858}, + { 1, -4096.0004096000002, 1130, 1147}, + { 1, -1638.40016384, 447, 464}, + { 1, -655.36006553599998, 174, 190}, + { 1, -262.14402621440001, 64, 81}, + { 1, -104.85761048576001, 21, 37}, + { 1, -41.943044194304001, 5, 20}, + { 1, -16.777217677721602, 0, 16}, + { 1, -6.7108870710886404, 0, 17}, + { 1, -2.6843548284354561, 0, 20}, + { 1, -1.0737419313741825, 0, 21}, + { 2.5, -1000000.1, 278450, 278466}, + { 2.5, -400000.03999999998, 111372, 111388}, + { 2.5, -160000.016, 44540, 44557}, + { 2.5, -64000.006399999998, 17808, 17824}, + { 2.5, -25600.002560000001, 7115, 7131}, + { 2.5, -10240.001024000001, 2838, 2854}, + { 2.5, -4096.0004096000002, 1127, 1144}, + { 2.5, -1638.40016384, 445, 461}, + { 2.5, -655.36006553599998, 172, 188}, + { 2.5, -262.14402621440001, 63, 79}, + { 2.5, -104.85761048576001, 20, 35}, + { 2.5, -41.943044194304001, 4, 19}, + { 2.5, -16.777217677721602, 0, 13}, + { 2.5, -6.7108870710886404, 0, 13}, + { 2.5, -2.6843548284354561, 0, 15}, + { 2.5, -1.0737419313741825, 2, 16}, + { 6.25, -1000000.1, 278440, 278456}, + { 6.25, -400000.03999999998, 111362, 111378}, + { 6.25, -160000.016, 44531, 44548}, + { 6.25, -64000.006399999998, 17800, 17816}, + { 6.25, -25600.002560000001, 7108, 7124}, + { 6.25, -10240.001024000001, 2831, 2848}, + { 6.25, -4096.0004096000002, 1121, 1138}, + { 6.25, -1638.40016384, 440, 456}, + { 6.25, -655.36006553599998, 167, 183}, + { 6.25, -262.14402621440001, 59, 75}, + { 6.25, -104.85761048576001, 18, 32}, + { 6.25, -41.943044194304001, 3, 16}, + { 6.25, -16.777217677721602, 0, 10}, + { 6.25, -6.7108870710886404, 0, 9}, + { 6.25, -2.6843548284354561, 0, 9}, + { 6.25, -1.0737419313741825, 4, 9}, + { 15.625, -1000000.1, 278415, 278432}, + { 15.625, -400000.03999999998, 111339, 111425}, + { 15.625, -160000.016, 44510, 44527}, + { 15.625, -64000.006399999998, 17781, 17797}, + { 15.625, -25600.002560000001, 7091, 7107}, + { 15.625, -10240.001024000001, 2816, 2833}, + { 15.625, -4096.0004096000002, 1108, 1125}, + { 15.625, -1638.40016384, 429, 445}, + { 15.625, -655.36006553599998, 159, 174}, + { 15.625, -262.14402621440001, 53, 67}, + { 15.625, -104.85761048576001, 14, 27}, + { 15.625, -41.943044194304001, 2, 11}, + { 15.625, -16.777217677721602, 0, 7}, + { 15.625, -6.7108870710886404, 0, 5}, + { 15.625, -2.6843548284354561, 5, 5}, + { 15.625, -1.0737419313741825, 5, 5}, + { 39.0625, -1000000.1, 278359, 431061}, + { 39.0625, -400000.03999999998, 111287, 111304}, + { 39.0625, -160000.016, 44463, 44480}, + { 39.0625, -64000.006399999998, 17738, 17755}, + { 39.0625, -25600.002560000001, 7053, 7069}, + { 39.0625, -10240.001024000001, 2784, 2800}, + { 39.0625, -4096.0004096000002, 1081, 1097}, + { 39.0625, -1638.40016384, 407, 422}, + { 39.0625, -655.36006553599998, 143, 157}, + { 39.0625, -262.14402621440001, 43, 56}, + { 39.0625, -104.85761048576001, 10, 19}, + { 39.0625, -41.943044194304001, 0, 7}, + { 39.0625, -16.777217677721602, 0, 4}, + { 39.0625, -6.7108870710886404, 0, 3}, + { 39.0625, -2.6843548284354561, 3, 3}, + { 39.0625, -1.0737419313741825, 3, 3}, + { 97.65625, -1000000.1, 278230, 278277}, + { 97.65625, -400000.03999999998, 111170, 111425}, + { 97.65625, -160000.016, 44358, 44374}, + { 97.65625, -64000.006399999998, 17645, 17661}, + { 97.65625, -25600.002560000001, 6972, 6988}, + { 97.65625, -10240.001024000001, 2715, 2731}, + { 97.65625, -4096.0004096000002, 1026, 1041}, + { 97.65625, -1638.40016384, 366, 380}, + { 97.65625, -655.36006553599998, 117, 129}, + { 97.65625, -262.14402621440001, 30, 40}, + { 97.65625, -104.85761048576001, 5, 12}, + { 97.65625, -41.943044194304001, 0, 4}, + { 97.65625, -16.777217677721602, 0, 3}, + { 97.65625, -6.7108870710886404, 0, 1}, + { 97.65625, -2.6843548284354561, 0, 1}, + { 97.65625, -1.0737419313741825, 0, 1}, + { 244.140625, -1000000.1, 277936, 796691}, + { 244.140625, -400000.03999999998, 110906, 110923}, + { 244.140625, -160000.016, 44124, 44141}, + { 244.140625, -64000.006399999998, 17442, 17458}, + { 244.140625, -25600.002560000001, 6801, 6816}, + { 244.140625, -10240.001024000001, 2577, 2593}, + { 244.140625, -4096.0004096000002, 924, 938}, + { 244.140625, -1638.40016384, 300, 312}, + { 244.140625, -655.36006553599998, 82, 92}, + { 244.140625, -262.14402621440001, 17, 24}, + { 244.140625, -104.85761048576001, 2, 7}, + { 244.140625, -41.943044194304001, 0, 3}, + { 244.140625, -16.777217677721602, 0, 1}, + { 244.140625, -6.7108870710886404, 0, 1}, + { 244.140625, -2.6843548284354561, 0, 1}, + { 244.140625, -1.0737419313741825, 0, 1}, + { 610.3515625, -1000000.1, 277277, 277294}, + { 610.3515625, -400000.03999999998, 110322, 111647}, + { 610.3515625, -160000.016, 43617, 43633}, + { 610.3515625, -64000.006399999998, 17014, 17030}, + { 610.3515625, -25600.002560000001, 6456, 6471}, + { 610.3515625, -10240.001024000001, 2321, 2335}, + { 610.3515625, -4096.0004096000002, 757, 769}, + { 610.3515625, -1638.40016384, 212, 221}, + { 610.3515625, -655.36006553599998, 48, 55}, + { 610.3515625, -262.14402621440001, 8, 13}, + { 610.3515625, -104.85761048576001, 0, 4}, + { 610.3515625, -41.943044194304001, 0, 1}, + { 610.3515625, -16.777217677721602, 0, 1}, + { 610.3515625, -6.7108870710886404, 0, 1}, + { 610.3515625, -2.6843548284354561, 0, 1}, + { 610.3515625, -1.0737419313741825, 0, 1}, + { 1525.87890625, -1000000.1, 275817, 431061}, + { 1525.87890625, -400000.03999999998, 109054, 109070}, + { 1525.87890625, -160000.016, 42546, 42562}, + { 1525.87890625, -64000.006399999998, 16151, 16167}, + { 1525.87890625, -25600.002560000001, 5814, 5828}, + { 1525.87890625, -10240.001024000001, 1902, 1914}, + { 1525.87890625, -4096.0004096000002, 535, 545}, + { 1525.87890625, -1638.40016384, 125, 131}, + { 1525.87890625, -655.36006553599998, 23, 28}, + { 1525.87890625, -262.14402621440001, 3, 7}, + { 1525.87890625, -104.85761048576001, 0, 1}, + { 1525.87890625, -41.943044194304001, 0, 1}, + { 1525.87890625, -16.777217677721602, 0, 1}, + { 1525.87890625, -6.7108870710886404, 0, 1}, + { 1525.87890625, -2.6843548284354561, 0, 1}, + { 1525.87890625, -1.0737419313741825, 0, 1}, + { 3814.697265625, -1000000.1, 272645, 272661}, + { 3814.697265625, -400000.03999999998, 106377, 106393}, + { 3814.697265625, -160000.016, 40390, 40406}, + { 3814.697265625, -64000.006399999998, 14545, 14560}, + { 3814.697265625, -25600.002560000001, 4765, 4777}, + { 3814.697265625, -10240.001024000001, 1346, 1356}, + { 3814.697265625, -4096.0004096000002, 316, 323}, + { 3814.697265625, -1638.40016384, 61, 66}, + { 3814.697265625, -655.36006553599998, 9, 13}, + { 3814.697265625, -262.14402621440001, 0, 4}, + { 3814.697265625, -104.85761048576001, 0, 1}, + { 3814.697265625, -41.943044194304001, 0, 1}, + { 3814.697265625, -16.777217677721602, 0, 1}, + { 3814.697265625, -6.7108870710886404, 0, 1}, + { 3814.697265625, -2.6843548284354561, 0, 1}, + { 3814.697265625, -1.0737419313741825, 0, 1}, + { 9536.7431640625, -1000000.1, 265953, 266155}, + { 9536.7431640625, -400000.03999999998, 100987, 101002}, + { 9536.7431640625, -160000.016, 36374, 36388}, + { 9536.7431640625, -64000.006399999998, 11921, 11934}, + { 9536.7431640625, -25600.002560000001, 3374, 3384}, + { 9536.7431640625, -10240.001024000001, 795, 802}, + { 9536.7431640625, -4096.0004096000002, 157, 162}, + { 9536.7431640625, -1638.40016384, 27, 30}, + { 9536.7431640625, -655.36006553599998, 3, 6}, + { 9536.7431640625, -262.14402621440001, 0, 1}, + { 9536.7431640625, -104.85761048576001, 0, 1}, + { 9536.7431640625, -41.943044194304001, 0, 1}, + { 9536.7431640625, -16.777217677721602, 0, 1}, + { 9536.7431640625, -6.7108870710886404, 0, 1}, + { 9536.7431640625, -2.6843548284354561, 0, 1}, + { 9536.7431640625, -1.0737419313741825, 0, 1}, + }; + static const unsigned total_elements = sizeof(domain) / sizeof(domain[0]); + static const unsigned stride = 16; + //static const unsigned a_elements = total_elements / stride; + BOOST_MATH_ASSERT(total_elements % stride == 0); + + static const double a_max = domain[total_elements - 1][0]; + static const double a_min = domain[0][0]; + static const double b_max = domain[stride - 1][1]; + static const double b_min = domain[0][1]; + + if (a < a_min) + return 0; // TODO: Use series? + if (b < b_min) + { + // + // This is a general heuristic that's more or less correct, + // but a bit too safe in most cases. Checked OK with + // random testing. + // + if (z > -b) + return 1; + if (a < 100) + return z < -b / (4 - 5 * (log(a)) * a / b) ? -1 : 0; + else + return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; + } + if (a > a_max) + { + // + // Crossover point is decreasing with increasing a + // upper limit is fine, lower limit is not: + // + if (b > b_max) + return 0; // TODO: don't know what else to do??? + unsigned index = total_elements - stride; + BOOST_MATH_ASSERT(domain[index][0] == a_max); + while (domain[index][1] < b) + ++index; + double b0 = domain[index - 1][1]; + double b1 = domain[index][1]; + double z0 = domain[index - 1][3]; + double z1 = domain[index][3]; + T upper_z_limit = static_cast((z0 * (b1 - b) + z1 * (b - b0)) / (b1 - b0)); + if (z > upper_z_limit) + return 1; + return z < -b / (4 - 5 * sqrt(log(a)) * a / b) ? -1 : 0; + + } + if (b > b_max) + { + return 0; // TODO: is there a better way??? + } + // + // Bi-linear interpolation case: + // + unsigned index = 0; + while (domain[index][0] < a) + index += stride; + while (domain[index][1] < b) + ++index; + // + // We now have 4 corners: + // + double x1 = domain[index - stride - 1][0]; + double x2 = domain[index][0]; + double y1 = domain[index - 1][1]; + double y2 = domain[index][1]; + double f11 = domain[index - stride - 1][2]; + BOOST_MATH_ASSERT(domain[index - stride - 1][0] == x1); + BOOST_MATH_ASSERT(domain[index - stride - 1][1] == y1); + double f12 = domain[index - stride][2]; + BOOST_MATH_ASSERT(domain[index - stride][0] == x1); + BOOST_MATH_ASSERT(domain[index - stride][1] == y2); + double f21 = domain[index - 1][2]; + BOOST_MATH_ASSERT(domain[index - 1][0] == x2); + BOOST_MATH_ASSERT(domain[index - 1][1] == y1); + double f22 = domain[index][2]; + BOOST_MATH_ASSERT(domain[index][0] == x2); + BOOST_MATH_ASSERT(domain[index][1] == y2); + // + // Interpolation is a crude tool and our corners have quite tight bounds, + // and the "impossible region" is bounded by convex planes. For the upper + // bound this is fine - bilinear interpolation will be over-conservative + // but safe. For the lower limit though we may calculate that the "safe" + // zone is in an unsafe place. To work around this we move our coordinates + // closer to the lowest corner of our bounding box by an amount + // proportional to the distance from the nearest corner. This has the effect + // of making our lower bound smaller than it would otherwise be, and more so nearer + // the centre of the bounding box. + // + T effective_x = static_cast(a + (std::min)(T(a - x1), T(x2 - a)) * 0.25); + T effective_y = static_cast(b + (std::min)(T(b - y1), T(y2 - b)) * 0.25); + + T lower_limit = static_cast(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - effective_x) * (y2 - effective_y) + f21 * (effective_x - x1) * (y2 - effective_y) + f12 * (x2 - effective_x) * (effective_y - y1) + f22 * (effective_x - x1) * (effective_y - y1))); + + // + // If one f value was zero, take the whole box as zero: + // + double min_f = (std::min)((std::min)(f11, f12), (std::min)(f21, f22)); + if (min_f == 0) + lower_limit = 0; + // + // Now we can test! + // + if (z < lower_limit) + return -1; + + BOOST_MATH_ASSERT(f11 <= domain[index - stride - 1][3]); + f11 = domain[index - stride - 1][3]; + BOOST_MATH_ASSERT(f12 <= domain[index - stride][3]); + f12 = domain[index - stride][3]; + BOOST_MATH_ASSERT(f21 <= domain[index - 1][3]); + f21 = domain[index - 1][3]; + BOOST_MATH_ASSERT(f22 <= domain[index][3]); + f22 = domain[index][3]; + + T upper_limit = static_cast(1 / ((x2 - x1) * (y2 - y1)) * (f11 * (x2 - a) * (y2 - b) + f21 * (a - x1) * (y2 - b) + f12 * (x2 - a) * (b - y1) + f22 * (a - x1) * (b - y1))); + if (z > upper_limit) + return 1; + return 0; + } + +} } } + + +#endif // BOOST_MATH_DETIAL_1F1_MAP_NEG_B_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp @@ -0,0 +1,522 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ +#define BOOST_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ + +#include +#include + +#include +#include + + namespace boost { namespace math { namespace detail { + + // forward declaration for initial values + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol); + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + struct hypergeometric_1F1_recurrence_a_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_a_coefficients(const T& a, const T& b, const T& z): + a(a), b(b), z(z) + { + } + + hypergeometric_1F1_recurrence_a_coefficients(const hypergeometric_1F1_recurrence_a_coefficients&) = default; + + hypergeometric_1F1_recurrence_a_coefficients operator=(const hypergeometric_1F1_recurrence_a_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T ai = a + i; + + const T an = b - ai; + const T bn = (2 * ai - b + z); + const T cn = -ai; + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + }; + + template + struct hypergeometric_1F1_recurrence_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_b_coefficients(const T& a, const T& b, const T& z): + a(a), b(b), z(z) + { + } + + hypergeometric_1F1_recurrence_b_coefficients(const hypergeometric_1F1_recurrence_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_b_coefficients& operator=(const hypergeometric_1F1_recurrence_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T bi = b + i; + + const T an = bi * (bi - 1); + const T bn = bi * (1 - bi - z); + const T cn = z * (bi - a); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + }; + // + // for use when we're recursing to a small b: + // + template + struct hypergeometric_1F1_recurrence_small_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_small_b_coefficients(const T& a, const T& b, const T& z, int N) : + a(a), b(b), z(z), N(N) + { + } + + hypergeometric_1F1_recurrence_small_b_coefficients(const hypergeometric_1F1_recurrence_small_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_small_b_coefficients operator=(const hypergeometric_1F1_recurrence_small_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T bi = b + (i + N); + const T bi_minus_1 = b + (i + N - 1); + + const T an = bi * bi_minus_1; + const T bn = bi * (-bi_minus_1 - z); + const T cn = z * (bi - a); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + int N; + }; + + template + struct hypergeometric_1F1_recurrence_a_and_b_coefficients + { + using result_type = boost::math::tuple; + + hypergeometric_1F1_recurrence_a_and_b_coefficients(const T& a, const T& b, const T& z, int offset = 0): + a(a), b(b), z(z), offset(offset) + { + } + + hypergeometric_1F1_recurrence_a_and_b_coefficients(const hypergeometric_1F1_recurrence_a_and_b_coefficients&) = default; + + hypergeometric_1F1_recurrence_a_and_b_coefficients operator=(const hypergeometric_1F1_recurrence_a_and_b_coefficients&) = delete; + + result_type operator()(std::intmax_t i) const + { + const T ai = a + (offset + i); + const T bi = b + (offset + i); + + const T an = bi * (b + (offset + i - 1)); + const T bn = bi * (z - (b + (offset + i - 1))); + const T cn = -ai * z; + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a; + const T b; + const T z; + int offset; + }; +#if 0 + // + // These next few recurrence relations are archived for future reference, some of them are novel, though all + // are trivially derived from the existing well known relations: + // + // Recurrence relation for double-stepping on both a and b: + // - b(b-1)(b-2) / (2-b+z) M(a-2,b-2,z) + [b(a-1)z / (2-b+z) + b(1-b+z) + abz(b+1) /(b+1)(z-b)] M(a,b,z) - a(a+1)z^2 / (b+1)(z-b) M(a+2,b+2,z) + // + template + struct hypergeometric_1F1_recurrence_2a_and_2b_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2a_and_2b_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T ai = a + (offset + i); + const T bi = b + (offset + i); + + const T an = -bi * (b + (offset + i - 1)) * (b + (offset + i - 2)) / (-(b + (offset + i - 2)) + z); + const T bn = bi * (a + (offset + i - 1)) * z / (z - (b + (offset + i - 2))) + + bi * (z - (b + (offset + i - 1))) + + ai * bi * z * (b + (offset + i + 1)) / ((b + (offset + i + 1)) * (z - bi)); + const T cn = -ai * (a + (offset + i + 1)) * z * z / ((b + (offset + i + 1)) * (z - bi)); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2a_and_2b_coefficients operator=(const hypergeometric_1F1_recurrence_2a_and_2b_coefficients&); + }; + + // + // Recurrence relation for double-stepping on a: + // -(b-a)(1 + b - a)/(2a-2-b+z)M(a-2,b,z) + [(b-a)(a-1)/(2a-2-b+z) + (2a-b+z) + a(b-a-1)/(2a+2-b+z)]M(a,b,z) -a(a+1)/(2a+2-b+z)M(a+2,b,z) + // + template + struct hypergeometric_1F1_recurrence_2a_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2a_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T ai = a + (offset + i); + // -(b-a)(1 + b - a)/(2a-2-b+z) + const T an = -(b - ai) * (b - (a + (offset + i - 1))) / (2 * (a + (offset + i - 1)) - b + z); + const T bn = (b - ai) * (a + (offset + i - 1)) / (2 * (a + (offset + i - 1)) - b + z) + (2 * ai - b + z) + ai * (b - (a + (offset + i + 1))) / (2 * (a + (offset + i + 1)) - b + z); + const T cn = -ai * (a + (offset + i + 1)) / (2 * (a + (offset + i + 1)) - b + z); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2a_coefficients operator=(const hypergeometric_1F1_recurrence_2a_coefficients&); + }; + + // + // Recurrence relation for double-stepping on b: + // b(b-1)^2(b-2)/((1-b)(2-b-z)) M(a,b-2,z) + [zb(b-1)(b-1-a)/((1-b)(2-b-z)) + b(1-b-z) + z(b-a)(b+1)b/((b+1)(b+z)) ] M(a,b,z) + z^2(b-a)(b+1-a)/((b+1)(b+z)) M(a,b+2,z) + // + template + struct hypergeometric_1F1_recurrence_2b_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_2b_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + i *= 2; + const T bi = b + (offset + i); + const T bi_m1 = b + (offset + i - 1); + const T bi_p1 = b + (offset + i + 1); + const T bi_m2 = b + (offset + i - 2); + + const T an = bi * (bi_m1) * (bi_m1) * (bi_m2) / (-bi_m1 * (-bi_m2 - z)); + const T bn = z * bi * bi_m1 * (bi_m1 - a) / (-bi_m1 * (-bi_m2 - z)) + bi * (-bi_m1 - z) + z * (bi - a) * bi_p1 * bi / (bi_p1 * (bi + z)); + const T cn = z * z * (bi - a) * (bi_p1 - a) / (bi_p1 * (bi + z)); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_2b_coefficients operator=(const hypergeometric_1F1_recurrence_2b_coefficients&); + }; + + // + // Recurrence relation for a+ b-: + // -z(b-a)(a-1-b)/(b(a-1+z)) M(a-1,b+1,z) + [(b-a)(a-1)b/(b(a-1+z)) + (2a-b+z) + a(b-a-1)/(a+z)] M(a,b,z) + a(1-b)/(a+z) M(a+1,b-1,z) + // + // This is potentially the most useful of these novel recurrences. + // - - + - + + template + struct hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients + { + typedef boost::math::tuple result_type; + + hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients(const T& a, const T& b, const T& z, int offset = 0) : + a(a), b(b), z(z), offset(offset) + { + } + + result_type operator()(std::intmax_t i) const + { + const T ai = a + (offset + i); + const T bi = b - (offset + i); + + const T an = -z * (bi - ai) * (ai - 1 - bi) / (bi * (ai - 1 + z)); + const T bn = z * ((-1 / (ai + z) - 1 / (ai + z - 1)) * (bi + z - 1) + 3) + bi - 1; + const T cn = ai * (1 - bi) / (ai + z); + + return boost::math::make_tuple(an, bn, cn); + } + + private: + const T a, b, z; + int offset; + hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients operator=(const hypergeometric_1F1_recurrence_a_plus_b_minus_coefficients&); + }; +#endif + + template + inline T hypergeometric_1F1_backward_recurrence_for_negative_a(const T& a, const T& b, const T& z, const Policy& pol, const char* function, long long& log_scaling) + { + BOOST_MATH_STD_USING // modf, frexp, fabs, pow + + std::intmax_t integer_part = 0; + T ak = modf(a, &integer_part); + // + // We need ak-1 positive to avoid infinite recursion below: + // + if (0 != ak) + { + ak += 2; + integer_part -= 2; + } + if (ak - 1 == b) + { + // When ak - 1 == b are recursion coefficients dissappear to zero and + // we end up with a NaN result. Reduce the recursion steps by 1 to + // avoid this. We rely on |b| small and therefore no infinite recursion. + ak -= 1; + integer_part += 1; + } + + if (-integer_part > static_cast(policies::get_max_series_iterations())) + return policies::raise_evaluation_error(function, "1F1 arguments sit in a range with a so negative that we have no evaluation method, got a = %1%", std::numeric_limits::quiet_NaN(), pol); + + T first {}; + T second {}; + if(ak == 0) + { + first = 1; + ak -= 1; + second = 1 - z / b; + if (fabs(second) < 0.5) + second = (b - z) / b; // cancellation avoidance + } + else + { + long long scaling1 {}; + long long scaling2 {}; + first = detail::hypergeometric_1F1_imp(ak, b, z, pol, scaling1); + ak -= 1; + second = detail::hypergeometric_1F1_imp(ak, b, z, pol, scaling2); + if (scaling1 != scaling2) + { + second *= exp(T(scaling2 - scaling1)); + } + log_scaling += scaling1; + } + ++integer_part; + + detail::hypergeometric_1F1_recurrence_a_coefficients s(ak, b, z); + + return tools::apply_recurrence_relation_backward(s, + static_cast(std::abs(integer_part)), + first, + second, &log_scaling); + } + + + template + T hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(const T& a, const T& b, const T& z, const Policy& pol, const char*, long long& log_scaling) + { + using std::swap; + BOOST_MATH_STD_USING // modf, frexp, fabs, pow + // + // We compute + // + // M[a + a_shift, b + b_shift; z] + // + // and recurse backwards on a and b down to + // + // M[a, b, z] + // + // With a + a_shift > 1 and b + b_shift > z + // + // There are 3 distinct regions to ensure stability during the recursions: + // + // a > 0 : stable for backwards on a + // a < 0, b > 0 : stable for backwards on a and b + // a < 0, b < 0 : stable for backwards on b (as long as |b| is small). + // + // We could simplify things by ignoring the middle region, but it's more efficient + // to recurse on a and b together when we can. + // + + BOOST_MATH_ASSERT(a < -1); // Not tested nor taken for -1 < a < 0 + + int b_shift = itrunc(z - b) + 2; + + int a_shift = itrunc(-a); + if (a + a_shift != 0) + { + a_shift += 2; + } + // + // If the shifts are so large that we would throw an evaluation_error, try the series instead, + // even though this will almost certainly throw as well: + // + if (b_shift > static_cast(boost::math::policies::get_max_series_iterations())) + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + if (a_shift > static_cast(boost::math::policies::get_max_series_iterations())) + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + int a_b_shift = b < 0 ? itrunc(b + b_shift) : b_shift; // The max we can shift on a and b together + int leading_a_shift = (std::min)(3, a_shift); // Just enough to make a negative + if (a_b_shift > a_shift - 3) + { + a_b_shift = a_shift < 3 ? 0 : a_shift - 3; + } + else + { + // Need to ensure that leading_a_shift is large enough that a will reach it's target + // after the first 2 phases (-,0) and (-,-) are over: + leading_a_shift = a_shift - a_b_shift; + } + int trailing_b_shift = b_shift - a_b_shift; + if (a_b_shift < 5) + { + // Might as well do things in two steps rather than 3: + if (a_b_shift > 0) + { + leading_a_shift += a_b_shift; + trailing_b_shift += a_b_shift; + } + a_b_shift = 0; + --leading_a_shift; + } + + BOOST_MATH_ASSERT(leading_a_shift > 1); + BOOST_MATH_ASSERT(a_b_shift + leading_a_shift + (a_b_shift == 0 ? 1 : 0) == a_shift); + BOOST_MATH_ASSERT(a_b_shift + trailing_b_shift == b_shift); + + if ((trailing_b_shift == 0) && (fabs(b) < 0.5) && a_b_shift) + { + // Better to have the final recursion on b alone, otherwise we lose precision when b is very small: + int diff = (std::min)(a_b_shift, 3); + a_b_shift -= diff; + leading_a_shift += diff; + trailing_b_shift += diff; + } + + T first {}; + T second {}; + long long scale1 {}; + long long scale2 {}; + first = boost::math::detail::hypergeometric_1F1_imp(T(a + a_shift), T(b + b_shift), z, pol, scale1); + // + // It would be good to compute "second" from first and the ratio - unfortunately we are right on the cusp + // recursion on a switching from stable backwards to stable forwards behaviour and so this is not possible here. + // + second = boost::math::detail::hypergeometric_1F1_imp(T(a + a_shift - 1), T(b + b_shift), z, pol, scale2); + if (scale1 != scale2) + second *= exp(T(scale2 - scale1)); + log_scaling += scale1; + + // + // Now we have [a + a_shift, b + b_shift, z] and [a + a_shift - 1, b + b_shift, z] + // and want to recurse until [a + a_shift - leading_a_shift, b + b_shift, z] and [a + a_shift - leadng_a_shift - 1, b + b_shift, z] + // which is leading_a_shift -1 steps. + // + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_a_coefficients(a + a_shift - 1, b + b_shift, z), + leading_a_shift, first, second, &log_scaling, &first); + + if (a_b_shift) + { + // + // Now we need to switch to an a+b shift so that we have: + // [a + a_shift - leading_a_shift, b + b_shift, z] and [a + a_shift - leadng_a_shift - 1, b + b_shift - 1, z] + // A&S 13.4.3 gives us what we need: + // + { + // local a's and b's: + T la = a + a_shift - leading_a_shift - 1; + T lb = b + b_shift; + second = ((1 + la - lb) * second - la * first) / (1 - lb); + } + // + // Now apply a_b_shift - 1 recursions to get down to + // [a + 1, b + trailing_b_shift + 1, z] and [a, b + trailing_b_shift, z] + // + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_a_and_b_coefficients(a, b + b_shift - a_b_shift, z, a_b_shift - 1), + a_b_shift - 1, first, second, &log_scaling, &first); + // + // Now we need to switch to a b shift, a different application of A&S 13.4.3 + // will get us there, we leave "second" where it is, and move "first" sideways: + // + { + T lb = b + trailing_b_shift + 1; + first = (second * (lb - 1) - a * first) / -(1 + a - lb); + } + } + else + { + // + // We have M[a+1, b+b_shift, z] and M[a, b+b_shift, z] and need M[a, b+b_shift-1, z] for + // recursion on b: A&S 13.4.3 gives us what we need. + // + T third = -(second * (1 + a - b - b_shift) - first * a) / (b + b_shift - 1); + swap(first, second); + swap(second, third); + --trailing_b_shift; + } + // + // Finish off by applying trailing_b_shift recursions: + // + if (trailing_b_shift) + { + second = boost::math::tools::apply_recurrence_relation_backward( + hypergeometric_1F1_recurrence_small_b_coefficients(a, b, z, trailing_b_shift), + trailing_b_shift, first, second, &log_scaling); + } + return second; + } + + + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_1F1_RECURRENCE_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp @@ -0,0 +1,60 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP + +#include +#include + + namespace boost{ namespace math{ namespace detail{ + + template + T hypergeometric_1F1_scaled_series(const T& a, const T& b, T z, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // + // Result is returned scaled by e^-z. + // Whenever the terms start becoming too large, we scale by some factor e^-n + // and keep track of the integer scaling factor n. At the end we can perform + // an exact subtraction of n from z and scale the result: + // + T sum(0), term(1), upper_limit(sqrt(boost::math::tools::max_value())), diff; + unsigned n = 0; + long long log_scaling_factor = 1 - lltrunc(boost::math::tools::log_max_value()); + T scaling_factor = exp(T(log_scaling_factor)); + std::intmax_t current_scaling = 0; + + do + { + sum += term; + if (sum >= upper_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + current_scaling += log_scaling_factor; + } + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + ++n; + diff = fabs(term / sum); + } while (diff > boost::math::policies::get_epsilon()); + + z = -z - current_scaling; + while (z < log_scaling_factor) + { + z -= log_scaling_factor; + sum *= scaling_factor; + } + return sum * exp(z); + } + + + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp @@ -0,0 +1,70 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP + +#include +#include + + namespace boost { namespace math { namespace detail { + + // forward declaration for initial values + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol); + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling); + + template + T max_b_for_1F1_small_a_negative_b_by_ratio(const T& z) + { + if (z < -998) + return (z * 2) / 3; + float max_b[][2] = + { + { 0.0f, -47.3046f }, {-6.7275f, -52.0351f }, { -8.9543f, -57.2386f }, {-11.9182f, -62.9625f }, {-14.421f, -69.2587f }, {-19.1943f, -76.1846f }, {-23.2252f, -83.803f }, {-28.1024f, -92.1833f }, {-34.0039f, -101.402f }, {-37.4043f, -111.542f }, {-45.2593f, -122.696f }, {-54.7637f, -134.966f }, {-60.2401f, -148.462f }, {-72.8905f, -163.308f }, {-88.1975f, -179.639f }, {-88.1975f, -197.603f }, {-106.719f, -217.363f }, {-129.13f, -239.1f }, {-142.043f, -263.01f }, {-156.247f, -289.311f }, {-189.059f, -318.242f }, {-207.965f, -350.066f }, {-228.762f, -385.073f }, {-276.801f, -423.58f }, {-304.482f, -465.938f }, {-334.93f, -512.532f }, {-368.423f, -563.785f }, {-405.265f, -620.163f }, {-445.792f, -682.18f }, {-539.408f, -750.398f }, {-593.349f, -825.437f }, {-652.683f, -907.981f }, {-717.952f, -998.779f } + }; + auto p = std::lower_bound(max_b, max_b + sizeof(max_b) / sizeof(max_b[0]), z, [](const float (&a)[2], const T& z) { return a[1] > z; }); + T b = p - max_b ? (*--p)[0] : 0; + // + // We need approximately an extra 10 recurrences per 50 binary digits precision above that of double: + // + b += (std::max)(0, boost::math::tools::digits() - 53) / 5; + return b; + } + + template + T hypergeometric_1F1_small_a_negative_b_by_ratio(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + // + // We grab the ratio for M[a, b, z] / M[a, b+1, z] and use it to seed 2 initial values, + // then recurse until b > 0, compute a reference value and normalize (Millers method). + // + int iterations = itrunc(-b, pol); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T ratio = boost::math::tools::function_ratio_from_forwards_recurrence(boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients(a, b, z), boost::math::tools::epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::hypergeometric_1F1_small_a_negative_b_by_ratio<%1%>(%1%,%1%,%1%)", max_iter, pol); + T first = 1; + T second = 1 / ratio; + long long scaling1 = 0; + BOOST_MATH_ASSERT(b + iterations != a); + second = boost::math::tools::apply_recurrence_relation_forward(boost::math::detail::hypergeometric_1F1_recurrence_b_coefficients(a, b + 1, z), iterations, first, second, &scaling1); + long long scaling2 = 0; + first = hypergeometric_1F1_imp(a, T(b + iterations + 1), z, pol, scaling2); + // + // Result is now first/second * e^(scaling2 - scaling1) + // + log_scaling += scaling2 - scaling1; + return first / second; + } + + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F1_SMALL_A_NEG_B_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_asym.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_asym.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_asym.hpp @@ -0,0 +1,179 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_ASYM_HPP +#define BOOST_MATH_HYPERGEOMETRIC_ASYM_HPP + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + + namespace boost { namespace math { + + namespace detail { + + // + // Asymptotic series based on https://dlmf.nist.gov/13.7#E1 + // + // Note that a and b must not be negative integers, in addition + // we require z > 0 and so apply Kummer's relation for z < 0. + // + template + inline T hypergeometric_1F1_asym_large_z_series(T a, const T& b, T z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::hypergeometric_1F1_asym_large_z_series<%1%>(%1%, %1%, %1%)"; + T prefix; + long long e; + int s; + if (z < 0) + { + a = b - a; + z = -z; + prefix = 1; + } + else + { + e = z > static_cast((std::numeric_limits::max)()) ? (std::numeric_limits::max)() : lltrunc(z, pol); + log_scaling += e; + prefix = exp(z - e); + } + if ((fabs(a) < 10) && (fabs(b) < 10)) + { + prefix *= pow(z, a) * pow(z, -b) * boost::math::tgamma(b, pol) / boost::math::tgamma(a, pol); + } + else + { + T t = log(z) * (a - b); + e = lltrunc(t, pol); + log_scaling += e; + prefix *= exp(t - e); + + t = boost::math::lgamma(b, &s, pol); + e = lltrunc(t, pol); + log_scaling += e; + prefix *= s * exp(t - e); + + t = boost::math::lgamma(a, &s, pol); + e = lltrunc(t, pol); + log_scaling -= e; + prefix /= s * exp(t - e); + } + // + // Checked 2F0: + // + unsigned k = 0; + T a1_poch(1 - a); + T a2_poch(b - a); + T z_mult(1 / z); + T sum = 0; + T abs_sum = 0; + T term = 1; + T last_term = 0; + do + { + sum += term; + last_term = term; + abs_sum += fabs(sum); + term *= a1_poch * a2_poch * z_mult; + term /= ++k; + a1_poch += 1; + a2_poch += 1; + if (fabs(sum) * boost::math::policies::get_epsilon() > fabs(term)) + break; + if(fabs(sum) / abs_sum < boost::math::policies::get_epsilon()) + return boost::math::policies::raise_evaluation_error(function, "Large-z asymptotic approximation to 1F1 has destroyed all the digits in the result due to cancellation. Current best guess is %1%", + prefix * sum, Policy()); + if(k > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "1F1: Unable to locate solution in a reasonable time:" + " large-z asymptotic approximation. Current best guess is %1%", prefix * sum, Policy()); + if((k > 10) && (fabs(term) > fabs(last_term))) + return boost::math::policies::raise_evaluation_error(function, "Large-z asymptotic approximation to 1F1 is divergent. Current best guess is %1%", prefix * sum, Policy()); + } while (true); + + return prefix * sum; + } + + + // experimental range + template + inline bool hypergeometric_1F1_asym_region(const T& a, const T& b, const T& z, const Policy&) + { + BOOST_MATH_STD_USING + int half_digits = policies::digits() / 2; + bool in_region = false; + + if (fabs(a) < 0.001f) + return false; // Haven't been able to make this work, why not? TODO! + + // + // We use the following heuristic, if after we have had half_digits terms + // of the 2F0 series, we require terms to be decreasing in size by a factor + // of at least 0.7. Assuming the earlier terms were converging much faster + // than this, then this should be enough to achieve convergence before the + // series shoots off to infinity. + // + if (z > 0) + { + T one_minus_a = 1 - a; + T b_minus_a = b - a; + if (fabs((one_minus_a + half_digits) * (b_minus_a + half_digits) / (half_digits * z)) < 0.7) + { + in_region = true; + // + // double check that we are not divergent at the start if a,b < 0: + // + if ((one_minus_a < 0) || (b_minus_a < 0)) + { + if (fabs(one_minus_a * b_minus_a / z) > 0.5) + in_region = false; + } + } + } + else if (fabs((1 - (b - a) + half_digits) * (a + half_digits) / (half_digits * z)) < 0.7) + { + if ((floor(b - a) == (b - a)) && (b - a < 0)) + return false; // Can't have a negative integer b-a. + in_region = true; + // + // double check that we are not divergent at the start if a,b < 0: + // + T a1 = 1 - (b - a); + if ((a1 < 0) || (a < 0)) + { + if (fabs(a1 * a / z) > 0.5) + in_region = false; + } + } + // + // Check for a and b negative integers as these aren't supported by the approximation: + // + if (in_region) + { + if ((a < 0) && (floor(a) == a)) + in_region = false; + if ((b < 0) && (floor(b) == b)) + in_region = false; + if (fabs(z) < 40) + in_region = false; + } + return in_region; + } + + } } } // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_HYPERGEOMETRIC_ASYM_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_cf.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_cf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_cf.hpp @@ -0,0 +1,228 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_DETAIL_HYPERGEOMETRIC_CF_HPP +#define BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP + + namespace boost { namespace math { namespace detail { + + // primary template for term of continued fraction + template + struct hypergeometric_pFq_cf_term; + + // partial specialization for 0F1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& b, const T& z): + n(1), b(b), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++b; ++n; + numer = -(z / (b * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T b; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1F0 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& z): + n(1), a(a), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++n; + numer = -((a * z) / n); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1F1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& z): + n(1), a(a), b(b), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++n; + numer = -((a * z) / (b * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 1f2 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z): + n(1), a(a), b(b), c(c), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++c; ++n; + numer = -((a * z) / ((b * c) * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b, c; + const T z; + T numer; + result_type term; + }; + + // partial specialization for 2f1 + template + struct hypergeometric_pFq_cf_term + { + typedef std::pair result_type; + + hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z): + n(1), a(a), b(b), c(c), z(z), + term(std::make_pair(T(0), T(1))) + { + } + + result_type operator()() + { + const result_type result = term; + ++a; ++b; ++c; ++n; + numer = -(((a * b) * z) / (c * n)); + term = std::make_pair(numer, 1 - numer); + return result; + } + + private: + unsigned n; + T a, b, c; + const T z; + T numer; + result_type term; + }; + + template + inline T compute_cf_pFq(detail::hypergeometric_pFq_cf_term& term, const Policy& pol) + { + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + const T result = tools::continued_fraction_b( + term, + boost::math::policies::get_epsilon(), + max_iter); + boost::math::policies::check_series_iterations( + "boost::math::hypergeometric_pFq_cf<%1%>(%1%,%1%,%1%)", + max_iter, + pol); + return result; + } + + template + inline T hypergeometric_0F1_cf(const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(b, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((z / b) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F0_cf(const T& a, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((a * z) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F1_cf(const T& a, const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, z); + T result = detail::compute_cf_pFq(f, pol); + result = (((a * z) / b) / result) + 1; + return result; + } + + template + inline T hypergeometric_1F2_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, c, z); + T result = detail::compute_cf_pFq(f, pol); + result = (((a * z) / (b * c)) / result) + 1; + return result; + } + + template + inline T hypergeometric_2F1_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_cf_term f(a, b, c, z); + T result = detail::compute_cf_pFq(f, pol); + result = ((((a * b) * z) / c) / result) + 1; + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp @@ -0,0 +1,665 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_PFQ_SERIES_HPP_ +#define BOOST_HYPERGEOMETRIC_PFQ_SERIES_HPP_ + +#ifndef BOOST_MATH_PFQ_MAX_B_TERMS +# define BOOST_MATH_PFQ_MAX_B_TERMS 5 +#endif + +#include +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + template + unsigned set_crossover_locations(const Seq& aj, const Seq& bj, const Real& z, unsigned int* crossover_locations) + { + BOOST_MATH_STD_USING + unsigned N_terms = 0; + + if(aj.size() == 1 && bj.size() == 1) + { + // + // For 1F1 we can work out where the peaks in the series occur, + // which is to say when: + // + // (a + k)z / (k(b + k)) == +-1 + // + // Then we are at either a maxima or a minima in the series, and the + // last such point must be a maxima since the series is globally convergent. + // Potentially then we are solving 2 quadratic equations and have up to 4 + // solutions, any solutions which are complex or negative are discarded, + // leaving us with 4 options: + // + // 0 solutions: The series is directly convergent. + // 1 solution : The series diverges to a maxima before converging. + // 2 solutions: The series is initially convergent, followed by divergence to a maxima before final convergence. + // 3 solutions: The series diverges to a maxima, converges to a minima before diverging again to a second maxima before final convergence. + // 4 solutions: The series converges to a minima before diverging to a maxima, converging to a minima, diverging to a second maxima and then converging. + // + // The first 2 situations are adequately handled by direct series evaluation, while the 2,3 and 4 solutions are not. + // + Real a = *aj.begin(); + Real b = *bj.begin(); + Real sq = 4 * a * z + b * b - 2 * b * z + z * z; + if (sq >= 0) + { + Real t = (-sqrt(sq) - b + z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + t = (sqrt(sq) - b + z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + } + sq = -4 * a * z + b * b + 2 * b * z + z * z; + if (sq >= 0) + { + Real t = (-sqrt(sq) - b - z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + t = (sqrt(sq) - b - z) / 2; + if (t >= 0) + { + crossover_locations[N_terms] = itrunc(t); + ++N_terms; + } + } + std::sort(crossover_locations, crossover_locations + N_terms, std::less()); + // + // Now we need to discard every other terms, as these are the minima: + // + switch (N_terms) + { + case 0: + case 1: + break; + case 2: + crossover_locations[0] = crossover_locations[1]; + --N_terms; + break; + case 3: + crossover_locations[1] = crossover_locations[2]; + --N_terms; + break; + case 4: + crossover_locations[0] = crossover_locations[1]; + crossover_locations[1] = crossover_locations[3]; + N_terms -= 2; + break; + } + } + else + { + unsigned n = 0; + for (auto bi = bj.begin(); bi != bj.end(); ++bi, ++n) + { + crossover_locations[n] = *bi >= 0 ? 0 : itrunc(-*bi) + 1; + } + std::sort(crossover_locations, crossover_locations + bj.size(), std::less()); + N_terms = (unsigned)bj.size(); + } + return N_terms; + } + + template + std::pair hypergeometric_pFq_checked_series_impl(const Seq& aj, const Seq& bj, const Real& z, const Policy& pol, const Terminal& termination, long long& log_scale) + { + BOOST_MATH_STD_USING + Real result = 1; + Real abs_result = 1; + Real term = 1; + Real term0 = 0; + Real tol = boost::math::policies::get_epsilon(); + std::uintmax_t k = 0; + Real upper_limit(sqrt(boost::math::tools::max_value())), diff; + Real lower_limit(1 / upper_limit); + long long log_scaling_factor = lltrunc(boost::math::tools::log_max_value()) - 2; + Real scaling_factor = exp(Real(log_scaling_factor)); + Real term_m1; + long long local_scaling = 0; + bool have_no_correct_bits = false; + + if ((aj.size() == 1) && (bj.size() == 0)) + { + if (fabs(z) > 1) + { + if ((z > 0) && (floor(*aj.begin()) != *aj.begin())) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == 1 and q == 0 and |z| > 1, result is imaginary", z, pol); + return std::make_pair(r, r); + } + std::pair r = hypergeometric_pFq_checked_series_impl(aj, bj, Real(1 / z), pol, termination, log_scale); + Real mul = pow(-z, -*aj.begin()); + r.first *= mul; + r.second *= mul; + return r; + } + } + + if (aj.size() > bj.size()) + { + if (aj.size() == bj.size() + 1) + { + if (fabs(z) > 1) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| > 1, series does not converge", z, pol); + return std::make_pair(r, r); + } + if (fabs(z) == 1) + { + Real s = 0; + for (auto i = bj.begin(); i != bj.end(); ++i) + s += *i; + for (auto i = aj.begin(); i != aj.end(); ++i) + s -= *i; + if ((z == 1) && (s <= 0)) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| == 1, in a situation where the series does not converge", z, pol); + return std::make_pair(r, r); + } + if ((z == -1) && (s <= -1)) + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p == q+1 and |z| == 1, in a situation where the series does not converge", z, pol); + return std::make_pair(r, r); + } + } + } + else + { + Real r = policies::raise_domain_error("boost::math::hypergeometric_pFq", "Got p > q+1, series does not converge", z, pol); + return std::make_pair(r, r); + } + } + + while (!termination(k)) + { + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term *= *ai + k; + } + if (term == 0) + { + // There is a negative integer in the aj's: + return std::make_pair(result, abs_result); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term /= *bi + k; + } + term *= z; + ++k; + term /= k; + //std::cout << k << " " << *bj.begin() + k << " " << result << " " << term << /*" " << term_at_k(*aj.begin(), *bj.begin(), z, k, pol) <<*/ std::endl; + result += term; + abs_result += abs(term); + //std::cout << "k = " << k << " term = " << term * exp(log_scale) << " result = " << result * exp(log_scale) << " abs_result = " << abs_result * exp(log_scale) << std::endl; + + // + // Rescaling: + // + if (fabs(abs_result) >= upper_limit) + { + abs_result /= scaling_factor; + result /= scaling_factor; + term /= scaling_factor; + log_scale += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(abs_result) < lower_limit) + { + abs_result *= scaling_factor; + result *= scaling_factor; + term *= scaling_factor; + log_scale -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + + if ((abs(result * tol) > abs(term)) && (abs(term0) > abs(term))) + break; + if (abs_result * tol > abs(result)) + { + // Check if result is so small compared to abs_resuslt that there are no longer any + // correct bits... we require two consecutive passes here before aborting to + // avoid false positives when result transiently drops to near zero then rebounds. + if (have_no_correct_bits) + { + // We have no correct bits in the result... just give up! + result = boost::math::policies::raise_evaluation_error("boost::math::hypergeometric_pFq<%1%>", "Cancellation is so severe that no bits in the reuslt are correct, last result was %1%", Real(result * exp(Real(log_scale))), pol); + return std::make_pair(result, result); + } + else + have_no_correct_bits = true; + } + else + have_no_correct_bits = false; + term0 = term; + } + //std::cout << "result = " << result << std::endl; + //std::cout << "local_scaling = " << local_scaling << std::endl; + //std::cout << "Norm result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(result) * exp(boost::multiprecision::mpfr_float_50(local_scaling)) << std::endl; + // + // We have to be careful when one of the b's crosses the origin: + // + if(bj.size() > BOOST_MATH_PFQ_MAX_B_TERMS) + policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>(Seq, Seq, %1%)", + "The number of b terms must be less than the value of BOOST_MATH_PFQ_MAX_B_TERMS (" BOOST_STRINGIZE(BOOST_MATH_PFQ_MAX_B_TERMS) "), but got %1%.", + Real(bj.size()), pol); + + unsigned crossover_locations[BOOST_MATH_PFQ_MAX_B_TERMS]; + + unsigned N_crossovers = set_crossover_locations(aj, bj, z, crossover_locations); + + bool terminate = false; // Set to true if one of the a's passes through the origin and terminates the series. + + for (unsigned n = 0; n < N_crossovers; ++n) + { + if (k < crossover_locations[n]) + { + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + if ((*ai < 0) && (floor(*ai) == *ai) && (*ai > static_cast(crossover_locations[n]))) + return std::make_pair(result, abs_result); // b's will never cross the origin! + } + // + // local results: + // + Real loop_result = 0; + Real loop_abs_result = 0; + long long loop_scale = 0; + // + // loop_error_scale will be used to increase the size of the error + // estimate (absolute sum), based on the errors inherent in calculating + // the pochhammer symbols. + // + Real loop_error_scale = 0; + //boost::multiprecision::mpfi_float err_est = 0; + // + // b hasn't crossed the origin yet and the series may spring back into life at that point + // so we need to jump forward to that term and then evaluate forwards and backwards from there: + // + unsigned s = crossover_locations[n]; + std::uintmax_t backstop = k; + long long s1(1), s2(1); + term = 0; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + if ((floor(*ai) == *ai) && (*ai < 0) && (-*ai <= static_cast(s))) + { + // One of the a terms has passed through zero and terminated the series: + terminate = true; + break; + } + else + { + int ls = 1; + Real p = log_pochhammer(*ai, s, pol, &ls); + s1 *= ls; + term += p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est += boost::multiprecision::mpfi_float(p); + } + } + //std::cout << "term = " << term << std::endl; + if (terminate) + break; + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + int ls = 1; + Real p = log_pochhammer(*bi, s, pol, &ls); + s2 *= ls; + term -= p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est -= boost::multiprecision::mpfi_float(p); + } + //std::cout << "term = " << term << std::endl; + Real p = lgamma(Real(s + 1), pol); + term -= p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est -= boost::multiprecision::mpfi_float(p); + p = s * log(fabs(z)); + term += p; + loop_error_scale = (std::max)(p, loop_error_scale); + //err_est += boost::multiprecision::mpfi_float(p); + //err_est = exp(err_est); + //std::cout << err_est << std::endl; + // + // Convert loop_error scale to the absolute error + // in term after exp is applied: + // + loop_error_scale *= tools::epsilon(); + // + // Convert to relative error after exp: + // + loop_error_scale = fabs(expm1(loop_error_scale, pol)); + // + // Convert to multiplier for the error term: + // + loop_error_scale /= tools::epsilon(); + + if (z < 0) + s1 *= (s & 1 ? -1 : 1); + + if (term <= tools::log_min_value()) + { + // rescale if we can: + long long scale = lltrunc(floor(term - tools::log_min_value()) - 2); + term -= scale; + loop_scale += scale; + } + if (term > 10) + { + int scale = itrunc(floor(term)); + term -= scale; + loop_scale += scale; + } + //std::cout << "term = " << term << std::endl; + term = s1 * s2 * exp(term); + //std::cout << "term = " << term << std::endl; + //std::cout << "loop_scale = " << loop_scale << std::endl; + k = s; + term0 = term; + long long saved_loop_scale = loop_scale; + bool terms_are_growing = true; + bool trivial_small_series_check = false; + do + { + loop_result += term; + loop_abs_result += fabs(term); + //std::cout << "k = " << k << " term = " << term * exp(loop_scale) << " result = " << loop_result * exp(loop_scale) << " abs_result = " << loop_abs_result * exp(loop_scale) << std::endl; + if (fabs(loop_result) >= upper_limit) + { + loop_result /= scaling_factor; + loop_abs_result /= scaling_factor; + term /= scaling_factor; + loop_scale += log_scaling_factor; + } + if (fabs(loop_result) < lower_limit) + { + loop_result *= scaling_factor; + loop_abs_result *= scaling_factor; + term *= scaling_factor; + loop_scale -= log_scaling_factor; + } + term_m1 = term; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term *= *ai + k; + } + if (term == 0) + { + // There is a negative integer in the aj's: + return std::make_pair(result, abs_result); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term /= *bi + k; + } + term *= z / (k + 1); + + ++k; + diff = fabs(term / loop_result); + terms_are_growing = fabs(term) > fabs(term_m1); + if (!trivial_small_series_check && !terms_are_growing) + { + // + // Now that we have started to converge, check to see if the value of + // this local sum is trivially small compared to the result. If so + // abort this part of the series. + // + trivial_small_series_check = true; + Real d; + if (loop_scale > local_scaling) + { + long long rescale = local_scaling - loop_scale; + if (rescale < tools::log_min_value()) + d = 1; // arbitrary value, we want to keep going + else + d = fabs(term / (result * exp(Real(rescale)))); + } + else + { + long long rescale = loop_scale - local_scaling; + if (rescale < tools::log_min_value()) + d = 0; // terminate this loop + else + d = fabs(term * exp(Real(rescale)) / result); + } + if (d < boost::math::policies::get_epsilon()) + break; + } + } while (!termination(k - s) && ((diff > boost::math::policies::get_epsilon()) || terms_are_growing)); + + //std::cout << "Norm loop result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(loop_result)* exp(boost::multiprecision::mpfr_float_50(loop_scale)) << std::endl; + // + // We now need to combine the results of the first series summation with whatever + // local results we have now. First though, rescale abs_result by loop_error_scale + // to factor in the error in the pochhammer terms at the start of this block: + // + std::uintmax_t next_backstop = k; + loop_abs_result += loop_error_scale * fabs(loop_result); + if (loop_scale > local_scaling) + { + // + // Need to shrink previous result: + // + long long rescale = local_scaling - loop_scale; + local_scaling = loop_scale; + log_scale -= rescale; + Real ex = exp(Real(rescale)); + result *= ex; + abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else if (local_scaling > loop_scale) + { + // + // Need to shrink local result: + // + long long rescale = loop_scale - local_scaling; + Real ex = exp(Real(rescale)); + loop_result *= ex; + loop_abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else + { + result += loop_result; + abs_result += loop_abs_result; + } + // + // Now go backwards as well: + // + k = s; + term = term0; + loop_result = 0; + loop_abs_result = 0; + loop_scale = saved_loop_scale; + trivial_small_series_check = false; + do + { + --k; + if (k == backstop) + break; + term_m1 = term; + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + term /= *ai + k; + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + if (*bi + k == 0) + { + // The series is undefined: + result = boost::math::policies::raise_domain_error("boost::math::hypergeometric_pFq<%1%>", "One of the b values was the negative integer %1%", *bi, pol); + return std::make_pair(result, result); + } + term *= *bi + k; + } + term *= (k + 1) / z; + loop_result += term; + loop_abs_result += fabs(term); + + if (!trivial_small_series_check && (fabs(term) < fabs(term_m1))) + { + // + // Now that we have started to converge, check to see if the value of + // this local sum is trivially small compared to the result. If so + // abort this part of the series. + // + trivial_small_series_check = true; + Real d; + if (loop_scale > local_scaling) + { + long long rescale = local_scaling - loop_scale; + if (rescale < tools::log_min_value()) + d = 1; // keep going + else + d = fabs(term / (result * exp(Real(rescale)))); + } + else + { + long long rescale = loop_scale - local_scaling; + if (rescale < tools::log_min_value()) + d = 0; // stop, underflow + else + d = fabs(term * exp(Real(rescale)) / result); + } + if (d < boost::math::policies::get_epsilon()) + break; + } + + //std::cout << "k = " << k << " result = " << result << " abs_result = " << abs_result << std::endl; + if (fabs(loop_result) >= upper_limit) + { + loop_result /= scaling_factor; + loop_abs_result /= scaling_factor; + term /= scaling_factor; + loop_scale += log_scaling_factor; + } + if (fabs(loop_result) < lower_limit) + { + loop_result *= scaling_factor; + loop_abs_result *= scaling_factor; + term *= scaling_factor; + loop_scale -= log_scaling_factor; + } + diff = fabs(term / loop_result); + } while (!termination(s - k) && ((diff > boost::math::policies::get_epsilon()) || (fabs(term) > fabs(term_m1)))); + + //std::cout << "Norm loop result = " << std::setprecision(35) << boost::multiprecision::mpfr_float_50(loop_result)* exp(boost::multiprecision::mpfr_float_50(loop_scale)) << std::endl; + // + // We now need to combine the results of the first series summation with whatever + // local results we have now. First though, rescale abs_result by loop_error_scale + // to factor in the error in the pochhammer terms at the start of this block: + // + loop_abs_result += loop_error_scale * fabs(loop_result); + // + if (loop_scale > local_scaling) + { + // + // Need to shrink previous result: + // + long long rescale = local_scaling - loop_scale; + local_scaling = loop_scale; + log_scale -= rescale; + Real ex = exp(Real(rescale)); + result *= ex; + abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else if (local_scaling > loop_scale) + { + // + // Need to shrink local result: + // + long long rescale = loop_scale - local_scaling; + Real ex = exp(Real(rescale)); + loop_result *= ex; + loop_abs_result *= ex; + result += loop_result; + abs_result += loop_abs_result; + } + else + { + result += loop_result; + abs_result += loop_abs_result; + } + // + // Reset k to the largest k we reached + // + k = next_backstop; + } + } + + return std::make_pair(result, abs_result); + } + + struct iteration_terminator + { + iteration_terminator(std::uintmax_t i) : m(i) {} + + bool operator()(std::uintmax_t v) const { return v >= m; } + + std::uintmax_t m; + }; + + template + Real hypergeometric_pFq_checked_series_impl(const Seq& aj, const Seq& bj, const Real& z, const Policy& pol, long long& log_scale) + { + BOOST_MATH_STD_USING + iteration_terminator term(boost::math::policies::get_max_series_iterations()); + std::pair result = hypergeometric_pFq_checked_series_impl(aj, bj, z, pol, term, log_scale); + // + // Check to see how many digits we've lost, if it's more than half, raise an evaluation error - + // this is an entirely arbitrary cut off, but not unreasonable. + // + if (result.second * sqrt(boost::math::policies::get_epsilon()) > abs(result.first)) + { + return boost::math::policies::raise_evaluation_error("boost::math::hypergeometric_pFq<%1%>", "Cancellation is so severe that fewer than half the bits in the result are correct, last result was %1%", Real(result.first * exp(Real(log_scale))), pol); + } + return result.first; + } + + template + inline Real hypergeometric_1F1_checked_series_impl(const Real& a, const Real& b, const Real& z, const Policy& pol, long long& log_scale) + { + std::array aj = { a }; + std::array bj = { b }; + return hypergeometric_pFq_checked_series_impl(aj, bj, z, pol, log_scale); + } + + } } } // namespaces + +#endif // BOOST_HYPERGEOMETRIC_PFQ_SERIES_HPP_ diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pade.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pade.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_pade.hpp @@ -0,0 +1,131 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_PADE_HPP +#define BOOST_MATH_HYPERGEOMETRIC_PADE_HPP + + namespace boost{ namespace math{ namespace detail{ + + // Luke: C ---------- SUBROUTINE R1F1P(CP, Z, A, B, N) ---------- + // Luke: C ----- PADE APPROXIMATION OF 1F1( 1 ; CP ; -Z ) ------- + template + inline T hypergeometric_1F1_pade(const T& cp, const T& zp, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T one = T(1); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T zz = z * z; + T b0 = one; + T a0 = one; + T xi1 = one; + T ct1 = cp + one; + T cp1 = cp - one; + + T b1 = one + (z / ct1); + T a1 = b1 - (z / cp); + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T b2 = T(0), a2 = T(0); + T result = T(0), prev_result; + + for (unsigned k = 1; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + const T ct2 = ct1 * ct1; + const T g1 = one + ((cp1 / (ct2 + ct1 + ct1)) * z); + const T g2 = ((xi1 / (ct2 - one)) * ((xi1 + cp1) / ct2)) * zz; + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b2 = (g1 * b1) + (g2 * b0); + a2 = (g1 * a1) + (g2 * a0); + + prev_result = result; + result = a2 / b2; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result)) + break; + + b0 = b1; b1 = b2; + a0 = a1; a1 = a2; + + ct1 += 2; + xi1 += 1; + } + + return a2 / b2; + } + + // Luke: C -------- SUBROUTINE R2F1P(BP, CP, Z, A, B, N) -------- + // Luke: C ---- PADE APPROXIMATION OF 2F1( 1 , BP; CP ; -Z ) ---- + template + inline T hypergeometric_2F1_pade(const T& bp, const T& cp, const T& zp, const Policy&) + { + BOOST_MATH_STD_USING + + static const T one = T(1); + + // Luke: C ---------- INITIALIZATION ----------- + const T z = -zp; + const T zz = z * z; + T b0 = one; + T a0 = one; + T xi1 = one; + T ct1 = cp; + const T b1c1 = (cp - one) * (bp - one); + + T b1 = one + ((z / (cp + one)) * (bp + one)); + T a1 = b1 - ((bp / cp) * z); + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T b2 = T(0), a2 = T(0); + T result = T(0), prev_result = a1 / b1; + + for (unsigned k = 1; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + const T ct2 = ct1 + xi1; + const T ct3 = ct2 * ct2; + const T g2 = (((((ct1 / ct3) * (bp - ct1)) / (ct3 - one)) * xi1) * (bp + xi1)) * zz; + ++xi1; + const T g1 = one + (((((xi1 + xi1) * ct1) + b1c1) / (ct3 + ct2 + ct2)) * z); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b2 = (g1 * b1) + (g2 * b0); + a2 = (g1 * a1) + (g2 * a0); + + prev_result = result; + result = a2 / b2; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result)) + break; + + b0 = b1; b1 = b2; + a0 = a1; a1 = a2; + + ++ct1; + } + + return a2 / b2; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_PADE_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_rational.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_rational.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_rational.hpp @@ -0,0 +1,167 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_RATIONAL_HPP +#define BOOST_MATH_HYPERGEOMETRIC_RATIONAL_HPP + + #include + + namespace boost{ namespace math{ namespace detail{ + + // Luke: C ------- SUBROUTINE R1F1P(AP, CP, Z, A, B, N) --------- + // Luke: C --- RATIONAL APPROXIMATION OF 1F1( AP ; CP ; -Z ) ---- + template + inline T hypergeometric_1F1_rational(const T& ap, const T& cp, const T& zp, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T zero = T(0), one = T(1), two = T(2), three = T(3); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T z2 = z / two; + + T ct1 = ap * (z / cp); + T ct2 = z2 / (one + cp); + T xn3 = zero; + T xn2 = one; + T xn1 = two; + T xn0 = three; + + T b1 = one; + T a1 = one; + T b2 = one + ((one + ap) * (z2 / cp)); + T a2 = b2 - ct1; + T b3 = one + ((two + b2) * (((two + ap) / three) * ct2)); + T a3 = b3 - ((one + ct2) * ct1); + ct1 = three; + + const unsigned max_iterations = boost::math::policies::get_max_series_iterations(); + + T a4 = T(0), b4 = T(0); + T result = T(0), prev_result = a3 / b3; + + for (unsigned k = 2; k < max_iterations; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + ct2 = (z2 / ct1) / (cp + xn1); + const T g1 = one + (ct2 * (xn2 - ap)); + ct2 *= ((ap + xn1) / (cp + xn2)); + const T g2 = ct2 * ((cp - xn1) + (((ap + xn0) / (ct1 + two)) * z2)); + const T g3 = ((ct2 * z2) * (((z2 / ct1) / (ct1 - two)) * ((ap + xn2)) / (cp + xn3))) * (ap - xn2); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b4 = (g1 * b3) + (g2 * b2) + (g3 * b1); + a4 = (g1 * a3) + (g2 * a2) + (g3 * a1); + + prev_result = result; + result = a4 / b4; + + // condition for interruption + if ((fabs(result) * boost::math::tools::epsilon()) > fabs(result - prev_result) / fabs(result)) + break; + + b1 = b2; b2 = b3; b3 = b4; + a1 = a2; a2 = a3; a3 = a4; + + xn3 = xn2; + xn2 = xn1; + xn1 = xn0; + xn0 += 1; + ct1 += two; + } + + return result; + } + + // Luke: C ----- SUBROUTINE R2F1P(AB, BP, CP, Z, A, B, N) ------- + // Luke: C -- RATIONAL APPROXIMATION OF 2F1( AB , BP; CP ; -Z ) - + template + inline T hypergeometric_2F1_rational(const T& ap, const T& bp, const T& cp, const T& zp, const unsigned n, const Policy& ) + { + BOOST_MATH_STD_USING + + static const T one = T(1), two = T(2), three = T(3), four = T(4), + six = T(6), half_7 = T(3.5), half_3 = T(1.5), forth_3 = T(0.75); + + // Luke: C ------------- INITIALIZATION ------------- + const T z = -zp; + const T z2 = z / two; + + T sabz = (ap + bp) * z; + const T ab = ap * bp; + const T abz = ab * z; + const T abz1 = z + (abz + sabz); + const T abz2 = abz1 + (sabz + (three * z)); + const T cp1 = cp + one; + const T ct1 = cp1 + cp1; + + T b1 = one; + T a1 = one; + T b2 = one + (abz1 / (cp + cp)); + T a2 = b2 - (abz / cp); + T b3 = one + ((abz2 / ct1) * (one + (abz1 / ((-six) + (three * ct1))))); + T a3 = b3 - ((abz / cp) * (one + ((abz2 - abz1) / ct1))); + sabz /= four; + + const T abz1_div_4 = abz1 / four; + const T cp1_inc = cp1 + one; + const T cp1_mul_cp1_inc = cp1 * cp1_inc; + + std::array d = {{ + ((half_7 - ab) * z2) - sabz, + abz1_div_4, + abz1_div_4 - (two * sabz), + cp1_inc, + cp1_mul_cp1_inc, + cp * cp1_mul_cp1_inc, + half_3, + forth_3, + forth_3 * z + }}; + + T xi = three; + T a4 = T(0), b4 = T(0); + for (unsigned k = 2; k < n; ++k) + { + // Luke: C ----- CALCULATION OF THE MULTIPLIERS ----- + // Luke: C ----------- FOR THE RECURSION ------------ + T g3 = (d[2] / d[7]) * (d[1] / d[5]); + d[1] += d[8] + sabz; + d[2] += d[8] - sabz; + g3 *= d[1] / d[6]; + T g1 = one + (((d[1] + d[0]) / d[6]) / d[3]); + T g2 = (d[1] / d[4]) / d[6]; + d[7] += two * d[6]; + ++d[6]; + g2 *= cp1 - (xi + ((d[2] + d[0]) / d[6])); + + // Luke: C ------- THE RECURRENCE RELATIONS --------- + // Luke: C ------------ ARE AS FOLLOWS -------------- + b4 = (g1 * b3) + (g2 * b2) + (g3 * b1); + a4 = (g1 * a3) + (g2 * a2) + (g3 * a1); + b1 = b2; b2 = b3; b3 = b4; + a1 = a2; a2 = a3; a3 = a4; + + d[8] += z2; + d[0] += two * d[8]; + d[5] += three * d[4]; + d[4] += two * d[3]; + ++d[3]; + ++xi; + } + + return a4 / b4; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_RATIONAL_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_separated_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_separated_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_separated_series.hpp @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_SEPARATED_SERIES_HPP +#define BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP + + namespace boost { namespace math { namespace detail { + + template + inline T hypergeometric_1F1_separated_series(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING + + std::uintmax_t max_iter = policies::get_max_series_iterations(); + const T factor = policies::get_epsilon(); + + T denom = 1, numer = 1; + T intermediate_result = 1, result = 1; + T a_pochhammer = a, z_pow = z; + unsigned N = 0; + while (--max_iter) + { + ++N; + const T mult = (((b + N) - 1) * N); + denom *= mult; numer *= mult; + numer += a_pochhammer * z_pow; + + result = numer / denom; + + if (fabs(factor * result) > fabs(result - intermediate_result)) + break; + + intermediate_result = result; + + a_pochhammer *= (a + N); + z_pow *= z; + } + + return result; + } + + } } } // namespaces + +#endif // BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_series.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/hypergeometric_series.hpp @@ -0,0 +1,434 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_DETAIL_HYPERGEOMETRIC_SERIES_HPP +#define BOOST_MATH_DETAIL_HYPERGEOMETRIC_SERIES_HPP + +#include +#include +#include +#include +#include +#include + + namespace boost { namespace math { namespace detail { + + // primary template for term of Taylor series + template + struct hypergeometric_pFq_generic_series_term; + + // partial specialization for 0F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& b, const T& z) + : n(0), term(1), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= ((1 / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T b, z; + }; + + // partial specialization for 1F0 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& z) + : n(0), term(1), a(a), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / (n + 1)) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, z; + }; + + // partial specialization for 1F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& b, const T& z) + : n(0), term(1), a(a), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, b, z; + }; + + // partial specialization for 1F2 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a, const T& b1, const T& b2, const T& z) + : n(0), term(1), a(a), b1(b1), b2(b2), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a + n) / ((b1 + n) * (b2 + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a, b1, b2, z; + }; + + // partial specialization for 2F0 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a1, const T& a2, const T& z) + : n(0), term(1), a1(a1), a2(a2), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a1 + n) * (a2 + n) / (n + 1)) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a1, a2, z; + }; + + // partial specialization for 2F1 + template + struct hypergeometric_pFq_generic_series_term + { + typedef T result_type; + + hypergeometric_pFq_generic_series_term(const T& a1, const T& a2, const T& b, const T& z) + : n(0), term(1), a1(a1), a2(a2), b(b), z(z) + { + } + + T operator()() + { + BOOST_MATH_STD_USING + const T r = term; + term *= (((a1 + n) * (a2 + n) / ((b + n) * (n + 1))) * z); + ++n; + return r; + } + + private: + unsigned n; + T term; + const T a1, a2, b, z; + }; + + // we don't need to define extra check and make a polinom from + // series, when p(i) and q(i) are negative integers and p(i) >= q(i) + // as described in functions.wolfram.alpha, because we always + // stop summation when result (in this case numerator) is zero. + template + inline T sum_pFq_series(detail::hypergeometric_pFq_generic_series_term& term, const Policy& pol) + { + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + const T result = boost::math::tools::sum_series(term, boost::math::policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::hypergeometric_pFq_generic_series<%1%>(%1%,%1%,%1%)", max_iter, pol); + return result; + } + + template + inline T hypergeometric_0F1_generic_series(const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(b, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_1F0_generic_series(const T& a, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T log_pochhammer(T z, unsigned n, const Policy pol, int* s = nullptr) + { + BOOST_MATH_STD_USING +#if 0 + if (z < 0) + { + if (n < -z) + { + if(s) + *s = (n & 1 ? -1 : 1); + return log_pochhammer(T(-z + (1 - (int)n)), n, pol); + } + else + { + int cross = itrunc(ceil(-z)); + return log_pochhammer(T(-z + (1 - cross)), cross, pol, s) + log_pochhammer(T(cross + z), n - cross, pol); + } + } + else +#endif + { + if (z + n < 0) + { + T r = log_pochhammer(T(-z - n + 1), n, pol, s); + if (s) + *s *= (n & 1 ? -1 : 1); + return r; + } + int s1, s2; + T r = boost::math::lgamma(T(z + n), &s1, pol) - boost::math::lgamma(z, &s2, pol); + if(s) + *s = s1 * s2; + return r; + } + } + + template + inline T hypergeometric_1F1_generic_series(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling, const char* function) + { + BOOST_MATH_STD_USING + T sum(0), term(1), upper_limit(sqrt(boost::math::tools::max_value())), diff; + T lower_limit(1 / upper_limit); + unsigned n = 0; + long long log_scaling_factor = lltrunc(boost::math::tools::log_max_value()) - 2; + T scaling_factor = exp(T(log_scaling_factor)); + T term_m1 = 0; + long long local_scaling = 0; + // + // When a is very small, then (a+n)/n => 1 faster than + // z / (b+n) => 1, as a result the series starts off + // converging, then at some unspecified time very gradually + // starts to diverge, potentially resulting in some very large + // values being missed. As a result we need a check for small + // a in the convergence criteria. Note that this issue occurs + // even when all the terms are positive. + // + bool small_a = fabs(a) < 0.25; + + unsigned summit_location = 0; + bool have_minima = false; + T sq = 4 * a * z + b * b - 2 * b * z + z * z; + if (sq >= 0) + { + T t = (-sqrt(sq) - b + z) / 2; + if (t > 1) // Don't worry about a minima between 0 and 1. + have_minima = true; + t = (sqrt(sq) - b + z) / 2; + if (t > 0) + summit_location = itrunc(t); + } + + if (summit_location > boost::math::policies::get_max_series_iterations() / 4) + { + // + // Skip forward to the location of the largest term in the series and + // evaluate outwards from there: + // + int s1, s2; + term = log_pochhammer(a, summit_location, pol, &s1) + summit_location * log(z) - log_pochhammer(b, summit_location, pol, &s2) - lgamma(T(summit_location + 1), pol); + //std::cout << term << " " << log_pochhammer(boost::multiprecision::mpfr_float(a), summit_location, pol, &s1) + summit_location * log(boost::multiprecision::mpfr_float(z)) - log_pochhammer(boost::multiprecision::mpfr_float(b), summit_location, pol, &s2) - lgamma(boost::multiprecision::mpfr_float(summit_location + 1), pol) << std::endl; + local_scaling = lltrunc(term); + log_scaling += local_scaling; + term = s1 * s2 * exp(term - local_scaling); + //std::cout << term << " " << exp(log_pochhammer(boost::multiprecision::mpfr_float(a), summit_location, pol, &s1) + summit_location * log(boost::multiprecision::mpfr_float(z)) - log_pochhammer(boost::multiprecision::mpfr_float(b), summit_location, pol, &s2) - lgamma(boost::multiprecision::mpfr_float(summit_location + 1), pol) - local_scaling) << std::endl; + n = summit_location; + } + else + summit_location = 0; + + T saved_term = term; + long long saved_scale = local_scaling; + + do + { + sum += term; + //std::cout << n << " " << term * exp(boost::multiprecision::mpfr_float(local_scaling)) << " " << rising_factorial(boost::multiprecision::mpfr_float(a), n) * pow(boost::multiprecision::mpfr_float(z), n) / (rising_factorial(boost::multiprecision::mpfr_float(b), n) * factorial(n)) << std::endl; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + term_m1 = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n - summit_location > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + ++n; + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon()) || (fabs(term_m1) < fabs(term)) || (small_a && n < 10)); + + // + // See if we need to go backwards as well: + // + if (summit_location) + { + // + // Backup state: + // + term = saved_term * exp(T(local_scaling - saved_scale)); + n = summit_location; + term *= (b + (n - 1)) * n / ((a + (n - 1)) * z); + --n; + + do + { + sum += term; + //std::cout << n << " " << term * exp(boost::multiprecision::mpfr_float(local_scaling)) << " " << rising_factorial(boost::multiprecision::mpfr_float(a), n) * pow(boost::multiprecision::mpfr_float(z), n) / (rising_factorial(boost::multiprecision::mpfr_float(b), n) * factorial(n)) << std::endl; + if (n == 0) + break; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + local_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + local_scaling -= log_scaling_factor; + } + term_m1 = term; + term *= (b + (n - 1)) * n / ((a + (n - 1)) * z); + if (summit_location - n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + --n; + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon()) || (fabs(term_m1) < fabs(term))); + } + + if (have_minima && n && summit_location) + { + // + // There are a few terms starting at n == 0 which + // haven't been accounted for yet... + // + unsigned backstop = n; + n = 0; + term = exp(T(-local_scaling)); + do + { + sum += term; + //std::cout << n << " " << term << " " << sum << std::endl; + if (fabs(sum) >= upper_limit) + { + sum /= scaling_factor; + term /= scaling_factor; + log_scaling += log_scaling_factor; + } + if (fabs(sum) < lower_limit) + { + sum *= scaling_factor; + term *= scaling_factor; + log_scaling -= log_scaling_factor; + } + //term_m1 = term; + term *= (((a + n) / ((b + n) * (n + 1))) * z); + if (n > boost::math::policies::get_max_series_iterations()) + return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + if (++n == backstop) + break; // we've caught up with ourselves. + diff = fabs(term / sum); + } while ((diff > boost::math::policies::get_epsilon())/* || (fabs(term_m1) < fabs(term))*/); + } + //std::cout << sum << std::endl; + return sum; + } + + template + inline T hypergeometric_1F2_generic_series(const T& a, const T& b1, const T& b2, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a, b1, b2, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_2F0_generic_series(const T& a1, const T& a2, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a1, a2, z); + return detail::sum_pFq_series(s, pol); + } + + template + inline T hypergeometric_2F1_generic_series(const T& a1, const T& a2, const T& b, const T& z, const Policy& pol) + { + detail::hypergeometric_pFq_generic_series_term s(a1, a2, b, z); + return detail::sum_pFq_series(s, pol); + } + + } } } // namespaces + +#endif // BOOST_MATH_DETAIL_HYPERGEOMETRIC_SERIES_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inv_ab.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inv_ab.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inv_ab.hpp @@ -0,0 +1,329 @@ +// (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) + +// +// This is not a complete header file, it is included by beta.hpp +// after it has defined it's definitions. This inverts the incomplete +// beta functions ibeta and ibetac on the first parameters "a" +// and "b" using a generic root finding algorithm (TOMS Algorithm 748). +// + +#ifndef BOOST_MATH_SP_DETAIL_BETA_INV_AB +#define BOOST_MATH_SP_DETAIL_BETA_INV_AB + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +struct beta_inv_ab_t +{ + beta_inv_ab_t(T b_, T z_, T p_, bool invert_, bool swap_ab_) : b(b_), z(z_), p(p_), invert(invert_), swap_ab(swap_ab_) {} + T operator()(T a) + { + return invert ? + p - boost::math::ibetac(swap_ab ? b : a, swap_ab ? a : b, z, Policy()) + : boost::math::ibeta(swap_ab ? b : a, swap_ab ? a : b, z, Policy()) - p; + } +private: + T b, z, p; + bool invert, swap_ab; +}; + +template +T inverse_negative_binomial_cornish_fisher(T n, T sf, T sfc, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING + // mean: + T m = n * (sfc) / sf; + T t = sqrt(n * (sfc)); + // standard deviation: + T sigma = t / sf; + // skewness + T sk = (1 + sfc) / t; + // kurtosis: + T k = (6 - sf * (5+sfc)) / (n * (sfc)); + // Get the inverse of a std normal distribution: + T x = boost::math::erfc_inv(p > q ? 2 * q : 2 * p, pol) * constants::root_two(); + // Set the sign: + if(p < 0.5) + x = -x; + T x2 = x * x; + // w is correction term due to skewness + T w = x + sk * (x2 - 1) / 6; + // + // Add on correction due to kurtosis. + // + if(n >= 10) + w += k * x * (x2 - 3) / 24 + sk * sk * x * (2 * x2 - 5) / -36; + + w = m + sigma * w; + if(w < tools::min_value()) + return tools::min_value(); + return w; +} + +template +T ibeta_inv_ab_imp(const T& b, const T& z, const T& p, const T& q, bool swap_ab, const Policy& pol) +{ + BOOST_MATH_STD_USING // for ADL of std lib math functions + // + // Special cases first: + // + BOOST_MATH_INSTRUMENT_CODE("b = " << b << " z = " << z << " p = " << p << " q = " << " swap = " << swap_ab); + if(p == 0) + { + return swap_ab ? tools::min_value() : tools::max_value(); + } + if(q == 0) + { + return swap_ab ? tools::max_value() : tools::min_value(); + } + // + // Function object, this is the functor whose root + // we have to solve: + // + beta_inv_ab_t f(b, z, (p < q) ? p : q, (p < q) ? false : true, swap_ab); + // + // Tolerance: full precision. + // + tools::eps_tolerance tol(policies::digits()); + // + // Now figure out a starting guess for what a may be, + // we'll start out with a value that'll put p or q + // right bang in the middle of their range, the functions + // are quite sensitive so we should need too many steps + // to bracket the root from there: + // + T guess = 0; + T factor = 5; + // + // Convert variables to parameters of a negative binomial distribution: + // + T n = b; + T sf = swap_ab ? z : 1-z; + T sfc = swap_ab ? 1-z : z; + T u = swap_ab ? p : q; + T v = swap_ab ? q : p; + if(u <= pow(sf, n)) + { + // + // Result is less than 1, negative binomial approximation + // is useless.... + // + if((p < q) != swap_ab) + { + guess = (std::min)(T(b * 2), T(1)); + } + else + { + guess = (std::min)(T(b / 2), T(1)); + } + } + if(n * n * n * u * sf > 0.005) + guess = 1 + inverse_negative_binomial_cornish_fisher(n, sf, sfc, u, v, pol); + + if(guess < 10) + { + // + // Negative binomial approximation not accurate in this area: + // + if((p < q) != swap_ab) + { + guess = (std::min)(T(b * 2), T(10)); + } + else + { + guess = (std::min)(T(b / 2), T(10)); + } + } + else + factor = (v < sqrt(tools::epsilon())) ? 2 : (guess < 20 ? 1.2f : 1.1f); + BOOST_MATH_INSTRUMENT_CODE("guess = " << guess); + // + // Max iterations permitted: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + std::pair r = bracket_and_solve_root(f, guess, factor, swap_ab ? true : false, tol, max_iter, pol); + if(max_iter >= policies::get_max_root_iterations()) + return policies::raise_evaluation_error("boost::math::ibeta_invab_imp<%1%>(%1%,%1%,%1%)", "Unable to locate the root within a reasonable number of iterations, closest approximation so far was %1%", r.first, pol); + return (r.first + r.second) / 2; +} + +} // namespace detail + +template +typename tools::promote_args::type + ibeta_inva(RT1 b, RT2 x, RT3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::ibeta_inva<%1%>(%1%,%1%,%1%)"; + if(p == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(p == 1) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(b), + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + false, pol), + function); +} + +template +typename tools::promote_args::type + ibetac_inva(RT1 b, RT2 x, RT3 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::ibetac_inva<%1%>(%1%,%1%,%1%)"; + if(q == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + if(q == 0) + { + return tools::min_value(); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(b), + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + false, pol), + function); +} + +template +typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 x, RT3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::ibeta_invb<%1%>(%1%,%1%,%1%)"; + if(p == 0) + { + return tools::min_value(); + } + if(p == 1) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(a), + static_cast(x), + static_cast(p), + static_cast(1 - static_cast(p)), + true, pol), + function); +} + +template +typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 x, RT3 q, const Policy& pol) +{ + static const char* function = "boost::math::ibeta_invb<%1%>(%1%, %1%, %1%)"; + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(q == 1) + { + return tools::min_value(); + } + if(q == 0) + { + return policies::raise_overflow_error(function, 0, Policy()); + } + + return policies::checked_narrowing_cast( + detail::ibeta_inv_ab_imp( + static_cast(a), + static_cast(x), + static_cast(1 - static_cast(q)), + static_cast(q), + true, pol), + function); +} + +template +inline typename tools::promote_args::type + ibeta_inva(RT1 b, RT2 x, RT3 p) +{ + return boost::math::ibeta_inva(b, x, p, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibetac_inva(RT1 b, RT2 x, RT3 q) +{ + return boost::math::ibetac_inva(b, x, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 x, RT3 p) +{ + return boost::math::ibeta_invb(a, x, p, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 x, RT3 q) +{ + return boost::math::ibetac_invb(a, x, q, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_DETAIL_BETA_INV_AB + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inverse.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inverse.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/ibeta_inverse.hpp @@ -0,0 +1,1024 @@ +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 2007 +// 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_IBETA_INVERSE_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_IBETA_INVERSE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// Helper object used by root finding +// code to convert eta to x. +// +template +struct temme_root_finder +{ + temme_root_finder(const T t_, const T a_) : t(t_), a(a_) {} + + boost::math::tuple operator()(T x) + { + BOOST_MATH_STD_USING // ADL of std names + + T y = 1 - x; + if(y == 0) + { + T big = tools::max_value() / 4; + return boost::math::make_tuple(static_cast(-big), static_cast(-big)); + } + if(x == 0) + { + T big = tools::max_value() / 4; + return boost::math::make_tuple(static_cast(-big), big); + } + T f = log(x) + a * log(y) + t; + T f1 = (1 / x) - (a / (y)); + return boost::math::make_tuple(f, f1); + } +private: + T t, a; +}; +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 2. +// +template +T temme_method_1_ibeta_inverse(T a, T b, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + const T r2 = sqrt(T(2)); + // + // get the first approximation for eta from the inverse + // error function (Eq: 2.9 and 2.10). + // + T eta0 = boost::math::erfc_inv(2 * z, pol); + eta0 /= -sqrt(a / 2); + + T terms[4] = { eta0 }; + T workspace[7]; + // + // calculate powers: + // + T B = b - a; + T B_2 = B * B; + T B_3 = B_2 * B; + // + // Calculate correction terms: + // + + // See eq following 2.15: + workspace[0] = -B * r2 / 2; + workspace[1] = (1 - 2 * B) / 8; + workspace[2] = -(B * r2 / 48); + workspace[3] = T(-1) / 192; + workspace[4] = -B * r2 / 3840; + terms[1] = tools::evaluate_polynomial(workspace, eta0, 5); + // Eq Following 2.17: + workspace[0] = B * r2 * (3 * B - 2) / 12; + workspace[1] = (20 * B_2 - 12 * B + 1) / 128; + workspace[2] = B * r2 * (20 * B - 1) / 960; + workspace[3] = (16 * B_2 + 30 * B - 15) / 4608; + workspace[4] = B * r2 * (21 * B + 32) / 53760; + workspace[5] = (-32 * B_2 + 63) / 368640; + workspace[6] = -B * r2 * (120 * B + 17) / 25804480; + terms[2] = tools::evaluate_polynomial(workspace, eta0, 7); + // Eq Following 2.17: + workspace[0] = B * r2 * (-75 * B_2 + 80 * B - 16) / 480; + workspace[1] = (-1080 * B_3 + 868 * B_2 - 90 * B - 45) / 9216; + workspace[2] = B * r2 * (-1190 * B_2 + 84 * B + 373) / 53760; + workspace[3] = (-2240 * B_3 - 2508 * B_2 + 2100 * B - 165) / 368640; + terms[3] = tools::evaluate_polynomial(workspace, eta0, 4); + // + // Bring them together to get a final estimate for eta: + // + T eta = tools::evaluate_polynomial(terms, T(1/a), 4); + // + // now we need to convert eta to x, by solving the appropriate + // quadratic equation: + // + T eta_2 = eta * eta; + T c = -exp(-eta_2 / 2); + T x; + if(eta_2 == 0) + x = 0.5; + else + x = (1 + eta * sqrt((1 + c) / eta_2)) / 2; + + BOOST_MATH_ASSERT(x >= 0); + BOOST_MATH_ASSERT(x <= 1); + BOOST_MATH_ASSERT(eta * (x - 0.5) >= 0); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 1: " << x << std::endl; +#endif + return x; +} +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 3. +// +template +T temme_method_2_ibeta_inverse(T /*a*/, T /*b*/, T z, T r, T theta, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + // + // Get first estimate for eta, see Eq 3.9 and 3.10, + // but note there is a typo in Eq 3.10: + // + T eta0 = boost::math::erfc_inv(2 * z, pol); + eta0 /= -sqrt(r / 2); + + T s = sin(theta); + T c = cos(theta); + // + // Now we need to perturb eta0 to get eta, which we do by + // evaluating the polynomial in 1/r at the bottom of page 151, + // to do this we first need the error terms e1, e2 e3 + // which we'll fill into the array "terms". Since these + // terms are themselves polynomials, we'll need another + // array "workspace" to calculate those... + // + T terms[4] = { eta0 }; + T workspace[6]; + // + // some powers of sin(theta)cos(theta) that we'll need later: + // + T sc = s * c; + T sc_2 = sc * sc; + T sc_3 = sc_2 * sc; + T sc_4 = sc_2 * sc_2; + T sc_5 = sc_2 * sc_3; + T sc_6 = sc_3 * sc_3; + T sc_7 = sc_4 * sc_3; + // + // Calculate e1 and put it in terms[1], see the middle of page 151: + // + workspace[0] = (2 * s * s - 1) / (3 * s * c); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co1[] = { -1, -5, 5 }; + workspace[1] = -tools::evaluate_even_polynomial(co1, s, 3) / (36 * sc_2); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co2[] = { 1, 21, -69, 46 }; + workspace[2] = tools::evaluate_even_polynomial(co2, s, 4) / (1620 * sc_3); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co3[] = { 7, -2, 33, -62, 31 }; + workspace[3] = -tools::evaluate_even_polynomial(co3, s, 5) / (6480 * sc_4); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co4[] = { 25, -52, -17, 88, -115, 46 }; + workspace[4] = tools::evaluate_even_polynomial(co4, s, 6) / (90720 * sc_5); + terms[1] = tools::evaluate_polynomial(workspace, eta0, 5); + // + // Now evaluate e2 and put it in terms[2]: + // + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co5[] = { 7, 12, -78, 52 }; + workspace[0] = -tools::evaluate_even_polynomial(co5, s, 4) / (405 * sc_3); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co6[] = { -7, 2, 183, -370, 185 }; + workspace[1] = tools::evaluate_even_polynomial(co6, s, 5) / (2592 * sc_4); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co7[] = { -533, 776, -1835, 10240, -13525, 5410 }; + workspace[2] = -tools::evaluate_even_polynomial(co7, s, 6) / (204120 * sc_5); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co8[] = { -1579, 3747, -3372, -15821, 45588, -45213, 15071 }; + workspace[3] = -tools::evaluate_even_polynomial(co8, s, 7) / (2099520 * sc_6); + terms[2] = tools::evaluate_polynomial(workspace, eta0, 4); + // + // And e3, and put it in terms[3]: + // + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co9[] = {449, -1259, -769, 6686, -9260, 3704 }; + workspace[0] = tools::evaluate_even_polynomial(co9, s, 6) / (102060 * sc_5); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co10[] = { 63149, -151557, 140052, -727469, 2239932, -2251437, 750479 }; + workspace[1] = -tools::evaluate_even_polynomial(co10, s, 7) / (20995200 * sc_6); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co11[] = { 29233, -78755, 105222, 146879, -1602610, 3195183, -2554139, 729754 }; + workspace[2] = tools::evaluate_even_polynomial(co11, s, 8) / (36741600 * sc_7); + terms[3] = tools::evaluate_polynomial(workspace, eta0, 3); + // + // Bring the correction terms together to evaluate eta, + // this is the last equation on page 151: + // + T eta = tools::evaluate_polynomial(terms, T(1/r), 4); + // + // Now that we have eta we need to back solve for x, + // we seek the value of x that gives eta in Eq 3.2. + // The two methods used are described in section 5. + // + // Begin by defining a few variables we'll need later: + // + T x; + T s_2 = s * s; + T c_2 = c * c; + T alpha = c / s; + alpha *= alpha; + T lu = (-(eta * eta) / (2 * s_2) + log(s_2) + c_2 * log(c_2) / s_2); + // + // Temme doesn't specify what value to switch on here, + // but this seems to work pretty well: + // + if(fabs(eta) < 0.7) + { + // + // Small eta use the expansion Temme gives in the second equation + // of section 5, it's a polynomial in eta: + // + workspace[0] = s * s; + workspace[1] = s * c; + workspace[2] = (1 - 2 * workspace[0]) / 3; + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co12[] = { 1, -13, 13 }; + workspace[3] = tools::evaluate_polynomial(co12, workspace[0], 3) / (36 * s * c); + static const BOOST_MATH_INT_TABLE_TYPE(T, int) co13[] = { 1, 21, -69, 46 }; + workspace[4] = tools::evaluate_polynomial(co13, workspace[0], 4) / (270 * workspace[0] * c * c); + x = tools::evaluate_polynomial(workspace, eta, 5); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 2 (small eta): " << x << std::endl; +#endif + } + else + { + // + // If eta is large we need to solve Eq 3.2 more directly, + // begin by getting an initial approximation for x from + // the last equation on page 155, this is a polynomial in u: + // + T u = exp(lu); + workspace[0] = u; + workspace[1] = alpha; + workspace[2] = 0; + workspace[3] = 3 * alpha * (3 * alpha + 1) / 6; + workspace[4] = 4 * alpha * (4 * alpha + 1) * (4 * alpha + 2) / 24; + workspace[5] = 5 * alpha * (5 * alpha + 1) * (5 * alpha + 2) * (5 * alpha + 3) / 120; + x = tools::evaluate_polynomial(workspace, u, 6); + // + // At this point we may or may not have the right answer, Eq-3.2 has + // two solutions for x for any given eta, however the mapping in 3.2 + // is 1:1 with the sign of eta and x-sin^2(theta) being the same. + // So we can check if we have the right root of 3.2, and if not + // switch x for 1-x. This transformation is motivated by the fact + // that the distribution is *almost* symmetric so 1-x will be in the right + // ball park for the solution: + // + if((x - s_2) * eta < 0) + x = 1 - x; +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 2 (large eta): " << x << std::endl; +#endif + } + // + // The final step is a few Newton-Raphson iterations to + // clean up our approximation for x, this is pretty cheap + // in general, and very cheap compared to an incomplete beta + // evaluation. The limits set on x come from the observation + // that the sign of eta and x-sin^2(theta) are the same. + // + T lower, upper; + if(eta < 0) + { + lower = 0; + upper = s_2; + } + else + { + lower = s_2; + upper = 1; + } + // + // If our initial approximation is out of bounds then bisect: + // + if((x < lower) || (x > upper)) + x = (lower+upper) / 2; + // + // And iterate: + // + x = tools::newton_raphson_iterate( + temme_root_finder(-lu, alpha), x, lower, upper, policies::digits() / 2); + + return x; +} +// +// See: +// "Asymptotic Inversion of the Incomplete Beta Function" +// N.M. Temme +// Journal of Computation and Applied Mathematics 41 (1992) 145-157. +// Section 4. +// +template +T temme_method_3_ibeta_inverse(T a, T b, T p, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + + // + // Begin by getting an initial approximation for the quantity + // eta from the dominant part of the incomplete beta: + // + T eta0; + if(p < q) + eta0 = boost::math::gamma_q_inv(b, p, pol); + else + eta0 = boost::math::gamma_p_inv(b, q, pol); + eta0 /= a; + // + // Define the variables and powers we'll need later on: + // + T mu = b / a; + T w = sqrt(1 + mu); + T w_2 = w * w; + T w_3 = w_2 * w; + T w_4 = w_2 * w_2; + T w_5 = w_3 * w_2; + T w_6 = w_3 * w_3; + T w_7 = w_4 * w_3; + T w_8 = w_4 * w_4; + T w_9 = w_5 * w_4; + T w_10 = w_5 * w_5; + T d = eta0 - mu; + T d_2 = d * d; + T d_3 = d_2 * d; + T d_4 = d_2 * d_2; + T w1 = w + 1; + T w1_2 = w1 * w1; + T w1_3 = w1 * w1_2; + T w1_4 = w1_2 * w1_2; + // + // Now we need to compute the perturbation error terms that + // convert eta0 to eta, these are all polynomials of polynomials. + // Probably these should be re-written to use tabulated data + // (see examples above), but it's less of a win in this case as we + // need to calculate the individual powers for the denominator terms + // anyway, so we might as well use them for the numerator-polynomials + // as well.... + // + // Refer to p154-p155 for the details of these expansions: + // + T e1 = (w + 2) * (w - 1) / (3 * w); + e1 += (w_3 + 9 * w_2 + 21 * w + 5) * d / (36 * w_2 * w1); + e1 -= (w_4 - 13 * w_3 + 69 * w_2 + 167 * w + 46) * d_2 / (1620 * w1_2 * w_3); + e1 -= (7 * w_5 + 21 * w_4 + 70 * w_3 + 26 * w_2 - 93 * w - 31) * d_3 / (6480 * w1_3 * w_4); + e1 -= (75 * w_6 + 202 * w_5 + 188 * w_4 - 888 * w_3 - 1345 * w_2 + 118 * w + 138) * d_4 / (272160 * w1_4 * w_5); + + T e2 = (28 * w_4 + 131 * w_3 + 402 * w_2 + 581 * w + 208) * (w - 1) / (1620 * w1 * w_3); + e2 -= (35 * w_6 - 154 * w_5 - 623 * w_4 - 1636 * w_3 - 3983 * w_2 - 3514 * w - 925) * d / (12960 * w1_2 * w_4); + e2 -= (2132 * w_7 + 7915 * w_6 + 16821 * w_5 + 35066 * w_4 + 87490 * w_3 + 141183 * w_2 + 95993 * w + 21640) * d_2 / (816480 * w_5 * w1_3); + e2 -= (11053 * w_8 + 53308 * w_7 + 117010 * w_6 + 163924 * w_5 + 116188 * w_4 - 258428 * w_3 - 677042 * w_2 - 481940 * w - 105497) * d_3 / (14696640 * w1_4 * w_6); + + T e3 = -((3592 * w_7 + 8375 * w_6 - 1323 * w_5 - 29198 * w_4 - 89578 * w_3 - 154413 * w_2 - 116063 * w - 29632) * (w - 1)) / (816480 * w_5 * w1_2); + e3 -= (442043 * w_9 + 2054169 * w_8 + 3803094 * w_7 + 3470754 * w_6 + 2141568 * w_5 - 2393568 * w_4 - 19904934 * w_3 - 34714674 * w_2 - 23128299 * w - 5253353) * d / (146966400 * w_6 * w1_3); + e3 -= (116932 * w_10 + 819281 * w_9 + 2378172 * w_8 + 4341330 * w_7 + 6806004 * w_6 + 10622748 * w_5 + 18739500 * w_4 + 30651894 * w_3 + 30869976 * w_2 + 15431867 * w + 2919016) * d_2 / (146966400 * w1_4 * w_7); + // + // Combine eta0 and the error terms to compute eta (Second equation p155): + // + T eta = eta0 + e1 / a + e2 / (a * a) + e3 / (a * a * a); + // + // Now we need to solve Eq 4.2 to obtain x. For any given value of + // eta there are two solutions to this equation, and since the distribution + // may be very skewed, these are not related by x ~ 1-x we used when + // implementing section 3 above. However we know that: + // + // cross < x <= 1 ; iff eta < mu + // x == cross ; iff eta == mu + // 0 <= x < cross ; iff eta > mu + // + // Where cross == 1 / (1 + mu) + // Many thanks to Prof Temme for clarifying this point. + // + // Therefore we'll just jump straight into Newton iterations + // to solve Eq 4.2 using these bounds, and simple bisection + // as the first guess, in practice this converges pretty quickly + // and we only need a few digits correct anyway: + // + if(eta <= 0) + eta = tools::min_value(); + T u = eta - mu * log(eta) + (1 + mu) * log(1 + mu) - mu; + T cross = 1 / (1 + mu); + T lower = eta < mu ? cross : 0; + T upper = eta < mu ? 1 : cross; + T x = (lower + upper) / 2; + x = tools::newton_raphson_iterate( + temme_root_finder(u, mu), x, lower, upper, policies::digits() / 2); +#ifdef BOOST_INSTRUMENT + std::cout << "Estimating x with Temme method 3: " << x << std::endl; +#endif + return x; +} + +template +struct ibeta_roots +{ + ibeta_roots(T _a, T _b, T t, bool inv = false) + : a(_a), b(_b), target(t), invert(inv) {} + + boost::math::tuple operator()(T x) + { + BOOST_MATH_STD_USING // ADL of std names + + BOOST_FPU_EXCEPTION_GUARD + + T f1; + T y = 1 - x; + T f = ibeta_imp(a, b, x, Policy(), invert, true, &f1) - target; + if(invert) + f1 = -f1; + if(y == 0) + y = tools::min_value() * 64; + if(x == 0) + x = tools::min_value() * 64; + + T f2 = f1 * (-y * a + (b - 2) * x + 1); + if(fabs(f2) < y * x * tools::max_value()) + f2 /= (y * x); + if(invert) + f2 = -f2; + + // make sure we don't have a zero derivative: + if(f1 == 0) + f1 = (invert ? -1 : 1) * tools::min_value() * 64; + + return boost::math::make_tuple(f, f1, f2); + } +private: + T a, b, target; + bool invert; +}; + +template +T ibeta_inv_imp(T a, T b, T p, T q, const Policy& pol, T* py) +{ + BOOST_MATH_STD_USING // For ADL of math functions. + + // + // The flag invert is set to true if we swap a for b and p for q, + // in which case the result has to be subtracted from 1: + // + bool invert = false; + // + // Handle trivial cases first: + // + if(q == 0) + { + if(py) *py = 0; + return 1; + } + else if(p == 0) + { + if(py) *py = 1; + return 0; + } + else if(a == 1) + { + if(b == 1) + { + if(py) *py = 1 - p; + return p; + } + // Change things around so we can handle as b == 1 special case below: + std::swap(a, b); + std::swap(p, q); + invert = true; + } + // + // Depending upon which approximation method we use, we may end up + // calculating either x or y initially (where y = 1-x): + // + T x = 0; // Set to a safe zero to avoid a + // MSVC 2005 warning C4701: potentially uninitialized local variable 'x' used + // But code inspection appears to ensure that x IS assigned whatever the code path. + T y; + + // For some of the methods we can put tighter bounds + // on the result than simply [0,1]: + // + T lower = 0; + T upper = 1; + // + // Student's T with b = 0.5 gets handled as a special case, swap + // around if the arguments are in the "wrong" order: + // + if(a == 0.5f) + { + if(b == 0.5f) + { + x = sin(p * constants::half_pi()); + x *= x; + if(py) + { + *py = sin(q * constants::half_pi()); + *py *= *py; + } + return x; + } + else if(b > 0.5f) + { + std::swap(a, b); + std::swap(p, q); + invert = !invert; + } + } + // + // Select calculation method for the initial estimate: + // + if((b == 0.5f) && (a >= 0.5f) && (p != 1)) + { + // + // We have a Student's T distribution: + x = find_ibeta_inv_from_t_dist(a, p, q, &y, pol); + } + else if(b == 1) + { + if(p < q) + { + if(a > 1) + { + x = pow(p, 1 / a); + y = -boost::math::expm1(log(p) / a, pol); + } + else + { + x = pow(p, 1 / a); + y = 1 - x; + } + } + else + { + x = exp(boost::math::log1p(-q, pol) / a); + y = -boost::math::expm1(boost::math::log1p(-q, pol) / a, pol); + } + if(invert) + std::swap(x, y); + if(py) + *py = y; + return x; + } + else if(a + b > 5) + { + // + // When a+b is large then we can use one of Prof Temme's + // asymptotic expansions, begin by swapping things around + // so that p < 0.5, we do this to avoid cancellations errors + // when p is large. + // + if(p > 0.5) + { + std::swap(a, b); + std::swap(p, q); + invert = !invert; + } + T minv = (std::min)(a, b); + T maxv = (std::max)(a, b); + if((sqrt(minv) > (maxv - minv)) && (minv > 5)) + { + // + // When a and b differ by a small amount + // the curve is quite symmetrical and we can use an error + // function to approximate the inverse. This is the cheapest + // of the three Temme expansions, and the calculated value + // for x will never be much larger than p, so we don't have + // to worry about cancellation as long as p is small. + // + x = temme_method_1_ibeta_inverse(a, b, p, pol); + y = 1 - x; + } + else + { + T r = a + b; + T theta = asin(sqrt(a / r)); + T lambda = minv / r; + if((lambda >= 0.2) && (lambda <= 0.8) && (r >= 10)) + { + // + // The second error function case is the next cheapest + // to use, it brakes down when the result is likely to be + // very small, if a+b is also small, but we can use a + // cheaper expansion there in any case. As before x won't + // be much larger than p, so as long as p is small we should + // be free of cancellation error. + // + T ppa = pow(p, 1/a); + if((ppa < 0.0025) && (a + b < 200)) + { + x = ppa * pow(a * boost::math::beta(a, b, pol), 1/a); + } + else + x = temme_method_2_ibeta_inverse(a, b, p, r, theta, pol); + y = 1 - x; + } + else + { + // + // If we get here then a and b are very different in magnitude + // and we need to use the third of Temme's methods which + // involves inverting the incomplete gamma. This is much more + // expensive than the other methods. We also can only use this + // method when a > b, which can lead to cancellation errors + // if we really want y (as we will when x is close to 1), so + // a different expansion is used in that case. + // + if(a < b) + { + std::swap(a, b); + std::swap(p, q); + invert = !invert; + } + // + // Try and compute the easy way first: + // + T bet = 0; + if(b < 2) + bet = boost::math::beta(a, b, pol); + if(bet != 0) + { + y = pow(b * q * bet, 1/b); + x = 1 - y; + } + else + y = 1; + if(y > 1e-5) + { + x = temme_method_3_ibeta_inverse(a, b, p, q, pol); + y = 1 - x; + } + } + } + } + else if((a < 1) && (b < 1)) + { + // + // Both a and b less than 1, + // there is a point of inflection at xs: + // + T xs = (1 - a) / (2 - a - b); + // + // Now we need to ensure that we start our iteration from the + // right side of the inflection point: + // + T fs = boost::math::ibeta(a, b, xs, pol) - p; + if(fabs(fs) / p < tools::epsilon() * 3) + { + // The result is at the point of inflection, best just return it: + *py = invert ? xs : 1 - xs; + return invert ? 1-xs : xs; + } + if(fs < 0) + { + std::swap(a, b); + std::swap(p, q); + invert = !invert; + xs = 1 - xs; + } + if (a < tools::min_value()) + { + if (py) + { + *py = invert ? 0 : 1; + } + return invert ? 1 : 0; // nothing interesting going on here. + } + // + // The call to beta may overflow, plus the alternative using lgamma may do the same + // if T is a type where 1/T is infinite for small values (denorms for example). + // + T bet = 0; + T xg; + bool overflow = false; +#ifndef BOOST_NO_EXCEPTIONS + try { +#endif + bet = boost::math::beta(a, b, pol); +#ifndef BOOST_NO_EXCEPTIONS + } + catch (const std::runtime_error&) + { + overflow = true; + } +#endif + if (overflow || !(boost::math::isfinite)(bet)) + { + xg = exp((boost::math::lgamma(a + 1, pol) + boost::math::lgamma(b, pol) - boost::math::lgamma(a + b, pol) + log(p)) / a); + } + else + xg = pow(a * p * bet, 1/a); + x = xg / (1 + xg); + y = 1 / (1 + xg); + // + // And finally we know that our result is below the inflection + // point, so set an upper limit on our search: + // + if(x > xs) + x = xs; + upper = xs; + } + else if((a > 1) && (b > 1)) + { + // + // Small a and b, both greater than 1, + // there is a point of inflection at xs, + // and it's complement is xs2, we must always + // start our iteration from the right side of the + // point of inflection. + // + T xs = (a - 1) / (a + b - 2); + T xs2 = (b - 1) / (a + b - 2); + T ps = boost::math::ibeta(a, b, xs, pol) - p; + + if(ps < 0) + { + std::swap(a, b); + std::swap(p, q); + std::swap(xs, xs2); + invert = !invert; + } + // + // Estimate x and y, using expm1 to get a good estimate + // for y when it's very small: + // + T lx = log(p * a * boost::math::beta(a, b, pol)) / a; + x = exp(lx); + y = x < 0.9 ? T(1 - x) : (T)(-boost::math::expm1(lx, pol)); + + if((b < a) && (x < 0.2)) + { + // + // Under a limited range of circumstances we can improve + // our estimate for x, frankly it's clear if this has much effect! + // + T ap1 = a - 1; + T bm1 = b - 1; + T a_2 = a * a; + T a_3 = a * a_2; + T b_2 = b * b; + T terms[5] = { 0, 1 }; + terms[2] = bm1 / ap1; + ap1 *= ap1; + terms[3] = bm1 * (3 * a * b + 5 * b + a_2 - a - 4) / (2 * (a + 2) * ap1); + ap1 *= (a + 1); + terms[4] = bm1 * (33 * a * b_2 + 31 * b_2 + 8 * a_2 * b_2 - 30 * a * b - 47 * b + 11 * a_2 * b + 6 * a_3 * b + 18 + 4 * a - a_3 + a_2 * a_2 - 10 * a_2) + / (3 * (a + 3) * (a + 2) * ap1); + x = tools::evaluate_polynomial(terms, x, 5); + } + // + // And finally we know that our result is below the inflection + // point, so set an upper limit on our search: + // + if(x > xs) + x = xs; + upper = xs; + } + else /*if((a <= 1) != (b <= 1))*/ + { + // + // If all else fails we get here, only one of a and b + // is above 1, and a+b is small. Start by swapping + // things around so that we have a concave curve with b > a + // and no points of inflection in [0,1]. As long as we expect + // x to be small then we can use the simple (and cheap) power + // term to estimate x, but when we expect x to be large then + // this greatly underestimates x and leaves us trying to + // iterate "round the corner" which may take almost forever... + // + // We could use Temme's inverse gamma function case in that case, + // this works really rather well (albeit expensively) even though + // strictly speaking we're outside it's defined range. + // + // However it's expensive to compute, and an alternative approach + // which models the curve as a distorted quarter circle is much + // cheaper to compute, and still keeps the number of iterations + // required down to a reasonable level. With thanks to Prof Temme + // for this suggestion. + // + if(b < a) + { + std::swap(a, b); + std::swap(p, q); + invert = !invert; + } + if(pow(p, 1/a) < 0.5) + { + x = pow(p * a * boost::math::beta(a, b, pol), 1 / a); + if(x == 0) + x = boost::math::tools::min_value(); + y = 1 - x; + } + else /*if(pow(q, 1/b) < 0.1)*/ + { + // model a distorted quarter circle: + y = pow(1 - pow(p, b * boost::math::beta(a, b, pol)), 1/b); + if(y == 0) + y = boost::math::tools::min_value(); + x = 1 - y; + } + } + + // + // Now we have a guess for x (and for y) we can set things up for + // iteration. If x > 0.5 it pays to swap things round: + // + if(x > 0.5) + { + std::swap(a, b); + std::swap(p, q); + std::swap(x, y); + invert = !invert; + T l = 1 - upper; + T u = 1 - lower; + lower = l; + upper = u; + } + // + // lower bound for our search: + // + // We're not interested in denormalised answers as these tend to + // these tend to take up lots of iterations, given that we can't get + // accurate derivatives in this area (they tend to be infinite). + // + if(lower == 0) + { + if(invert && (py == 0)) + { + // + // We're not interested in answers smaller than machine epsilon: + // + lower = boost::math::tools::epsilon(); + if(x < lower) + x = lower; + } + else + lower = boost::math::tools::min_value(); + if(x < lower) + x = lower; + } + // + // Figure out how many digits to iterate towards: + // + int digits = boost::math::policies::digits() / 2; + if((x < 1e-50) && ((a < 1) || (b < 1))) + { + // + // If we're in a region where the first derivative is very + // large, then we have to take care that the root-finder + // doesn't terminate prematurely. We'll bump the precision + // up to avoid this, but we have to take care not to set the + // precision too high or the last few iterations will just + // thrash around and convergence may be slow in this case. + // Try 3/4 of machine epsilon: + // + digits *= 3; + digits /= 2; + } + // + // Now iterate, we can use either p or q as the target here + // depending on which is smaller: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + x = boost::math::tools::halley_iterate( + boost::math::detail::ibeta_roots(a, b, (p < q ? p : q), (p < q ? false : true)), x, lower, upper, digits, max_iter); + policies::check_root_iterations("boost::math::ibeta<%1%>(%1%, %1%, %1%)", max_iter, pol); + // + // We don't really want these asserts here, but they are useful for sanity + // checking that we have the limits right, uncomment if you suspect bugs *only*. + // + //BOOST_MATH_ASSERT(x != upper); + //BOOST_MATH_ASSERT((x != lower) || (x == boost::math::tools::min_value()) || (x == boost::math::tools::epsilon())); + // + // Tidy up, if we "lower" was too high then zero is the best answer we have: + // + if(x == lower) + x = 0; + if(py) + *py = invert ? x : 1 - x; + return invert ? 1-x : x; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol) +{ + static const char* function = "boost::math::ibeta_inv<%1%>(%1%,%1%,%1%)"; + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol); + if((p < 0) || (p > 1)) + return policies::raise_domain_error(function, "Argument p outside the range [0,1] in the incomplete beta function inverse (got p=%1%).", p, pol); + + value_type rx, ry; + + rx = detail::ibeta_inv_imp( + static_cast(a), + static_cast(b), + static_cast(p), + static_cast(1 - p), + forwarding_policy(), &ry); + + if(py) *py = policies::checked_narrowing_cast(ry, function); + return policies::checked_narrowing_cast(rx, function); +} + +template +inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py) +{ + return ibeta_inv(a, b, p, py, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p) +{ + typedef typename tools::promote_args::type result_type; + return ibeta_inv(a, b, p, static_cast(nullptr), policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return ibeta_inv(a, b, p, static_cast(nullptr), pol); +} + +template +inline typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol) +{ + static const char* function = "boost::math::ibetac_inv<%1%>(%1%,%1%,%1%)"; + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + if(a <= 0) + return policies::raise_domain_error(function, "The argument a to the incomplete beta function inverse must be greater than zero (got a=%1%).", a, pol); + if(b <= 0) + return policies::raise_domain_error(function, "The argument b to the incomplete beta function inverse must be greater than zero (got b=%1%).", b, pol); + if((q < 0) || (q > 1)) + return policies::raise_domain_error(function, "Argument q outside the range [0,1] in the incomplete beta function inverse (got q=%1%).", q, pol); + + value_type rx, ry; + + rx = detail::ibeta_inv_imp( + static_cast(a), + static_cast(b), + static_cast(1 - q), + static_cast(q), + forwarding_policy(), &ry); + + if(py) *py = policies::checked_narrowing_cast(ry, function); + return policies::checked_narrowing_cast(rx, function); +} + +template +inline typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py) +{ + return ibetac_inv(a, b, q, py, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q) +{ + typedef typename tools::promote_args::type result_type; + return ibetac_inv(a, b, q, static_cast(nullptr), policies::policy<>()); +} + +template +inline typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return ibetac_inv(a, b, q, static_cast(nullptr), pol); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/iconv.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/iconv.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/iconv.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2009 John Maddock +// 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_ICONV_HPP +#define BOOST_MATH_ICONV_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost { namespace math { namespace detail{ + +template +inline int iconv_imp(T v, Policy const&, std::true_type const&) +{ + return static_cast(v); +} + +template +inline int iconv_imp(T v, Policy const& pol, std::false_type const&) +{ + BOOST_MATH_STD_USING + return iround(v, pol); +} + +template +inline int iconv(T v, Policy const& pol) +{ + typedef typename std::is_convertible::type tag_type; + return iconv_imp(v, pol, tag_type()); +} + + +}}} // namespaces + +#endif // BOOST_MATH_ICONV_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/igamma_inverse.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/igamma_inverse.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/igamma_inverse.hpp @@ -0,0 +1,560 @@ +// (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_IGAMMA_INVERSE_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +T find_inverse_s(T p, T q) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 32. + // + BOOST_MATH_STD_USING + T t; + if(p < 0.5) + { + t = sqrt(-2 * log(p)); + } + else + { + t = sqrt(-2 * log(q)); + } + static const double a[4] = { 3.31125922108741, 11.6616720288968, 4.28342155967104, 0.213623493715853 }; + static const double b[5] = { 1, 6.61053765625462, 6.40691597760039, 1.27364489782223, 0.3611708101884203e-1 }; + T s = t - tools::evaluate_polynomial(a, t) / tools::evaluate_polynomial(b, t); + if(p < 0.5) + s = -s; + return s; +} + +template +T didonato_SN(T a, T x, unsigned N, T tolerance = 0) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 34. + // + T sum = 1; + if(N >= 1) + { + T partial = x / (a + 1); + sum += partial; + for(unsigned i = 2; i <= N; ++i) + { + partial *= x / (a + i); + sum += partial; + if(partial < tolerance) + break; + } + } + return sum; +} + +template +inline T didonato_FN(T p, T a, T x, unsigned N, T tolerance, const Policy& pol) +{ + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + // See equation 34. + // + BOOST_MATH_STD_USING + T u = log(p) + boost::math::lgamma(a + 1, pol); + return exp((u + x - log(didonato_SN(a, x, N, tolerance))) / a); +} + +template +T find_inverse_gamma(T a, T p, T q, const Policy& pol, bool* p_has_10_digits) +{ + // + // In order to understand what's going on here, you will + // need to refer to: + // + // Computation of the Incomplete Gamma Function Ratios and their Inverse + // ARMIDO R. DIDONATO and ALFRED H. MORRIS, JR. + // ACM Transactions on Mathematical Software, Vol. 12, No. 4, + // December 1986, Pages 377-393. + // + BOOST_MATH_STD_USING + + T result; + *p_has_10_digits = false; + + if(a == 1) + { + result = -log(q); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(a < 1) + { + T g = boost::math::tgamma(a, pol); + T b = q * g; + BOOST_MATH_INSTRUMENT_VARIABLE(g); + BOOST_MATH_INSTRUMENT_VARIABLE(b); + if((b > 0.6) || ((b >= 0.45) && (a >= 0.3))) + { + // DiDonato & Morris Eq 21: + // + // There is a slight variation from DiDonato and Morris here: + // the first form given here is unstable when p is close to 1, + // making it impossible to compute the inverse of Q(a,x) for small + // q. Fortunately the second form works perfectly well in this case. + // + T u; + if((b * q > 1e-8) && (q > 1e-5)) + { + u = pow(p * g * a, 1 / a); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + } + else + { + u = exp((-q / a) - constants::euler()); + BOOST_MATH_INSTRUMENT_VARIABLE(u); + } + result = u / (1 - (u / (a + 1))); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if((a < 0.3) && (b >= 0.35)) + { + // DiDonato & Morris Eq 22: + T t = exp(-constants::euler() - b); + T u = t * exp(t); + result = t * exp(u); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if((b > 0.15) || (a >= 0.3)) + { + // DiDonato & Morris Eq 23: + T y = -log(b); + T u = y - (1 - a) * log(y); + result = y - (1 - a) * log(u) - log(1 + (1 - a) / (1 + u)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (b > 0.1) + { + // DiDonato & Morris Eq 24: + T y = -log(b); + T u = y - (1 - a) * log(y); + result = y - (1 - a) * log(u) - log((u * u + 2 * (3 - a) * u + (2 - a) * (3 - a)) / (u * u + (5 - a) * u + 2)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato & Morris Eq 25: + T y = -log(b); + T c1 = (a - 1) * log(y); + T c1_2 = c1 * c1; + T c1_3 = c1_2 * c1; + T c1_4 = c1_2 * c1_2; + T a_2 = a * a; + T a_3 = a_2 * a; + + T c2 = (a - 1) * (1 + c1); + T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2); + T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6); + T c5 = (a - 1) * (-(c1_4 / 4) + + (11 * a - 17) * c1_3 / 6 + + (-3 * a_2 + 13 * a -13) * c1_2 + + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2 + + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12); + + T y_2 = y * y; + T y_3 = y_2 * y; + T y_4 = y_2 * y_2; + result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(b < 1e-28f) + *p_has_10_digits = true; + } + } + else + { + // DiDonato and Morris Eq 31: + T s = find_inverse_s(p, q); + + BOOST_MATH_INSTRUMENT_VARIABLE(s); + + T s_2 = s * s; + T s_3 = s_2 * s; + T s_4 = s_2 * s_2; + T s_5 = s_4 * s; + T ra = sqrt(a); + + BOOST_MATH_INSTRUMENT_VARIABLE(ra); + + T w = a + s * ra + (s * s -1) / 3; + w += (s_3 - 7 * s) / (36 * ra); + w -= (3 * s_4 + 7 * s_2 - 16) / (810 * a); + w += (9 * s_5 + 256 * s_3 - 433 * s) / (38880 * a * ra); + + BOOST_MATH_INSTRUMENT_VARIABLE(w); + + if((a >= 500) && (fabs(1 - w / a) < 1e-6)) + { + result = w; + *p_has_10_digits = true; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (p > 0.5) + { + if(w < 3 * a) + { + result = w; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + T D = (std::max)(T(2), T(a * (a - 1))); + T lg = boost::math::lgamma(a, pol); + T lb = log(q) + lg; + if(lb < -D * 2.3) + { + // DiDonato and Morris Eq 25: + T y = -lb; + T c1 = (a - 1) * log(y); + T c1_2 = c1 * c1; + T c1_3 = c1_2 * c1; + T c1_4 = c1_2 * c1_2; + T a_2 = a * a; + T a_3 = a_2 * a; + + T c2 = (a - 1) * (1 + c1); + T c3 = (a - 1) * (-(c1_2 / 2) + (a - 2) * c1 + (3 * a - 5) / 2); + T c4 = (a - 1) * ((c1_3 / 3) - (3 * a - 5) * c1_2 / 2 + (a_2 - 6 * a + 7) * c1 + (11 * a_2 - 46 * a + 47) / 6); + T c5 = (a - 1) * (-(c1_4 / 4) + + (11 * a - 17) * c1_3 / 6 + + (-3 * a_2 + 13 * a -13) * c1_2 + + (2 * a_3 - 25 * a_2 + 72 * a - 61) * c1 / 2 + + (25 * a_3 - 195 * a_2 + 477 * a - 379) / 12); + + T y_2 = y * y; + T y_3 = y_2 * y; + T y_4 = y_2 * y_2; + result = y + c1 + (c2 / y) + (c3 / y_2) + (c4 / y_3) + (c5 / y_4); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato and Morris Eq 33: + T u = -lb + (a - 1) * log(w) - log(1 + (1 - a) / (1 + w)); + result = -lb + (a - 1) * log(u) - log(1 + (1 - a) / (1 + u)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + else + { + T z = w; + T ap1 = a + 1; + T ap2 = a + 2; + if(w < 0.15f * ap1) + { + // DiDonato and Morris Eq 35: + T v = log(p) + boost::math::lgamma(ap1, pol); + z = exp((v + w) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol); + z = exp((v + z - s) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2), pol); + z = exp((v + z - s) / a); + s = boost::math::log1p(z / ap1 * (1 + z / ap2 * (1 + z / (a + 3))), pol); + z = exp((v + z - s) / a); + BOOST_MATH_INSTRUMENT_VARIABLE(z); + } + + if((z <= 0.01 * ap1) || (z > 0.7 * ap1)) + { + result = z; + if(z <= 0.002 * ap1) + *p_has_10_digits = true; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // DiDonato and Morris Eq 36: + T ls = log(didonato_SN(a, z, 100, T(1e-4))); + T v = log(p) + boost::math::lgamma(ap1, pol); + z = exp((v + z - ls) / a); + result = z * (1 - (a * log(z) - z - v + ls) / (a - z)); + + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + } + return result; +} + +template +struct gamma_p_inverse_func +{ + gamma_p_inverse_func(T a_, T p_, bool inv) : a(a_), p(p_), invert(inv) + { + // + // If p is too near 1 then P(x) - p suffers from cancellation + // errors causing our root-finding algorithms to "thrash", better + // to invert in this case and calculate Q(x) - (1-p) instead. + // + // Of course if p is *very* close to 1, then the answer we get will + // be inaccurate anyway (because there's not enough information in p) + // but at least we will converge on the (inaccurate) answer quickly. + // + if(p > 0.9) + { + p = 1 - p; + invert = !invert; + } + } + + boost::math::tuple operator()(const T& x)const + { + BOOST_FPU_EXCEPTION_GUARD + // + // Calculate P(x) - p and the first two derivates, or if the invert + // flag is set, then Q(x) - q and it's derivatives. + // + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING // For ADL of std functions. + + T f, f1; + value_type ft; + f = static_cast(boost::math::detail::gamma_incomplete_imp( + static_cast(a), + static_cast(x), + true, invert, + forwarding_policy(), &ft)); + f1 = static_cast(ft); + T f2; + T div = (a - x - 1) / x; + f2 = f1; + if(fabs(div) > 1) + { + // split if statement to address M1 mac clang bug; + // see issue 826 + if (tools::max_value() / fabs(div) < f2) + { + // overflow: + f2 = -tools::max_value() / 2; + } + else + { + f2 *= div; + } + } + else + { + f2 *= div; + } + + if(invert) + { + f1 = -f1; + f2 = -f2; + } + + return boost::math::make_tuple(static_cast(f - p), f1, f2); + } +private: + T a, p; + bool invert; +}; + +template +T gamma_p_inv_imp(T a, T p, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions. + + static const char* function = "boost::math::gamma_p_inv<%1%>(%1%, %1%)"; + + BOOST_MATH_INSTRUMENT_VARIABLE(a); + BOOST_MATH_INSTRUMENT_VARIABLE(p); + + if(a <= 0) + return policies::raise_domain_error(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol); + if((p < 0) || (p > 1)) + return policies::raise_domain_error(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got p=%1%).", p, pol); + if(p == 1) + return policies::raise_overflow_error(function, nullptr, Policy()); + if(p == 0) + return 0; + bool has_10_digits; + T guess = detail::find_inverse_gamma(a, p, 1 - p, pol, &has_10_digits); + if((policies::digits() <= 36) && has_10_digits) + return guess; + T lower = tools::min_value(); + if(guess <= lower) + guess = tools::min_value(); + BOOST_MATH_INSTRUMENT_VARIABLE(guess); + // + // Work out how many digits to converge to, normally this is + // 2/3 of the digits in T, but if the first derivative is very + // large convergence is slow, so we'll bump it up to full + // precision to prevent premature termination of the root-finding routine. + // + unsigned digits = policies::digits(); + if(digits < 30) + { + digits *= 2; + digits /= 3; + } + else + { + digits /= 2; + digits -= 1; + } + if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) + digits = policies::digits() - 2; + // + // Go ahead and iterate: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + guess = tools::halley_iterate( + detail::gamma_p_inverse_func(a, p, false), + guess, + lower, + tools::max_value(), + digits, + max_iter); + policies::check_root_iterations(function, max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(guess); + if(guess == lower) + guess = policies::raise_underflow_error(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol); + return guess; +} + +template +T gamma_q_inv_imp(T a, T q, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions. + + static const char* function = "boost::math::gamma_q_inv<%1%>(%1%, %1%)"; + + if(a <= 0) + return policies::raise_domain_error(function, "Argument a in the incomplete gamma function inverse must be >= 0 (got a=%1%).", a, pol); + if((q < 0) || (q > 1)) + return policies::raise_domain_error(function, "Probability must be in the range [0,1] in the incomplete gamma function inverse (got q=%1%).", q, pol); + if(q == 0) + return policies::raise_overflow_error(function, nullptr, Policy()); + if(q == 1) + return 0; + bool has_10_digits; + T guess = detail::find_inverse_gamma(a, 1 - q, q, pol, &has_10_digits); + if((policies::digits() <= 36) && has_10_digits) + return guess; + T lower = tools::min_value(); + if(guess <= lower) + guess = tools::min_value(); + // + // Work out how many digits to converge to, normally this is + // 2/3 of the digits in T, but if the first derivative is very + // large convergence is slow, so we'll bump it up to full + // precision to prevent premature termination of the root-finding routine. + // + unsigned digits = policies::digits(); + if(digits < 30) + { + digits *= 2; + digits /= 3; + } + else + { + digits /= 2; + digits -= 1; + } + if((a < 0.125) && (fabs(gamma_p_derivative(a, guess, pol)) > 1 / sqrt(tools::epsilon()))) + digits = policies::digits(); + // + // Go ahead and iterate: + // + std::uintmax_t max_iter = policies::get_max_root_iterations(); + guess = tools::halley_iterate( + detail::gamma_p_inverse_func(a, q, true), + guess, + lower, + tools::max_value(), + digits, + max_iter); + policies::check_root_iterations(function, max_iter, pol); + if(guess == lower) + guess = policies::raise_underflow_error(function, "Expected result known to be non-zero, but is smaller than the smallest available number.", pol); + return guess; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + gamma_p_inv(T1 a, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::gamma_p_inv_imp( + static_cast(a), + static_cast(p), pol); +} + +template +inline typename tools::promote_args::type + gamma_q_inv(T1 a, T2 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::gamma_q_inv_imp( + static_cast(a), + static_cast(p), pol); +} + +template +inline typename tools::promote_args::type + gamma_p_inv(T1 a, T2 p) +{ + return gamma_p_inv(a, p, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + gamma_q_inv(T1 a, T2 p) +{ + return gamma_q_inv(a, p, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_IGAMMA_INVERSE_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/igamma_large.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/igamma_large.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/igamma_large.hpp @@ -0,0 +1,778 @@ +// 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) +// +// This file implements the asymptotic expansions of the incomplete +// gamma functions P(a, x) and Q(a, x), used when a is large and +// x ~ a. +// +// The primary reference is: +// +// "The Asymptotic Expansion of the Incomplete Gamma Functions" +// N. M. Temme. +// Siam J. Math Anal. Vol 10 No 4, July 1979, p757. +// +// A different way of evaluating these expansions, +// plus a lot of very useful background information is in: +// +// "A Set of Algorithms For the Incomplete Gamma Functions." +// N. M. Temme. +// Probability in the Engineering and Informational Sciences, +// 8, 1994, 291. +// +// An alternative implementation is in: +// +// "Computation of the Incomplete Gamma Function Ratios and their Inverse." +// A. R. Didonato and A. H. Morris. +// ACM TOMS, Vol 12, No 4, Dec 1986, p377. +// +// There are various versions of the same code below, each accurate +// to a different precision. To understand the code, refer to Didonato +// and Morris, from Eq 17 and 18 onwards. +// +// The coefficients used here are not taken from Didonato and Morris: +// the domain over which these expansions are used is slightly different +// to theirs, and their constants are not quite accurate enough for +// 128-bit long double's. Instead the coefficients were calculated +// using the methods described by Temme p762 from Eq 3.8 onwards. +// The values obtained agree with those obtained by Didonato and Morris +// (at least to the first 30 digits that they provide). +// At double precision the degrees of polynomial required for full +// machine precision are close to those recommended to Didonato and Morris, +// but of course many more terms are needed for larger types. +// +#ifndef BOOST_MATH_DETAIL_IGAMMA_LARGE +#define BOOST_MATH_DETAIL_IGAMMA_LARGE + +#ifdef _MSC_VER +#pragma once +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace detail{ + +// This version will never be called (at runtime), it's a stub used +// when T is unsuitable to be passed to these routines: +// +template +inline T igamma_temme_large(T, T, const Policy& /* pol */, std::integral_constant const *) +{ + // stub function, should never actually be called + BOOST_MATH_ASSERT(0); + return 0; +} +// +// This version is accurate for up to 64-bit mantissa's, +// (80-bit long double, or 10^-20). +// +template +T igamma_temme_large(T a, T x, const Policy& pol, std::integral_constant const *) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[13]; + + static const T C0[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0833333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0148148148148148148148), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00115740740740740740741), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000352733686067019400353), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0001787551440329218107), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.39192631785224377817e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.218544851067999216147e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.18540622107151599607e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.829671134095308600502e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.176659527368260793044e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.670785354340149858037e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.102618097842403080426e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.438203601845335318655e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.914769958223679023418e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.255141939949462497669e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.583077213255042506746e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.243619480206674162437e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.502766928011417558909e-11), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + static const T C1[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00185185185185185185185), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00347222222222222222222), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00264550264550264550265), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000990226337448559670782), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000205761316872427983539), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.40187757201646090535e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.18098550334489977837e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.764916091608111008464e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.161209008945634460038e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.464712780280743434226e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.137863344691572095931e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.575254560351770496402e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.119516285997781473243e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.175432417197476476238e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.100915437106004126275e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.416279299184258263623e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.856390702649298063807e-10), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + static const T C2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00413359788359788359788), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00268132716049382716049), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000771604938271604938272), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.200938786008230452675e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000107366532263651605215), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.529234488291201254164e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.127606351886187277134e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.342357873409613807419e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.137219573090629332056e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.629899213838005502291e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142806142060642417916e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.204770984219908660149e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.140925299108675210533e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.622897408492202203356e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.136704883966171134993e-8), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + static const T C3[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000649434156378600823045), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000229472093621399176955), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000469189494395255712128), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000267720632062838852962), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.756180167188397641073e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.239650511386729665193e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.110826541153473023615e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.56749528269915965675e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.142309007324358839146e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.278610802915281422406e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.169584040919302772899e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.809946490538808236335e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.191111684859736540607e-7), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + static const T C4[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000861888290916711698605), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000784039221720066627474), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000299072480303190179733), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.146384525788434181781e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.664149821546512218666e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.396836504717943466443e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.113757269706784190981e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.250749722623753280165e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.169541495365583060147e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.890750753220530968883e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.229293483400080487057e-6), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + static const T C5[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000336798553366358150309), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.697281375836585777429e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277275324495939207873), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000199325705161888477003), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.679778047793720783882e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.141906292064396701483e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.135940481897686932785e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.801847025633420153972e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.229148117650809517038e-5), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + static const T C6[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000531307936463992223166), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000592166437353693882865), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000270878209671804482771), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.790235323266032787212e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.815396936756196875093e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.561168275310624965004e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.183291165828433755673e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.307961345060330478256e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.346515536880360908674e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.20291327396058603727e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.57887928631490037089e-6), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + static const T C7[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000344367606892377671254), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.517179090826059219337e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000334931610811422363117), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000281269515476323702274), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000109765822446847310235), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.127410090954844853795e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.277444515115636441571e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.182634888057113326614e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.578769494973505239894e-5), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + static const T C8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000652623918595309418922), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000839498720672087279993), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000438297098541721005061), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.696909145842055197137e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000166448466420675478374), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000127835176797692185853), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.462995326369130429061e-4), + }; + workspace[8] = tools::evaluate_polynomial(C8, z); + + static const T C9[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000596761290192746250124), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.720489541602001055909e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000678230883766732836162), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0006401475260262758451), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000277501076343287044992), + }; + workspace[9] = tools::evaluate_polynomial(C9, z); + + static const T C10[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00133244544948006563713), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0019144384985654775265), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00110893691345966373396), + }; + workspace[10] = tools::evaluate_polynomial(C10, z); + + static const T C11[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00157972766073083495909), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000162516262783915816899), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00206334210355432762645), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00213896861856890981541), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00101085593912630031708), + }; + workspace[11] = tools::evaluate_polynomial(C11, z); + + static const T C12[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00407251211951401664727), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00640336283380806979482), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00404101610816766177474), + }; + workspace[12] = tools::evaluate_polynomial(C12, z); + + T result = tools::evaluate_polynomial<13, T, T>(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} +// +// This one is accurate for 53-bit mantissa's +// (IEEE double precision or 10^-17). +// +template +T igamma_temme_large(T a, T x, const Policy& pol, std::integral_constant const *) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[10]; + + static const T C0[] = { + static_cast(-0.33333333333333333L), + static_cast(0.083333333333333333L), + static_cast(-0.014814814814814815L), + static_cast(0.0011574074074074074L), + static_cast(0.0003527336860670194L), + static_cast(-0.00017875514403292181L), + static_cast(0.39192631785224378e-4L), + static_cast(-0.21854485106799922e-5L), + static_cast(-0.185406221071516e-5L), + static_cast(0.8296711340953086e-6L), + static_cast(-0.17665952736826079e-6L), + static_cast(0.67078535434014986e-8L), + static_cast(0.10261809784240308e-7L), + static_cast(-0.43820360184533532e-8L), + static_cast(0.91476995822367902e-9L), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + static const T C1[] = { + static_cast(-0.0018518518518518519L), + static_cast(-0.0034722222222222222L), + static_cast(0.0026455026455026455L), + static_cast(-0.00099022633744855967L), + static_cast(0.00020576131687242798L), + static_cast(-0.40187757201646091e-6L), + static_cast(-0.18098550334489978e-4L), + static_cast(0.76491609160811101e-5L), + static_cast(-0.16120900894563446e-5L), + static_cast(0.46471278028074343e-8L), + static_cast(0.1378633446915721e-6L), + static_cast(-0.5752545603517705e-7L), + static_cast(0.11951628599778147e-7L), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + static const T C2[] = { + static_cast(0.0041335978835978836L), + static_cast(-0.0026813271604938272L), + static_cast(0.00077160493827160494L), + static_cast(0.20093878600823045e-5L), + static_cast(-0.00010736653226365161L), + static_cast(0.52923448829120125e-4L), + static_cast(-0.12760635188618728e-4L), + static_cast(0.34235787340961381e-7L), + static_cast(0.13721957309062933e-5L), + static_cast(-0.6298992138380055e-6L), + static_cast(0.14280614206064242e-6L), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + static const T C3[] = { + static_cast(0.00064943415637860082L), + static_cast(0.00022947209362139918L), + static_cast(-0.00046918949439525571L), + static_cast(0.00026772063206283885L), + static_cast(-0.75618016718839764e-4L), + static_cast(-0.23965051138672967e-6L), + static_cast(0.11082654115347302e-4L), + static_cast(-0.56749528269915966e-5L), + static_cast(0.14230900732435884e-5L), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + static const T C4[] = { + static_cast(-0.0008618882909167117L), + static_cast(0.00078403922172006663L), + static_cast(-0.00029907248030319018L), + static_cast(-0.14638452578843418e-5L), + static_cast(0.66414982154651222e-4L), + static_cast(-0.39683650471794347e-4L), + static_cast(0.11375726970678419e-4L), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + static const T C5[] = { + static_cast(-0.00033679855336635815L), + static_cast(-0.69728137583658578e-4L), + static_cast(0.00027727532449593921L), + static_cast(-0.00019932570516188848L), + static_cast(0.67977804779372078e-4L), + static_cast(0.1419062920643967e-6L), + static_cast(-0.13594048189768693e-4L), + static_cast(0.80184702563342015e-5L), + static_cast(-0.22914811765080952e-5L), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + static const T C6[] = { + static_cast(0.00053130793646399222L), + static_cast(-0.00059216643735369388L), + static_cast(0.00027087820967180448L), + static_cast(0.79023532326603279e-6L), + static_cast(-0.81539693675619688e-4L), + static_cast(0.56116827531062497e-4L), + static_cast(-0.18329116582843376e-4L), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + static const T C7[] = { + static_cast(0.00034436760689237767L), + static_cast(0.51717909082605922e-4L), + static_cast(-0.00033493161081142236L), + static_cast(0.0002812695154763237L), + static_cast(-0.00010976582244684731L), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + static const T C8[] = { + static_cast(-0.00065262391859530942L), + static_cast(0.00083949872067208728L), + static_cast(-0.00043829709854172101L), + }; + workspace[8] = tools::evaluate_polynomial(C8, z); + workspace[9] = static_cast(-0.00059676129019274625L); + + T result = tools::evaluate_polynomial<10, T, T>(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} +// +// This one is accurate for 24-bit mantissa's +// (IEEE float precision, or 10^-8) +// +template +T igamma_temme_large(T a, T x, const Policy& pol, std::integral_constant const *) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[3]; + + static const T C0[] = { + static_cast(-0.333333333L), + static_cast(0.0833333333L), + static_cast(-0.0148148148L), + static_cast(0.00115740741L), + static_cast(0.000352733686L), + static_cast(-0.000178755144L), + static_cast(0.391926318e-4L), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + static const T C1[] = { + static_cast(-0.00185185185L), + static_cast(-0.00347222222L), + static_cast(0.00264550265L), + static_cast(-0.000990226337L), + static_cast(0.000205761317L), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + static const T C2[] = { + static_cast(0.00413359788L), + static_cast(-0.00268132716L), + static_cast(0.000771604938L), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + T result = tools::evaluate_polynomial(workspace, 1/a); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} +// +// And finally, a version for 113-bit mantissa's +// (128-bit long doubles, or 10^-34). +// Note this one has been optimised for a > 200 +// It's use for a < 200 is not recommended, that would +// require many more terms in the polynomials. +// +template +T igamma_temme_large(T a, T x, const Policy& pol, std::integral_constant const *) +{ + BOOST_MATH_STD_USING // ADL of std functions + T sigma = (x - a) / a; + T phi = -boost::math::log1pmx(sigma, pol); + T y = a * phi; + T z = sqrt(2 * phi); + if(x < a) + z = -z; + + T workspace[14]; + + static const T C0[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0833333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0148148148148148148148148148148148148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00115740740740740740740740740740740741), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003527336860670194003527336860670194), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000178755144032921810699588477366255144), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.391926317852243778169704095630021556e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.218544851067999216147364295512443661e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.185406221071515996070179883622956325e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.829671134095308600501624213166443227e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.17665952736826079304360054245742403e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.670785354340149858036939710029613572e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.102618097842403080425739573227252951e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.438203601845335318655297462244719123e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.914769958223679023418248817633113681e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.255141939949462497668779537993887013e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.583077213255042506746408945040035798e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.243619480206674162436940696707789943e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.502766928011417558909054985925744366e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110043920319561347708374174497293411e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.337176326240098537882769884169200185e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.13923887224181620659193661848957998e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.285348938070474432039669099052828299e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.513911183424257261899064580300494205e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.197522882943494428353962401580710912e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.809952115670456133407115668702575255e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.165225312163981618191514820265351162e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.253054300974788842327061090060267385e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.116869397385595765888230876507793475e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.477003704982048475822167804084816597e-17), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.969912605905623712420709685898585354e-18), + }; + workspace[0] = tools::evaluate_polynomial(C0, z); + + static const T C1[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00185185185185185185185185185185185185), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00347222222222222222222222222222222222), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026455026455026455026455026455026455), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000990226337448559670781893004115226337), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000205761316872427983539094650205761317), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.401877572016460905349794238683127572e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.180985503344899778370285914867533523e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.76491609160811100846374214980916921e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16120900894563446003775221882217767e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.464712780280743434226135033938722401e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137863344691572095931187533077488877e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.575254560351770496402194531835048307e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119516285997781473243076536699698169e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.175432417197476476237547551202312502e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.100915437106004126274577504686681675e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.416279299184258263623372347219858628e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.856390702649298063807431562579670208e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.606721510160475861512701762169919581e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.716249896481148539007961017165545733e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.293318664377143711740636683615595403e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.599669636568368872330374527568788909e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.216717865273233141017100472779701734e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.497833997236926164052815522048108548e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.202916288237134247736694804325894226e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.413125571381061004935108332558187111e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.828651623988309644380188591057589316e-18), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.341003088693333279336339355910600992e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.138541953028939715357034547426313703e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.281234665322887466568860332727259483e-16), + }; + workspace[1] = tools::evaluate_polynomial(C1, z); + + static const T C2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0041335978835978835978835978835978836), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00268132716049382716049382716049382716), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000771604938271604938271604938271604938), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.200938786008230452674897119341563786e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107366532263651605215391223621676297), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.529234488291201254164217127180090143e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.127606351886187277133779191392360117e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.34235787340961380741902003904747389e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137219573090629332055943852926020279e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.629899213838005502290672234278391876e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.142806142060642417915846008822771748e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.204770984219908660149195854409200226e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.140925299108675210532930244154315272e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.622897408492202203356394293530327112e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.136704883966171134992724380284402402e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.942835615901467819547711211663208075e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.128722524000893180595479368872770442e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.556459561343633211465414765894951439e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119759355463669810035898150310311343e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.416897822518386350403836626692480096e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.109406404278845944099299008640802908e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.4662239946390135746326204922464679e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.990510576390690597844122258212382301e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.189318767683735145056885183170630169e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.885922187259112726176031067028740667e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.373782039804640545306560251777191937e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.786883363903515525774088394065960751e-15), + }; + workspace[2] = tools::evaluate_polynomial(C2, z); + + static const T C3[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000649434156378600823045267489711934156), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000229472093621399176954732510288065844), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000469189494395255712128140111679206329), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000267720632062838852962309752433209223), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.756180167188397641072538191879755666e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.239650511386729665193314027333231723e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110826541153473023614770299726861227e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.567495282699159656749963105701560205e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14230900732435883914551894470580433e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.278610802915281422405802158211174452e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16958404091930277289864168795820267e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.809946490538808236335278504852724081e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.191111684859736540606728140872727635e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.239286204398081179686413514022282056e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.206201318154887984369925818486654549e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.946049666185513217375417988510192814e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.215410497757749078380130268468744512e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.138882333681390304603424682490735291e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.218947616819639394064123400466489455e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.979099895117168512568262802255883368e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.217821918801809621153859472011393244e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.62088195734079014258166361684972205e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.212697836327973697696702537114614471e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.934468879151743333127396765626749473e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.204536712267828493249215913063207436e-13), + }; + workspace[3] = tools::evaluate_polynomial(C3, z); + + static const T C4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000861888290916711698604702719929057378), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00078403922172006662747403488144228885), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000299072480303190179733389609932819809), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.146384525788434181781232535690697556e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.664149821546512218665853782451862013e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.396836504717943466443123507595386882e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113757269706784190980552042885831759e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.250749722623753280165221942390057007e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169541495365583060147164356781525752e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.890750753220530968882898422505515924e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.229293483400080487057216364891158518e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.295679413754404904696572852500004588e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.288658297427087836297341274604184504e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.141897394378032193894774303903982717e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.344635804994648970659527720474194356e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.230245171745280671320192735850147087e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.394092330280464052750697640085291799e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.186023389685045019134258533045185639e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.435632300505661804380678327446262424e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.127860010162962312660550463349930726e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.467927502665791946200382739991760062e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.214924647061348285410535341910721086e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.490881561480965216323649688463984082e-12), + }; + workspace[4] = tools::evaluate_polynomial(C4, z); + + static const T C5[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000336798553366358150308767592718210002), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.697281375836585777429398828575783308e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00027727532449593920787336425196507501), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000199325705161888477003360405280844238), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.679778047793720783881640176604435742e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.141906292064396701483392727105575757e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.135940481897686932784583938837504469e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.80184702563342015397192571980419684e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.229148117650809517038048790128781806e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.325247355129845395166230137750005047e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.346528464910852649559195496827579815e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.184471871911713432765322367374920978e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.482409670378941807563762631738989002e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.179894667217435153025754291716644314e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.630619450001352343517516981425944698e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.316241762877456793773762181540969623e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.784092425369742929000839303523267545e-9), + }; + workspace[5] = tools::evaluate_polynomial(C5, z); + + static const T C6[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00053130793646399222316574854297762391), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000592166437353693882864836225604401187), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000270878209671804482771279183488328692), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.790235323266032787212032944390816666e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.815396936756196875092890088464682624e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.561168275310624965003775619041471695e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.183291165828433755673259749374098313e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.307961345060330478256414192546677006e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.346515536880360908673728529745376913e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.202913273960586037269527254582695285e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.578879286314900370889997586203187687e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233863067382665698933480579231637609e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.88286007463304835250508524317926246e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.474359588804081278032150770595852426e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.125454150207103824457130611214783073e-7), + }; + workspace[6] = tools::evaluate_polynomial(C6, z); + + static const T C7[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000344367606892377671254279625108523655), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.517179090826059219337057843002058823e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000334931610811422363116635090580012327), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000281269515476323702273722110707777978), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000109765822446847310235396824500789005), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.127410090954844853794579954588107623e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.277444515115636441570715073933712622e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.182634888057113326614324442681892723e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.578769494973505239894178121070843383e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.493875893393627039981813418398565502e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105953670140260427338098566209633945e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.616671437611040747858836254004890765e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.175629733590604619378669693914265388e-6), + }; + workspace[7] = tools::evaluate_polynomial(C7, z); + + static const T C8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000652623918595309418922034919726622692), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000839498720672087279993357516764983445), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000438297098541721005061087953050560377), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.696909145842055197136911097362072702e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00016644846642067547837384572662326101), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000127835176797692185853344001461664247), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.462995326369130429061361032704489636e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.455790986792270771162749294232219616e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105952711258051954718238500312872328e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.678334290486516662273073740749269432e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210754766662588042469972680229376445e-5), + }; + workspace[8] = tools::evaluate_polynomial(C8, z); + + static const T C9[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000596761290192746250124390067179459605), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.720489541602001055908571930225015052e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000678230883766732836161951166000673426), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000640147526026275845100045652582354779), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000277501076343287044992374518205845463), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.181970083804651510461686554030325202e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.847950711706850318239732559632810086e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.610519208250153101764709122740859458e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210739201834048624082975255893773306e-4), + }; + workspace[9] = tools::evaluate_polynomial(C9, z); + + static const T C10[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00133244544948006563712694993432717968), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00191443849856547752650089885832852254), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0011089369134596637339607446329267522), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.993240412264229896742295262075817566e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000508745012930931989848393025305956774), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00042735056665392884328432271160040444), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000168588537679107988033552814662382059), + }; + workspace[10] = tools::evaluate_polynomial(C10, z); + + static const T C11[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157972766073083495908785631307733022), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000162516262783915816898635123980270998), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00206334210355432762645284467690276817), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00213896861856890981541061922797693947), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00101085593912630031708085801712479376), + }; + workspace[11] = tools::evaluate_polynomial(C11, z); + + static const T C12[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00407251211951401664727281097914544601), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00640336283380806979482363809026579583), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00404101610816766177473974858518094879), + }; + workspace[12] = tools::evaluate_polynomial(C12, z); + workspace[13] = -0.0059475779383993002845382844736066323L; + + T result = tools::evaluate_polynomial(workspace, T(1/a)); + result *= exp(-y) / sqrt(2 * constants::pi() * a); + if(x < a) + result = -result; + + result += boost::math::erfc(sqrt(y), pol) / 2; + + return result; +} + +} // namespace detail +} // namespace math +} // namespace math + + +#endif // BOOST_MATH_DETAIL_IGAMMA_LARGE + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/lambert_w_lookup_table.ipp b/libcxx/src/third-party/boost/math/special_functions/detail/lambert_w_lookup_table.ipp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/lambert_w_lookup_table.ipp @@ -0,0 +1,134 @@ +// Copyright Paul A. Bristow 2017. +// Distributed under 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) + +// I:/modular-boost/libs/math/include/boost/math/special_functions/lambert_w_lookup_table.ipp + +// A collection of 128-bit precision integral z argument Lambert W values computed using 37 decimal digits precision. +// C++ floating-point precision is 128-bit long double. +// Output as 53 decimal digits, suffixed L. + +// C++ floating-point type is provided by lambert_w.hpp typedef. +// For example: typedef lookup_t double; (or float or long double) + +// Written by I:\modular-boost\libs\math\test\lambert_w_lookup_table_generator.cpp Thu Jan 25 16:52:07 2018 + +// Sizes of arrays of z values for Lambert W[0], W[1] ... W[64]" and W[-1], W[-2] ... W[-64]. + +namespace boost { +namespace math { +namespace lambert_w_detail { +namespace lambert_w_lookup +{ +static constexpr std::size_t noof_sqrts = 12; +static constexpr std::size_t noof_halves = 12; +static constexpr std::size_t noof_w0es = 65; +static constexpr std::size_t noof_w0zs = 65; +static constexpr std::size_t noof_wm1es = 64; +static constexpr std::size_t noof_wm1zs = 64; + +static constexpr lookup_t halves[noof_halves] = +{ // Common to Lambert W0 and W-1 (and exactly representable). + 0.5L, 0.25L, 0.125L, 0.0625L, 0.03125L, 0.015625L, 0.0078125L, 0.00390625L, 0.001953125L, 0.0009765625L, 0.00048828125L, 0.000244140625L +}; // halves, 0.5, 0.25, ... 0.000244140625, common to W0 and W-1. + +static constexpr lookup_t sqrtw0s[noof_sqrts] = +{ // For Lambert W0 only. + 0.6065306597126334242631173765403218567L, 0.77880078307140486866846070009071995L, 0.882496902584595403104717592968701829L, 0.9394130628134757862473572557999761753L, 0.9692332344763440819139583751755278177L, 0.9844964370054084060204319075254540376L, 0.9922179382602435121227899136829802692L, 0.996101369470117490071323985506950379L, 0.9980487811074754727142805899944244847L, 0.9990239141819756622368328253791383317L, 0.9995118379398893653889967919448497792L, 0.9997558891748972165136242351259789505L +}; // sqrtw0s + +static constexpr lookup_t sqrtwm1s[noof_sqrts] = +{ // For Lambert W-1 only. + 1.648721270700128146848650787814163572L, 1.284025416687741484073420568062436458L, 1.133148453066826316829007227811793873L, 1.064494458917859429563390594642889673L, 1.031743407499102670938747815281507144L, 1.015747708586685747458535072082351749L, 1.007843097206447977693453559760123579L, 1.003913889338347573443609603903460282L, 1.001955033591002812046518898047477216L, 1.000977039492416535242845292611606506L, 1.000488400478694473126173623807163354L, 1.000244170429747854937005233924135774L +}; // sqrtwm1s + +static constexpr lookup_t w0es[noof_w0zs] = +{ // Fukushima e powers array e[0] = 2.718, 1., e[2] = e^-1 = 0.135, e[3] = e^-2 = 0.133 ... e[64] = 4.3596100000630809736231248158884615452e-28. + 2.7182818284590452353602874713526624978e+00L, + 1.0000000000000000000000000000000000000e+00L, 3.6787944117144232159552377016146086745e-01L, 1.3533528323661269189399949497248440341e-01L, 4.9787068367863942979342415650061776632e-02L, + 1.8315638888734180293718021273241242212e-02L, 6.7379469990854670966360484231484242488e-03L, 2.4787521766663584230451674308166678915e-03L, 9.1188196555451620800313608440928262647e-04L, + 3.3546262790251183882138912578086101931e-04L, 1.2340980408667954949763669073003382607e-04L, 4.5399929762484851535591515560550610238e-05L, 1.6701700790245659312635517360580879078e-05L, + 6.1442123533282097586823081788055323112e-06L, 2.2603294069810543257852772905386894694e-06L, 8.3152871910356788406398514256526229461e-07L, 3.0590232050182578837147949770228963937e-07L, + 1.1253517471925911451377517906012719164e-07L, 4.1399377187851666596510277189552806229e-08L, 1.5229979744712628436136629233517431862e-08L, 5.6027964375372675400129828162064630798e-09L, + 2.0611536224385578279659403801558209764e-09L, 7.5825604279119067279417432412681264430e-10L, 2.7894680928689248077189130306442932077e-10L, 1.0261879631701890303927527840612497760e-10L, + 3.7751345442790977516449695475234067792e-11L, 1.3887943864964020594661763746086856910e-11L, 5.1090890280633247198744001934792157666e-12L, 1.8795288165390832947582704184221926212e-12L, + 6.9144001069402030094125846587414092712e-13L, 2.5436656473769229103033856148576816666e-13L, 9.3576229688401746049158322233787067450e-14L, 3.4424771084699764583923893328515572846e-14L, + 1.2664165549094175723120904155965096382e-14L, 4.6588861451033973641842455436101684114e-15L, 1.7139084315420129663027203425760492412e-15L, 6.3051167601469893856390211922465427614e-16L, + 2.3195228302435693883122636097380800411e-16L, 8.5330476257440657942780498229412441658e-17L, 3.1391327920480296287089646522319196491e-17L, 1.1548224173015785986262442063323868655e-17L, + 4.2483542552915889953292347828586580179e-18L, 1.5628821893349887680908829951058341550e-18L, 5.7495222642935598066643808805734234249e-19L, 2.1151310375910804866314010070226514702e-19L, + 7.7811322411337965157133167292798981918e-20L, 2.8625185805493936444701216291839372068e-20L, 1.0530617357553812378763324449428108806e-20L, 3.8739976286871871129314774972691278293e-21L, + 1.4251640827409351062853210280340602263e-21L, 5.2428856633634639371718053028323436716e-22L, 1.9287498479639177830173428165270125748e-22L, 7.0954741622847041389832693878080734877e-23L, + 2.6102790696677048047026953153318648093e-23L, 9.6026800545086760302307696700074909076e-24L, 3.5326285722008070297353928101772088374e-24L, 1.2995814250075030736007134060714855303e-24L, + 4.7808928838854690812771770423179628939e-25L, 1.7587922024243116489558751288034363178e-25L, 6.4702349256454603261540395529264893765e-26L, 2.3802664086944006058943245888024963309e-26L, + 8.7565107626965203384887328007391660366e-27L, 3.2213402859925160890012477758489437534e-27L, 1.1850648642339810062850307390972809891e-27L, 4.3596100000630809736231248158884596428e-28L, + +}; // w0es + +static constexpr lookup_t w0zs[noof_w0zs] = +{ // z values for W[0], W[1], W[2] ... W[64] (Fukushima array Fk). + 0.0000000000000000000000000000000000000e+00L, + 2.7182818284590452353602874713526624978e+00L, 1.4778112197861300454460854921150015626e+01L, 6.0256610769563003222785588963745153691e+01L, 2.1839260013257695631244104481144351361e+02L, + 7.4206579551288301710557790020276139812e+02L, 2.4205727609564107356503230832603296776e+03L, 7.6764321089992101948460416680168500271e+03L, 2.3847663896333826197948736795623109390e+04L, + 7.2927755348178456069389970204894839685e+04L, 2.2026465794806716516957900645284244366e+05L, 6.5861555886717600300859134371483559776e+05L, 1.9530574970280470496960624587818413980e+06L, + 5.7513740961159665432393360873381476632e+06L, 1.6836459978306874888489314790750032292e+07L, 4.9035260587081659589527825691375819733e+07L, 1.4217776832812596218820837985250320561e+08L, + 4.1063419681078006965118239806655900596e+08L, 1.1818794444719492004981570586630806042e+09L, 3.3911637183005579560532906419857313738e+09L, 9.7033039081958055593821366108308111737e+09L, + 2.7695130424147508641409976558651358487e+10L, 7.8868082614895014356985518811525255163e+10L, 2.2413047926372475980079655175092843139e+11L, 6.3573893111624333505933989166748517618e+11L, + 1.8001224834346468131040337866531539479e+12L, 5.0889698451498078710141863447784789126e+12L, 1.4365302496248562650461177217211790925e+13L, 4.0495197800161304862957327843914007993e+13L, + 1.1400869461717722015726999684446230289e+14L, 3.2059423744573386440971405952224204950e+14L, 9.0051433962267018216365614546207459567e+14L, 2.5268147258457822451512967243234631750e+15L, + 7.0832381329352301326018261305316090522e+15L, 1.9837699245933465967698692976753294646e+16L, 5.5510470830970075484537561902113104381e+16L, 1.5520433569614702817608320254284931407e+17L, + 4.3360826779369661842459877227403719730e+17L, 1.2105254067703227363724895246493485480e+18L, 3.3771426165357561311906703760513324357e+18L, 9.4154106734807994163159964299613921804e+18L, + 2.6233583234732252918129199544138403574e+19L, 7.3049547543861043990576614751671879498e+19L, 2.0329709713386190214340167519800405595e+20L, 5.6547040503180956413560918381429636734e+20L, + 1.5720421975868292906615658755032744790e+21L, 4.3682149334771264822761478593874428627e+21L, 1.2132170565093316762294432610117848880e+22L, 3.3680332378068632345542636794533635462e+22L, + 9.3459982052259884835729892206738573922e+22L, 2.5923527642935362320437266614667426924e+23L, 7.1876803203773878618909930893087860822e+23L, 1.9921241603726199616378561653688236827e+24L, + 5.5192924995054165325072406547517121131e+24L, 1.5286067837683347062387143159276002521e+25L, 4.2321318958281094260005100745711666956e+25L, 1.1713293177672778461879598480402173158e+26L, + 3.2408603996214813669049988277609543829e+26L, 8.9641258264226027960478448084812796397e+26L, 2.4787141382364034104243901241243054434e+27L, 6.8520443388941057019777430988685937812e+27L, + 1.8936217407781711443114787060753312270e+28L, 5.2317811346197017832254642778313331353e+28L, 1.4450833904658542238325922893692265683e+29L, 3.9904954117194348050619127737142206367e+29L + +}; // w0zs + +static constexpr lookup_t wm1es[noof_wm1es] = +{ // Fukushima e array e[0] = e^1 = 2.718, e[1] = e^2 = 7.39 ... e[64] = 4.60718e+28. + 2.7182818284590452353602874713526624978e+00L, + 7.3890560989306502272304274605750078132e+00L, 2.0085536923187667740928529654581717897e+01L, 5.4598150033144239078110261202860878403e+01L, 1.4841315910257660342111558004055227962e+02L, + 4.0342879349273512260838718054338827961e+02L, 1.0966331584284585992637202382881214324e+03L, 2.9809579870417282747435920994528886738e+03L, 8.1030839275753840077099966894327599650e+03L, + 2.2026465794806716516957900645284244366e+04L, 5.9874141715197818455326485792257781614e+04L, 1.6275479141900392080800520489848678317e+05L, 4.4241339200892050332610277594908828178e+05L, + 1.2026042841647767777492367707678594494e+06L, 3.2690173724721106393018550460917213155e+06L, 8.8861105205078726367630237407814503508e+06L, 2.4154952753575298214775435180385823880e+07L, + 6.5659969137330511138786503259060033569e+07L, 1.7848230096318726084491003378872270388e+08L, 4.8516519540979027796910683054154055868e+08L, 1.3188157344832146972099988837453027851e+09L, + 3.5849128461315915616811599459784206892e+09L, 9.7448034462489026000346326848229752776e+09L, 2.6489122129843472294139162152811882341e+10L, 7.2004899337385872524161351466126157915e+10L, + 1.9572960942883876426977639787609534279e+11L, 5.3204824060179861668374730434117744166e+11L, 1.4462570642914751736770474229969288569e+12L, 3.9313342971440420743886205808435276858e+12L, + 1.0686474581524462146990468650741401650e+13L, 2.9048849665247425231085682111679825667e+13L, 7.8962960182680695160978022635108224220e+13L, 2.1464357978591606462429776153126088037e+14L, + 5.8346174252745488140290273461039101900e+14L, 1.5860134523134307281296446257746601252e+15L, 4.3112315471151952271134222928569253908e+15L, 1.1719142372802611308772939791190194522e+16L, + 3.1855931757113756220328671701298646000e+16L, 8.6593400423993746953606932719264934250e+16L, 2.3538526683701998540789991074903480451e+17L, 6.3984349353005494922266340351557081888e+17L, + 1.7392749415205010473946813036112352261e+18L, 4.7278394682293465614744575627442803708e+18L, 1.2851600114359308275809299632143099258e+19L, 3.4934271057485095348034797233406099533e+19L, + 9.4961194206024488745133649117118323102e+19L, 2.5813128861900673962328580021527338043e+20L, 7.0167359120976317386547159988611740546e+20L, 1.9073465724950996905250998409538484474e+21L, + 5.1847055285870724640874533229334853848e+21L, 1.4093490824269387964492143312370168789e+22L, 3.8310080007165768493035695487861993899e+22L, 1.0413759433029087797183472933493796440e+23L, + 2.8307533032746939004420635480140745409e+23L, 7.6947852651420171381827455901293939921e+23L, 2.0916594960129961539070711572146737782e+24L, 5.6857199993359322226403488206332533034e+24L, + 1.5455389355901039303530766911174620068e+25L, 4.2012104037905142549565934307191617684e+25L, 1.1420073898156842836629571831447656302e+26L, 3.1042979357019199087073421411071003721e+26L, + 8.4383566687414544890733294803731179601e+26L, 2.2937831594696098790993528402686136005e+27L, 6.2351490808116168829092387089284697448e+27L +}; // wm1es + +static constexpr lookup_t wm1zs[noof_wm1zs] = +{ // Fukushima G array of z values for integral K, (Fukushima Gk) g[0] (k = -1) = 1 ... g[64] = -1.0264389699511303e-26. + -3.6787944117144232159552377016146086745e-01L, + -2.7067056647322538378799898994496880682e-01L, -1.4936120510359182893802724695018532990e-01L, -7.3262555554936721174872085092964968848e-02L, -3.3689734995427335483180242115742121244e-02L, + -1.4872513059998150538271004584900007349e-02L, -6.3831737588816134560219525908649783853e-03L, -2.6837010232200947105711130062468881545e-03L, -1.1106882367801159454787302165703044346e-03L, + -4.5399929762484851535591515560550610238e-04L, -1.8371870869270225243899069096638966986e-04L, -7.3730548239938517104187698145666387735e-05L, -2.9384282290753706235208604777002963102e-05L, + -1.1641402067449950376895791995913672125e-05L, -4.5885348075273868255721924655343445906e-06L, -1.8005627955081458322204028649620350662e-06L, -7.0378941219347833214067471222239770590e-07L, + -2.7413963540482731185045932620331377352e-07L, -1.0645313231320808326024667350792279852e-07L, -4.1223072448771156559318807603116419528e-08L, -1.5923376898615004128677660806663065530e-08L, + -6.1368298043116345769816086674174450569e-09L, -2.3602323152914347699033314033408744848e-09L, -9.0603229062698346039479269140561762700e-10L, -3.4719859662410051486654409365217142276e-10L, + -1.3283631472964644271673440503045960993e-10L, -5.0747278046555248958473301297399200773e-11L, -1.9360320299432568426355237044475945959e-11L, -7.3766303773930764398798182830872768331e-12L, + -2.8072868906520523814747496670136120235e-12L, -1.0671679036256927021016406931839827582e-12L, -4.0525329757101362313986893299088308423e-13L, -1.5374324278841211301808010293913555758e-13L, + -5.8272886672428440854292491647585674200e-14L, -2.2067908660514462849736574172862899665e-14L, -8.3502821888768497979241489950570881481e-15L, -3.1572276215253043438828784344882603413e-15L, + -1.1928704609782512589094065678481294667e-15L, -4.5038074274761565346423524046963087756e-16L, -1.6993417021166355981316939131434632072e-16L, -6.4078169762734539491726202799339200356e-17L, + -2.4147993510032951187990399698408378385e-17L, -9.0950634616416460925150243301974013218e-18L, -3.4236981860988704669138593608831552044e-18L, -1.2881333612472271400115547331327717431e-18L, + -4.8440839844747536942311292467369300505e-19L, -1.8207788854829779430777944237164900798e-19L, -6.8407875971564885101695409345634890862e-20L, -2.5690139750480973292141845983878483991e-20L, + -9.6437492398195889150867140826350628738e-21L, -3.6186918227651991108814673877821174787e-21L, -1.3573451162272064984454015639725697008e-21L, -5.0894204288895982960223079251039701810e-22L, + -1.9076194289884357960571121174956927722e-22L, -7.1476978375412669048039237333931704166e-23L, -2.6773000149758626855152191436980592206e-23L, -1.0025115553818576399048488234179587012e-23L, + -3.7527362568743669891693429406973638384e-24L, -1.4043571811296963574776515073934728352e-24L, -5.2539064576179122030932396804434996219e-25L, -1.9650175744554348142907611432678556896e-25L, + -7.3474021582506822389671905824031421322e-26L, -2.7465543000397410133825686340097295749e-26L, -1.0264389699511282259046957018510946438e-26L +}; // wm1zs +} // namespace lambert_w_lookup +} // namespace detail +} // namespace math +} // namespace boost diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/lanczos_sse2.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/lanczos_sse2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/lanczos_sse2.hpp @@ -0,0 +1,238 @@ +// (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 + +#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(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast(2.506628274631000270164908177133837338626L), + static_cast(1u), + static_cast(210.8242777515793458725097339207133627117L), + static_cast(66u), + static_cast(8071.672002365816210638002902272250613822L), + static_cast(1925u), + static_cast(186056.2653952234950402949897160456992822L), + static_cast(32670u), + static_cast(2876370.628935372441225409051620849613599L), + static_cast(357423u), + static_cast(31426415.58540019438061423162831820536287L), + static_cast(2637558u), + static_cast(248874557.8620541565114603864132294232163L), + static_cast(13339535u), + static_cast(1439720407.311721673663223072794912393972L), + static_cast(45995730u), + static_cast(6039542586.35202800506429164430729792107L), + static_cast(105258076u), + static_cast(17921034426.03720969991975575445893111267L), + static_cast(150917976u), + static_cast(35711959237.35566804944018545154716670596L), + static_cast(120543840u), + static_cast(42919803642.64909876895789904700198885093L), + static_cast(39916800u), + static_cast(23531376880.41075968857200767445163675473L), + static_cast(0u) + }; + + static const double lim = 4.31965e+25; // By experiment, the largest x for which the SSE2 code does not go bad. + + if (x > lim) + { + double z = 1 / x; + return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]); + } + + __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(const double& x) +{ + static const ALIGN16 double coeff[26] = { + static_cast(0.006061842346248906525783753964555936883222L), + static_cast(1u), + static_cast(0.5098416655656676188125178644804694509993L), + static_cast(66u), + static_cast(19.51992788247617482847860966235652136208L), + static_cast(1925u), + static_cast(449.9445569063168119446858607650988409623L), + static_cast(32670u), + static_cast(6955.999602515376140356310115515198987526L), + static_cast(357423u), + static_cast(75999.29304014542649875303443598909137092L), + static_cast(2637558u), + static_cast(601859.6171681098786670226533699352302507L), + static_cast(13339535u), + static_cast(3481712.15498064590882071018964774556468L), + static_cast(45995730u), + static_cast(14605578.08768506808414169982791359218571L), + static_cast(105258076u), + static_cast(43338889.32467613834773723740590533316085L), + static_cast(150917976u), + static_cast(86363131.28813859145546927288977868422342L), + static_cast(120543840u), + static_cast(103794043.1163445451906271053616070238554L), + static_cast(39916800u), + static_cast(56906521.91347156388090791033559122686859L), + static_cast(0u) + }; + + static const double lim = 4.76886e+25; // By experiment, the largest x for which the SSE2 code does not go bad. + + if (x > lim) + { + double z = 1 / x; + return ((((((((((((coeff[24] * z + coeff[22]) * z + coeff[20]) * z + coeff[18]) * z + coeff[16]) * z + coeff[14]) * z + coeff[12]) * z + coeff[10]) * z + coeff[8]) * z + coeff[6]) * z + coeff[4]) * z + coeff[2]) * z + coeff[0]) / ((((((((((((coeff[25] * z + coeff[23]) * z + coeff[21]) * z + coeff[19]) * z + coeff[17]) * z + coeff[15]) * z + coeff[13]) * z + coeff[11]) * z + coeff[9]) * z + coeff[7]) * z + coeff[5]) * z + coeff[3]) * z + coeff[1]); + } + + __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 + +static_assert(sizeof(double) == sizeof(long double), "sizeof(long double) != sizeof(double) is not supported"); + +template <> +inline long double lanczos13m53::lanczos_sum(const long double& x) +{ + return lanczos_sum(static_cast(x)); +} +template <> +inline long double lanczos13m53::lanczos_sum_expG_scaled(const long double& x) +{ + return lanczos_sum_expG_scaled(static_cast(x)); +} +#endif + +} // namespace lanczos +} // namespace math +} // namespace boost + +#undef ALIGN16 + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS + + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/lgamma_small.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/lgamma_small.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/lgamma_small.hpp @@ -0,0 +1,532 @@ +// (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_DETAIL_LGAMMA_SMALL +#define BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace detail{ + +// +// These need forward declaring to keep GCC happy: +// +template +T gamma_imp(T z, const Policy& pol, const Lanczos& l); +template +T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos& l); + +// +// lgamma for small arguments: +// +template +T lgamma_small_imp(T z, T zm1, T zm2, const std::integral_constant&, const Policy& /* l */, const Lanczos&) +{ + // This version uses rational approximations for small + // values of z accurate enough for 64-bit mantissas + // (80-bit long doubles), works well for 53-bit doubles as well. + // Lanczos is only used to select the Lanczos function. + + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + if(z < tools::epsilon()) + { + result = -log(z); + } + else if((zm1 == 0) || (zm2 == 0)) + { + // nothing to do, result is zero.... + } + else if(z > 2) + { + // + // Begin by performing argument reduction until + // z is in [2,3): + // + if(z >= 3) + { + do + { + z -= 1; + zm2 -= 1; + result += log(z); + }while(z >= 3); + // Update zm2, we need it below: + zm2 = z - 2; + } + + // + // Use the following form: + // + // lgamma(z) = (z-2)(z+1)(Y + R(z-2)) + // + // where R(z-2) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-2) has the following properties: + // + // At double: Max error found: 4.231e-18 + // At long double: Max error found: 1.987e-21 + // Maximum Deviation Found (approximation error): 5.900e-24 + // + static const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.180355685678449379109e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25126649619989678683e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.494103151567532234274e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.172491608709613993966e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.259453563205438108893e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.541009869215204396339e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.324588649825948492091e-4)) + }; + static const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.196202987197795200688e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.148019669424231326694e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.541391432071720958364e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.988504251128010129477e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.82130967464889339326e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.224936291922115757597e-3)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.223352763208617092964e-6)) + }; + + static const float Y = 0.158963680267333984375e0f; + + T r = zm2 * (z + 1); + T R = tools::evaluate_polynomial(P, zm2); + R /= tools::evaluate_polynomial(Q, zm2); + + result += r * Y + r * R; + } + else + { + // + // If z is less than 1 use recurrence to shift to + // z in the interval [1,2]: + // + if(z < 1) + { + result += -log(z); + zm2 = zm1; + zm1 = z; + z += 1; + } + // + // Two approximations, on for z in [1,1.5] and + // one for z in [1.5,2]: + // + if(z <= 1.5) + { + // + // Use the following form: + // + // lgamma(z) = (z-1)(z-2)(Y + R(z-1)) + // + // where R(z-1) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-1) has the following properties: + // + // At double precision: Max error found: 1.230011e-17 + // At 80-bit long double precision: Max error found: 5.631355e-21 + // Maximum Deviation Found: 3.139e-021 + // Expected Error Term: 3.139e-021 + + // + static const float Y = 0.52815341949462890625f; + + static const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.490622454069039543534e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.969117530159521214579e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.414983358359495381969e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.406567124211938417342e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.158413586390692192217e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.240149820648571559892e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100346687696279557415e-2)) + }; + static const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.302349829846463038743e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.348739585360723852576e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.191415588274426679201e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.507137738614363510846e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.577039722690451849648e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.195768102601107189171e-2)) + }; + + T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1); + T prefix = zm1 * zm2; + + result += prefix * Y + prefix * r; + } + else + { + // + // Use the following form: + // + // lgamma(z) = (2-z)(1-z)(Y + R(2-z)) + // + // where R(2-z) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(2-z) has the following properties: + // + // At double precision, max error found: 1.797565e-17 + // At 80-bit long double precision, max error found: 9.306419e-21 + // Maximum Deviation Found: 2.151e-021 + // Expected Error Term: 2.150e-021 + // + static const float Y = 0.452017307281494140625f; + + static const T P[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.292329721830270012337e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.144216267757192309184e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.142440390738631274135e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.542809694055053558157e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.850535976868336437746e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.431171342679297331241e-3)) + }; + static const T Q[] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.150169356054485044494e1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.846973248876495016101e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.220095151814995745555e0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.25582797155975869989e-1)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.100666795539143372762e-2)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.827193521891290553639e-6)) + }; + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2)); + + result += r * Y + r * R; + } + } + return result; +} +template +T lgamma_small_imp(T z, T zm1, T zm2, const std::integral_constant&, const Policy& /* l */, const Lanczos&) +{ + // + // This version uses rational approximations for small + // values of z accurate enough for 113-bit mantissas + // (128-bit long doubles). + // + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + if(z < tools::epsilon()) + { + result = -log(z); + BOOST_MATH_INSTRUMENT_CODE(result); + } + else if((zm1 == 0) || (zm2 == 0)) + { + // nothing to do, result is zero.... + } + else if(z > 2) + { + // + // Begin by performing argument reduction until + // z is in [2,3): + // + if(z >= 3) + { + do + { + z -= 1; + result += log(z); + }while(z >= 3); + zm2 = z - 2; + } + BOOST_MATH_INSTRUMENT_CODE(zm2); + BOOST_MATH_INSTRUMENT_CODE(z); + BOOST_MATH_INSTRUMENT_CODE(result); + + // + // Use the following form: + // + // lgamma(z) = (z-2)(z+1)(Y + R(z-2)) + // + // where R(z-2) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // Maximum Deviation Found (approximation error) 3.73e-37 + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.018035568567844937910504030027467476655), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.013841458273109517271750705401202404195), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.062031842739486600078866923383017722399), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.052518418329052161202007865149435256093), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.01881718142472784129191838493267755758), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0025104830367021839316463675028524702846), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00021043176101831873281848891452678568311), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00010249622350908722793327719494037981166), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11381479670982006841716879074288176994e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.49999811718089980992888533630523892389e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.70529798686542184668416911331718963364e-8) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.5877485070422317542808137697939233685), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.8797959228352591788629602533153837126), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.8030885955284082026405495275461180977), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.69774331297747390169238306148355428436), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.17261566063277623942044077039756583802), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.02729301254544230229429621192443000121), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026776425891195270663133581960016620433), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00015244249160486584591370355730402168106), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.43997034032479866020546814475414346627e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.46295080708455613044541885534408170934e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.93326638207459533682980757982834180952e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.42316456553164995177177407325292867513e-13) + }; + + T R = tools::evaluate_polynomial(P, zm2); + R /= tools::evaluate_polynomial(Q, zm2); + + static const float Y = 0.158963680267333984375F; + + T r = zm2 * (z + 1); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // + // If z is less than 1 use recurrence to shift to + // z in the interval [1,2]: + // + if(z < 1) + { + result += -log(z); + zm2 = zm1; + zm1 = z; + z += 1; + } + BOOST_MATH_INSTRUMENT_CODE(result); + BOOST_MATH_INSTRUMENT_CODE(z); + BOOST_MATH_INSTRUMENT_CODE(zm2); + // + // Three approximations, on for z in [1,1.35], [1.35,1.625] and [1.625,1] + // + if(z <= 1.35) + { + // + // Use the following form: + // + // lgamma(z) = (z-1)(z-2)(Y + R(z-1)) + // + // where R(z-1) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(z-1) has the following properties: + // + // Maximum Deviation Found (approximation error) 1.659e-36 + // Expected Error Term (theoretical error) 1.343e-36 + // Max error found at 128-bit long double precision 1.007e-35 + // + static const float Y = 0.54076099395751953125f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.036454670944013329356512090082402429697), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.066235835556476033710068679907798799959), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.67492399795577182387312206593595565371), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4345555263962411429855341651960000166), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4894319559821365820516771951249649563), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.87210277668067964629483299712322411566), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29602090537771744401524080430529369136), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0561832587517836908929331992218879676), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0053236785487328044334381502530383140443), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00018629360291358130461736386077971890789), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.10164985672213178500790406939467614498e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13680157145361387405588201461036338274e-8) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.9106336261005990534095838574132225599), + BOOST_MATH_BIG_CONSTANT(T, 113, 10.258804800866438510889341082793078432), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.88588976846826108836629960537466889), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.3455000546999704314454891036700998428), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.6428823682421746343233362007194282703), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.97465989807254572142266753052776132252), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15121052897097822172763084966793352524), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.012017363555383555123769849654484594893), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0003583032812720649835431669893011257277) + }; + + T r = tools::evaluate_polynomial(P, zm1) / tools::evaluate_polynomial(Q, zm1); + T prefix = zm1 * zm2; + + result += prefix * Y + prefix * r; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else if(z <= 1.625) + { + // + // Use the following form: + // + // lgamma(z) = (2-z)(1-z)(Y + R(2-z)) + // + // where R(2-z) is a rational approximation optimised for + // low absolute error - as long as it's absolute error + // is small compared to the constant Y - then any rounding + // error in it's computation will get wiped out. + // + // R(2-z) has the following properties: + // + // Max error found at 128-bit long double precision 9.634e-36 + // Maximum Deviation Found (approximation error) 1.538e-37 + // Expected Error Term (theoretical error) 2.350e-38 + // + static const float Y = 0.483787059783935546875f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.017977422421608624353488126610933005432), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.18484528905298309555089509029244135703), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.40401251514859546989565001431430884082), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.40277179799147356461954182877921388182), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.21993421441282936476709677700477598816), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.069595742223850248095697771331107571011), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.012681481427699686635516772923547347328), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0012489322866834830413292771335113136034), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.57058739515423112045108068834668269608e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.8207548771933585614380644961342925976e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.9629552288944259229543137757200262073), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.7118380799042118987185957298964772755), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.5569815272165399297600586376727357187), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0546764918220835097855665680632153367), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26574021300894401276478730940980810831), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.03996289731752081380552901986471233462), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033398680924544836817826046380586480873), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00013288854760548251757651556792598235735), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.17194794958274081373243161848194745111e-5) + }; + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(0.625 - zm1)) / tools::evaluate_polynomial(Q, T(0.625 - zm1)); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // + // Same form as above. + // + // Max error found (at 128-bit long double precision) 1.831e-35 + // Maximum Deviation Found (approximation error) 8.588e-36 + // Expected Error Term (theoretical error) 1.458e-36 + // + static const float Y = 0.443811893463134765625f; + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.021027558364667626231512090082402429494), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15128811104498736604523586803722368377), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26249631480066246699388544451126410278), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.21148748610533489823742352180628489742), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.093964130697489071999873506148104370633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.024292059227009051652542804957550866827), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0036284453226534839926304745756906117066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0002939230129315195346843036254392485984), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11088589183158123733132268042570710338e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13240510580220763969511741896361984162e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.4240003754444040525462170802796471996), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.4868383476933178722203278602342786002), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.4047068395206343375520721509193698547), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.47583809087867443858344765659065773369), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.09865724264554556400463655444270700132), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.012238223514176587501074150988445109735), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00084625068418239194670614419707491797097), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.2796574430456237061420839429225710602e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.30202973883316730694433702165188835331e-6) + }; + // (2 - x) * (1 - x) * (c + R(2 - x)) + T r = zm2 * zm1; + T R = tools::evaluate_polynomial(P, T(-zm2)) / tools::evaluate_polynomial(Q, T(-zm2)); + + result += r * Y + r * R; + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + BOOST_MATH_INSTRUMENT_CODE(result); + return result; +} +template +T lgamma_small_imp(T z, T zm1, T zm2, const std::integral_constant&, const Policy& pol, const Lanczos& l) +{ + // + // No rational approximations are available because either + // T has no numeric_limits support (so we can't tell how + // many digits it has), or T has more digits than we know + // what to do with.... we do have a Lanczos approximation + // though, and that can be used to keep errors under control. + // + BOOST_MATH_STD_USING // for ADL of std names + T result = 0; + if(z < tools::epsilon()) + { + result = -log(z); + } + else if(z < 0.5) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, Lanczos())); + } + else if(z >= 3) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, Lanczos())); + } + else if(z >= 1.5) + { + // special case near 2: + T dz = zm2; + result = dz * log((z + lanczos_g_near_1_and_2(l) - T(0.5)) / boost::math::constants::e()); + result += boost::math::log1p(dz / (lanczos_g_near_1_and_2(l) + T(1.5)), pol) * T(1.5); + result += boost::math::log1p(Lanczos::lanczos_sum_near_2(dz), pol); + } + else + { + // special case near 1: + T dz = zm1; + result = dz * log((z + lanczos_g_near_1_and_2(l) - T(0.5)) / boost::math::constants::e()); + result += boost::math::log1p(dz / (lanczos_g_near_1_and_2(l) + T(0.5)), pol) / 2; + result += boost::math::log1p(Lanczos::lanczos_sum_near_1(dz), pol); + } + return result; +} + +}}} // namespaces + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_DETAIL_LGAMMA_SMALL + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/polygamma.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/polygamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/polygamma.hpp @@ -0,0 +1,560 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2013 Paul Bristow +// Distributed under 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_POLYGAMMA_DETAIL_2013_07_30_HPP_ + #define _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#endif + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +namespace boost { namespace math { namespace detail{ + + template + T polygamma_atinfinityplus(const int n, const T& x, const Policy& pol, const char* function) // for large values of x such as for x> 400 + { + // See http://functions.wolfram.com/GammaBetaErf/PolyGamma2/06/02/0001/ + BOOST_MATH_STD_USING + // + // sum == current value of accumulated sum. + // term == value of current term to be added to sum. + // part_term == value of current term excluding the Bernoulli number part + // + if(n + x == x) + { + // x is crazy large, just concentrate on the first part of the expression and use logs: + if(n == 1) return 1 / x; + T nlx = n * log(x); + if((nlx < tools::log_max_value()) && (n < (int)max_factorial::value)) + return ((n & 1) ? 1 : -1) * boost::math::factorial(n - 1, pol) * pow(x, -n); + else + return ((n & 1) ? 1 : -1) * exp(boost::math::lgamma(T(n), pol) - n * log(x)); + } + T term, sum, part_term; + T x_squared = x * x; + // + // Start by setting part_term to: + // + // (n-1)! / x^(n+1) + // + // which is common to both the first term of the series (with k = 1) + // and to the leading part. + // We can then get to the leading term by: + // + // part_term * (n + 2 * x) / 2 + // + // and to the first term in the series + // (excluding the Bernoulli number) by: + // + // part_term n * (n + 1) / (2x) + // + // If either the factorial would overflow, + // or the power term underflows, this just gets set to 0 and then we + // know that we have to use logs for the initial terms: + // + part_term = ((n > (int)boost::math::max_factorial::value) && (T(n) * n > tools::log_max_value())) + ? T(0) : static_cast(boost::math::factorial(n - 1, pol) * pow(x, -n - 1)); + if(part_term == 0) + { + // Either n is very large, or the power term underflows, + // set the initial values of part_term, term and sum via logs: + part_term = static_cast(boost::math::lgamma(n, pol) - (n + 1) * log(x)); + sum = exp(part_term + log(n + 2 * x) - boost::math::constants::ln_two()); + part_term += log(T(n) * (n + 1)) - boost::math::constants::ln_two() - log(x); + part_term = exp(part_term); + } + else + { + sum = part_term * (n + 2 * x) / 2; + part_term *= (T(n) * (n + 1)) / 2; + part_term /= x; + } + // + // If the leading term is 0, so is the result: + // + if(sum == 0) + return sum; + + for(unsigned k = 1;;) + { + term = part_term * boost::math::bernoulli_b2n(k, pol); + sum += term; + // + // Normal termination condition: + // + if(fabs(term / sum) < tools::epsilon()) + break; + // + // Increment our counter, and move part_term on to the next value: + // + ++k; + part_term *= T(n + 2 * k - 2) * (n - 1 + 2 * k); + part_term /= (2 * k - 1) * 2 * k; + part_term /= x_squared; + // + // Emergency get out termination condition: + // + if(k > policies::get_max_series_iterations()) + { + return policies::raise_evaluation_error(function, "Series did not converge, closest value was %1%", sum, pol); + } + } + + if((n - 1) & 1) + sum = -sum; + + return sum; + } + + template + T polygamma_attransitionplus(const int n, const T& x, const Policy& pol, const char* function) + { + // See: http://functions.wolfram.com/GammaBetaErf/PolyGamma2/16/01/01/0017/ + + // Use N = (0.4 * digits) + (4 * n) for target value for x: + BOOST_MATH_STD_USING + const int d4d = static_cast(0.4F * policies::digits_base10()); + const int N = d4d + (4 * n); + const int m = n; + const int iter = N - itrunc(x); + + if(iter > (int)policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, ("Exceeded maximum series evaluations evaluating at n = " + std::to_string(n) + " and x = %1%").c_str(), x, pol); + + const int minus_m_minus_one = -m - 1; + + T z(x); + T sum0(0); + T z_plus_k_pow_minus_m_minus_one(0); + + // Forward recursion to larger x, need to check for overflow first though: + if(log(z + iter) * minus_m_minus_one > -tools::log_max_value()) + { + for(int k = 1; k <= iter; ++k) + { + z_plus_k_pow_minus_m_minus_one = pow(z, minus_m_minus_one); + sum0 += z_plus_k_pow_minus_m_minus_one; + z += 1; + } + sum0 *= boost::math::factorial(n, pol); + } + else + { + for(int k = 1; k <= iter; ++k) + { + T log_term = log(z) * minus_m_minus_one + boost::math::lgamma(T(n + 1), pol); + sum0 += exp(log_term); + z += 1; + } + } + if((n - 1) & 1) + sum0 = -sum0; + + return sum0 + polygamma_atinfinityplus(n, z, pol, function); + } + + template + T polygamma_nearzero(int n, T x, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // + // If we take this expansion for polygamma: http://functions.wolfram.com/06.15.06.0003.02 + // and substitute in this expression for polygamma(n, 1): http://functions.wolfram.com/06.15.03.0009.01 + // we get an alternating series for polygamma when x is small in terms of zeta functions of + // integer arguments (which are easy to evaluate, at least when the integer is even). + // + // In order to avoid spurious overflow, save the n! term for later, and rescale at the end: + // + T scale = boost::math::factorial(n, pol); + // + // "factorial_part" contains everything except the zeta function + // evaluations in each term: + // + T factorial_part = 1; + // + // "prefix" is what we'll be adding the accumulated sum to, it will + // be n! / z^(n+1), but since we're scaling by n! it's just + // 1 / z^(n+1) for now: + // + T prefix = pow(x, n + 1); + if(prefix == 0) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + prefix = 1 / prefix; + // + // First term in the series is necessarily < zeta(2) < 2, so + // ignore the sum if it will have no effect on the result anyway: + // + if(prefix > 2 / policies::get_epsilon()) + return ((n & 1) ? 1 : -1) * + (tools::max_value() / prefix < scale ? policies::raise_overflow_error(function, nullptr, pol) : prefix * scale); + // + // As this is an alternating series we could accelerate it using + // "Convergence Acceleration of Alternating Series", + // Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier, Experimental Mathematics, 1999. + // In practice however, it appears not to make any difference to the number of terms + // required except in some edge cases which are filtered out anyway before we get here. + // + T sum = prefix; + for(unsigned k = 0;;) + { + // Get the k'th term: + T term = factorial_part * boost::math::zeta(T(k + n + 1), pol); + sum += term; + // Termination condition: + if(fabs(term) < fabs(sum * boost::math::policies::get_epsilon())) + break; + // + // Move on k and factorial_part: + // + ++k; + factorial_part *= (-x * (n + k)) / k; + // + // Last chance exit: + // + if(k > policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol); + } + // + // We need to multiply by the scale, at each stage checking for overflow: + // + if(boost::math::tools::max_value() / scale < sum) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + sum *= scale; + return n & 1 ? sum : T(-sum); + } + + // + // Helper function which figures out which slot our coefficient is in + // given an angle multiplier for the cosine term of power: + // + template + typename Table::value_type::reference dereference_table(Table& table, unsigned row, unsigned power) + { + return table[row][power / 2]; + } + + + + template + T poly_cot_pi(int n, T x, T xc, const Policy& pol, const char* function) + { + BOOST_MATH_STD_USING + // Return n'th derivative of cot(pi*x) at x, these are simply + // tabulated for up to n = 9, beyond that it is possible to + // calculate coefficients as follows: + // + // The general form of each derivative is: + // + // pi^n * SUM{k=0, n} C[k,n] * cos^k(pi * x) * csc^(n+1)(pi * x) + // + // With constant C[0,1] = -1 and all other C[k,n] = 0; + // Then for each k < n+1: + // C[k-1, n+1] -= k * C[k, n]; + // C[k+1, n+1] += (k-n-1) * C[k, n]; + // + // Note that there are many different ways of representing this derivative thanks to + // the many trigonometric identies available. In particular, the sum of powers of + // cosines could be replaced by a sum of cosine multiple angles, and indeed if you + // plug the derivative into Mathematica this is the form it will give. The two + // forms are related via the Chebeshev polynomials of the first kind and + // T_n(cos(x)) = cos(n x). The polynomial form has the great advantage that + // all the cosine terms are zero at half integer arguments - right where this + // function has it's minimum - thus avoiding cancellation error in this region. + // + // And finally, since every other term in the polynomials is zero, we can save + // space by only storing the non-zero terms. This greatly complexifies + // subscripting the tables in the calculation, but halves the storage space + // (and complexity for that matter). + // + T s = fabs(x) < fabs(xc) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(xc, pol); + T c = boost::math::cos_pi(x, pol); + switch(n) + { + case 1: + return -constants::pi() / (s * s); + case 2: + { + return 2 * constants::pi() * constants::pi() * c / boost::math::pow<3>(s, pol); + } + case 3: + { + constexpr int P[] = { -2, -4 }; + return boost::math::pow<3>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<4>(s, pol); + } + case 4: + { + constexpr int P[] = { 16, 8 }; + return boost::math::pow<4>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<5>(s, pol); + } + case 5: + { + constexpr int P[] = { -16, -88, -16 }; + return boost::math::pow<5>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<6>(s, pol); + } + case 6: + { + constexpr int P[] = { 272, 416, 32 }; + return boost::math::pow<6>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<7>(s, pol); + } + case 7: + { + constexpr int P[] = { -272, -2880, -1824, -64 }; + return boost::math::pow<7>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<8>(s, pol); + } + case 8: + { + constexpr int P[] = { 7936, 24576, 7680, 128 }; + return boost::math::pow<8>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<9>(s, pol); + } + case 9: + { + constexpr int P[] = { -7936, -137216, -185856, -31616, -256 }; + return boost::math::pow<9>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<10>(s, pol); + } + case 10: + { + constexpr int P[] = { 353792, 1841152, 1304832, 128512, 512 }; + return boost::math::pow<10>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<11>(s, pol); + } + case 11: + { + constexpr int P[] = { -353792, -9061376, -21253376, -8728576, -518656, -1024}; + return boost::math::pow<11>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<12>(s, pol); + } + case 12: + { + constexpr int P[] = { 22368256, 175627264, 222398464, 56520704, 2084864, 2048 }; + return boost::math::pow<12>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<13>(s, pol); + } +#ifndef BOOST_NO_LONG_LONG + case 13: + { + constexpr long long P[] = { -22368256LL, -795300864LL, -2868264960LL, -2174832640LL, -357888000LL, -8361984LL, -4096 }; + return boost::math::pow<13>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<14>(s, pol); + } + case 14: + { + constexpr long long P[] = { 1903757312LL, 21016670208LL, 41731645440LL, 20261765120LL, 2230947840LL, 33497088LL, 8192 }; + return boost::math::pow<14>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<15>(s, pol); + } + case 15: + { + constexpr long long P[] = { -1903757312LL, -89702612992LL, -460858269696LL, -559148810240LL, -182172651520LL, -13754155008LL, -134094848LL, -16384 }; + return boost::math::pow<15>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<16>(s, pol); + } + case 16: + { + constexpr long long P[] = { 209865342976LL, 3099269660672LL, 8885192097792LL, 7048869314560LL, 1594922762240LL, 84134068224LL, 536608768LL, 32768 }; + return boost::math::pow<16>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<17>(s, pol); + } + case 17: + { + constexpr long long P[] = { -209865342976LL, -12655654469632LL, -87815735738368LL, -155964390375424LL, -84842998005760LL, -13684856848384LL, -511780323328LL, -2146926592LL, -65536 }; + return boost::math::pow<17>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<18>(s, pol); + } + case 18: + { + constexpr long long P[] = { 29088885112832LL, 553753414467584LL, 2165206642589696LL, 2550316668551168LL, 985278548541440LL, 115620218667008LL, 3100738912256LL, 8588754944LL, 131072 }; + return boost::math::pow<18>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<19>(s, pol); + } + case 19: + { + constexpr long long P[] = { -29088885112832LL, -2184860175433728LL, -19686087844429824LL, -48165109676113920LL, -39471306959486976LL, -11124607890751488LL, -965271355195392LL, -18733264797696LL, -34357248000LL, -262144 }; + return boost::math::pow<19>(constants::pi(), pol) * tools::evaluate_even_polynomial(P, c) / boost::math::pow<20>(s, pol); + } + case 20: + { + constexpr long long P[] = { 4951498053124096LL, 118071834535526400LL, 603968063567560704LL, 990081991141490688LL, 584901762421358592LL, 122829335169859584LL, 7984436548730880LL, 112949304754176LL, 137433710592LL, 524288 }; + return boost::math::pow<20>(constants::pi(), pol) * c * tools::evaluate_even_polynomial(P, c) / boost::math::pow<21>(s, pol); + } +#endif + } + + // + // We'll have to compute the coefficients up to n, + // complexity is O(n^2) which we don't worry about for now + // as the values are computed once and then cached. + // However, if the final evaluation would have too many + // terms just bail out right away: + // + if((unsigned)n / 2u > policies::get_max_series_iterations()) + return policies::raise_evaluation_error(function, "The value of n is so large that we're unable to compute the result in reasonable time, best guess is %1%", 0, pol); +#ifdef BOOST_HAS_THREADS + static std::mutex m; + std::lock_guard l(m); +#endif + static int digits = tools::digits(); + static std::vector > table(1, std::vector(1, T(-1))); + + int current_digits = tools::digits(); + + if(digits != current_digits) + { + // Oh my... our precision has changed! + table = std::vector >(1, std::vector(1, T(-1))); + digits = current_digits; + } + + int index = n - 1; + + if(index >= (int)table.size()) + { + for(int i = (int)table.size() - 1; i < index; ++i) + { + int offset = i & 1; // 1 if the first cos power is 0, otherwise 0. + int sin_order = i + 2; // order of the sin term + int max_cos_order = sin_order - 1; // largest order of the polynomial of cos terms + int max_columns = (max_cos_order - offset) / 2; // How many entries there are in the current row. + int next_offset = offset ? 0 : 1; + int next_max_columns = (max_cos_order + 1 - next_offset) / 2; // How many entries there will be in the next row + table.push_back(std::vector(next_max_columns + 1, T(0))); + + for(int column = 0; column <= max_columns; ++column) + { + int cos_order = 2 * column + offset; // order of the cosine term in entry "column" + BOOST_MATH_ASSERT(column < (int)table[i].size()); + BOOST_MATH_ASSERT((cos_order + 1) / 2 < (int)table[i + 1].size()); + table[i + 1][(cos_order + 1) / 2] += ((cos_order - sin_order) * table[i][column]) / (sin_order - 1); + if(cos_order) + table[i + 1][(cos_order - 1) / 2] += (-cos_order * table[i][column]) / (sin_order - 1); + } + } + + } + T sum = boost::math::tools::evaluate_even_polynomial(&table[index][0], c, table[index].size()); + if(index & 1) + sum *= c; // First coefficient is order 1, and really an odd polynomial. + if(sum == 0) + return sum; + // + // The remaining terms are computed using logs since the powers and factorials + // get real large real quick: + // + T power_terms = n * log(boost::math::constants::pi()); + if(s == 0) + return sum * boost::math::policies::raise_overflow_error(function, nullptr, pol); + power_terms -= log(fabs(s)) * (n + 1); + power_terms += boost::math::lgamma(T(n), pol); + power_terms += log(fabs(sum)); + + if(power_terms > boost::math::tools::log_max_value()) + return sum * boost::math::policies::raise_overflow_error(function, nullptr, pol); + + return exp(power_terms) * ((s < 0) && ((n + 1) & 1) ? -1 : 1) * boost::math::sign(sum); + } + + template + struct polygamma_initializer + { + struct init + { + init() + { + // Forces initialization of our table of coefficients and mutex: + boost::math::polygamma(30, T(-2.5f), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } + }; + + template + const typename polygamma_initializer::init polygamma_initializer::initializer; + + template + inline T polygamma_imp(const int n, T x, const Policy &pol) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::polygamma<%1%>(int, %1%)"; + polygamma_initializer::initializer.force_instantiate(); + if(n < 0) + return policies::raise_domain_error(function, "Order must be >= 0, but got %1%", static_cast(n), pol); + if(x < 0) + { + if(floor(x) == x) + { + // + // Result is infinity if x is odd, and a pole error if x is even. + // + if(lltrunc(x) & 1) + return policies::raise_overflow_error(function, nullptr, pol); + else + return policies::raise_pole_error(function, "Evaluation at negative integer %1%", x, pol); + } + T z = 1 - x; + T result = polygamma_imp(n, z, pol) + constants::pi() * poly_cot_pi(n, z, x, pol, function); + return n & 1 ? T(-result) : result; + } + // + // Limit for use of small-x-series is chosen + // so that the series doesn't go too divergent + // in the first few terms. Ordinarily this + // would mean setting the limit to ~ 1 / n, + // but we can tolerate a small amount of divergence: + // + T small_x_limit = (std::min)(T(T(5) / n), T(0.25f)); + if(x < small_x_limit) + { + return polygamma_nearzero(n, x, pol, function); + } + else if(x > 0.4F * policies::digits_base10() + 4.0f * n) + { + return polygamma_atinfinityplus(n, x, pol, function); + } + else if(x == 1) + { + return (n & 1 ? 1 : -1) * boost::math::factorial(n, pol) * boost::math::zeta(T(n + 1), pol); + } + else if(x == 0.5f) + { + T result = (n & 1 ? 1 : -1) * boost::math::factorial(n, pol) * boost::math::zeta(T(n + 1), pol); + if(fabs(result) >= ldexp(tools::max_value(), -n - 1)) + return boost::math::sign(result) * policies::raise_overflow_error(function, nullptr, pol); + result *= ldexp(T(1), n + 1) - 1; + return result; + } + else + { + return polygamma_attransitionplus(n, x, pol, function); + } + } + +} } } // namespace boost::math::detail + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // _BOOST_POLYGAMMA_DETAIL_2013_07_30_HPP_ + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/round_fwd.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/round_fwd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/round_fwd.hpp @@ -0,0 +1,86 @@ +// Copyright John Maddock 2008. + +// 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_ROUND_FWD_HPP +#define BOOST_MATH_SPECIAL_ROUND_FWD_HPP + +#include +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost +{ + namespace math + { + + template + typename tools::promote_args::type trunc(const T& v, const Policy& pol); + template + typename tools::promote_args::type trunc(const T& v); + template + int itrunc(const T& v, const Policy& pol); + template + int itrunc(const T& v); + template + long ltrunc(const T& v, const Policy& pol); + template + long ltrunc(const T& v); + template + long long lltrunc(const T& v, const Policy& pol); + template + long long lltrunc(const T& v); + template + typename tools::promote_args::type round(const T& v, const Policy& pol); + template + typename tools::promote_args::type round(const T& v); + template + int iround(const T& v, const Policy& pol); + template + int iround(const T& v); + template + long lround(const T& v, const Policy& pol); + template + long lround(const T& v); + template + long long llround(const T& v, const Policy& pol); + template + long long llround(const T& v); + template + T modf(const T& v, T* ipart, const Policy& pol); + template + T modf(const T& v, T* ipart); + template + T modf(const T& v, int* ipart, const Policy& pol); + template + T modf(const T& v, int* ipart); + template + T modf(const T& v, long* ipart, const Policy& pol); + template + T modf(const T& v, long* ipart); + template + T modf(const T& v, long long* ipart, const Policy& pol); + template + T modf(const T& v, long long* ipart); + } +} + +#undef BOOST_MATH_STD_USING +#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE\ + using boost::math::round;\ + using boost::math::iround;\ + using boost::math::lround;\ + using boost::math::trunc;\ + using boost::math::itrunc;\ + using boost::math::ltrunc;\ + using boost::math::modf; + + +#endif // BOOST_MATH_SPECIAL_ROUND_FWD_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/t_distribution_inv.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/t_distribution_inv.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/t_distribution_inv.hpp @@ -0,0 +1,549 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007 +// 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_SF_DETAIL_INV_T_HPP +#define BOOST_MATH_SF_DETAIL_INV_T_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +// +// The main method used is due to Hill: +// +// G. W. Hill, Algorithm 396, Student's t-Quantiles, +// Communications of the ACM, 13(10): 619-620, Oct., 1970. +// +template +T inverse_students_t_hill(T ndf, T u, const Policy& pol) +{ + BOOST_MATH_STD_USING + BOOST_MATH_ASSERT(u <= 0.5); + + T a, b, c, d, q, x, y; + + if (ndf > 1e20f) + return -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + + a = 1 / (ndf - 0.5f); + b = 48 / (a * a); + c = ((20700 * a / b - 98) * a - 16) * a + 96.36f; + d = ((94.5f / (b + c) - 3) / b + 1) * sqrt(a * constants::pi() / 2) * ndf; + y = pow(d * 2 * u, 2 / ndf); + + if (y > (0.05f + a)) + { + // + // Asymptotic inverse expansion about normal: + // + x = -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + y = x * x; + + if (ndf < 5) + c += 0.3f * (ndf - 4.5f) * (x + 0.6f); + c += (((0.05f * d * x - 5) * x - 7) * x - 2) * x + b; + y = (((((0.4f * y + 6.3f) * y + 36) * y + 94.5f) / c - y - 3) / b + 1) * x; + y = boost::math::expm1(a * y * y, pol); + } + else + { + y = static_cast(((1 / (((ndf + 6) / (ndf * y) - 0.089f * d - 0.822f) + * (ndf + 2) * 3) + 0.5 / (ndf + 4)) * y - 1) + * (ndf + 1) / (ndf + 2) + 1 / y); + } + q = sqrt(ndf * y); + + return -q; +} +// +// Tail and body series are due to Shaw: +// +// www.mth.kcl.ac.uk/~shaww/web_page/papers/Tdistribution06.pdf +// +// Shaw, W.T., 2006, "Sampling Student's T distribution - use of +// the inverse cumulative distribution function." +// Journal of Computational Finance, Vol 9 Issue 4, pp 37-73, Summer 2006 +// +template +T inverse_students_t_tail_series(T df, T v, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Tail series expansion, see section 6 of Shaw's paper. + // w is calculated using Eq 60: + T w = boost::math::tgamma_delta_ratio(df / 2, constants::half(), pol) + * sqrt(df * constants::pi()) * v; + // define some variables: + T np2 = df + 2; + T np4 = df + 4; + T np6 = df + 6; + // + // Calculate the coefficients d(k), these depend only on the + // number of degrees of freedom df, so at least in theory + // we could tabulate these for fixed df, see p15 of Shaw: + // + T d[7] = { 1, }; + d[1] = -(df + 1) / (2 * np2); + np2 *= (df + 2); + d[2] = -df * (df + 1) * (df + 3) / (8 * np2 * np4); + np2 *= df + 2; + d[3] = -df * (df + 1) * (df + 5) * (((3 * df) + 7) * df -2) / (48 * np2 * np4 * np6); + np2 *= (df + 2); + np4 *= (df + 4); + d[4] = -df * (df + 1) * (df + 7) * + ( (((((15 * df) + 154) * df + 465) * df + 286) * df - 336) * df + 64 ) + / (384 * np2 * np4 * np6 * (df + 8)); + np2 *= (df + 2); + d[5] = -df * (df + 1) * (df + 3) * (df + 9) + * (((((((35 * df + 452) * df + 1573) * df + 600) * df - 2020) * df) + 928) * df -128) + / (1280 * np2 * np4 * np6 * (df + 8) * (df + 10)); + np2 *= (df + 2); + np4 *= (df + 4); + np6 *= (df + 6); + d[6] = -df * (df + 1) * (df + 11) + * ((((((((((((945 * df) + 31506) * df + 425858) * df + 2980236) * df + 11266745) * df + 20675018) * df + 7747124) * df - 22574632) * df - 8565600) * df + 18108416) * df - 7099392) * df + 884736) + / (46080 * np2 * np4 * np6 * (df + 8) * (df + 10) * (df +12)); + // + // Now bring everything together to provide the result, + // this is Eq 62 of Shaw: + // + T rn = sqrt(df); + T div = pow(rn * w, 1 / df); + T power = div * div; + T result = tools::evaluate_polynomial<7, T, T>(d, power); + result *= rn; + result /= div; + return -result; +} + +template +T inverse_students_t_body_series(T df, T u, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Body series for small N: + // + // Start with Eq 56 of Shaw: + // + T v = boost::math::tgamma_delta_ratio(df / 2, constants::half(), pol) + * sqrt(df * constants::pi()) * (u - constants::half()); + // + // Workspace for the polynomial coefficients: + // + T c[11] = { 0, 1, }; + // + // Figure out what the coefficients are, note these depend + // only on the degrees of freedom (Eq 57 of Shaw): + // + T in = 1 / df; + c[2] = static_cast(0.16666666666666666667 + 0.16666666666666666667 * in); + c[3] = static_cast((0.0083333333333333333333 * in + + 0.066666666666666666667) * in + + 0.058333333333333333333); + c[4] = static_cast(((0.00019841269841269841270 * in + + 0.0017857142857142857143) * in + + 0.026785714285714285714) * in + + 0.025198412698412698413); + c[5] = static_cast((((2.7557319223985890653e-6 * in + + 0.00037477954144620811287) * in + - 0.0011078042328042328042) * in + + 0.010559964726631393298) * in + + 0.012039792768959435626); + c[6] = static_cast(((((2.5052108385441718775e-8 * in + - 0.000062705427288760622094) * in + + 0.00059458674042007375341) * in + - 0.0016095979637646304313) * in + + 0.0061039211560044893378) * in + + 0.0038370059724226390893); + c[7] = static_cast((((((1.6059043836821614599e-10 * in + + 0.000015401265401265401265) * in + - 0.00016376804137220803887) * in + + 0.00069084207973096861986) * in + - 0.0012579159844784844785) * in + + 0.0010898206731540064873) * in + + 0.0032177478835464946576); + c[8] = static_cast(((((((7.6471637318198164759e-13 * in + - 3.9851014346715404916e-6) * in + + 0.000049255746366361445727) * in + - 0.00024947258047043099953) * in + + 0.00064513046951456342991) * in + - 0.00076245135440323932387) * in + + 0.000033530976880017885309) * in + + 0.0017438262298340009980); + c[9] = static_cast((((((((2.8114572543455207632e-15 * in + + 1.0914179173496789432e-6) * in + - 0.000015303004486655377567) * in + + 0.000090867107935219902229) * in + - 0.00029133414466938067350) * in + + 0.00051406605788341121363) * in + - 0.00036307660358786885787) * in + - 0.00031101086326318780412) * in + + 0.00096472747321388644237); + c[10] = static_cast(((((((((8.2206352466243297170e-18 * in + - 3.1239569599829868045e-7) * in + + 4.8903045291975346210e-6) * in + - 0.000033202652391372058698) * in + + 0.00012645437628698076975) * in + - 0.00028690924218514613987) * in + + 0.00035764655430568632777) * in + - 0.00010230378073700412687) * in + - 0.00036942667800009661203) * in + + 0.00054229262813129686486); + // + // The result is then a polynomial in v (see Eq 56 of Shaw): + // + return tools::evaluate_odd_polynomial<11, T, T>(c, v); +} + +template +T inverse_students_t(T df, T u, T v, const Policy& pol, bool* pexact = nullptr) +{ + // + // df = number of degrees of freedom. + // u = probability. + // v = 1 - u. + // l = lanczos type to use. + // + BOOST_MATH_STD_USING + bool invert = false; + T result = 0; + if(pexact) + *pexact = false; + if(u > v) + { + // function is symmetric, invert it: + std::swap(u, v); + invert = true; + } + if((floor(df) == df) && (df < 20)) + { + // + // we have integer degrees of freedom, try for the special + // cases first: + // + T tolerance = ldexp(1.0f, (2 * policies::digits()) / 3); + + switch(itrunc(df, Policy())) + { + case 1: + { + // + // df = 1 is the same as the Cauchy distribution, see + // Shaw Eq 35: + // + if(u == 0.5) + result = 0; + else + result = -cos(constants::pi() * u) / sin(constants::pi() * u); + if(pexact) + *pexact = true; + break; + } + case 2: + { + // + // df = 2 has an exact result, see Shaw Eq 36: + // + result =(2 * u - 1) / sqrt(2 * u * v); + if(pexact) + *pexact = true; + break; + } + case 4: + { + // + // df = 4 has an exact result, see Shaw Eq 38 & 39: + // + T alpha = 4 * u * v; + T root_alpha = sqrt(alpha); + T r = 4 * cos(acos(root_alpha) / 3) / root_alpha; + T x = sqrt(r - 4); + result = u - 0.5f < 0 ? (T)-x : x; + if(pexact) + *pexact = true; + break; + } + case 6: + { + // + // We get numeric overflow in this area: + // + if(u < 1e-150) + return (invert ? -1 : 1) * inverse_students_t_hill(df, u, pol); + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + T a = 4 * (u - u * u);//1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = boost::math::cbrt(a, pol); + static const T c = static_cast(0.85498797333834849467655443627193); + T p = 6 * (1 + c * (1 / b - 1)); + T p0; + do{ + T p2 = p * p; + T p4 = p2 * p2; + T p5 = p * p4; + p0 = p; + // next term is given by Eq 41: + p = 2 * (8 * a * p5 - 270 * p2 + 2187) / (5 * (4 * a * p4 - 216 * p - 243)); + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? (T)-p : p; + break; + } +#if 0 + // + // These are Shaw's "exact" but iterative solutions + // for even df, the numerical accuracy of these is + // rather less than Hill's method, so these are disabled + // for now, which is a shame because they are reasonably + // quick to evaluate... + // + case 8: + { + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + static const T c8 = 0.85994765706259820318168359251872L; + T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = pow(a, T(1) / 4); + T p = 8 * (1 + c8 * (1 / b - 1)); + T p0 = p; + do{ + T p5 = p * p; + p5 *= p5 * p; + p0 = p; + // Next term is given by Eq 42: + p = 2 * (3 * p + (640 * (160 + p * (24 + p * (p + 4)))) / (-5120 + p * (-2048 - 960 * p + a * p5))) / 7; + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? -p : p; + break; + } + case 10: + { + // + // Newton-Raphson iteration of a polynomial case, + // choice of seed value is taken from Shaw's online + // supplement: + // + static const T c10 = 0.86781292867813396759105692122285L; + T a = 4 * (u - u * u); //1 - 4 * (u - 0.5f) * (u - 0.5f); + T b = pow(a, T(1) / 5); + T p = 10 * (1 + c10 * (1 / b - 1)); + T p0; + do{ + T p6 = p * p; + p6 *= p6 * p6; + p0 = p; + // Next term given by Eq 43: + p = (8 * p) / 9 + (218750 * (21875 + 4 * p * (625 + p * (75 + 2 * p * (5 + p))))) / + (9 * (-68359375 + 8 * p * (-2343750 + p * (-546875 - 175000 * p + 8 * a * p6)))); + }while(fabs((p - p0) / p) > tolerance); + // + // Use Eq 45 to extract the result: + // + p = sqrt(p - df); + result = (u - 0.5f) < 0 ? -p : p; + break; + } +#endif + default: + goto calculate_real; + } + } + else + { +calculate_real: + if(df > 0x10000000) + { + result = -boost::math::erfc_inv(2 * u, pol) * constants::root_two(); + if((pexact) && (df >= 1e20)) + *pexact = true; + } + else if(df < 3) + { + // + // Use a roughly linear scheme to choose between Shaw's + // tail series and body series: + // + T crossover = 0.2742f - df * 0.0242143f; + if(u > crossover) + { + result = boost::math::detail::inverse_students_t_body_series(df, u, pol); + } + else + { + result = boost::math::detail::inverse_students_t_tail_series(df, u, pol); + } + } + else + { + // + // Use Hill's method except in the extreme tails + // where we use Shaw's tail series. + // The crossover point is roughly exponential in -df: + // + T crossover = ldexp(1.0f, iround(T(df / -0.654f), typename policies::normalise >::type())); + if(u > crossover) + { + result = boost::math::detail::inverse_students_t_hill(df, u, pol); + } + else + { + result = boost::math::detail::inverse_students_t_tail_series(df, u, pol); + } + } + } + return invert ? (T)-result : result; +} + +template +inline T find_ibeta_inv_from_t_dist(T a, T p, T /*q*/, T* py, const Policy& pol) +{ + T u = p / 2; + T v = 1 - u; + T df = a * 2; + T t = boost::math::detail::inverse_students_t(df, u, v, pol); + *py = t * t / (df + t * t); + return df / (df + t * t); +} + +template +inline T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const std::false_type*) +{ + BOOST_MATH_STD_USING + // + // Need to use inverse incomplete beta to get + // required precision so not so fast: + // + T probability = (p > 0.5) ? 1 - p : p; + T t, x, y(0); + x = ibeta_inv(df / 2, T(0.5), 2 * probability, &y, pol); + if(df * y > tools::max_value() * x) + t = policies::raise_overflow_error("boost::math::students_t_quantile<%1%>(%1%,%1%)", nullptr, pol); + else + t = sqrt(df * y / x); + // + // Figure out sign based on the size of p: + // + if(p < 0.5) + t = -t; + return t; +} + +template +T fast_students_t_quantile_imp(T df, T p, const Policy& pol, const std::true_type*) +{ + BOOST_MATH_STD_USING + bool invert = false; + if((df < 2) && (floor(df) != df)) + return boost::math::detail::fast_students_t_quantile_imp(df, p, pol, static_cast(nullptr)); + if(p > 0.5) + { + p = 1 - p; + invert = true; + } + // + // Get an estimate of the result: + // + bool exact; + T t = inverse_students_t(df, p, T(1-p), pol, &exact); + if((t == 0) || exact) + return invert ? -t : t; // can't do better! + // + // Change variables to inverse incomplete beta: + // + T t2 = t * t; + T xb = df / (df + t2); + T y = t2 / (df + t2); + T a = df / 2; + // + // t can be so large that x underflows, + // just return our estimate in that case: + // + if(xb == 0) + return t; + // + // Get incomplete beta and it's derivative: + // + T f1; + T f0 = xb < y ? ibeta_imp(a, constants::half(), xb, pol, false, true, &f1) + : ibeta_imp(constants::half(), a, y, pol, true, true, &f1); + + // Get cdf from incomplete beta result: + T p0 = f0 / 2 - p; + // Get pdf from derivative: + T p1 = f1 * sqrt(y * xb * xb * xb / df); + // + // Second derivative divided by p1: + // + // yacas gives: + // + // In> PrettyForm(Simplify(D(t) (1 + t^2/v) ^ (-(v+1)/2))) + // + // | | v + 1 | | + // | -| ----- + 1 | | + // | | 2 | | + // -| | 2 | | + // | | t | | + // | | -- + 1 | | + // | ( v + 1 ) * | v | * t | + // --------------------------------------------- + // v + // + // Which after some manipulation is: + // + // -p1 * t * (df + 1) / (t^2 + df) + // + T p2 = t * (df + 1) / (t * t + df); + // Halley step: + t = fabs(t); + t += p0 / (p1 + p0 * p2 / 2); + return !invert ? -t : t; +} + +template +inline T fast_students_t_quantile(T df, T p, const Policy& pol) +{ + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef std::integral_constant::digits <= 53) + && + (std::numeric_limits::is_specialized) + && + (std::numeric_limits::radix == 2) + > tag_type; + return policies::checked_narrowing_cast(fast_students_t_quantile_imp(static_cast(df), static_cast(p), pol, static_cast(nullptr)), "boost::math::students_t_quantile<%1%>(%1%,%1%,%1%)"); +} + +}}} // namespaces + +#endif // BOOST_MATH_SF_DETAIL_INV_T_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_bernoulli.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_bernoulli.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_bernoulli.hpp @@ -0,0 +1,721 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2013 John Maddock +// Copyright 2013 Paul Bristow +// Distributed under 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_UNCHECKED_BERNOULLI_HPP +#define BOOST_MATH_UNCHECKED_BERNOULLI_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + +namespace detail { + +template +struct max_bernoulli_index +{ + static constexpr unsigned value = 17; +}; + +template <> +struct max_bernoulli_index<1> +{ + static constexpr unsigned value = 32; +}; + +template <> +struct max_bernoulli_index<2> +{ + static constexpr unsigned value = 129; +}; + +template <> +struct max_bernoulli_index<3> +{ + static constexpr unsigned value = 1156; +}; + +template <> +struct max_bernoulli_index<4> +{ + static constexpr unsigned value = 11; +}; + +template +struct bernoulli_imp_variant +{ + static constexpr unsigned value = + (std::numeric_limits::max_exponent == 128) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 1 : + ( + (std::numeric_limits::max_exponent == 1024) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 2 : + ( + (std::numeric_limits::max_exponent == 16384) + && (std::numeric_limits::radix == 2) + && (std::numeric_limits::digits <= std::numeric_limits::digits) + && (std::is_convertible::value) ? 3 : (!std::is_convertible::value ? 4 : 0) + ) + ); +}; + +} // namespace detail + +template +struct max_bernoulli_b2n : public detail::max_bernoulli_index::value>{}; + +namespace detail{ + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array::value> numerators = +#else + static const std::array::value> numerators = +#endif + {{ + std::int64_t( +1LL), + std::int64_t( +1LL), + std::int64_t( -1LL), + std::int64_t( +1LL), + std::int64_t( -1LL), + std::int64_t( +5LL), + std::int64_t( -691LL), + std::int64_t( +7LL), + std::int64_t( -3617LL), + std::int64_t( +43867LL), + std::int64_t( -174611LL), + std::int64_t( +854513LL), + std::int64_t( -236364091LL), + std::int64_t( +8553103LL), + std::int64_t( -23749461029LL), + std::int64_t(+8615841276005LL), + std::int64_t(-7709321041217LL), + std::int64_t(+2577687858367LL) + }}; + +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array::value> denominators = +#else + static const std::array::value> denominators = +#endif + {{ + std::int64_t( 1LL), + std::int64_t( 6LL), + std::int64_t( 30LL), + std::int64_t( 42LL), + std::int64_t( 30LL), + std::int64_t( 66LL), + std::int64_t( 2730LL), + std::int64_t( 6LL), + std::int64_t( 510LL), + std::int64_t( 798LL), + std::int64_t( 330LL), + std::int64_t( 138LL), + std::int64_t( 2730LL), + std::int64_t( 6LL), + std::int64_t( 870LL), + std::int64_t( 14322LL), + std::int64_t( 510LL), + std::int64_t( 6LL) + }}; + return T(numerators[n]) / denominators[n]; +} + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array::value> bernoulli_data = +#else + static const std::array::value> bernoulli_data = +#endif + {{ + +1.00000000000000000000000000000000000000000F, + +0.166666666666666666666666666666666666666667F, + -0.0333333333333333333333333333333333333333333F, + +0.0238095238095238095238095238095238095238095F, + -0.0333333333333333333333333333333333333333333F, + +0.0757575757575757575757575757575757575757576F, + -0.253113553113553113553113553113553113553114F, + +1.16666666666666666666666666666666666666667F, + -7.09215686274509803921568627450980392156863F, + +54.9711779448621553884711779448621553884712F, + -529.124242424242424242424242424242424242424F, + +6192.12318840579710144927536231884057971014F, + -86580.2531135531135531135531135531135531136F, + +1.42551716666666666666666666666666666666667e6F, + -2.72982310678160919540229885057471264367816e7F, + +6.01580873900642368384303868174835916771401e8F, + -1.51163157670921568627450980392156862745098e10F, + +4.29614643061166666666666666666666666666667e11F, + -1.37116552050883327721590879485616327721591e13F, + +4.88332318973593166666666666666666666666667e14F, + -1.92965793419400681486326681448632668144863e16F, + +8.41693047573682615000553709856035437430786e17F, + -4.03380718540594554130768115942028985507246e19F, + +2.11507486380819916056014539007092198581560e21F, + -1.20866265222965259346027311937082525317819e23F, + +7.50086674607696436685572007575757575757576e24F, + -5.03877810148106891413789303052201257861635e26F, + +3.65287764848181233351104308429711779448622e28F, + -2.84987693024508822262691464329106781609195e30F, + +2.38654274996836276446459819192192149717514e32F, + -2.13999492572253336658107447651910973926742e34F, + +2.05009757234780975699217330956723102516667e36F, + -2.09380059113463784090951852900279701847092e38F, + }}; + + return bernoulli_data[n]; +} + + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array::value> bernoulli_data = +#else + static const std::array::value> bernoulli_data = +#endif + {{ + +1.00000000000000000000000000000000000000000, + +0.166666666666666666666666666666666666666667, + -0.0333333333333333333333333333333333333333333, + +0.0238095238095238095238095238095238095238095, + -0.0333333333333333333333333333333333333333333, + +0.0757575757575757575757575757575757575757576, + -0.253113553113553113553113553113553113553114, + +1.16666666666666666666666666666666666666667, + -7.09215686274509803921568627450980392156863, + +54.9711779448621553884711779448621553884712, + -529.124242424242424242424242424242424242424, + +6192.12318840579710144927536231884057971014, + -86580.2531135531135531135531135531135531136, + +1.42551716666666666666666666666666666666667e6, + -2.72982310678160919540229885057471264367816e7, + +6.01580873900642368384303868174835916771401e8, + -1.51163157670921568627450980392156862745098e10, + +4.29614643061166666666666666666666666666667e11, + -1.37116552050883327721590879485616327721591e13, + +4.88332318973593166666666666666666666666667e14, + -1.92965793419400681486326681448632668144863e16, + +8.41693047573682615000553709856035437430786e17, + -4.03380718540594554130768115942028985507246e19, + +2.11507486380819916056014539007092198581560e21, + -1.20866265222965259346027311937082525317819e23, + +7.50086674607696436685572007575757575757576e24, + -5.03877810148106891413789303052201257861635e26, + +3.65287764848181233351104308429711779448622e28, + -2.84987693024508822262691464329106781609195e30, + +2.38654274996836276446459819192192149717514e32, + -2.13999492572253336658107447651910973926742e34, + +2.05009757234780975699217330956723102516667e36, + -2.09380059113463784090951852900279701847092e38, + +2.27526964884635155596492603527692645814700e40, + -2.62577102862395760473030497361582020814490e42, + +3.21250821027180325182047923042649852435219e44, + -4.15982781667947109139170744952623589366896e46, + +5.69206954820352800238834562191210586444805e48, + -8.21836294197845756922906534686173330145509e50, + +1.25029043271669930167323398297028955241772e53, + -2.00155832332483702749253291988132987687242e55, + +3.36749829153643742333966769033387530162196e57, + -5.94709705031354477186604968440515408405791e59, + +1.10119103236279775595641307904376916046305e62, + -2.13552595452535011886583850190410656789733e64, + +4.33288969866411924196166130593792062184514e66, + -9.18855282416693282262005552155018971389604e68, + +2.03468967763290744934550279902200200659751e71, + -4.70038339580357310785752555350060606545967e73, + +1.13180434454842492706751862577339342678904e76, + -2.83822495706937069592641563364817647382847e78, + +7.40642489796788506297508271409209841768797e80, + -2.00964548027566044834656196727153631868673e83, + +5.66571700508059414457193460305193569614195e85, + -1.65845111541362169158237133743199123014950e88, + +5.03688599504923774192894219151801548124424e90, + -1.58614682376581863693634015729664387827410e93, + +5.17567436175456269840732406825071225612408e95, + -1.74889218402171173396900258776181591451415e98, + +6.11605199949521852558245252642641677807677e100, + -2.21227769127078349422883234567129324455732e103, + +8.27227767987709698542210624599845957312047e105, + -3.19589251114157095835916343691808148735263e108, + +1.27500822233877929823100243029266798669572e111, + -5.25009230867741338994028246245651754469199e113, + +2.23018178942416252098692981988387281437383e116, + -9.76845219309552044386335133989802393011669e118, + +4.40983619784529542722726228748131691918758e121, + -2.05085708864640888397293377275830154864566e124, + +9.82144332797912771075729696020975210414919e126, + -4.84126007982088805087891967099634127611305e129, + +2.45530888014809826097834674040886903996737e132, + -1.28069268040847475487825132786017857218118e135, + +6.86761671046685811921018885984644004360924e137, + -3.78464685819691046949789954163795568144895e140, + +2.14261012506652915508713231351482720966602e143, + -1.24567271371836950070196429616376072194583e146, + +7.43457875510001525436796683940520613117807e148, + -4.55357953046417048940633332233212748767721e151, + +2.86121128168588683453638472510172325229190e154, + -1.84377235520338697276882026536287854875414e157, + +1.21811545362210466995013165065995213558174e160, + -8.24821871853141215484818457296893447301419e162, + +5.72258779378329433296516498142978615918685e165, + -4.06685305250591047267679693831158655602196e168, + +2.95960920646420500628752695815851870426379e171, + -2.20495225651894575090311752273445984836379e174, + +1.68125970728895998058311525151360665754464e177, + -1.31167362135569576486452806355817153004431e180, + +1.04678940094780380821832853929823089643829e183, + -8.54328935788337077185982546299082774593270e185, + +7.12878213224865423522884066771438224721245e188, + -6.08029314555358993000847118686477458461988e191, + +5.29967764248499239300942910043247266228490e194, + -4.71942591687458626443646229013379911103761e197, + +4.29284137914029810894168296541074669045521e200, + -3.98767449682322074434477655542938795106651e203, + +3.78197804193588827138944181161393327898220e206, + -3.66142336836811912436858082151197348755196e209, + +3.61760902723728623488554609298914089477541e212, + -3.64707726451913543621383088655499449048682e215, + +3.75087554364544090983452410104814189306842e218, + -3.93458672964390282694891288533713429355657e221, + +4.20882111481900820046571171111494898242731e224, + -4.59022962206179186559802940573325591059371e227, + +5.10317257726295759279198185106496768539760e230, + -5.78227623036569554015377271242917142512200e233, + +6.67624821678358810322637794412809363451080e236, + -7.85353076444504163225916259639312444428230e239, + +9.41068940670587255245443288258762485293948e242, + -1.14849338734651839938498599206805592548354e246, + +1.42729587428487856771416320087122499897180e249, + -1.80595595869093090142285728117654560926719e252, + +2.32615353076608052161297985184708876161736e255, + -3.04957517154995947681942819261542593785327e258, + +4.06858060764339734424012124124937318633684e261, + -5.52310313219743616252320044093186392324280e264, + +7.62772793964343924869949690204961215533859e267, + -1.07155711196978863132793524001065396932667e271, + +1.53102008959691884453440916153355334355847e274, + -2.22448916821798346676602348865048510824835e277, + +3.28626791906901391668189736436895275365183e280, + -4.93559289559603449020711938191575963496999e283, + +7.53495712008325067212266049779283956727824e286, + -1.16914851545841777278088924731655041783900e290, + +1.84352614678389394126646201597702232396492e293, + -2.95368261729680829728014917350525183485207e296, + +4.80793212775015697668878704043264072227967e299, + -7.95021250458852528538243631671158693036798e302, + +1.33527841873546338750122832017820518292039e306 + }}; + + return bernoulli_data[n]; +} + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array::value> bernoulli_data = +#else + static const std::array::value> bernoulli_data = +#endif + {{ + +1.00000000000000000000000000000000000000000L, + +0.166666666666666666666666666666666666666667L, + -0.0333333333333333333333333333333333333333333L, + +0.0238095238095238095238095238095238095238095L, + -0.0333333333333333333333333333333333333333333L, + +0.0757575757575757575757575757575757575757576L, + -0.253113553113553113553113553113553113553114L, + +1.16666666666666666666666666666666666666667L, + -7.09215686274509803921568627450980392156863L, + +54.9711779448621553884711779448621553884712L, + -529.124242424242424242424242424242424242424L, + +6192.12318840579710144927536231884057971014L, + -86580.2531135531135531135531135531135531136L, + +1.42551716666666666666666666666666666666667E6L, + -2.72982310678160919540229885057471264367816E7L, + +6.01580873900642368384303868174835916771401E8L, + -1.51163157670921568627450980392156862745098E10L, + +4.29614643061166666666666666666666666666667E11L, + -1.37116552050883327721590879485616327721591E13L, + +4.88332318973593166666666666666666666666667E14L, + -1.92965793419400681486326681448632668144863E16L, + +8.41693047573682615000553709856035437430786E17L, + -4.03380718540594554130768115942028985507246E19L, + +2.11507486380819916056014539007092198581560E21L, + -1.20866265222965259346027311937082525317819E23L, + +7.50086674607696436685572007575757575757576E24L, + -5.03877810148106891413789303052201257861635E26L, + +3.65287764848181233351104308429711779448622E28L, + -2.84987693024508822262691464329106781609195E30L, + +2.38654274996836276446459819192192149717514E32L, + -2.13999492572253336658107447651910973926742E34L, + +2.05009757234780975699217330956723102516667E36L, + -2.09380059113463784090951852900279701847092E38L, + +2.27526964884635155596492603527692645814700E40L, + -2.62577102862395760473030497361582020814490E42L, + +3.21250821027180325182047923042649852435219E44L, + -4.15982781667947109139170744952623589366896E46L, + +5.69206954820352800238834562191210586444805E48L, + -8.21836294197845756922906534686173330145509E50L, + +1.25029043271669930167323398297028955241772E53L, + -2.00155832332483702749253291988132987687242E55L, + +3.36749829153643742333966769033387530162196E57L, + -5.94709705031354477186604968440515408405791E59L, + +1.10119103236279775595641307904376916046305E62L, + -2.13552595452535011886583850190410656789733E64L, + +4.33288969866411924196166130593792062184514E66L, + -9.18855282416693282262005552155018971389604E68L, + +2.03468967763290744934550279902200200659751E71L, + -4.70038339580357310785752555350060606545967E73L, + +1.13180434454842492706751862577339342678904E76L, + -2.83822495706937069592641563364817647382847E78L, + +7.40642489796788506297508271409209841768797E80L, + -2.00964548027566044834656196727153631868673E83L, + +5.66571700508059414457193460305193569614195E85L, + -1.65845111541362169158237133743199123014950E88L, + +5.03688599504923774192894219151801548124424E90L, + -1.58614682376581863693634015729664387827410E93L, + +5.17567436175456269840732406825071225612408E95L, + -1.74889218402171173396900258776181591451415E98L, + +6.11605199949521852558245252642641677807677E100L, + -2.21227769127078349422883234567129324455732E103L, + +8.27227767987709698542210624599845957312047E105L, + -3.19589251114157095835916343691808148735263E108L, + +1.27500822233877929823100243029266798669572E111L, + -5.25009230867741338994028246245651754469199E113L, + +2.23018178942416252098692981988387281437383E116L, + -9.76845219309552044386335133989802393011669E118L, + +4.40983619784529542722726228748131691918758E121L, + -2.05085708864640888397293377275830154864566E124L, + +9.82144332797912771075729696020975210414919E126L, + -4.84126007982088805087891967099634127611305E129L, + +2.45530888014809826097834674040886903996737E132L, + -1.28069268040847475487825132786017857218118E135L, + +6.86761671046685811921018885984644004360924E137L, + -3.78464685819691046949789954163795568144895E140L, + +2.14261012506652915508713231351482720966602E143L, + -1.24567271371836950070196429616376072194583E146L, + +7.43457875510001525436796683940520613117807E148L, + -4.55357953046417048940633332233212748767721E151L, + +2.86121128168588683453638472510172325229190E154L, + -1.84377235520338697276882026536287854875414E157L, + +1.21811545362210466995013165065995213558174E160L, + -8.24821871853141215484818457296893447301419E162L, + +5.72258779378329433296516498142978615918685E165L, + -4.06685305250591047267679693831158655602196E168L, + +2.95960920646420500628752695815851870426379E171L, + -2.20495225651894575090311752273445984836379E174L, + +1.68125970728895998058311525151360665754464E177L, + -1.31167362135569576486452806355817153004431E180L, + +1.04678940094780380821832853929823089643829E183L, + -8.54328935788337077185982546299082774593270E185L, + +7.12878213224865423522884066771438224721245E188L, + -6.08029314555358993000847118686477458461988E191L, + +5.29967764248499239300942910043247266228490E194L, + -4.71942591687458626443646229013379911103761E197L, + +4.29284137914029810894168296541074669045521E200L, + -3.98767449682322074434477655542938795106651E203L, + +3.78197804193588827138944181161393327898220E206L, + -3.66142336836811912436858082151197348755196E209L, + +3.61760902723728623488554609298914089477541E212L, + -3.64707726451913543621383088655499449048682E215L, + +3.75087554364544090983452410104814189306842E218L, + -3.93458672964390282694891288533713429355657E221L, + +4.20882111481900820046571171111494898242731E224L, + -4.59022962206179186559802940573325591059371E227L, + +5.10317257726295759279198185106496768539760E230L, + -5.78227623036569554015377271242917142512200E233L, + +6.67624821678358810322637794412809363451080E236L, + -7.85353076444504163225916259639312444428230E239L, + +9.41068940670587255245443288258762485293948E242L, + -1.14849338734651839938498599206805592548354E246L, + +1.42729587428487856771416320087122499897180E249L, + -1.80595595869093090142285728117654560926719E252L, + +2.32615353076608052161297985184708876161736E255L, + -3.04957517154995947681942819261542593785327E258L, + +4.06858060764339734424012124124937318633684E261L, + -5.52310313219743616252320044093186392324280E264L, + +7.62772793964343924869949690204961215533859E267L, + -1.07155711196978863132793524001065396932667E271L, + +1.53102008959691884453440916153355334355847E274L, + -2.22448916821798346676602348865048510824835E277L, + +3.28626791906901391668189736436895275365183E280L, + -4.93559289559603449020711938191575963496999E283L, + +7.53495712008325067212266049779283956727824E286L, + -1.16914851545841777278088924731655041783900E290L, + +1.84352614678389394126646201597702232396492E293L, + -2.95368261729680829728014917350525183485207E296L, + +4.80793212775015697668878704043264072227967E299L, + -7.95021250458852528538243631671158693036798E302L, + +1.33527841873546338750122832017820518292039E306L, +#if LDBL_MAX_EXP == 16384 + // Entries 260 - 600 http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C258%2C600%2C2}] + -2.277640649601959593875058983506938037019e309L, + 3.945184036046326234163525556422667595884e312L, + -6.938525772130602106071724989641405550473e315L, + 1.238896367577564823729057820219210929986e319L, + -2.245542599169309759499987966025604480745e322L, + 4.131213176073842359732511639489669404266e325L, + -7.713581346815269584960928069762882771369e328L, + 1.461536066837669600638613788471335541313e332L, + -2.809904606225532896862935642992712059631e335L, + 5.480957121318876639512096994413992284327e338L, + -1.084573284087686110518125291186079616320e342L, + 2.176980775647663539729165173863716459962e345L, + -4.431998786117553751947439433256752608068e348L, + 9.150625657715535047417756278073770096073e351L, + -1.915867353003157351316577579148683133613e355L, + 4.067256303542212258698836003682016040629e358L, + -8.754223791037736616228150209910348734629e361L, + 1.910173688735533667244373747124109379826e365L, + -4.225001320265091714631115064713174404607e368L, + 9.471959352547827678466770796787503034505e371L, + -2.152149973279986829719817376756088198573e375L, + 4.955485775334221051344839716507812871361e378L, + -1.156225941759134696630956889716381968142e382L, + 2.733406597646137698610991926705098514017e385L, + -6.546868135325176947099912523279938546333e388L, + 1.588524912441221472814692121069821695547e392L, + -3.904354800861715180218598151050191841308e395L, + 9.719938686092045781827273411668132975319e398L, + -2.450763621049522051234479737511375679283e402L, + 6.257892098396815305085674126334317095277e405L, + -1.618113552083806592527989531636955084420e409L, + 4.236528795217618357348618613216833722648e412L, + -1.123047068199051008086174989124136878992e416L, + 3.013971787525654770217283559392286666886e419L, + -8.188437573221553030375681429202969070420e422L, + 2.251910591336716809153958146725775718707e426L, + -6.268411292043789823075314151509139413399e429L, + 1.765990845202322642693572112511312471527e433L, + -5.035154436231331651259071296731160882240e436L, + 1.452779356460483245253765356664402207266e440L, + -4.241490890130137339052414960684151515166e443L, + 1.252966001692427774088293833338841893293e447L, + -3.744830047478272947978103227876747240343e450L, + 1.132315806695710930595876001089232216024e454L, + -3.463510845942701805991786197773934662578e457L, + 1.071643382649675572086865465873916611537e461L, + -3.353824475439933688957233489984711465335e464L, + 1.061594257145875875963152734129803268488e468L, + -3.398420969215528955528654193586189805265e471L, + 1.100192502000434096206138068020551065890e475L, + -3.601686379213993374332690210094863486472e478L, + 1.192235170430164900533187239994513019475e482L, + -3.990342751779668381699052942504119409180e485L, + 1.350281800938769780891258894167663309221e489L, + -4.619325443466054312873093650888507562249e492L, + 1.597522243968586548227514639959727696694e496L, + -5.584753729092155108530929002119620487652e499L, + 1.973443623104646193229794524759543752089e503L, + -7.048295441989615807045620880311201930244e506L, + 2.544236702499719094591873151590280263560e510L, + -9.281551595258615205927443367289948150345e513L, + 3.421757163154453657766296828520235351572e517L, + -1.274733639384538364282697627345068947433e521L, + 4.798524805311016034711205886780460173566e524L, + -1.825116948422858388787806917284878870034e528L, + 7.013667442807288452441777981425055613982e531L, + -2.723003862685989740898815670978399383114e535L, + 1.068014853917260290630122222858884658850e539L, + -4.231650952273697842269381683768681118533e542L, + 1.693650052202594386658903598564772900388e546L, + -6.846944855806453360616258582310883597678e549L, + 2.795809132238082267120232174243715559601e553L, + -1.153012972808983269106716828311318981951e557L, + 4.802368854268746357511997492039592697149e560L, + -2.019995255271910836389761734035403905781e564L, + 8.580207235032617856059250643095019760968e567L, + -3.680247942263468164408192134916355198549e571L, + 1.593924457586765331397457407661306895942e575L, + -6.970267175232643679233530367569943057501e578L, + 3.077528087427698518703282907890556154309e582L, + -1.371846760052887888926055417297342106614e586L, + 6.173627360829553396851763207025505289166e589L, + -2.804703130495506384463249394043486916669e593L, + 1.286250900087150126167490951216207186092e597L, + -5.954394420063617872366818601092036543220e600L, + 2.782297785278756426177542270854984091406e604L, + -1.312214674935307746141207680066262384215e608L, + 6.246299145383554153167974732783934504370e611L, + -3.000812007679574430883792565577444226490e615L, + 1.454904877136007844493861746476079537075e619L, + -7.118558521873800304612781121044077357278e622L, + 3.514739820897817389472822276832677887997e626L, + -1.751137068816377401163011262831890828437e630L, + 8.803498091818800678575314081978951179602e633L, + -4.465612911700593572269200981612564161010e637L, + 2.285494565287530681465757798517033542888e641L, + -1.180145168917737098025683613598595411329e645L, + 6.147941849198393232663105284575149616925e648L, + -3.231069156963603593233679426198974663352e652L, + 1.713042725635435041806895849197608270935e656L, + -9.161761363270648920537613435771882898051e659L, + 4.942675965960539112005679080810117766825e663L, + -2.689684712697383518131267222872386600031e667L, + 1.476320014229917759615308193449511534656e671L, + -8.173037740864781506597184122049453514594e674L, + 4.563462313190521363235182420178784459580e678L, + -2.569790015236158475703055501886439298708e682L, + 1.459410219452119981958355737832022375085e686L, + -8.358304882556983795372406183642486436653e689L, + 4.827305091483557818593092377664570208355e693L, + -2.811394311081493166793414157061950132403e697L, + 1.651026863340675349245561261339568827739e701L, + -9.776578579336866764167878646459810047899e704L, + 5.837207965197521880181236529616560780535e708L, + -3.513938957938032127105389702846371181520e712L, + 2.132747371360190507595748444536911078788e716L, + -1.305047363239192640729466563372665311602e720L, + 8.050825342678337497636292798039996484780e723L, + -5.006884161223862543665524155681082112689e727L, + 3.139016066011452177570812014513491361235e731L, + -1.983829535212711378291469356666001365873e735L, + 1.263822427649676371257598052486237628698e739L, + -8.115678659900522918802121684491754629503e742L, + 5.252995164972075271667364371449050412435e746L, + -3.427038125662404660056511738625477058135e750L, + 2.253446011834352733279946306835940729858e754L, + -1.493407341897034717876962786798831719683e758L, + 9.974681322653365118752729509398728354442e761L, + -6.714230142773850863927710112350816379426e765L, + 4.554668668931723346600337564274944733530e769L, + -3.113635386023220127834102980385275379533e773L, + 2.144945411287666204679363498162954050208e777L, + -1.488982121181387164932397544378555256016e781L, + 1.041537218854627455352298173588983048748e785L, + -7.341073881786613676177562822942175683993e788L, + 5.213524272587199574980117351016322518428e792L, + -3.730592531776514409283897139216167197989e796L, + 2.689592876341877079083449497724049500175e800L, + -1.953643788231947582529884602972233135002e804L, + 1.429691073080500563348668321308878246277e808L, + -1.054059177095488639836063073070536825675e812L, + 7.828919160938693948399336431565350676613e815L, + -5.857884457184396382550955498026762014753e819L, + 4.415401588264172474136969345712659422380e823L, + -3.352573884181287635796498822858109969161e827L, + 2.564210385719224000156548240934108974447e831L, + -1.975534392116037602837941409848663077528e835L, + 1.533062123975940045180943006948008486466e839L, + -1.198306160488763291730059994812781226903e843L, + 9.434034267770711698676321369174735725321e846L, + -7.480619200038505368468483892246806488879e850L, + 5.974161898439971564124576801455052907638e854L, + -4.805125663714699771668630995361572639386e858L, + 3.892332138028039952403812726744593073776e862L, + -3.175276505779699340738548328810180869575e866L, + 2.608608681939322393581069188271626122519e870L, + -2.158148554392732439392868052394994052628e874L, + 1.797993483301448477700600221980862686033e878L, + -1.508407575089108597171576068862286462909e882L, + 1.274273406242459482708930389008701147244e886L, + -1.083950475353171986748233157909397370193e890L, + 9.284292630726328432038470356821265395331e893L, + -8.007012115449516364480417355063446317414e897L, + 6.952871948429568933888979915833266241471e901L, + -6.078828929473797621198666799700739891205e905L, + 5.350908089710964244671334224708057812633e909L, + -4.742168072503284973969982758434401589090e913L, + 4.231149239401967697257534662010605751136e917L, + -3.800684612827828851942743291026898158947e921L, + 3.436984796314246158361599955909956583986e925L, + -3.128930718993658356398482705317381808301e929L, + // + // 602-1300: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C602%2C1300%2C2}] + 2.867524740577223817164663595437919813239e933L, -2.645462974939090580963101220449509725942e937L, 2.456800827789169780295419018499543141869e941L, -2.296690549725790064673528302231294870532e945L, 2.161174697699793265715182091764676666457e949L, -2.047023224586087259305754002882269123194e953L, 1.951604806042481282712736234132803700277e957L, -1.872785206668284042110390583158639495143e961L, 1.808847160923282257302788929692654262867e965L, -1.758427529634609613399327744595257497188e969L, 1.720468488019528147087036246754294757647e973L, -1.694180279355332648057740852839804839425e977L, 1.679013685251183870616469618951463869496e981L, -1.674640861433092946269144173974414945664e985L, 1.680943600147858322148767806987527412112e989L, -1.698008433134805056489370119323402510305e993L, 1.726128304411348354183882648263448448633e997L, -1.765810838736918108045764015629875016219e1001L, 1.817793526882665071123822455897912718293e1005L, -1.883066459765807128944897377914669600374e1009L, 1.962903588035940537938222992228124233567e1013L, -2.058903881920696086033171142046100185783e1017L, 2.173044241735786946064676598703393618281e1021L, -2.307746591425236218893160658331303115253e1025L, 2.465962312241418731528973526597433097256e1029L, -2.651278087802503406316742676403301581549e1033L, 2.868048395658440423778896607880692085708e1037L, -3.121561373094393453726645989392054731637e1041L, 3.418246710091027042099932753084126095820e1045L, -3.765936717592482928796920675282930034018e1049L, 4.174194967165213973474293718362757753877e1053L, -4.654731142471753017867105249805137855862e1057L, 5.221926310090434518253178454907900079787e1061L, -5.893500145664015254409680930288710794031e1065L, 6.691361332576333738130720616841706994101e1069L, -7.642695184575063524608775697714741180954e1073L, 8.781359617440634128952082759434723165820e1077L, -1.014968338800868135594698909567734048618e1082L, 1.180079105471061498849752479044520598414e1086L, -1.380162016721660241308046692646452732446e1090L, 1.623685158291375662775444238282343536948e1094L, -1.921404880943289359290531906131400049399e1098L, 2.287040419533950152851434188305457266969e1102L, -2.738162880206032093123060939173765335255e1106L, 3.297371307848643161532227459901386725801e1110L, -3.993854689967542662299211323085023297602e1114L, 4.865474805885735467044047308902313673643e1118L, -5.961554732739027308247618738765152679497e1122L, 7.346627151757492821447573639763873833441e1126L, -9.105493288459908620636712748727395637965e1130L, 1.135007867626164861991621396462821975167e1135L, -1.422876214067403769204874786137232627418e1139L, 1.793912271573925309173135913914667878908e1143L, -2.274542916104231188526120123855259514144e1147L, 2.900273688809987694128857655036783261991e1151L, -3.719022795563122339874875448447744493398e1155L, 4.795753420982845153626611023078973364321e1159L, -6.218937220186281310109009529226561379773e1163L, 8.109611247999584815668395828940708619394e1167L, -1.063412316303440216539797215354141158589e1172L, 1.402214363674117662460496032135704328989e1176L, -1.859223235464558752766840772026058694872e1180L, 2.478828203789903637835992128856742276028e1184L, -3.323169416193176673655321536761413885767e1188L, 4.479640207312477092938541546776915956580e1192L, -6.071721672924085739424644485636889518799e1196L, 8.274698015123579607850404326757887762270e1200L, -1.133855131459773018024052539697784205966e1205L, 1.562146222050424344025824344480153248984e1209L, -2.163904570724750459592352173471446831752e1213L, 3.013703210722669908901286635073603018696e1217L, -4.219903244242308803914269531001720703294e1221L, 5.940703220571043642186808904696174833998e1225L, -8.408147464216029127243257448169774333631e1229L, 1.196419999747411909144144315499654470715e1234L, -1.711518922741148710381740436694440587059e1238L, 2.461434539630850545757453894977350505251e1242L, -3.558748530932574002484841810677232366801e1246L, 5.172525606281917297657859608800373729529e1250L, -7.557850217376323621984784308774476917753e1254L, 1.110141075986004209769735296234549704181e1259L, -1.639216556732622481406083885926912451281e1263L, 2.433138328152562628385514545400044125983e1267L, -3.630476645219033020888837165221286413171e1271L, 5.445289518636306992942604775585977779418e1275L, -8.209806424989072060381590985042272020067e1279L, 1.244209849774134691374848390346442737613e1284L, -1.895384488692308848372754844910263931874e1288L, 2.902272596647764894203369746806169285113e1292L, -4.466944174025026625137032739317650862593e1296L, 6.910485739507636504313238347702354354916e1300L, -1.074550085668784170644854815272144687769e1305L, 1.679419258904938802199084915274175753529e1309L, -2.638155207645646220849795321076977230763e1313L, 4.165284786632654168563096850610185378233e1317L, -6.609774274649031371770290191295685774584e1321L, 1.054194100570841329575393359295845860860e1326L, -1.689822316104196916970708778265725885275e1330L, 2.722340957904912685605914893019783431164e1334L, -4.407776313964403233676810178851005163725e1338L, 7.172436210641903635864868181569129834361e1342L, -1.172947440100495955246356688225986736990e1347L, 1.927745674072824377954824961348211728006e1351L, -3.184013467435655962214317208087993711563e1355L, 5.285045125125832341263897233405196808096e1359L, -8.815883582819232027207118521581424783107e1363L, 1.477818368424505276711779171224799759099e1368L, -2.489482576496570159333357550363134602876e1372L, 4.214292881345076419678976329218843808204e1376L, -7.169068531615459070909644981451297906220e1380L, 1.225513133750594558180516896275774441895e1385L, -2.105160827387119480607950260289853896637e1389L, 3.633787605672960549893307203363402915249e1393L, -6.302830804027849515239463308430185990705e1397L, 1.098521433860299633481449685364914115468e1402L, -1.923858597401607622723144320370279518600e1406L, 3.385512828549942051667348582951554570164e1410L, -5.986286250836771248147827011780631183980e1414L, 1.063572794668186370728928272374836554300e1419L, -1.898666684876492795233907174493757572290e1423L, 3.405627002840442789235393111726609930533e1427L, -6.137724140284450036591063946055819333244e1431L, 1.111411024660941507986132154479364267486e1436L, -2.022060876221034821890406900217875915949e1440L, 3.696248025817144690840539132103538834108e1444L, -6.788448439024998306316860676030442691610e1448L, 1.252615233049059554031883468823648511657e1453L, -2.322190433141265975888955985950824418729e1457L, 4.325200102353909846882217732999001735342e1461L, -8.093531903011880118699218269369570178812e1465L, 1.521558881878323790120983450270946857209e1470L, -2.873780311010933807686415826253380907421e1474L, 5.452903697278823304173192839252276211670e1478L, -1.039457922537509500320638240809547113575e1483L, 1.990610112724715126895008793014214505760e1487L, -3.829667853173777076954453401761025071562e1491L, 7.401624504283011888971231756333356050310e1495L, -1.437075122764477911733220492562365990710e1500L, 2.802940275035867428066581228962104019228e1504L, -5.491938363067613321364335249495394164430e1508L, 1.080961960603953462180593404647115933651e1513L, -2.137290931892412298654741768897581319007e1517L, 4.245031321673807283498263276791307370788e1521L, -8.469499523038763989328773224520912663309e1525L, 1.697421812794203793865032206191322699261e1530L, -3.417217332563937242285349373774004020539e1534L, 6.910378594841763785923780822895851271770e1538L, -1.403696282437585785557998429691459557649e1543L, 2.864060533055333035232343601021192111053e1547L, -5.869818290384811353182423286543086530728e1551L, 1.208359745327224593486268988808338456906e1556L, -2.498576742140453770373914215325521001990e1560L, 5.189311407347546310078739863704346083861e1564L, -1.082537954843916294257278789980768336964e1569L, 2.268238255751421312559806122980932952706e1573L, -4.773557403917983369065731568732198697502e1577L, 1.009019097334998841920279535262007639746e1582L, -2.142181266523235177327239693359275472557e1586L, 4.567814904130855969979178320003286614868e1590L, -9.782550516204803195398428611221899469345e1594L, 2.104180123097086948576304557651398411373e1599L, -4.545658958087323864004652894518442709646e1603L, 9.862563944609427542603740078470901803131e1607L, -2.149105846582226970866569209122813809019e1612L, 4.703235567543888152049628411354542509156e1616L, -1.033719212601584878353206879472796545848e1621L, 2.281767401903848796732740825793310514456e1625L, -5.058236070813950229238666252351966279306e1629L, 1.126112519657857205642546937554224492775e1634L, -2.517766761987679577706779689880657777343e1638L, 5.653225190181653388317503182908983211029e1642L, -1.274735955461074142223278576503188429497e1647L, 2.886578974679460464298863945016671299242e1651L, -6.564203307141426181809363135003467581753e1655L, 1.499036144473064593308260681782048262301e1660L, -3.437714715599902386917108442954580869236e1664L, 7.916830957072777234152907034541325149479e1668L, -1.830850567422571420661248197094782575285e1673L, 4.251778280827419894527511469762091846660e1677L, -9.915182507286989818033146623995507108134e1681L, 2.321878208636697663781227497233334385222e1686L, -5.459879022461660582811365437190884471726e1690L, 1.289222044549922720398543474297554204559e1695L, -3.056819658344217799458557578658863826289e1699L, 7.277891759142725294172926258364455941365e1703L, -1.739928293433385104144012025546489673795e1708L, 4.176797408823713136137404972612780406904e1712L, -1.006788178307821554781930741698052910780e1717L, 2.436754569909644399766538111317379484511e1721L, -5.921896599028498715774458493117079340155e1725L, 1.445045688171565118619109316933316429671e1730L, -3.540547766876069233350621578795319652040e1734L, 8.710114552028472554054293344204504325978e1738L, -2.151484527880464463303897113553085899101e1743L, 5.335928195512405709733771642389502809087e1747L, -1.328726408335015910030370523083559660016e1752L, 3.322090527232917400247098823651437597786e1756L, -8.339387326241218096865362177688582376376e1760L, 2.101842203781264395369771906884644062395e1765L, -5.318704469415522036482913743767085545209e1769L, 1.351288005941730688647540059088127991581e1774L, -3.446853546858473171100748720136784228698e1778L, 8.827284762030783576089954173424852998700e1782L, -2.269642226090373319660782216907175419317e1787L, 5.858820683661708553422363777419430816755e1791L, -1.518385813684321665045387969920683656625e1796L, 3.950661327164595923092260035122668890334e1800L, -1.031976516347387969958181456058243183780e1805L, 2.706317892325103782207094286049104555552e1809L, -7.125140422584701175967252533378906957380e1813L, 1.883260203116768075569432925204868418472e1818L, -4.997193687108743666000994570700725873035e1822L, 1.331182722092654526185433799891693838871e1827L, -3.559930289076558484535632566755216035553e1831L, 9.557281027056970446117541983785660301558e1835L, -2.575805002229372523547972911961335317502e1840L, 6.969058431277067406841032797913179025984e1844L, -1.892842481279278678390672746902260183506e1849L, 5.160964211693777744707760614147460787285e1853L, -1.412602588198037643242529860614298968137e1858L, 3.881313379962387603749693387037174052146e1862L, -1.070542170988009009334148472388319844527e1867L, 2.964094312414144330805731101996829908435e1871L, -8.238350132106899955856124602934281976453e1875L, 2.298504171050560756192352106062598639825e1880L, -6.437303944649223478093890316531995121228e1884L, 1.809727811843121957353712606428292269805e1889L, -5.107047553992257935533518628886728031061e1893L, 1.446674478990385642488446075734631327506e1898L, -4.113513327511444762766719175770513771122e1902L, 1.174067517257431444028448391638451935667e1907L, -3.363630086409895071362533854123306097827e1911L, 9.672868956071838221096869293070568259792e1915L, -2.792101741911955365960369780457612630184e1920L, 8.089710604557382430162031502761771390568e1924L, -2.352650988877130983061761312962677887796e1929L, 6.867549079740051556501575104006222995568e1933L, -2.012161201632998475706904405535757516336e1938L, 5.917489529279588702317256137229398357271e1942L, -1.746718667239329545125902248821502764273e1947L, 5.175069416058975040990816515838893249437e1951L, -1.538913401594651457295303469904084052963e1956L, 4.593185746210984655636051293374195150815e1960L, -1.375981868450401919299150690829612124045e1965L, 4.137207965217520410530508053863759216958e1969L, -1.248518564582257710069294326648626362439e1974L, 3.781575291117895093413381897917341286951e1978L, -1.149575999691408110085856948595444100435e1983L, 3.507413095836612229403470531176947165451e1987L, -1.074032838410645352804690949680310176413e1992L, 3.300857202456564870338466973024760446263e1996L, -1.018149578840803516349758843017979498322e2001L, 3.151876950233613792531594490714752800621e2005L, -9.792574827376149360558532022944033224780e2009L, 3.053456145978161645823454710737904504036e2014L, -9.555442346102849014299990542596620094035e2018L, 3.001037449298122384017009412541525703002e2023L, -9.459120112371096268275049056229023773120e2027L, 2.992168042152196502453442556462819104060e2032L, -9.498922680869041470681858599915282791899e2036L, 3.026307717971075309746179763189393755074e2041L, -9.676079238806159594565350708123427510151e2045L, 3.104778286352798464772361361434013339088e2050L, -9.997786802782252742109475924344598057966e2054L, 3.230847952724856366943939804248186203776e2059L, -1.047769651900498931701604323213605884945e2064L, 3.409958102134053489747140426163802214042e2068L, -1.113687894644055086152064258459886518528e2073L, 3.650114509271160332136458711252217684956e2077L, -1.200536387553969483433239131469825141412e2082L, 3.962482337718333099498977337189304099484e2086L, -1.312441206957064803437100929905979391106e2091L, 4.362246723746013772563799740886664288515e2095L, -1.454975881895253548422481637083633839534e2100L, 4.869831412214692119172895822285084162147e2104L, -1.635618419512383251104125916207188960680e2109L, 5.512611314145041257838234038980389596534e2113L, -1.864392957231340288547618808749072127289e2118L, 6.327317613106621547060670091824665547127e2122L, -2.154772001506498703267302897994526372056e2127L, 7.363426139490286496267931634843475368903e2131L, -2.524950643808031915843604894357998905460e2136L, 8.687956390288096215918373666581638675156e2140L, -2.999656978200020459428228924242615592768e2145L, 1.039231328851609224822335039430898644149e2150L, -3.612742437616019936358910410005123924796e2154L, 1.260211309932738404790711574105022002093e2159L, -4.410916378453971105434385837025433805752e2163L, 1.549140617923265948720013792673729394719e2168L, -5.459173749226782924959103886664322964926e2172L, 1.930343307630952098252884031069043541182e2177L, -6.848749229218425353808144618581305978045e2181L, 2.438117138001365487681440577590059588102e2186L, -8.708873656769794358508423272379627581292e2190L, 3.121268068338199458891764932384819739714e2195L, -1.122430216307539309816165910733145404999e2200L, 4.049900779207199370582177687160985635615e2204L, -1.466167983141158219266077836130256565915e2209L, 5.325678718693772500250292767751070974887e2213L, -1.940955845102272053048140384364058448998e2218L, 7.097467198361219669927211698104447309186e2222L, -2.603968771680987683436428778397387110896e2227L, 9.585403285394812946713320044815117440444e2231L, -3.540176030547640510648455468270569908446e2236L, 1.311827683984025111744358347783996339730e2241L, -4.877124229155333857009747836542843294702e2245L, 1.819213075760490882591173222316749809951e2250L, -6.808221630329265915405178596748950929642e2254L, 2.556299969544109052724772800143396857058e2259L, -9.629763347675306704861859899230073979116e2263L, 3.639508580119285595844040783082958425575e2268L, -1.380037493555816309137481185927387732499e2273L, 5.249980712165216709135893538080020409581e2277L, -2.003737844109055078145975651407367170529e2282L, 7.672522280806944397358668566379646540213e2286L, -2.947454993639165318799389781921184991045e2291L, 1.135966912801707623489383623092951142963e2296L, -4.392293711194501621873299212059053651432e2300L, 1.703813210168560937608104155973968112409e2305L, -6.630636743874062041158387022015853902938e2309L, 2.588742636486379690203698247275411406029e2314L, -1.013959594068423546627946242481463893979e2319L, 3.984265821528043268586235974854766821078e2323L, -1.570614519682157047612769672066387881154e2328L, 6.211297381339606877062824459742129064477e2332L, -2.464246931985476159686671650962783785426e2337L, 9.807833742601662212615240518855757197483e2341L, -3.916036434571217691317276306031837539092e2346L, 1.568566392975837368624727722120313955274e2351L, -6.302885887601142677858008037129298948063e2355L, 2.540704455306077495480843691828334210014e2360L, -1.027412480318234348899627142408950111875e2365L, 4.167823618450297116765978030480648316769e2369L, -1.696076602731914277275203926124423530377e2374L, 6.923904505633301788461482786634220738504e2378L, -2.835463065742506394026733592206185459035e2383L, 1.164828772275756526225951620927486307632e2388L, -4.800242878545012539781545966693324656699e2392L, 1.984381759611877246529319121941597679107e2397L, -8.228979942542641498511023600269641046627e2401L, 3.423130231367101727862739208673375060101e2406L, -1.428418168129733054582191895023094524495e2411L, 5.979153801634459282232521647160044877770e2415L, -2.510581926948409809562349588087762800160e2420L, 1.057443785053915411991029410076722022815e2425L, -4.467723713549428749678277264414266162837e2429L, 1.893474116528533144079731251913008472748e2434L, -8.049601965052954947260081891142509464888e2438L, 3.432648527503971149009691133946275281368e2443L, -1.468324699963694393989960228042259134294e2448L, + // + // 1302-1600: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1302%2C1600%2C2}] + 6.300146502435743791500010801885493871234e2452L, -2.711520667146768856688291798851999580833e2457L, 1.170595555513900137297344452318266434006e2462L, -5.069095411973246242900074508988493530542e2466L, 2.201819284807954055092117706033113168896e2471L, -9.593088725189386197503123561368325167085e2475L, 4.192362385909155628936230811010649614060e2480L, -1.837725836941968309866675158105812946762e2485L, 8.080201101491972605313807752565294881374e2489L, -3.563536075527215702966392543784039539240e2494L, 1.576361051321107275181955665159661781175e2499L, -6.994292466180175594372663323941761853364e2503L, 3.112744353537336702834647901141392426258e2508L, -1.389481328370627358752727485697345194612e2513L, 6.221134636655213696041740685131223999953e2517L, -2.793779613656947577224654924852010601105e2522L, 1.258399062987759035354039924686781081603e2527L, -5.685208194704131918461885165870560583895e2531L, 2.576167857759537340210434756292816456179e2536L, -1.170846052338591953257169251219597581763e2541L, 5.337296787116189575571202979672747140313e2545L, -2.440264475369219459038748840841422948951e2550L, 1.119037151526195093932933161706501865175e2555L, -5.146858829220973887154576240993607686435e2559L, 2.374259791963193693837576781321391741634e2564L, -1.098501215269400934956638118646657823799e2569L, 5.097500369683616795005376807036889542869e2573L, -2.372446971688020647583535886090779018865e2578L, 1.107430282014636546248612381377039463753e2583L, -5.184597227131050012643138079903381280471e2587L, 2.434392040100910394476893838832599310265e2592L, -1.146412753331162872665743308094817095949e2597L, 5.414578104816988124950636101250217797539e2601L, -2.564835392810685332173156758121489913946e2606L, 1.218495070518549208066544111736985586178e2611L, -5.805713573821806672815019495319510297824e2615L, 2.774298194574319430697819781128985128618e2620L, -1.329580186505564627453485444017911980430e2625L, 6.390545858902318479863947547243743500916e2629L, -3.080502542499571035376377703435361520427e2634L, 1.489236104239976282318361008292980814533e2639L, -7.220413839991892382038608955317126799684e2643L, 3.510874916591640642524021216241607185085e2648L, -1.712070118580404599831061485055269100525e2653L, 8.372956919832386730490070625622785478703e2657L, -4.106629146981883685523102256292669054596e2662L, 2.019945438530802964718619732330776495740e2667L, -9.964133277392242111939720494354938982970e2671L, 4.929278642971447854669801547226335041410e2676L, -2.445509657169810919463982615395074704130e2681L, 1.216734421265677299127016883839223226884e2686L, -6.071008437677720186241562251151490713584e2690L, 3.037824949882992896564570441252792097027e2695L, -1.524402878612630565501569310883356490225e2700L, 7.671320530781999359200097739951316234193e2704L, -3.871436167706734376478728954716915204399e2709L, 1.959313530432202158587932399068682252335e2714L, -9.944063618400630821320953821427307024297e2718L, 5.061161998202463346818982228476199873781e2723L, -2.583219090831132705328958245740715185448e2728L, 1.322193991367293532684189527174543501836e2733L, -6.786569982732483290873213417465458376706e2737L, 3.493212334804776543395067018414547811062e2742L, -1.803090099978261928508495412750404640933e2747L, 9.333100843930216567894508007158644926767e2751L, -4.844499031405982604449146511179496492045e2756L, 2.521648090959971240812330574936006906830e2761L, -1.316227870932708474838173333385377250286e2766L, 6.889488826832738674261056521130795910494e2770L, -3.616184242864384509259984293501533623932e2775L, 1.903356124758119137116543283603627028779e2780L, -1.004601544584640657081847200643996069583e2785L, 5.317043885597842225603585588404817559596e2789L, -2.821938866752488868682751438901900485500e2794L, 1.501842023003449590337997900945924161741e2799L, -8.014908048137216649348740300633172710524e2803L, 4.289126235121619907138036129192558937445e2808L, -2.301619137231461344870820700320913118444e2813L, 1.238485136850053215006962645111854705210e2818L, -6.682503731149007943059244518074044280490e2822L, 3.615572393938012932030234169574978859655e2827L, -1.961565108627429629104703146282982075623e2832L, 1.067123259692924564435881096382837264046e2837L, -5.821179870182035246401397327057170726418e2841L, 3.184127229476322727732208017279268211356e2846L, -1.746429902183019597973436257300843998825e2851L, 9.604873565299766333876882842813498685054e2855L, -5.296759978724702692134960752308186890356e2860L, 2.928906353338652198977536576170287112391e2865L, -1.623961162577704769945821804737884742792e2870L, 9.028574047002736235613238355032484299017e2874L, -5.033087486357905828950503441308068892610e2879L, 2.813325650062267479031371852434194635210e2884L, -1.576791132296320840138263753339056345362e2889L, 8.861258343945925667272164531504265693289e2893L, -4.993236404321511029440212686547068244002e2898L, 2.821192993950901287717082243608730217471e2903L, -1.598254169674379493385730199445427966752e2908L, 9.078617590346932363947095804057608979359e2912L, -5.170742114456472142154347566092068443393e2917L, 2.952866185102528847516095880416675972086e2922L, -1.690794578626103552690094140317813413244e2927L, 9.707168799669516048238542260085175133847e2931L, -5.587884732306715493795271931175883605707e2936L, 3.225179489154957423492905957887744116530e2941L, -1.866424419669188178697802576490431604300e2946L, 1.082967626854618222657109354056973072044e2951L, -6.300392007169862865282706277272018077291e2955L, 3.675066377245428685118763485986517510658e2960L, -2.149348371085132073107516253339849053182e2965L, 1.260349351812619395000600434630904474324e2970L, -7.409963623771231302980906971935254993610e2974L, 4.367980758467862686643231700861155889684e2979L, -2.581566823350789671250829457603555544100e2984L, 1.529757357568342629912560827243282062227e2989L, -9.088595394263364554625061567617375176719e2993L, 5.413829169254585648363594604231030415354e2998L, -3.233288119606092759447005827969216281573e3003L, 1.936042437734875803183915765854038424658e3008L, -1.162289934202291715747729318797398221667e3013L, 6.995870350500567071550614251287615697508e3017L, -4.221776496490106417392945233048068288503e3022L, 2.554309239868912570382343877718991746122e3027L, -1.549440871550119801225143558087410562418e3032L, 9.423199525954784955533959981278992475051e3036L, -5.745689660772387668861183913170050552119e3041L, 3.512407521007240798565045328376471603253e3046L, -2.152708113797517364614914569890010876143e3051L, 1.322761289733739440340237168659770154654e3056L, -8.148777388506488753591136948542248584098e3060L, 5.032880858479326069741729004270784264612e3065L, -3.116396010103058126269735274818345780360e3070L, 1.934634831148214353514796782480703021435e3075L, -1.204077166243116651938489240924641810276e3080L, 7.513065583444964704795707060501161621868e3084L, -4.699873512563164914493150520500838535415e3089L, 2.947541197349762411713872934523813866703e3094L, -1.853262416286420077763886100673646141885e3099L, 1.168196427912100545575264493997591040800e3104L, -7.382362285873345348505276546404015842875e3108L, 4.677071041058096429847797962954927487730e3113L, -2.970642034084362431442183248944824506476e3118L, 1.891572688282564476274920103912259755482e3123L, -1.207509963440193713810418554061532113326e3128L, 7.727731208240101791845515599659441557781e3132L, -4.957988488048495669466804712012179891532e3137L, 3.188965862446236259925047956715566822864e3142L, -2.056286895821370106507670239256782411337e3147L, 1.329246918771714093479509313343886287414e3152L, -8.614188519577835653765633797787633659253e3156L, + // + // 1602-1900: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1602%2C1900%2C2}] + 5.596396533621874175909933615343145642161e3161L, -3.644908483469388437457938883454376864180e3166L, 2.379838409026860469990569665632800095988e3171L, -1.557720925267669865362152155022069166772e3176L, 1.022143420270029721682551084917730373739e3181L, -6.723767358891570842116651998814252095792e3185L, 4.433950491570308179905446963723780229747e3190L, -2.931196854668917448553150023532223509373e3195L, 1.942557068752664549549945921392100172355e3200L, -1.290553202978622786891265558106235068695e3205L, 8.595082329732118303768775883557789195136e3209L, -5.738453265222970049867280061719670658457e3214L, 3.840687915100689856736926915331157331684e3219L, -2.576862441955523551149886625900059307506e3224L, 1.733166107320377310388765047659987844208e3229L, -1.168569552450178559412843683052610870569e3234L, 7.898289836694980777809433306209459851871e3238L, -5.351485909164216694400535493924387979018e3243L, 3.634772439350395177931952925644409735777e3248L, -2.474801048002975145046569303233576339695e3253L, 1.689126939254790850063878942448569759390e3258L, -1.155691524500722774057997965355407962525e3263L, 7.926435404542361405718288670391575676323e3267L, -5.449654814183048796524718620178906854846e3272L, 3.755898589900254795894812942275711835138e3277L, -2.594843902682143854622514329649211211808e3282L, 1.797048752397789969347915328338360264536e3287L, -1.247551415074438712713815166107969504456e3292L, 8.681719521514448143910215886388510318746e3296L, -6.056203898213120922016159444227958572276e3301L, 4.234882876331814099029781995617143573641e3306L, -2.968432911643338866295929748049749932906e3311L, 2.085723508930484816454740610260790948864e3316L, -1.469023169879432026361623513301566735138e3321L, 1.037150346505052892302077637883522696572e3326L, -7.339977067836656769144838365069396168014e3330L, 5.206985412168234130596004552956337839140e3335L, -3.702673773319239583641029108403509825141e3340L, 2.639251227995760315076225206168354089692e3345L, -1.885736353072698581595150856674914203383e3350L, 1.350563292338261784288559687678302458996e3355L, -9.695749980998301526113046898985991802000e3359L, 6.977167462628398202151721319169989304520e3364L, -5.032768280399753942925624560483352299263e3369L, 3.638844963651800168080623511900705036698e3374L, -2.637228631269251606169613775399022890118e3379L, 1.915836351653767108720464847696767898597e3384L, -1.395064293615007319328267865803567670760e3389L, 1.018249052614943190644465556486933211307e3394L, -7.449662162606857550867922631658930320805e3398L, 5.463119632208085241594107781601567713991e3403L, -4.015736541676989144201935890497836963875e3408L, 2.958754190183866660901503059509579790900e3413L, -2.185096074054288399312733179064098492511e3418L, 1.617517444557020250864919655301189186103e3423L, -1.200170662015511746748935675940010250555e3428L, 8.925888349899029449015791684428724952411e3432L, -6.653851763691885517669938275618991145962e3437L, 4.971722031098457895973348076474071155918e3442L, -3.723500582577984967442020337848702786829e3447L, 2.795153783541721373364976034391375710110e3452L, -2.103141577212720698169118819883801186873e3457L, 1.586129575320959267959148073466004084241e3462L, -1.198988457279648730711646682156242973137e3467L, 9.084402368157025658430300252246526602197e3471L, -6.898927494435965163817354296023108913714e3476L, 5.251332286149361587885046891266325872375e3481L, -4.006442950956739933884502808470603581850e3486L, 3.063718202820270282280659950794978994604e3491L, -2.348215284130973783732145823834807395920e3496L, 1.803952490148087317330011096671019781340e3501L, -1.389022326803437345760911068933754707688e3506L, 1.071986115818329525986099441493200866389e3511L, -8.292085224650940719705699485423856363908e3515L, 6.428829064452939640541475198655560890344e3520L, -4.995654440302797445368056643032307686314e3525L, 3.890847042582299188849273838681034339406e3530L, -3.037288555751484681537442833929275697351e3535L, 2.376385803695694695338601696534348875191e3540L, -1.863527130251861900692886008704804849076e3545L, 1.464674913498036269270793715104706378182e3550L, -1.153804954579033578659954846698233083197e3555L, 9.109783835348935092264268296199541780964e3559L, -7.208869193983001804305451104827153729326e3564L, 5.717530734277611949162917337810749919265e3569L, -4.544970302634007326980094771330550661605e3574L, 3.621042850825283032134228901678636353355e3579L, -2.891447067949778492831490654980043715471e3584L, 2.314060419397710657435821461707043283167e3589L, -1.856140759923563235273220981623595304434e3594L, 1.492185412981476596273279338314204171587e3599L, -1.202290032627175365810126250991853594801e3604L, 9.708881154579770196658265042625239421053e3608L, -7.857809850747029705680072304049448493252e3613L, 6.373898598298513400228819113197728735438e3618L, -5.181780406472117449048907989647202286666e3623L, 4.222036621953044040518942750638183171221e3628L, -3.447728386429130175025813550845575613047e3633L, 2.821701521717856346224159586852612710800e3638L, -2.314488376711998526455043944505424906920e3643L, 1.902671298033180765286213227393060711096e3648L, -1.567603736821312488140289549008391847440e3653L, 1.294408945316538946551785312385509945367e3658L, -1.071194533081615830960091702262923009420e3663L, 8.884351908108581551151252566466606126397e3667L, -7.384866682828103669170236267589653324531e3672L, 6.152023838008155718180876735217718355563e3677L, -5.136304310431705506236573876510219357975e3682L, 4.297736808124296434723193397876220759378e3687L, -3.603994887745884762510172194982172483480e3692L, 3.028884745605031552399167746007361297342e3697L, -2.551141302205187365552982635794121855138e3702L, 2.153467982869535549299173317536193051608e3707L, -1.821769476343602094059466497311600827296e3712L, 1.544537580582347892980177956984101211006e3717L, -1.312358705945937257247030754517293537539e3722L, 1.117518229297781388884979995402355617235e3727L, -9.536820860779441793021624381677086661097e3731L, 8.156400668831968026931547065507466530546e3736L, -6.990984948728184142718575396052260691181e3741L, 6.005124901126818071638224144541102727563e3746L, -5.169500241880947716732682089328427995109e3751L, 4.459815478235310026240134567325749844182e3756L, -3.855902253361684187081283218890336962427e3761L, 3.340988024176995223515640815937037040546e3766L, -2.901099226680215736735094376078800376829e3771L, 2.524573363444334459448089563912567842927e3776L, -2.201659455716348555524529213295341212492e3781L, 1.924190302190936448078364755844591374353e3786L, -1.685313186099770223843319514432495898517e3791L, 1.479268235966730475749985741048766689808e3796L, -1.301205702893883803117530921635013780575e3801L, 1.147035071153450453405384269242743907426e3806L, -1.013300250456366849150496776951686112298e3811L, 8.970761720605591762300958007557533865346e3815L, -7.958829781488943084496783248922217392838e3820L, 7.076146954685024795720193943027902028642e3825L, -6.304798526260409199660290516451546966159e3830L, 5.629519616664188107056583939722984509867e3835L, -5.037281594099054092767959480843344929292e3840L, 4.516946091316834843581919268794683123349e3845L, -4.058975118925834202620358386772092359951e3850L, 3.655187798978978909014603682039470653549e3855L, -3.298555903041546671060101785513812175322e3860L, 2.983031738662727912016882399515879119620e3865L, -2.703403043317732979516341931451317866898e3870L, 2.455170460800096241793872443768546335444e3875L, -2.234443928432490538417605502448376856290e3880L, 2.037854924078003280537856980560782325730e3885L, -1.862482033918775734840779765743099458137e3890L, + // + // 1902-2200: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C1902%2C2200%2C2}] + 1.705787724951999960095629912416210969679e3895L, -1.565564556110550991891247404758895970376e3900L, 1.439889351869832939488618785632174464789e3905L, -1.327084102784257406218693901793045990520e3910L, 1.225682557296027075027021534960026145706e3915L, -1.134401635488994148555787301654561211982e3920L, 1.052116934052356802920509999705307165985e3925L, -9.778417073593082219082361206542342793584e3929L, 9.107088061888562704837019028349522303725e3934L, -8.499551364633102138471246155980056936129e3939L, 7.949082681085658044610890152056533167407e3944L, -7.449748809722797718736397140511396011691e3949L, 6.996307824769340144608141799981589288378e3954L, -6.584122718472954006131003060359621706243e3959L, 6.209086595833487707192492087176843233407e3964L, -5.867557793863165391821489909125720982339e3969L, 5.556303538475260373917478405626416604297e3974L, -5.272450955936249442242634142613834212778e3979L, 5.013444428433789818228792126117223030641e3984L, -4.777008429684552423800736200488532033034e3989L, 4.561115100786341787876705283291018781137e3994L, -4.363955932181992701667719449097126840439e3999L, 4.183917007557000586305945495258591147615e4004L, -4.019557342177353010692923286760895584096e4009L, 3.869589913635745758786275231296652917580e4014L, -3.732865038934070181861017140563175000872e4019L, 3.608355799736107390800162778737339576843e4024L, -3.495145258697474565347261083975193776541e4029L, 3.392415245050326563747729613872524362741e4034L, -3.299436517958948801426629481782413630714e4039L, 3.215560142306355508598119430378551642857e4044L, -3.140209934146377815556058799557727461298e4049L, 3.072875852591406752692761744649563131272e4054L, -3.013108231854799187724018548255922550991e4059L, 2.960512761914376268185064129600549308882e4064L, -2.914746139139036596123006476633770383901e4069L, 2.875512319506974985103149834921665445532e4074L, -2.842559316984704569380036093537576068104e4079L, 2.815676498441436148701483904115879856704e4084L, -2.794692334326268275058539147656334465534e4089L, 2.779472571396106785963004020814493340829e4094L, -2.769918800191406321625251621260024635680e4099L, 2.765967395840433013288935879837390099329e4104L, -2.767588816244119880300161388073836623878e4109L, 2.774787246856347651152278076466043136230e4114L, -2.787600586224957950622601135620189837948e4119L, 2.806100771288225169339048358106052817280e4124L, -2.830394446218080573456394167711739786431e4129L, 2.860623983452244712039094143642843717029e4134L, -2.896968870550611723525738907034588104300e4139L, 2.939647481737606306044335918078617963078e4144L, -2.988919258547518526076380181812161398808e4149L, 3.045087329976721023952450383837883029431e4154L, -3.108501609077197464748958150625867523408e4159L, 3.179562410123820875787052833975010965963e4164L, -3.258724638491880104953913719767939138170e4169L, 3.346502614347964869115073881474258766546e4174L, -3.443475601364631413158991572423086599816e4179L, 3.550294123121350747300886840907918182129e4184L, -3.667687162886053419715985091863398517145e4189L, 3.796470357354794420044278000297864085607e4194L, -3.937555311976846882455930574021795626971e4199L, 4.091960185075595842547638450930710467324e4204L, -4.260821710519620959138720129506770036460e4209L, 4.445408854703156440576808070360934740837e4214L, -4.647138333645908068599900650548418672065e4219L, 4.867592250805288922190809906525766574205e4224L, -5.108538156515551259475573296900660666192e4229L, 5.371951876776035157276013631113314852508e4234L, -5.660043513521220243900043448456234873940e4239L, 5.975287081834808618140945840817834710330e4244L, -6.320454323372684034118816565375206053746e4249L, 6.698653321371992324876559665938996023646e4254L, -7.113372643219128807424340495235606473967e4259L, 7.568531854202750881338746432078817214052e4264L, -8.068539383842553693076672384509126681464e4269L, 8.618358887685935324188596304168259394311e4274L, -9.223585437012291673660319256730398171887e4279L, 9.890533091606747031464718533600572123091e4284L, -1.062633567277107015128545384570274268438e4290L, 1.143906286231591191271274413511275981288e4295L, -1.233785411712565904499340744089870916842e4300L, 1.333307331840530219050170916015276125870e4305L, -1.443648758235403286296065629219598769529e4310L, 1.566147425967471851736562867318748510088e4315L, -1.702326086290842780634120184324081017286e4320L, 1.853920350455786350409148418966087344063e4325L, -2.022911043115598592197907512410632615740e4330L, 2.211561842992792253055716743938240466613e4335L, -2.422463130294011318178080247305407476096e4340L, 2.658583129381772791030436640519847627789e4345L, -2.923327636881988941081365085520742216540e4350L, 3.220609866329557159104267531058019683271e4355L, -3.554932228621330128152149026066400241546e4360L, 3.931482212643167323798366327390058684499e4365L, -4.356244944221399578650235478583297389113e4370L, 4.836135498303121165971331625888490168138e4375L, -5.379154636371461359750682662639062606297e4380L, 5.994572359716861309678596804350346692501e4385L, -6.693144535124290060793936095397161934045e4390L, 7.487368894313509797084395689517008597061e4395L, -8.391787970609807810531578161564037339793e4400L, 9.423348062978921203475110312003096820035e4405L, -1.060182516651648405903017734022504884319e4411L, 1.195033105063952979885086754342706651656e4416L, -1.349591538868673992167798923586925758429e4421L, 1.527028315253291113905307092657539132480e4426L, -1.731065051510920640409442255224015234974e4431L, 1.966076741510092840076264635935585216200e4436L, -2.237214093245750681191361238831105906202e4441L, 2.550550094903891445719729187215253324232e4446L, -2.913255853313667303707651906277658164129e4451L, 3.333811847072394764285817140850092324169e4456L, -3.822262084288044913490118858492563410392e4461L, 4.390520310533864198186202368026630430120e4466L, -5.052739449335052080092114976206610871466e4471L, 5.825757966350870043117899492954521458799e4476L, -6.729639942938203582008846884575881320532e4481L, 7.788329466816396015493306357116312471970e4486L, -9.030444674469025073047417528762134025409e4491L, 1.049024263381993629167658236142000524752e4497L, -1.220879351508964912255081664072251573277e4502L, 1.423541151220109512749655991050110438471e4507L, -1.662940118618541616964708044356967429362e4512L, 1.946219185900482116137855064775635250366e4517L, -2.281995008842006909631764011781911322493e4522L, 2.680678198213108543648324254258111216040e4527L, -3.154866427472784086389609599207759103500e4532L, 3.719827710160801797530420206201570269720e4537L, -4.394095404360277919140027580071549980218e4542L, 5.200201854779615608741690339830306148442e4547L, -6.165584312943608652377791415603277251516e4552L, 7.323705248531382981433751104158852636445e4557L, -8.715439846124090647163930834760361817820e4562L, 1.039079696609215651011736087603304766850e4568L, -1.241105689556982425619608247473478857800e4573L, 1.485143079696380339521658550262280772546e4578L, -1.780437412164973637340821168154300094802e4583L, 2.138372099157518882088209435171770222745e4588L, -2.572985071149069551034276570909360759588e4593L, 3.101615379617643734762997559011097203354e4598L, -3.745713657616368229906151946770042703357e4603L, 4.531859496161940719835150033082561700677e4608L, -5.493040495326927998321538336584233566465e4613L, 6.670262730603009306595018122252730741798e4618L, -8.114581584793494903775255213273982440688e4623L, 9.889666561810883044159054730371102725871e4628L, -1.207504541653929734716275932570097623330e4634L, 1.477021377885843688233899471354959308782e4639L, -1.809984912147908767583043524070645821179e4644L, + // + // 2202-2320: http://www.wolframalpha.com/input/?i=TABLE[N[Bernoulli[i]%2C40]%2C+{i%2C2202%2C2320%2C2}] + 2.222043594325228980916360265527780300093e4649L, -2.732869701246338361699515268224049951411e4654L, 3.367233945421922463553518272642397177145e4659L, -4.156377225041273602431272489314020150392e4664L, 5.139764368092890466235162431795350591151e4669L, -6.367329693760865476879589228002216011370e4674L, 7.902356742934106007362514378717026407839e4679L, -9.825176966314431712897976595483070301406e4684L, 1.223792760178593282435724837135946867088e4690L, -1.527068151452750404853140815207477555192e4695L, 1.908935682572268829496101580401263597905e4700L, -2.390593888616966248780378941331847473699e4705L, 2.999171106576893833644521002894489856321e4710L, -3.769440655453736670024798444784356437578e4715L, 4.746047769851891438576002047529258107351e4720L, -5.986405469241447720766576164546767533359e4725L, 7.564466155536872051712519119999711534616e4730L, -9.575641408047918720040356745796976488951e4735L, 1.214322951835035451699619713803395497423e4741L, -1.542682591979864353012093794301924196234e4746L, 1.963334539793192183270983986567556358603e4751L, -2.503148969013901182572118121398034622584e4756L, 3.197076711250102964526567664729089847162e4761L, -4.090653552025822488578293526174572934858e4766L, 5.243302769651520536759521264615159906699e4771L, -6.732697170903775309261288127044088674182e4776L, 8.660529543801770516930589210020128142543e4781L, -1.116015823611149634592870112730519454113e4787L, 1.440675306432920129218036927923030695520e4792L, -1.863078034853256227415397798026969938881e4797L, 2.413595413458810442409656314019115041699e4802L, -3.132317029597258599678590012779717945144e4807L, 4.072246763371584312534474102756137619716e4812L, -5.303577511521827157146305369181950467569e4817L, 6.919417518688636032335131253584331645491e4822L, -9.043473312934241153732087612484569398979e4827L, 1.184037400265044213826044590639924237359e4833L, -1.552956685415800894409743993367334099777e4838L, 2.040404893052952221581694807126473204625e4843L, -2.685565763841580219033402331219206776210e4848L, 3.540927057361929050327811875290025248120e4853L, -4.676912607538885419407656762767991163574e4858L, 6.188165903566760647569323704623433330229e4863L, -8.202087471895029964699042637255411806373e4868L, 1.089045274355389654614196651761310970580e4874L, -1.448524684976553869119447042300206226148e4879L, 1.930028100376784839502387280956424581974e4884L, -2.576074799096023589462128312524664980682e4889L, 3.444369635011990347297134928452972402038e4894L, -4.613354441299253694113609154769978684993e4899L, 6.189834306866879018555349507257537840922e4904L, -8.319470760665157534580593571258276368233e4909L, 1.120124240070996761986102680587384813245e4915L, -1.510740451399746828351090108638980398124e4920L, 2.041108231091323198877509959371257503819e4925L, -2.762447751447012472733302936575873838539e4930L, +#endif + }}; + + return bernoulli_data[n]; +} + +template +inline T unchecked_bernoulli_imp(std::size_t n, const std::integral_constant& ) +{ + // + // Special case added for multiprecision types that have no conversion from long long, + // there are very few such types, but mpfr_class is one. + // + static const std::array::value> numerators = + {{ + std::int32_t( +1LL), + std::int32_t( +1LL), + std::int32_t( -1LL), + std::int32_t( +1LL), + std::int32_t( -1LL), + std::int32_t( +5LL), + std::int32_t( -691LL), + std::int32_t( +7LL), + std::int32_t( -3617LL), + std::int32_t( +43867LL), + std::int32_t( -174611LL), + std::int32_t( +854513LL), + }}; + + static const std::array::value> denominators = + {{ + std::int32_t( 1LL), + std::int32_t( 6LL), + std::int32_t( 30LL), + std::int32_t( 42LL), + std::int32_t( 30LL), + std::int32_t( 66LL), + std::int32_t( 2730LL), + std::int32_t( 6LL), + std::int32_t( 510LL), + std::int32_t( 798LL), + std::int32_t( 330LL), + std::int32_t( 138LL), + }}; + return T(numerators[n]) / T(denominators[n]); +} + +} // namespace detail + +template +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n) +{ + typedef std::integral_constant::value> tag_type; + + return detail::unchecked_bernoulli_imp(n, tag_type()); +} + +}} // namespaces + +#endif // BOOST_MATH_UNCHECKED_BERNOULLI_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_factorial.hpp b/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_factorial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/detail/unchecked_factorial.hpp @@ -0,0 +1,1019 @@ +// 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_SP_UC_FACTORIALS_HPP +#define BOOST_MATH_SP_UC_FACTORIALS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#ifdef _MSC_VER +#pragma warning(push) // Temporary until lexical cast fixed. +#pragma warning(disable: 4127 4701) +#endif +#include +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost { namespace math +{ +// Forward declarations: +template +struct max_factorial; + +// Definitions: +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION float unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(float)) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array factorials = { { +#else + static const std::array factorials = {{ +#endif + 1.0F, + 1.0F, + 2.0F, + 6.0F, + 24.0F, + 120.0F, + 720.0F, + 5040.0F, + 40320.0F, + 362880.0F, + 3628800.0F, + 39916800.0F, + 479001600.0F, + 6227020800.0F, + 87178291200.0F, + 1307674368000.0F, + 20922789888000.0F, + 355687428096000.0F, + 6402373705728000.0F, + 121645100408832000.0F, + 0.243290200817664e19F, + 0.5109094217170944e20F, + 0.112400072777760768e22F, + 0.2585201673888497664e23F, + 0.62044840173323943936e24F, + 0.15511210043330985984e26F, + 0.403291461126605635584e27F, + 0.10888869450418352160768e29F, + 0.304888344611713860501504e30F, + 0.8841761993739701954543616e31F, + 0.26525285981219105863630848e33F, + 0.822283865417792281772556288e34F, + 0.26313083693369353016721801216e36F, + 0.868331761881188649551819440128e37F, + 0.29523279903960414084761860964352e39F, + }}; + + return factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 34; +}; + +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION double unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(double)) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array factorials = { { +#else + static const std::array factorials = {{ +#endif + 1.0, + 1.0, + 2.0, + 6.0, + 24.0, + 120.0, + 720.0, + 5040.0, + 40320.0, + 362880.0, + 3628800.0, + 39916800.0, + 479001600.0, + 6227020800.0, + 87178291200.0, + 1307674368000.0, + 20922789888000.0, + 355687428096000.0, + 6402373705728000.0, + 121645100408832000.0, + 0.243290200817664e19, + 0.5109094217170944e20, + 0.112400072777760768e22, + 0.2585201673888497664e23, + 0.62044840173323943936e24, + 0.15511210043330985984e26, + 0.403291461126605635584e27, + 0.10888869450418352160768e29, + 0.304888344611713860501504e30, + 0.8841761993739701954543616e31, + 0.26525285981219105863630848e33, + 0.822283865417792281772556288e34, + 0.26313083693369353016721801216e36, + 0.868331761881188649551819440128e37, + 0.29523279903960414084761860964352e39, + 0.103331479663861449296666513375232e41, + 0.3719933267899012174679994481508352e42, + 0.137637530912263450463159795815809024e44, + 0.5230226174666011117600072241000742912e45, + 0.203978820811974433586402817399028973568e47, + 0.815915283247897734345611269596115894272e48, + 0.3345252661316380710817006205344075166515e50, + 0.1405006117752879898543142606244511569936e52, + 0.6041526306337383563735513206851399750726e53, + 0.265827157478844876804362581101461589032e55, + 0.1196222208654801945619631614956577150644e57, + 0.5502622159812088949850305428800254892962e58, + 0.2586232415111681806429643551536119799692e60, + 0.1241391559253607267086228904737337503852e62, + 0.6082818640342675608722521633212953768876e63, + 0.3041409320171337804361260816606476884438e65, + 0.1551118753287382280224243016469303211063e67, + 0.8065817517094387857166063685640376697529e68, + 0.427488328406002556429801375338939964969e70, + 0.2308436973392413804720927426830275810833e72, + 0.1269640335365827592596510084756651695958e74, + 0.7109985878048634518540456474637249497365e75, + 0.4052691950487721675568060190543232213498e77, + 0.2350561331282878571829474910515074683829e79, + 0.1386831185456898357379390197203894063459e81, + 0.8320987112741390144276341183223364380754e82, + 0.507580213877224798800856812176625227226e84, + 0.3146997326038793752565312235495076408801e86, + 0.1982608315404440064116146708361898137545e88, + 0.1268869321858841641034333893351614808029e90, + 0.8247650592082470666723170306785496252186e91, + 0.5443449390774430640037292402478427526443e93, + 0.3647111091818868528824985909660546442717e95, + 0.2480035542436830599600990418569171581047e97, + 0.1711224524281413113724683388812728390923e99, + 0.1197857166996989179607278372168909873646e101, + 0.8504785885678623175211676442399260102886e102, + 0.6123445837688608686152407038527467274078e104, + 0.4470115461512684340891257138125051110077e106, + 0.3307885441519386412259530282212537821457e108, + 0.2480914081139539809194647711659403366093e110, + 0.188549470166605025498793226086114655823e112, + 0.1451830920282858696340707840863082849837e114, + 0.1132428117820629783145752115873204622873e116, + 0.8946182130782975286851441715398316520698e117, + 0.7156945704626380229481153372318653216558e119, + 0.5797126020747367985879734231578109105412e121, + 0.4753643337012841748421382069894049466438e123, + 0.3945523969720658651189747118012061057144e125, + 0.3314240134565353266999387579130131288001e127, + 0.2817104114380550276949479442260611594801e129, + 0.2422709538367273238176552320344125971528e131, + 0.210775729837952771721360051869938959523e133, + 0.1854826422573984391147968456455462843802e135, + 0.1650795516090846108121691926245361930984e137, + 0.1485715964481761497309522733620825737886e139, + 0.1352001527678402962551665687594951421476e141, + 0.1243841405464130725547532432587355307758e143, + 0.1156772507081641574759205162306240436215e145, + 0.1087366156656743080273652852567866010042e147, + 0.103299784882390592625997020993947270954e149, + 0.9916779348709496892095714015418938011582e150, + 0.9619275968248211985332842594956369871234e152, + 0.942689044888324774562618574305724247381e154, + 0.9332621544394415268169923885626670049072e156, + 0.9332621544394415268169923885626670049072e158, + 0.9425947759838359420851623124482936749562e160, + 0.9614466715035126609268655586972595484554e162, + 0.990290071648618040754671525458177334909e164, + 0.1029901674514562762384858386476504428305e167, + 0.1081396758240290900504101305800329649721e169, + 0.1146280563734708354534347384148349428704e171, + 0.1226520203196137939351751701038733888713e173, + 0.132464181945182897449989183712183259981e175, + 0.1443859583202493582204882102462797533793e177, + 0.1588245541522742940425370312709077287172e179, + 0.1762952551090244663872161047107075788761e181, + 0.1974506857221074023536820372759924883413e183, + 0.2231192748659813646596607021218715118256e185, + 0.2543559733472187557120132004189335234812e187, + 0.2925093693493015690688151804817735520034e189, + 0.339310868445189820119825609358857320324e191, + 0.396993716080872089540195962949863064779e193, + 0.4684525849754290656574312362808384164393e195, + 0.5574585761207605881323431711741977155627e197, + 0.6689502913449127057588118054090372586753e199, + 0.8094298525273443739681622845449350829971e201, + 0.9875044200833601362411579871448208012564e203, + 0.1214630436702532967576624324188129585545e206, + 0.1506141741511140879795014161993280686076e208, + 0.1882677176888926099743767702491600857595e210, + 0.237217324288004688567714730513941708057e212, + 0.3012660018457659544809977077527059692324e214, + 0.3856204823625804217356770659234636406175e216, + 0.4974504222477287440390234150412680963966e218, + 0.6466855489220473672507304395536485253155e220, + 0.8471580690878820510984568758152795681634e222, + 0.1118248651196004307449963076076169029976e225, + 0.1487270706090685728908450891181304809868e227, + 0.1992942746161518876737324194182948445223e229, + 0.269047270731805048359538766214698040105e231, + 0.3659042881952548657689727220519893345429e233, + 0.5012888748274991661034926292112253883237e235, + 0.6917786472619488492228198283114910358867e237, + 0.9615723196941089004197195613529725398826e239, + 0.1346201247571752460587607385894161555836e242, + 0.1898143759076170969428526414110767793728e244, + 0.2695364137888162776588507508037290267094e246, + 0.3854370717180072770521565736493325081944e248, + 0.5550293832739304789551054660550388118e250, + 0.80479260574719919448490292577980627711e252, + 0.1174997204390910823947958271638517164581e255, + 0.1727245890454638911203498659308620231933e257, + 0.2556323917872865588581178015776757943262e259, + 0.380892263763056972698595524350736933546e261, + 0.571338395644585459047893286526105400319e263, + 0.8627209774233240431623188626544191544816e265, + 0.1311335885683452545606724671234717114812e268, + 0.2006343905095682394778288746989117185662e270, + 0.308976961384735088795856467036324046592e272, + 0.4789142901463393876335775239063022722176e274, + 0.7471062926282894447083809372938315446595e276, + 0.1172956879426414428192158071551315525115e279, + 0.1853271869493734796543609753051078529682e281, + 0.2946702272495038326504339507351214862195e283, + 0.4714723635992061322406943211761943779512e285, + 0.7590705053947218729075178570936729485014e287, + 0.1229694218739449434110178928491750176572e290, + 0.2004401576545302577599591653441552787813e292, + 0.3287218585534296227263330311644146572013e294, + 0.5423910666131588774984495014212841843822e296, + 0.9003691705778437366474261723593317460744e298, + 0.1503616514864999040201201707840084015944e301, + 0.2526075744973198387538018869171341146786e303, + 0.4269068009004705274939251888899566538069e305, + 0.7257415615307998967396728211129263114717e307, + }}; + + return factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION long double unchecked_factorial(unsigned i BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(long double)) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array factorials = { { +#else + static const std::array factorials = {{ +#endif + 1L, + 1L, + 2L, + 6L, + 24L, + 120L, + 720L, + 5040L, + 40320L, + 362880.0L, + 3628800.0L, + 39916800.0L, + 479001600.0L, + 6227020800.0L, + 87178291200.0L, + 1307674368000.0L, + 20922789888000.0L, + 355687428096000.0L, + 6402373705728000.0L, + 121645100408832000.0L, + 0.243290200817664e19L, + 0.5109094217170944e20L, + 0.112400072777760768e22L, + 0.2585201673888497664e23L, + 0.62044840173323943936e24L, + 0.15511210043330985984e26L, + 0.403291461126605635584e27L, + 0.10888869450418352160768e29L, + 0.304888344611713860501504e30L, + 0.8841761993739701954543616e31L, + 0.26525285981219105863630848e33L, + 0.822283865417792281772556288e34L, + 0.26313083693369353016721801216e36L, + 0.868331761881188649551819440128e37L, + 0.29523279903960414084761860964352e39L, + 0.103331479663861449296666513375232e41L, + 0.3719933267899012174679994481508352e42L, + 0.137637530912263450463159795815809024e44L, + 0.5230226174666011117600072241000742912e45L, + 0.203978820811974433586402817399028973568e47L, + 0.815915283247897734345611269596115894272e48L, + 0.3345252661316380710817006205344075166515e50L, + 0.1405006117752879898543142606244511569936e52L, + 0.6041526306337383563735513206851399750726e53L, + 0.265827157478844876804362581101461589032e55L, + 0.1196222208654801945619631614956577150644e57L, + 0.5502622159812088949850305428800254892962e58L, + 0.2586232415111681806429643551536119799692e60L, + 0.1241391559253607267086228904737337503852e62L, + 0.6082818640342675608722521633212953768876e63L, + 0.3041409320171337804361260816606476884438e65L, + 0.1551118753287382280224243016469303211063e67L, + 0.8065817517094387857166063685640376697529e68L, + 0.427488328406002556429801375338939964969e70L, + 0.2308436973392413804720927426830275810833e72L, + 0.1269640335365827592596510084756651695958e74L, + 0.7109985878048634518540456474637249497365e75L, + 0.4052691950487721675568060190543232213498e77L, + 0.2350561331282878571829474910515074683829e79L, + 0.1386831185456898357379390197203894063459e81L, + 0.8320987112741390144276341183223364380754e82L, + 0.507580213877224798800856812176625227226e84L, + 0.3146997326038793752565312235495076408801e86L, + 0.1982608315404440064116146708361898137545e88L, + 0.1268869321858841641034333893351614808029e90L, + 0.8247650592082470666723170306785496252186e91L, + 0.5443449390774430640037292402478427526443e93L, + 0.3647111091818868528824985909660546442717e95L, + 0.2480035542436830599600990418569171581047e97L, + 0.1711224524281413113724683388812728390923e99L, + 0.1197857166996989179607278372168909873646e101L, + 0.8504785885678623175211676442399260102886e102L, + 0.6123445837688608686152407038527467274078e104L, + 0.4470115461512684340891257138125051110077e106L, + 0.3307885441519386412259530282212537821457e108L, + 0.2480914081139539809194647711659403366093e110L, + 0.188549470166605025498793226086114655823e112L, + 0.1451830920282858696340707840863082849837e114L, + 0.1132428117820629783145752115873204622873e116L, + 0.8946182130782975286851441715398316520698e117L, + 0.7156945704626380229481153372318653216558e119L, + 0.5797126020747367985879734231578109105412e121L, + 0.4753643337012841748421382069894049466438e123L, + 0.3945523969720658651189747118012061057144e125L, + 0.3314240134565353266999387579130131288001e127L, + 0.2817104114380550276949479442260611594801e129L, + 0.2422709538367273238176552320344125971528e131L, + 0.210775729837952771721360051869938959523e133L, + 0.1854826422573984391147968456455462843802e135L, + 0.1650795516090846108121691926245361930984e137L, + 0.1485715964481761497309522733620825737886e139L, + 0.1352001527678402962551665687594951421476e141L, + 0.1243841405464130725547532432587355307758e143L, + 0.1156772507081641574759205162306240436215e145L, + 0.1087366156656743080273652852567866010042e147L, + 0.103299784882390592625997020993947270954e149L, + 0.9916779348709496892095714015418938011582e150L, + 0.9619275968248211985332842594956369871234e152L, + 0.942689044888324774562618574305724247381e154L, + 0.9332621544394415268169923885626670049072e156L, + 0.9332621544394415268169923885626670049072e158L, + 0.9425947759838359420851623124482936749562e160L, + 0.9614466715035126609268655586972595484554e162L, + 0.990290071648618040754671525458177334909e164L, + 0.1029901674514562762384858386476504428305e167L, + 0.1081396758240290900504101305800329649721e169L, + 0.1146280563734708354534347384148349428704e171L, + 0.1226520203196137939351751701038733888713e173L, + 0.132464181945182897449989183712183259981e175L, + 0.1443859583202493582204882102462797533793e177L, + 0.1588245541522742940425370312709077287172e179L, + 0.1762952551090244663872161047107075788761e181L, + 0.1974506857221074023536820372759924883413e183L, + 0.2231192748659813646596607021218715118256e185L, + 0.2543559733472187557120132004189335234812e187L, + 0.2925093693493015690688151804817735520034e189L, + 0.339310868445189820119825609358857320324e191L, + 0.396993716080872089540195962949863064779e193L, + 0.4684525849754290656574312362808384164393e195L, + 0.5574585761207605881323431711741977155627e197L, + 0.6689502913449127057588118054090372586753e199L, + 0.8094298525273443739681622845449350829971e201L, + 0.9875044200833601362411579871448208012564e203L, + 0.1214630436702532967576624324188129585545e206L, + 0.1506141741511140879795014161993280686076e208L, + 0.1882677176888926099743767702491600857595e210L, + 0.237217324288004688567714730513941708057e212L, + 0.3012660018457659544809977077527059692324e214L, + 0.3856204823625804217356770659234636406175e216L, + 0.4974504222477287440390234150412680963966e218L, + 0.6466855489220473672507304395536485253155e220L, + 0.8471580690878820510984568758152795681634e222L, + 0.1118248651196004307449963076076169029976e225L, + 0.1487270706090685728908450891181304809868e227L, + 0.1992942746161518876737324194182948445223e229L, + 0.269047270731805048359538766214698040105e231L, + 0.3659042881952548657689727220519893345429e233L, + 0.5012888748274991661034926292112253883237e235L, + 0.6917786472619488492228198283114910358867e237L, + 0.9615723196941089004197195613529725398826e239L, + 0.1346201247571752460587607385894161555836e242L, + 0.1898143759076170969428526414110767793728e244L, + 0.2695364137888162776588507508037290267094e246L, + 0.3854370717180072770521565736493325081944e248L, + 0.5550293832739304789551054660550388118e250L, + 0.80479260574719919448490292577980627711e252L, + 0.1174997204390910823947958271638517164581e255L, + 0.1727245890454638911203498659308620231933e257L, + 0.2556323917872865588581178015776757943262e259L, + 0.380892263763056972698595524350736933546e261L, + 0.571338395644585459047893286526105400319e263L, + 0.8627209774233240431623188626544191544816e265L, + 0.1311335885683452545606724671234717114812e268L, + 0.2006343905095682394778288746989117185662e270L, + 0.308976961384735088795856467036324046592e272L, + 0.4789142901463393876335775239063022722176e274L, + 0.7471062926282894447083809372938315446595e276L, + 0.1172956879426414428192158071551315525115e279L, + 0.1853271869493734796543609753051078529682e281L, + 0.2946702272495038326504339507351214862195e283L, + 0.4714723635992061322406943211761943779512e285L, + 0.7590705053947218729075178570936729485014e287L, + 0.1229694218739449434110178928491750176572e290L, + 0.2004401576545302577599591653441552787813e292L, + 0.3287218585534296227263330311644146572013e294L, + 0.5423910666131588774984495014212841843822e296L, + 0.9003691705778437366474261723593317460744e298L, + 0.1503616514864999040201201707840084015944e301L, + 0.2526075744973198387538018869171341146786e303L, + 0.4269068009004705274939251888899566538069e305L, + 0.7257415615307998967396728211129263114717e307L, + }}; + + return factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +#ifdef BOOST_MATH_USE_FLOAT128 + +template <> +inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION BOOST_MATH_FLOAT128_TYPE unchecked_factorial(unsigned i) +{ +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array factorials = { { +#else + static const std::array factorials = { { +#endif + 1, + 1, + 2, + 6, + 24, + 120, + 720, + 5040, + 40320, + 362880.0Q, + 3628800.0Q, + 39916800.0Q, + 479001600.0Q, + 6227020800.0Q, + 87178291200.0Q, + 1307674368000.0Q, + 20922789888000.0Q, + 355687428096000.0Q, + 6402373705728000.0Q, + 121645100408832000.0Q, + 0.243290200817664e19Q, + 0.5109094217170944e20Q, + 0.112400072777760768e22Q, + 0.2585201673888497664e23Q, + 0.62044840173323943936e24Q, + 0.15511210043330985984e26Q, + 0.403291461126605635584e27Q, + 0.10888869450418352160768e29Q, + 0.304888344611713860501504e30Q, + 0.8841761993739701954543616e31Q, + 0.26525285981219105863630848e33Q, + 0.822283865417792281772556288e34Q, + 0.26313083693369353016721801216e36Q, + 0.868331761881188649551819440128e37Q, + 0.29523279903960414084761860964352e39Q, + 0.103331479663861449296666513375232e41Q, + 0.3719933267899012174679994481508352e42Q, + 0.137637530912263450463159795815809024e44Q, + 0.5230226174666011117600072241000742912e45Q, + 0.203978820811974433586402817399028973568e47Q, + 0.815915283247897734345611269596115894272e48Q, + 0.3345252661316380710817006205344075166515e50Q, + 0.1405006117752879898543142606244511569936e52Q, + 0.6041526306337383563735513206851399750726e53Q, + 0.265827157478844876804362581101461589032e55Q, + 0.1196222208654801945619631614956577150644e57Q, + 0.5502622159812088949850305428800254892962e58Q, + 0.2586232415111681806429643551536119799692e60Q, + 0.1241391559253607267086228904737337503852e62Q, + 0.6082818640342675608722521633212953768876e63Q, + 0.3041409320171337804361260816606476884438e65Q, + 0.1551118753287382280224243016469303211063e67Q, + 0.8065817517094387857166063685640376697529e68Q, + 0.427488328406002556429801375338939964969e70Q, + 0.2308436973392413804720927426830275810833e72Q, + 0.1269640335365827592596510084756651695958e74Q, + 0.7109985878048634518540456474637249497365e75Q, + 0.4052691950487721675568060190543232213498e77Q, + 0.2350561331282878571829474910515074683829e79Q, + 0.1386831185456898357379390197203894063459e81Q, + 0.8320987112741390144276341183223364380754e82Q, + 0.507580213877224798800856812176625227226e84Q, + 0.3146997326038793752565312235495076408801e86Q, + 0.1982608315404440064116146708361898137545e88Q, + 0.1268869321858841641034333893351614808029e90Q, + 0.8247650592082470666723170306785496252186e91Q, + 0.5443449390774430640037292402478427526443e93Q, + 0.3647111091818868528824985909660546442717e95Q, + 0.2480035542436830599600990418569171581047e97Q, + 0.1711224524281413113724683388812728390923e99Q, + 0.1197857166996989179607278372168909873646e101Q, + 0.8504785885678623175211676442399260102886e102Q, + 0.6123445837688608686152407038527467274078e104Q, + 0.4470115461512684340891257138125051110077e106Q, + 0.3307885441519386412259530282212537821457e108Q, + 0.2480914081139539809194647711659403366093e110Q, + 0.188549470166605025498793226086114655823e112Q, + 0.1451830920282858696340707840863082849837e114Q, + 0.1132428117820629783145752115873204622873e116Q, + 0.8946182130782975286851441715398316520698e117Q, + 0.7156945704626380229481153372318653216558e119Q, + 0.5797126020747367985879734231578109105412e121Q, + 0.4753643337012841748421382069894049466438e123Q, + 0.3945523969720658651189747118012061057144e125Q, + 0.3314240134565353266999387579130131288001e127Q, + 0.2817104114380550276949479442260611594801e129Q, + 0.2422709538367273238176552320344125971528e131Q, + 0.210775729837952771721360051869938959523e133Q, + 0.1854826422573984391147968456455462843802e135Q, + 0.1650795516090846108121691926245361930984e137Q, + 0.1485715964481761497309522733620825737886e139Q, + 0.1352001527678402962551665687594951421476e141Q, + 0.1243841405464130725547532432587355307758e143Q, + 0.1156772507081641574759205162306240436215e145Q, + 0.1087366156656743080273652852567866010042e147Q, + 0.103299784882390592625997020993947270954e149Q, + 0.9916779348709496892095714015418938011582e150Q, + 0.9619275968248211985332842594956369871234e152Q, + 0.942689044888324774562618574305724247381e154Q, + 0.9332621544394415268169923885626670049072e156Q, + 0.9332621544394415268169923885626670049072e158Q, + 0.9425947759838359420851623124482936749562e160Q, + 0.9614466715035126609268655586972595484554e162Q, + 0.990290071648618040754671525458177334909e164Q, + 0.1029901674514562762384858386476504428305e167Q, + 0.1081396758240290900504101305800329649721e169Q, + 0.1146280563734708354534347384148349428704e171Q, + 0.1226520203196137939351751701038733888713e173Q, + 0.132464181945182897449989183712183259981e175Q, + 0.1443859583202493582204882102462797533793e177Q, + 0.1588245541522742940425370312709077287172e179Q, + 0.1762952551090244663872161047107075788761e181Q, + 0.1974506857221074023536820372759924883413e183Q, + 0.2231192748659813646596607021218715118256e185Q, + 0.2543559733472187557120132004189335234812e187Q, + 0.2925093693493015690688151804817735520034e189Q, + 0.339310868445189820119825609358857320324e191Q, + 0.396993716080872089540195962949863064779e193Q, + 0.4684525849754290656574312362808384164393e195Q, + 0.5574585761207605881323431711741977155627e197Q, + 0.6689502913449127057588118054090372586753e199Q, + 0.8094298525273443739681622845449350829971e201Q, + 0.9875044200833601362411579871448208012564e203Q, + 0.1214630436702532967576624324188129585545e206Q, + 0.1506141741511140879795014161993280686076e208Q, + 0.1882677176888926099743767702491600857595e210Q, + 0.237217324288004688567714730513941708057e212Q, + 0.3012660018457659544809977077527059692324e214Q, + 0.3856204823625804217356770659234636406175e216Q, + 0.4974504222477287440390234150412680963966e218Q, + 0.6466855489220473672507304395536485253155e220Q, + 0.8471580690878820510984568758152795681634e222Q, + 0.1118248651196004307449963076076169029976e225Q, + 0.1487270706090685728908450891181304809868e227Q, + 0.1992942746161518876737324194182948445223e229Q, + 0.269047270731805048359538766214698040105e231Q, + 0.3659042881952548657689727220519893345429e233Q, + 0.5012888748274991661034926292112253883237e235Q, + 0.6917786472619488492228198283114910358867e237Q, + 0.9615723196941089004197195613529725398826e239Q, + 0.1346201247571752460587607385894161555836e242Q, + 0.1898143759076170969428526414110767793728e244Q, + 0.2695364137888162776588507508037290267094e246Q, + 0.3854370717180072770521565736493325081944e248Q, + 0.5550293832739304789551054660550388118e250Q, + 0.80479260574719919448490292577980627711e252Q, + 0.1174997204390910823947958271638517164581e255Q, + 0.1727245890454638911203498659308620231933e257Q, + 0.2556323917872865588581178015776757943262e259Q, + 0.380892263763056972698595524350736933546e261Q, + 0.571338395644585459047893286526105400319e263Q, + 0.8627209774233240431623188626544191544816e265Q, + 0.1311335885683452545606724671234717114812e268Q, + 0.2006343905095682394778288746989117185662e270Q, + 0.308976961384735088795856467036324046592e272Q, + 0.4789142901463393876335775239063022722176e274Q, + 0.7471062926282894447083809372938315446595e276Q, + 0.1172956879426414428192158071551315525115e279Q, + 0.1853271869493734796543609753051078529682e281Q, + 0.2946702272495038326504339507351214862195e283Q, + 0.4714723635992061322406943211761943779512e285Q, + 0.7590705053947218729075178570936729485014e287Q, + 0.1229694218739449434110178928491750176572e290Q, + 0.2004401576545302577599591653441552787813e292Q, + 0.3287218585534296227263330311644146572013e294Q, + 0.5423910666131588774984495014212841843822e296Q, + 0.9003691705778437366474261723593317460744e298Q, + 0.1503616514864999040201201707840084015944e301Q, + 0.2526075744973198387538018869171341146786e303Q, + 0.4269068009004705274939251888899566538069e305Q, + 0.7257415615307998967396728211129263114717e307Q, + } }; + + return factorials[i]; +} + +template <> +struct max_factorial +{ + static constexpr unsigned value = 170; +}; + +#endif + +template +struct unchecked_factorial_initializer +{ + struct init + { + init() + { + boost::math::unchecked_factorial(3); + } + void force_instantiate()const {} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename unchecked_factorial_initializer::init unchecked_factorial_initializer::initializer; + + +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant&) +{ + // + // If you're foolish enough to instantiate factorial + // on an integer type then you end up here. But this code is + // only intended for (fixed precision) multiprecision types. + // + // Note, factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + // + static_assert(!std::is_integral::value && !std::numeric_limits::is_integer, "Type T must not be an integral type"); + + // We rely on C++11 thread safe initialization here: + static const std::array factorials = {{ + T(boost::math::tools::convert_from_string("1")), + T(boost::math::tools::convert_from_string("1")), + T(boost::math::tools::convert_from_string("2")), + T(boost::math::tools::convert_from_string("6")), + T(boost::math::tools::convert_from_string("24")), + T(boost::math::tools::convert_from_string("120")), + T(boost::math::tools::convert_from_string("720")), + T(boost::math::tools::convert_from_string("5040")), + T(boost::math::tools::convert_from_string("40320")), + T(boost::math::tools::convert_from_string("362880")), + T(boost::math::tools::convert_from_string("3628800")), + T(boost::math::tools::convert_from_string("39916800")), + T(boost::math::tools::convert_from_string("479001600")), + T(boost::math::tools::convert_from_string("6227020800")), + T(boost::math::tools::convert_from_string("87178291200")), + T(boost::math::tools::convert_from_string("1307674368000")), + T(boost::math::tools::convert_from_string("20922789888000")), + T(boost::math::tools::convert_from_string("355687428096000")), + T(boost::math::tools::convert_from_string("6402373705728000")), + T(boost::math::tools::convert_from_string("121645100408832000")), + T(boost::math::tools::convert_from_string("2432902008176640000")), + T(boost::math::tools::convert_from_string("51090942171709440000")), + T(boost::math::tools::convert_from_string("1124000727777607680000")), + T(boost::math::tools::convert_from_string("25852016738884976640000")), + T(boost::math::tools::convert_from_string("620448401733239439360000")), + T(boost::math::tools::convert_from_string("15511210043330985984000000")), + T(boost::math::tools::convert_from_string("403291461126605635584000000")), + T(boost::math::tools::convert_from_string("10888869450418352160768000000")), + T(boost::math::tools::convert_from_string("304888344611713860501504000000")), + T(boost::math::tools::convert_from_string("8841761993739701954543616000000")), + T(boost::math::tools::convert_from_string("265252859812191058636308480000000")), + T(boost::math::tools::convert_from_string("8222838654177922817725562880000000")), + T(boost::math::tools::convert_from_string("263130836933693530167218012160000000")), + T(boost::math::tools::convert_from_string("8683317618811886495518194401280000000")), + T(boost::math::tools::convert_from_string("295232799039604140847618609643520000000")), + T(boost::math::tools::convert_from_string("10333147966386144929666651337523200000000")), + T(boost::math::tools::convert_from_string("371993326789901217467999448150835200000000")), + T(boost::math::tools::convert_from_string("13763753091226345046315979581580902400000000")), + T(boost::math::tools::convert_from_string("523022617466601111760007224100074291200000000")), + T(boost::math::tools::convert_from_string("20397882081197443358640281739902897356800000000")), + T(boost::math::tools::convert_from_string("815915283247897734345611269596115894272000000000")), + T(boost::math::tools::convert_from_string("33452526613163807108170062053440751665152000000000")), + T(boost::math::tools::convert_from_string("1405006117752879898543142606244511569936384000000000")), + T(boost::math::tools::convert_from_string("60415263063373835637355132068513997507264512000000000")), + T(boost::math::tools::convert_from_string("2658271574788448768043625811014615890319638528000000000")), + T(boost::math::tools::convert_from_string("119622220865480194561963161495657715064383733760000000000")), + T(boost::math::tools::convert_from_string("5502622159812088949850305428800254892961651752960000000000")), + T(boost::math::tools::convert_from_string("258623241511168180642964355153611979969197632389120000000000")), + T(boost::math::tools::convert_from_string("12413915592536072670862289047373375038521486354677760000000000")), + T(boost::math::tools::convert_from_string("608281864034267560872252163321295376887552831379210240000000000")), + T(boost::math::tools::convert_from_string("30414093201713378043612608166064768844377641568960512000000000000")), + T(boost::math::tools::convert_from_string("1551118753287382280224243016469303211063259720016986112000000000000")), + T(boost::math::tools::convert_from_string("80658175170943878571660636856403766975289505440883277824000000000000")), + T(boost::math::tools::convert_from_string("4274883284060025564298013753389399649690343788366813724672000000000000")), + T(boost::math::tools::convert_from_string("230843697339241380472092742683027581083278564571807941132288000000000000")), + T(boost::math::tools::convert_from_string("12696403353658275925965100847566516959580321051449436762275840000000000000")), + T(boost::math::tools::convert_from_string("710998587804863451854045647463724949736497978881168458687447040000000000000")), + T(boost::math::tools::convert_from_string("40526919504877216755680601905432322134980384796226602145184481280000000000000")), + T(boost::math::tools::convert_from_string("2350561331282878571829474910515074683828862318181142924420699914240000000000000")), + T(boost::math::tools::convert_from_string("138683118545689835737939019720389406345902876772687432540821294940160000000000000")), + T(boost::math::tools::convert_from_string("8320987112741390144276341183223364380754172606361245952449277696409600000000000000")), + T(boost::math::tools::convert_from_string("507580213877224798800856812176625227226004528988036003099405939480985600000000000000")), + T(boost::math::tools::convert_from_string("31469973260387937525653122354950764088012280797258232192163168247821107200000000000000")), + T(boost::math::tools::convert_from_string("1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000")), + T(boost::math::tools::convert_from_string("126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000")), + T(boost::math::tools::convert_from_string("8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000")), + T(boost::math::tools::convert_from_string("544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000")), + T(boost::math::tools::convert_from_string("36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000")), + T(boost::math::tools::convert_from_string("2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000")), + T(boost::math::tools::convert_from_string("171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000")), + T(boost::math::tools::convert_from_string("11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000")), + T(boost::math::tools::convert_from_string("850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000")), + T(boost::math::tools::convert_from_string("61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000")), + T(boost::math::tools::convert_from_string("4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000")), + T(boost::math::tools::convert_from_string("330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000")), + T(boost::math::tools::convert_from_string("24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000")), + T(boost::math::tools::convert_from_string("1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000")), + T(boost::math::tools::convert_from_string("145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000")), + T(boost::math::tools::convert_from_string("11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000")), + T(boost::math::tools::convert_from_string("894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000")), + T(boost::math::tools::convert_from_string("71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000")), + T(boost::math::tools::convert_from_string("5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000")), + T(boost::math::tools::convert_from_string("475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000")), + T(boost::math::tools::convert_from_string("39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000")), + T(boost::math::tools::convert_from_string("3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000")), + T(boost::math::tools::convert_from_string("281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000")), + T(boost::math::tools::convert_from_string("24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000")), + T(boost::math::tools::convert_from_string("2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000")), + T(boost::math::tools::convert_from_string("185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000")), + T(boost::math::tools::convert_from_string("16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000")), + T(boost::math::tools::convert_from_string("1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000")), + T(boost::math::tools::convert_from_string("135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000")), + T(boost::math::tools::convert_from_string("12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000")), + T(boost::math::tools::convert_from_string("1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000")), + T(boost::math::tools::convert_from_string("108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000")), + T(boost::math::tools::convert_from_string("10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000")), + T(boost::math::tools::convert_from_string("991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000")), + T(boost::math::tools::convert_from_string("96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000")), + T(boost::math::tools::convert_from_string("9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000")), + T(boost::math::tools::convert_from_string("933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000")), + T(boost::math::tools::convert_from_string("93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000")), + }}; + + return factorials[i]; +} + +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant&) +{ + // + // If you're foolish enough to instantiate factorial + // on an integer type then you end up here. But this code is + // only intended for (variable precision) multiprecision types. + // + // Note, factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + // + static_assert(!std::is_integral::value && !std::numeric_limits::is_integer, "Type T must not be an integral type"); + + static const char* const factorial_strings[] = { + "1", + "1", + "2", + "6", + "24", + "120", + "720", + "5040", + "40320", + "362880", + "3628800", + "39916800", + "479001600", + "6227020800", + "87178291200", + "1307674368000", + "20922789888000", + "355687428096000", + "6402373705728000", + "121645100408832000", + "2432902008176640000", + "51090942171709440000", + "1124000727777607680000", + "25852016738884976640000", + "620448401733239439360000", + "15511210043330985984000000", + "403291461126605635584000000", + "10888869450418352160768000000", + "304888344611713860501504000000", + "8841761993739701954543616000000", + "265252859812191058636308480000000", + "8222838654177922817725562880000000", + "263130836933693530167218012160000000", + "8683317618811886495518194401280000000", + "295232799039604140847618609643520000000", + "10333147966386144929666651337523200000000", + "371993326789901217467999448150835200000000", + "13763753091226345046315979581580902400000000", + "523022617466601111760007224100074291200000000", + "20397882081197443358640281739902897356800000000", + "815915283247897734345611269596115894272000000000", + "33452526613163807108170062053440751665152000000000", + "1405006117752879898543142606244511569936384000000000", + "60415263063373835637355132068513997507264512000000000", + "2658271574788448768043625811014615890319638528000000000", + "119622220865480194561963161495657715064383733760000000000", + "5502622159812088949850305428800254892961651752960000000000", + "258623241511168180642964355153611979969197632389120000000000", + "12413915592536072670862289047373375038521486354677760000000000", + "608281864034267560872252163321295376887552831379210240000000000", + "30414093201713378043612608166064768844377641568960512000000000000", + "1551118753287382280224243016469303211063259720016986112000000000000", + "80658175170943878571660636856403766975289505440883277824000000000000", + "4274883284060025564298013753389399649690343788366813724672000000000000", + "230843697339241380472092742683027581083278564571807941132288000000000000", + "12696403353658275925965100847566516959580321051449436762275840000000000000", + "710998587804863451854045647463724949736497978881168458687447040000000000000", + "40526919504877216755680601905432322134980384796226602145184481280000000000000", + "2350561331282878571829474910515074683828862318181142924420699914240000000000000", + "138683118545689835737939019720389406345902876772687432540821294940160000000000000", + "8320987112741390144276341183223364380754172606361245952449277696409600000000000000", + "507580213877224798800856812176625227226004528988036003099405939480985600000000000000", + "31469973260387937525653122354950764088012280797258232192163168247821107200000000000000", + "1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000", + "126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000", + "8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000", + "544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000", + "36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000", + "2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000", + "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000", + "11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000", + "850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000", + "61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000", + "4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000", + "330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000", + "24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000", + "1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000", + "145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000", + "11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000", + "894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000", + "71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000", + "5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000", + "475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000", + "39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000", + "3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000", + "281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000", + "24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000", + "2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000", + "185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000", + "16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000", + "1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000", + "135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000", + "12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000", + "1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000", + "108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000", + "10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000", + "991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000", + "96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000", + "9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000", + "933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000", + "93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000", + }; + // + // we rely on C++11 thread safe initialization in the event that we have no thread locals: + // + static BOOST_MATH_THREAD_LOCAL T factorials[sizeof(factorial_strings) / sizeof(factorial_strings[0])]; + static BOOST_MATH_THREAD_LOCAL int digits = 0; + + int current_digits = boost::math::tools::digits(); + + if(digits != current_digits) + { + digits = current_digits; + for(unsigned k = 0; k < sizeof(factorials) / sizeof(factorials[0]); ++k) + factorials[k] = static_cast(boost::math::tools::convert_from_string(factorial_strings[k])); + } + + return factorials[i]; +} + +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant::digits>&) +{ + return unchecked_factorial(i); +} + +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant::digits>&) +{ + return unchecked_factorial(i); +} + +#if DBL_MANT_DIG != LDBL_MANT_DIG +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant&) +{ + return unchecked_factorial(i); +} +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +template +inline T unchecked_factorial_imp(unsigned i, const std::integral_constant&) +{ + return unchecked_factorial(i); +} +#endif + +template +inline T unchecked_factorial(unsigned i) +{ + typedef typename boost::math::policies::precision >::type tag_type; + return unchecked_factorial_imp(i, tag_type()); +} + +#ifdef BOOST_MATH_USE_FLOAT128 +#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL : std::numeric_limits::digits == 113 ? max_factorial::value +#else +#define BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL +#endif + +template +struct max_factorial +{ + static constexpr unsigned value = + std::numeric_limits::digits == std::numeric_limits::digits ? max_factorial::value + : std::numeric_limits::digits == std::numeric_limits::digits ? max_factorial::value + : std::numeric_limits::digits == std::numeric_limits::digits ? max_factorial::value + BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL + : 100; +}; + +#undef BOOST_MATH_DETAIL_FLOAT128_MAX_FACTORIAL + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +template +constexpr unsigned max_factorial::value; +#endif + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_UC_FACTORIALS_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/digamma.hpp b/libcxx/src/third-party/boost/math/special_functions/digamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/digamma.hpp @@ -0,0 +1,629 @@ +// (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_SF_DIGAMMA_HPP +#define BOOST_MATH_SF_DIGAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ +namespace math{ +namespace detail{ +// +// Begin by defining the smallest value for which it is safe to +// use the asymptotic expansion for digamma: +// +inline unsigned digamma_large_lim(const std::integral_constant*) +{ return 20; } +inline unsigned digamma_large_lim(const std::integral_constant*) +{ return 20; } +inline unsigned digamma_large_lim(const void*) +{ return 10; } +// +// Implementations of the asymptotic expansion come next, +// the coefficients of the series have been evaluated +// in advance at high precision, and the series truncated +// at the first term that's too small to effect the result. +// Note that the series becomes divergent after a while +// so truncation is very important. +// +// This first one gives 34-digit precision for x >= 20: +// +template +inline T digamma_imp_large(T x, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.003968253968253968253968253968253968253968253968254), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0041666666666666666666666666666666666666666666666667), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0075757575757575757575757575757575757575757575757576), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.021092796092796092796092796092796092796092796092796), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.44325980392156862745098039215686274509803921568627), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.0539543302701197438039543302701197438039543302701), + BOOST_MATH_BIG_CONSTANT(T, 113, -26.456212121212121212121212121212121212121212121212), + BOOST_MATH_BIG_CONSTANT(T, 113, 281.4601449275362318840579710144927536231884057971), + BOOST_MATH_BIG_CONSTANT(T, 113, -3607.510546398046398046398046398046398046398046398), + BOOST_MATH_BIG_CONSTANT(T, 113, 54827.583333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 113, -974936.82385057471264367816091954022988505747126437), + BOOST_MATH_BIG_CONSTANT(T, 113, 20052695.796688078946143462272494530559046688078946), + BOOST_MATH_BIG_CONSTANT(T, 113, -472384867.72162990196078431372549019607843137254902), + BOOST_MATH_BIG_CONSTANT(T, 113, 12635724795.916666666666666666666666666666666666667) + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// 19-digit precision for x >= 10: +// +template +inline T digamma_imp_large(T x, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.003968253968253968253968253968253968253968253968254), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0041666666666666666666666666666666666666666666666667), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0075757575757575757575757575757575757575757575757576), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.021092796092796092796092796092796092796092796092796), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.44325980392156862745098039215686274509803921568627), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.0539543302701197438039543302701197438039543302701), + BOOST_MATH_BIG_CONSTANT(T, 64, -26.456212121212121212121212121212121212121212121212), + BOOST_MATH_BIG_CONSTANT(T, 64, 281.4601449275362318840579710144927536231884057971), + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// 17-digit precision for x >= 10: +// +template +inline T digamma_imp_large(T x, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.003968253968253968253968253968253968253968253968254), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0041666666666666666666666666666666666666666666666667), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0075757575757575757575757575757575757575757575757576), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.021092796092796092796092796092796092796092796092796), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.44325980392156862745098039215686274509803921568627) + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// 9-digit precision for x >= 10: +// +template +inline T digamma_imp_large(T x, const std::integral_constant*) +{ + BOOST_MATH_STD_USING // ADL of std functions. + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 24, 0.083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 24, -0.0083333333333333333333333333333333333333333333333333), + BOOST_MATH_BIG_CONSTANT(T, 24, 0.003968253968253968253968253968253968253968253968254) + }; + x -= 1; + T result = log(x); + result += 1 / (2 * x); + T z = 1 / (x*x); + result -= z * tools::evaluate_polynomial(P, z); + return result; +} +// +// Fully generic asymptotic expansion in terms of Bernoulli numbers, see: +// http://functions.wolfram.com/06.14.06.0012.01 +// +template +struct digamma_series_func +{ +private: + int k; + T xx; + T term; +public: + digamma_series_func(T x) : k(1), xx(x * x), term(1 / (x * x)) {} + T operator()() + { + T result = term * boost::math::bernoulli_b2n(k) / (2 * k); + term /= xx; + ++k; + return result; + } + typedef T result_type; +}; + +template +inline T digamma_imp_large(T x, const Policy& pol, const std::integral_constant*) +{ + BOOST_MATH_STD_USING + digamma_series_func s(x); + T result = log(x) - 1 / (2 * x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, -result); + result = -result; + policies::check_series_iterations("boost::math::digamma<%1%>(%1%)", max_iter, pol); + return result; +} +// +// Now follow rational approximations over the range [1,2]. +// +// 35-digit precision: +// +template +T digamma_imp_1_2(T x, const std::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Max error found at 128-bit long double precision: 5.541e-35 + // Maximum Deviation Found (approximation error): 1.965e-35 + // + static const float Y = 0.99558162689208984375F; + + static const T root1 = T(1569415565) / 1073741824uL; + static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + static const T root3 = ((T(111616537) / 1073741824uL) / 1073741824uL) / 1073741824uL; + static const T root4 = (((T(503992070) / 1073741824uL) / 1073741824uL) / 1073741824uL) / 1073741824uL; + static const T root5 = BOOST_MATH_BIG_CONSTANT(T, 113, 0.52112228569249997894452490385577338504019838794544e-36); + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.25479851061131551526977464225335883769), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.18684290534374944114622235683619897417), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.80360876047931768958995775910991929922), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.67227342794829064330498117008564270136), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.26569010991230617151285010695543858005), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.05775672694575986971640757748003553385), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0071432147823164975485922555833274240665), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00048740753910766168912364555706064993274), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.16454996865214115723416538844975174761e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.20327832297631728077731148515093164955e-6) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6210924610812025425088411043163287646), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.6850757078559596612621337395886392594), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.4320913706209965531250495490639289418), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.4410872083455009362557012239501953402), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.081385727399251729505165509278152487225), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089478633066857163432104815183858149496), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00055861622855066424871506755481997374154), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.1760168552357342401304462967950178554e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.20585454493572473724556649516040874384e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.90745971844439990284514121823069162795e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.48857673606545846774761343500033283272e-13), + }; + T g = x - root1; + g -= root2; + g -= root3; + g -= root4; + g -= root5; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} +// +// 19-digit precision: +// +template +T digamma_imp_1_2(T x, const std::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Max error found at 80-bit long double precision: 5.016e-20 + // Maximum Deviation Found (approximation error): 3.575e-20 + // + static const float Y = 0.99558162689208984375F; + + static const T root1 = T(1569415565) / 1073741824uL; + static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.9016312093258695918615325266959189453125e-19); + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.254798510611315515235), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.314628554532916496608), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.665836341559876230295), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.314767657147375752913), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0541156266153505273939), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00289268368333918761452) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.1195759927055347547), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.54350554664961128724), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.486986018231042975162), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0660481487173569812846), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00298999662592323990972), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.165079794012604905639e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.317940243105952177571e-7) + }; + T g = x - root1; + g -= root2; + g -= root3; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} +// +// 18-digit precision: +// +template +T digamma_imp_1_2(T x, const std::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Maximum Deviation Found: 1.466e-18 + // At double precision, max error found: 2.452e-17 + // + static const float Y = 0.99558162689208984F; + + static const T root1 = T(1569415565) / 1073741824uL; + static const T root2 = (T(381566830) / 1073741824uL) / 1073741824uL; + static const T root3 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.9016312093258695918615325266959189453125e-19); + + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.25479851061131551), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.32555031186804491), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.65031853770896507), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.28919126444774784), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.045251321448739056), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0020713321167745952) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.0767117023730469), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.4606242909763515), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.43593529692665969), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.054151797245674225), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0021284987017821144), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.55789841321675513e-6) + }; + T g = x - root1; + g -= root2; + g -= root3; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} +// +// 9-digit precision: +// +template +inline T digamma_imp_1_2(T x, const std::integral_constant*) +{ + // + // Now the approximation, we use the form: + // + // digamma(x) = (x - root) * (Y + R(x-1)) + // + // Where root is the location of the positive root of digamma, + // Y is a constant, and R is optimised for low absolute error + // compared to Y. + // + // Maximum Deviation Found: 3.388e-010 + // At float precision, max error found: 2.008725e-008 + // + static const float Y = 0.99558162689208984f; + static const T root = 1532632.0f / 1048576; + static const T root_minor = static_cast(0.3700660185912626595423257213284682051735604e-6L); + static const T P[] = { + 0.25479851023250261e0f, + -0.44981331915268368e0f, + -0.43916936919946835e0f, + -0.61041765350579073e-1f + }; + static const T Q[] = { + 0.1e1, + 0.15890202430554952e1f, + 0.65341249856146947e0f, + 0.63851690523355715e-1f + }; + T g = x - root; + g -= root_minor; + T r = tools::evaluate_polynomial(P, T(x-1)) / tools::evaluate_polynomial(Q, T(x-1)); + T result = g * Y + g * r; + + return result; +} + +template +T digamma_imp(T x, const Tag* t, const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= -1) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + T remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1-x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + if(x == 0) + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, x, pol); + // + // If we're above the lower-limit for the + // asymptotic expansion then use it: + // + if(x >= digamma_large_lim(t)) + { + result += digamma_imp_large(x, t); + } + else + { + // + // If x > 2 reduce to the interval [1,2]: + // + while(x > 2) + { + x -= 1; + result += 1/x; + } + // + // If x < 1 use recurrence to shift to > 1: + // + while(x < 1) + { + result -= 1/x; + x += 1; + } + result += digamma_imp_1_2(x, t); + } + return result; +} + +template +T digamma_imp(T x, const std::integral_constant* t, const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= -1) + { + // Reflect: + x = 1 - x; + // Argument reduction for tan: + T remainder = x - floor(x); + // Shift to negative if > 0.5: + if(remainder > 0.5) + { + remainder -= 1; + } + // + // check for evaluation at a negative pole: + // + if(remainder == 0) + { + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, (1 - x), pol); + } + result = constants::pi() / tan(constants::pi() * remainder); + } + if(x == 0) + return policies::raise_pole_error("boost::math::digamma<%1%>(%1%)", nullptr, x, pol); + // + // If we're above the lower-limit for the + // asymptotic expansion then use it, the + // limit is a linear interpolation with + // limit = 10 at 50 bit precision and + // limit = 250 at 1000 bit precision. + // + int lim = 10 + ((tools::digits() - 50) * 240L) / 950; + T two_x = ldexp(x, 1); + if(x >= lim) + { + result += digamma_imp_large(x, pol, t); + } + else if(floor(x) == x) + { + // + // Special case for integer arguments, see + // http://functions.wolfram.com/06.14.03.0001.01 + // + result = -constants::euler(); + T val = 1; + while(val < x) + { + result += 1 / val; + val += 1; + } + } + else if(floor(two_x) == two_x) + { + // + // Special case for half integer arguments, see: + // http://functions.wolfram.com/06.14.03.0007.01 + // + result = -2 * constants::ln_two() - constants::euler(); + int n = itrunc(x); + if(n) + { + for(int k = 1; k < n; ++k) + result += 1 / T(k); + for(int k = n; k <= 2 * n - 1; ++k) + result += 2 / T(k); + } + } + else + { + // + // Rescale so we can use the asymptotic expansion: + // + while(x < lim) + { + result -= 1 / x; + x += 1; + } + result += digamma_imp_large(x, pol, t); + } + return result; +} +// +// Initializer: ensure all our constants are initialized prior to the first call of main: +// +template +struct digamma_initializer +{ + struct init + { + init() + { + typedef typename policies::precision::type precision_type; + do_init(std::integral_constant()); + } + void do_init(const std::true_type&) + { + boost::math::digamma(T(1.5), Policy()); + boost::math::digamma(T(500), Policy()); + } + void do_init(const std::false_type&){} + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename digamma_initializer::init digamma_initializer::initializer; + +} // namespace detail + +template +inline typename tools::promote_args::type + digamma(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef std::integral_constant 113) ? 0 : + precision_type::value <= 24 ? 24 : + precision_type::value <= 53 ? 53 : + precision_type::value <= 64 ? 64 : + precision_type::value <= 113 ? 113 : 0 > tag_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + // Force initialization of constants: + detail::digamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::digamma_imp( + static_cast(x), + static_cast(nullptr), forwarding_policy()), "boost::math::digamma<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type + digamma(T x) +{ + return digamma(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_1.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_1.hpp @@ -0,0 +1,798 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_1_HPP +#define BOOST_MATH_ELLINT_1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the first kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&); +template +T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&); +template +T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&); + +// Elliptic integral (Legendre form) of the first kind +template +T ellint_f_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + static const char* function = "boost::math::ellint_f<%1%>(%1%,%1%)"; + BOOST_MATH_INSTRUMENT_VARIABLE(phi); + BOOST_MATH_INSTRUMENT_VARIABLE(k); + BOOST_MATH_INSTRUMENT_VARIABLE(function); + + bool invert = false; + if(phi < 0) + { + BOOST_MATH_INSTRUMENT_VARIABLE(phi); + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error(function, nullptr, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(phi > 1 / tools::epsilon()) + { + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + + result = 2 * phi * ellint_k_imp(k, pol, precision_tag_type()) / constants::pi(); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + BOOST_MATH_INSTRUMENT_CODE("pi/2 = " << constants::pi() / 2); + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + BOOST_MATH_INSTRUMENT_VARIABLE(m); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > 0.5) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + } + T sinp = sin(rphi); + sinp *= sinp; + if (sinp * k * k >= 1) + { + return policies::raise_domain_error(function, + "Got k^2 * sin^2(phi) = %1%, but the function requires this < 1", sinp * k * k, pol); + } + T cosp = cos(rphi); + cosp *= cosp; + BOOST_MATH_INSTRUMENT_VARIABLE(sinp); + BOOST_MATH_INSTRUMENT_VARIABLE(cosp); + if(sinp > tools::min_value()) + { + BOOST_MATH_ASSERT(rphi != 0); // precondition, can't be true if sin(rphi) != 0. + // + // Use http://dlmf.nist.gov/19.25#E5, note that + // c-1 simplifies to cot^2(rphi) which avoid cancellation: + // + T c = 1 / sinp; + result = static_cast(s * ellint_rf_imp(T(cosp / sinp), T(c - k * k), c, pol)); + } + else + result = s * sin(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(m != 0) + { + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + + result += m * ellint_k_imp(k, pol, precision_tag_type()); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + return invert ? T(-result) : result; +} + +// Complete elliptic integral (Legendre form) of the first kind +template +T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + static const char* function = "boost::math::ellint_k<%1%>(%1%)"; + + if (abs(k) > 1) + { + return policies::raise_domain_error(function, + "Got k = %1%, function requires |k| <= 1", k, pol); + } + if (abs(k) == 1) + { + return policies::raise_overflow_error(function, nullptr, pol); + } + + T x = 0; + T y = 1 - k * k; + T z = 1; + T value = ellint_rf_imp(x, y, z, pol); + + return value; +} + +// +// Special versions for double and 80-bit long double precision, +// double precision versions use the coefficients from: +// "Fast computation of complete elliptic integrals and Jacobian elliptic functions", +// Celestial Mechanics and Dynamical Astronomy, April 2012. +// +// Higher precision coefficients for 80-bit long doubles can be calculated +// using for example: +// Table[N[SeriesCoefficient[ EllipticK [ m ], { m, 875/1000, i} ], 20], {i, 0, 24}] +// and checking the value of the first neglected term with: +// N[SeriesCoefficient[ EllipticK [ m ], { m, 875/1000, 24} ], 20] * (2.5/100)^24 +// +// For m > 0.9 we don't use the method of the paper above, but simply call our +// existing routines. The routine used in the above paper was tried (and is +// archived in the code below), but was found to have slightly higher error rates. +// +template +BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&) +{ + using std::abs; + using namespace boost::math::tools; + + T m = k * k; + + switch (static_cast(m * 20)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + 1.591003453790792180, + 0.416000743991786912, + 0.245791514264103415, + 0.179481482914906162, + 0.144556057087555150, + 0.123200993312427711, + 0.108938811574293531, + 0.098853409871592910, + 0.091439629201749751, + 0.085842591595413900, + 0.081541118718303215, + 0.078199656811256481910 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + 1.635256732264579992, + 0.471190626148732291, + 0.309728410831499587, + 0.252208311773135699, + 0.226725623219684650, + 0.215774446729585976, + 0.213108771877348910, + 0.216029124605188282, + 0.223255831633057896, + 0.234180501294209925, + 0.248557682972264071, + 0.266363809892617521 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15); + } + case 4: + case 5: + //else if (m < 0.3) + { + constexpr T coef[] = + { + 1.685750354812596043, + 0.541731848613280329, + 0.401524438390690257, + 0.369642473420889090, + 0.376060715354583645, + 0.405235887085125919, + 0.453294381753999079, + 0.520518947651184205, + 0.609426039204995055, + 0.724263522282908870, + 0.871013847709812357, + 1.057652872753547036 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25); + } + case 6: + case 7: + //else if (m < 0.4) + { + constexpr T coef[] = + { + 1.744350597225613243, + 0.634864275371935304, + 0.539842564164445538, + 0.571892705193787391, + 0.670295136265406100, + 0.832586590010977199, + 1.073857448247933265, + 1.422091460675497751, + 1.920387183402304829, + 2.632552548331654201, + 3.652109747319039160, + 5.115867135558865806, + 7.224080007363877411 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35); + } + case 8: + case 9: + //else if (m < 0.5) + { + constexpr T coef[] = + { + 1.813883936816982644, + 0.763163245700557246, + 0.761928605321595831, + 0.951074653668427927, + 1.315180671703161215, + 1.928560693477410941, + 2.937509342531378755, + 4.594894405442878062, + 7.330071221881720772, + 11.87151259742530180, + 19.45851374822937738, + 32.20638657246426863, + 53.73749198700554656, + 90.27388602940998849 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45); + } + case 10: + case 11: + //else if (m < 0.6) + { + constexpr T coef[] = + { + 1.898924910271553526, + 0.950521794618244435, + 1.151077589959015808, + 1.750239106986300540, + 2.952676812636875180, + 5.285800396121450889, + 9.832485716659979747, + 18.78714868327559562, + 36.61468615273698145, + 72.45292395127771801, + 145.1079577347069102, + 293.4786396308497026, + 598.3851815055010179, + 1228.420013075863451, + 2536.529755382764488 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55); + } + case 12: + case 13: + //else if (m < 0.7) + { + constexpr T coef[] = + { + 2.007598398424376302, + 1.248457231212347337, + 1.926234657076479729, + 3.751289640087587680, + 8.119944554932045802, + 18.66572130873555361, + 44.60392484291437063, + 109.5092054309498377, + 274.2779548232413480, + 697.5598008606326163, + 1795.716014500247129, + 4668.381716790389910, + 12235.76246813664335, + 32290.17809718320818, + 85713.07608195964685, + 228672.1890493117096, + 612757.2711915852774 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65); + } + case 14: + case 15: + //else if (m < 0.8) + { + constexpr T coef[] = + { + 2.156515647499643235, + 1.791805641849463243, + 3.826751287465713147, + 10.38672468363797208, + 31.40331405468070290, + 100.9237039498695416, + 337.3268282632272897, + 1158.707930567827917, + 4060.990742193632092, + 14454.00184034344795, + 52076.66107599404803, + 189493.6591462156887, + 695184.5762413896145, + 2567994.048255284686, + 9541921.966748386322, + 35634927.44218076174, + 133669298.4612040871, + 503352186.6866284541, + 1901975729.538660119, + 7208915015.330103756 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75); + } + case 16: + //else if (m < 0.85) + { + constexpr T coef[] = + { + 2.318122621712510589, + 2.616920150291232841, + 7.897935075731355823, + 30.50239715446672327, + 131.4869365523528456, + 602.9847637356491617, + 2877.024617809972641, + 14110.51991915180325, + 70621.44088156540229, + 358977.2665825309926, + 1847238.263723971684, + 9600515.416049214109, + 50307677.08502366879, + 265444188.6527127967, + 1408862325.028702687, + 7515687935.373774627 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825); + } + case 17: + //else if (m < 0.90) + { + constexpr T coef[] = + { + 2.473596173751343912, + 3.727624244118099310, + 15.60739303554930496, + 84.12850842805887747, + 506.9818197040613935, + 3252.277058145123644, + 21713.24241957434256, + 149037.0451890932766, + 1043999.331089990839, + 7427974.817042038995, + 53503839.67558661151, + 389249886.9948708474, + 2855288351.100810619, + 21090077038.76684053, + 156699833947.7902014, + 1170222242422.439893, + 8777948323668.937971, + 66101242752484.95041, + 499488053713388.7989, + 37859743397240299.20 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875); + } + default: + // + // This handles all cases where m > 0.9, + // including all error handling: + // + return ellint_k_imp(k, pol, std::integral_constant()); +#if 0 + else + { + T lambda_prime = (1 - sqrt(k)) / (2 * (1 + sqrt(k))); + T k_prime = ellint_k(sqrt((1 - k) * (1 + k))); // K(m') + T lambda_prime_4th = boost::math::pow<4>(lambda_prime); + T q_prime = ((((((20910 * lambda_prime_4th) + 1707) * lambda_prime_4th + 150) * lambda_prime_4th + 15) * lambda_prime_4th + 2) * lambda_prime_4th + 1) * lambda_prime; + /*T q_prime_2 = lambda_prime + + 2 * boost::math::pow<5>(lambda_prime) + + 15 * boost::math::pow<9>(lambda_prime) + + 150 * boost::math::pow<13>(lambda_prime) + + 1707 * boost::math::pow<17>(lambda_prime) + + 20910 * boost::math::pow<21>(lambda_prime);*/ + return -log(q_prime) * k_prime / boost::math::constants::pi(); + } +#endif + } +} +template +BOOST_FORCEINLINE T ellint_k_imp(T k, const Policy& pol, std::integral_constant const&) +{ + using std::abs; + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(m * 20)) + { + case 0: + case 1: + { + constexpr T coef[] = + { + 1.5910034537907921801L, + 0.41600074399178691174L, + 0.24579151426410341536L, + 0.17948148291490616181L, + 0.14455605708755514976L, + 0.12320099331242771115L, + 0.10893881157429353105L, + 0.098853409871592910399L, + 0.091439629201749751268L, + 0.085842591595413899672L, + 0.081541118718303214749L, + 0.078199656811256481910L, + 0.075592617535422415648L, + 0.073562939365441925050L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05L); + } + case 2: + case 3: + { + constexpr T coef[] = + { + 1.6352567322645799924L, + 0.47119062614873229055L, + 0.30972841083149958708L, + 0.25220831177313569923L, + 0.22672562321968464974L, + 0.21577444672958597588L, + 0.21310877187734890963L, + 0.21602912460518828154L, + 0.22325583163305789567L, + 0.23418050129420992492L, + 0.24855768297226407136L, + 0.26636380989261752077L, + 0.28772845215611466775L, + 0.31290024539780334906L, + 0.34223105446381299902L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15L); + } + case 4: + case 5: + { + constexpr T coef[] = + { + 1.6857503548125960429L, + 0.54173184861328032882L, + 0.40152443839069025682L, + 0.36964247342088908995L, + 0.37606071535458364462L, + 0.40523588708512591863L, + 0.45329438175399907924L, + 0.52051894765118420473L, + 0.60942603920499505544L, + 0.72426352228290886975L, + 0.87101384770981235737L, + 1.0576528727535470365L, + 1.2945970872087764321L, + 1.5953368253888783747L, + 1.9772844873556364793L, + 2.4628890581910021287L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25L); + } + case 6: + case 7: + { + constexpr T coef[] = + { + 1.7443505972256132429L, + 0.63486427537193530383L, + 0.53984256416444553751L, + 0.57189270519378739093L, + 0.67029513626540610034L, + 0.83258659001097719939L, + 1.0738574482479332654L, + 1.4220914606754977514L, + 1.9203871834023048288L, + 2.6325525483316542006L, + 3.6521097473190391602L, + 5.1158671355588658061L, + 7.2240800073638774108L, + 10.270306349944787227L, + 14.685616935355757348L, + 21.104114212004582734L, + 30.460132808575799413L, + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35L); + } + case 8: + case 9: + { + constexpr T coef[] = + { + 1.8138839368169826437L, + 0.76316324570055724607L, + 0.76192860532159583095L, + 0.95107465366842792679L, + 1.3151806717031612153L, + 1.9285606934774109412L, + 2.9375093425313787550L, + 4.5948944054428780618L, + 7.3300712218817207718L, + 11.871512597425301798L, + 19.458513748229377383L, + 32.206386572464268628L, + 53.737491987005546559L, + 90.273886029409988491L, + 152.53312130253275268L, + 259.02388747148299086L, + 441.78537518096201946L, + 756.39903981567380952L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45L); + } + case 10: + case 11: + { + constexpr T coef[] = + { + 1.8989249102715535257L, + 0.95052179461824443490L, + 1.1510775899590158079L, + 1.7502391069863005399L, + 2.9526768126368751802L, + 5.2858003961214508892L, + 9.8324857166599797471L, + 18.787148683275595622L, + 36.614686152736981447L, + 72.452923951277718013L, + 145.10795773470691023L, + 293.47863963084970259L, + 598.38518150550101790L, + 1228.4200130758634505L, + 2536.5297553827644880L, + 5263.9832725075189576L, + 10972.138126273491753L, + 22958.388550988306870L, + 48203.103373625406989L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55L); + } + case 12: + case 13: + { + constexpr T coef[] = + { + 2.0075983984243763017L, + 1.2484572312123473371L, + 1.9262346570764797287L, + 3.7512896400875876798L, + 8.1199445549320458022L, + 18.665721308735553611L, + 44.603924842914370633L, + 109.50920543094983774L, + 274.27795482324134804L, + 697.55980086063261629L, + 1795.7160145002471293L, + 4668.3817167903899100L, + 12235.762468136643348L, + 32290.178097183208178L, + 85713.076081959646847L, + 228672.18904931170958L, + 612757.27119158527740L, + 1.6483233976504668314e6L, + 4.4492251046211960936e6L, + 1.2046317340783185238e7L, + 3.2705187507963254185e7L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65L); + } + case 14: + case 15: + { + constexpr T coef[] = + { + 2.1565156474996432354L, + 1.7918056418494632425L, + 3.8267512874657131470L, + 10.386724683637972080L, + 31.403314054680702901L, + 100.92370394986954165L, + 337.32682826322728966L, + 1158.7079305678279173L, + 4060.9907421936320917L, + 14454.001840343447947L, + 52076.661075994048028L, + 189493.65914621568866L, + 695184.57624138961450L, + 2.5679940482552846861e6L, + 9.5419219667483863221e6L, + 3.5634927442180761743e7L, + 1.3366929846120408712e8L, + 5.0335218668662845411e8L, + 1.9019757295386601192e9L, + 7.2089150153301037563e9L, + 2.7398741806339510931e10L, + 1.0439286724885300495e11L, + 3.9864875581513728207e11L, + 1.5254661585564745591e12L, + 5.8483259088850315936e12 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75L); + } + case 16: + { + constexpr T coef[] = + { + 2.3181226217125105894L, + 2.6169201502912328409L, + 7.8979350757313558232L, + 30.502397154466723270L, + 131.48693655235284561L, + 602.98476373564916170L, + 2877.0246178099726410L, + 14110.519919151803247L, + 70621.440881565402289L, + 358977.26658253099258L, + 1.8472382637239716844e6L, + 9.6005154160492141090e6L, + 5.0307677085023668786e7L, + 2.6544418865271279673e8L, + 1.4088623250287026866e9L, + 7.5156879353737746270e9L, + 4.0270783964955246149e10L, + 2.1662089325801126339e11L, + 1.1692489201929996116e12L, + 6.3306543358985679881e12 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825L); + } + case 17: + { + constexpr T coef[] = + { + 2.4735961737513439120L, + 3.7276242441180993105L, + 15.607393035549304964L, + 84.128508428058877470L, + 506.98181970406139349L, + 3252.2770581451236438L, + 21713.242419574342564L, + 149037.04518909327662L, + 1.0439993310899908390e6L, + 7.4279748170420389947e6L, + 5.3503839675586611510e7L, + 3.8924988699487084738e8L, + 2.8552883511008106195e9L, + 2.1090077038766840525e10L, + 1.5669983394779020136e11L, + 1.1702222424224398927e12L, + 8.7779483236689379709e12L, + 6.6101242752484950408e13L, + 4.9948805371338879891e14L, + 3.7859743397240299201e15L, + 2.8775996123036112296e16L, + 2.1926346839925760143e17L, + 1.6744985438468349361e18L, + 1.2814410112866546052e19L, + 9.8249807041031260167e19 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875L); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_k_imp(k, pol, std::integral_constant()); + } +} + +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_1(T k, const Policy& pol, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef std::integral_constant::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 +#endif + > precision_tag_type; + return policies::checked_narrowing_cast(detail::ellint_k_imp(static_cast(k), pol, precision_tag_type()), "boost::math::ellint_1<%1%>(%1%)"); +} + +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_1(T1 k, T2 phi, const std::false_type&) +{ + return boost::math::ellint_1(k, phi, policies::policy<>()); +} + +} + +// Complete elliptic integral (Legendre form) of the first kind +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_1(T k) +{ + return ellint_1(k, policies::policy<>()); +} + +// Elliptic integral (Legendre form) of the first kind +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_f_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_1<%1%>(%1%,%1%)"); +} + +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_1(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_1(k, phi, tag_type()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_1_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_2.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_2.hpp @@ -0,0 +1,751 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_2_HPP +#define BOOST_MATH_ELLINT_2_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the second kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +T ellint_e_imp(T k, const Policy& pol, const std::integral_constant&); +template +T ellint_e_imp(T k, const Policy& pol, const std::integral_constant&); +template +T ellint_e_imp(T k, const Policy& pol, const std::integral_constant&); + +// Elliptic integral (Legendre form) of the second kind +template +T ellint_e_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if (phi == 0) + return 0; + + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error("boost::math::ellint_e<%1%>(%1%,%1%)", nullptr, pol); + } + else if(phi > 1 / tools::epsilon()) + { + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + result = 2 * phi * ellint_e_imp(k, pol, precision_tag_type()) / constants::pi(); + } + else if(k == 0) + { + return invert ? T(-phi) : phi; + } + else if(fabs(k) == 1) + { + // + // For k = 1 ellipse actually turns to a line and every pi/2 in phi is exactly 1 in arc length + // Periodicity though is in pi, curve follows sin(pi) for 0 <= phi <= pi/2 and then + // 2 - sin(pi- phi) = 2 + sin(phi - pi) for pi/2 <= phi <= pi, so general form is: + // + // 2n + sin(phi - n * pi) ; |phi - n * pi| <= pi / 2 + // + T m = boost::math::round(phi / boost::math::constants::pi()); + T remains = phi - m * boost::math::constants::pi(); + T value = 2 * m + sin(remains); + + // negative arc length for negative phi + return invert ? -value : value; + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > 0.5) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + } + T k2 = k * k; + if(boost::math::pow<3>(rphi) * k2 / 6 < tools::epsilon() * fabs(rphi)) + { + // See http://functions.wolfram.com/EllipticIntegrals/EllipticE2/06/01/03/0001/ + result = s * rphi; + } + else + { + // http://dlmf.nist.gov/19.25#E10 + T sinp = sin(rphi); + if (k2 * sinp * sinp >= 1) + { + return policies::raise_domain_error("boost::math::ellint_2<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); + } + T cosp = cos(rphi); + T c = 1 / (sinp * sinp); + T cm1 = cosp * cosp / (sinp * sinp); // c - 1 + result = s * ((1 - k2) * ellint_rf_imp(cm1, T(c - k2), c, pol) + k2 * (1 - k2) * ellint_rd(cm1, c, T(c - k2), pol) / 3 + k2 * sqrt(cm1 / (c * (c - k2)))); + } + if (m != 0) + { + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + result += m * ellint_e_imp(k, pol, precision_tag_type()); + } + } + return invert ? T(-result) : result; +} + +// Complete elliptic integral (Legendre form) of the second kind +template +T ellint_e_imp(T k, const Policy& pol, std::integral_constant const&) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (abs(k) > 1) + { + return policies::raise_domain_error("boost::math::ellint_e<%1%>(%1%)", + "Got k = %1%, function requires |k| <= 1", k, pol); + } + if (abs(k) == 1) + { + return static_cast(1); + } + + T x = 0; + T t = k * k; + T y = 1 - t; + T z = 1; + T value = 2 * ellint_rg_imp(x, y, z, pol); + + return value; +} +// +// Special versions for double and 80-bit long double precision, +// double precision versions use the coefficients from: +// "Fast computation of complete elliptic integrals and Jacobian elliptic functions", +// Celestial Mechanics and Dynamical Astronomy, April 2012. +// +// Higher precision coefficients for 80-bit long doubles can be calculated +// using for example: +// Table[N[SeriesCoefficient[ EllipticE [ m ], { m, 875/1000, i} ], 20], {i, 0, 24}] +// and checking the value of the first neglected term with: +// N[SeriesCoefficient[ EllipticE [ m ], { m, 875/1000, 24} ], 20] * (2.5/100)^24 +// +// For m > 0.9 we don't use the method of the paper above, but simply call our +// existing routines. +// +template +BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant const&) +{ + using std::abs; + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(20 * m)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + 1.550973351780472328, + -0.400301020103198524, + -0.078498619442941939, + -0.034318853117591992, + -0.019718043317365499, + -0.013059507731993309, + -0.009442372874146547, + -0.007246728512402157, + -0.005807424012956090, + -0.004809187786009338, + -0.004086399233255150 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + 1.510121832092819728, + -0.417116333905867549, + -0.090123820404774569, + -0.043729944019084312, + -0.027965493064761785, + -0.020644781177568105, + -0.016650786739707238, + -0.014261960828842520, + -0.012759847429264803, + -0.011799303775587354, + -0.011197445703074968 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15); + } + case 4: + case 5: + //else if (m < 0.3) + { + constexpr T coef[] = + { + 1.467462209339427155, + -0.436576290946337775, + -0.105155557666942554, + -0.057371843593241730, + -0.041391627727340220, + -0.034527728505280841, + -0.031495443512532783, + -0.030527000890325277, + -0.030916984019238900, + -0.032371395314758122, + -0.034789960386404158 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25); + } + case 6: + case 7: + //else if (m < 0.4) + { + constexpr T coef[] = + { + 1.422691133490879171, + -0.459513519621048674, + -0.125250539822061878, + -0.078138545094409477, + -0.064714278472050002, + -0.062084339131730311, + -0.065197032815572477, + -0.072793895362578779, + -0.084959075171781003, + -0.102539850131045997, + -0.127053585157696036, + -0.160791120691274606 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35); + } + case 8: + case 9: + //else if (m < 0.5) + { + constexpr T coef[] = + { + 1.375401971871116291, + -0.487202183273184837, + -0.153311701348540228, + -0.111849444917027833, + -0.108840952523135768, + -0.122954223120269076, + -0.152217163962035047, + -0.200495323642697339, + -0.276174333067751758, + -0.393513114304375851, + -0.575754406027879147, + -0.860523235727239756, + -1.308833205758540162 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45); + } + case 10: + case 11: + //else if (m < 0.6) + { + constexpr T coef[] = + { + 1.325024497958230082, + -0.521727647557566767, + -0.194906430482126213, + -0.171623726822011264, + -0.202754652926419141, + -0.278798953118534762, + -0.420698457281005762, + -0.675948400853106021, + -1.136343121839229244, + -1.976721143954398261, + -3.531696773095722506, + -6.446753640156048150, + -11.97703130208884026 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55); + } + case 12: + case 13: + //else if (m < 0.7) + { + constexpr T coef[] = + { + 1.270707479650149744, + -0.566839168287866583, + -0.262160793432492598, + -0.292244173533077419, + -0.440397840850423189, + -0.774947641381397458, + -1.498870837987561088, + -3.089708310445186667, + -6.667595903381001064, + -14.89436036517319078, + -34.18120574251449024, + -80.15895841905397306, + -191.3489480762984920, + -463.5938853480342030, + -1137.380822169360061 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65); + } + case 14: + case 15: + //else if (m < 0.8) + { + constexpr T coef[] = + { + 1.211056027568459525, + -0.630306413287455807, + -0.387166409520669145, + -0.592278235311934603, + -1.237555584513049844, + -3.032056661745247199, + -8.181688221573590762, + -23.55507217389693250, + -71.04099935893064956, + -221.8796853192349888, + -712.1364793277635425, + -2336.125331440396407, + -7801.945954775964673, + -26448.19586059191933, + -90799.48341621365251, + -315126.0406449163424, + -1104011.344311591159 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75); + } + case 16: + //else if (m < 0.85) + { + constexpr T coef[] = + { + 1.161307152196282836, + -0.701100284555289548, + -0.580551474465437362, + -1.243693061077786614, + -3.679383613496634879, + -12.81590924337895775, + -49.25672530759985272, + -202.1818735434090269, + -869.8602699308701437, + -3877.005847313289571, + -17761.70710170939814, + -83182.69029154232061, + -396650.4505013548170, + -1920033.413682634405 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825); + } + case 17: + //else if (m < 0.90) + { + constexpr T coef[] = + { + 1.124617325119752213, + -0.770845056360909542, + -0.844794053644911362, + -2.490097309450394453, + -10.23971741154384360, + -49.74900546551479866, + -267.0986675195705196, + -1532.665883825229947, + -9222.313478526091951, + -57502.51612140314030, + -368596.1167416106063, + -2415611.088701091428, + -16120097.81581656797, + -109209938.5203089915, + -749380758.1942496220, + -5198725846.725541393, + -36409256888.12139973 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_e_imp(k, pol, std::integral_constant()); + } +} +template +BOOST_FORCEINLINE T ellint_e_imp(T k, const Policy& pol, std::integral_constant const&) +{ + using std::abs; + using namespace boost::math::tools; + + T m = k * k; + switch (static_cast(20 * m)) + { + case 0: + case 1: + //if (m < 0.1) + { + constexpr T coef[] = + { + 1.5509733517804723277L, + -0.40030102010319852390L, + -0.078498619442941939212L, + -0.034318853117591992417L, + -0.019718043317365499309L, + -0.013059507731993309191L, + -0.0094423728741465473894L, + -0.0072467285124021568126L, + -0.0058074240129560897940L, + -0.0048091877860093381762L, + -0.0040863992332551506768L, + -0.0035450302604139562644L, + -0.0031283511188028336315L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.05L); + } + case 2: + case 3: + //else if (m < 0.2) + { + constexpr T coef[] = + { + 1.5101218320928197276L, + -0.41711633390586754922L, + -0.090123820404774568894L, + -0.043729944019084311555L, + -0.027965493064761784548L, + -0.020644781177568105268L, + -0.016650786739707238037L, + -0.014261960828842519634L, + -0.012759847429264802627L, + -0.011799303775587354169L, + -0.011197445703074968018L, + -0.010850368064799902735L, + -0.010696133481060989818L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.15L); + } + case 4: + case 5: + //else if (m < 0.3L) + { + constexpr T coef[] = + { + 1.4674622093394271555L, + -0.43657629094633777482L, + -0.10515555766694255399L, + -0.057371843593241729895L, + -0.041391627727340220236L, + -0.034527728505280841188L, + -0.031495443512532782647L, + -0.030527000890325277179L, + -0.030916984019238900349L, + -0.032371395314758122268L, + -0.034789960386404158240L, + -0.038182654612387881967L, + -0.042636187648900252525L, + -0.048302272505241634467 + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.25L); + } + case 6: + case 7: + //else if (m < 0.4L) + { + constexpr T coef[] = + { + 1.4226911334908791711L, + -0.45951351962104867394L, + -0.12525053982206187849L, + -0.078138545094409477156L, + -0.064714278472050001838L, + -0.062084339131730310707L, + -0.065197032815572476910L, + -0.072793895362578779473L, + -0.084959075171781003264L, + -0.10253985013104599679L, + -0.12705358515769603644L, + -0.16079112069127460621L, + -0.20705400012405941376L, + -0.27053164884730888948L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.35L); + } + case 8: + case 9: + //else if (m < 0.5L) + { + constexpr T coef[] = + { + 1.3754019718711162908L, + -0.48720218327318483652L, + -0.15331170134854022753L, + -0.11184944491702783273L, + -0.10884095252313576755L, + -0.12295422312026907610L, + -0.15221716396203504746L, + -0.20049532364269733857L, + -0.27617433306775175837L, + -0.39351311430437585139L, + -0.57575440602787914711L, + -0.86052323572723975634L, + -1.3088332057585401616L, + -2.0200280559452241745L, + -3.1566019548237606451L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.45L); + } + case 10: + case 11: + //else if (m < 0.6L) + { + constexpr T coef[] = + { + 1.3250244979582300818L, + -0.52172764755756676713L, + -0.19490643048212621262L, + -0.17162372682201126365L, + -0.20275465292641914128L, + -0.27879895311853476205L, + -0.42069845728100576224L, + -0.67594840085310602110L, + -1.1363431218392292440L, + -1.9767211439543982613L, + -3.5316967730957225064L, + -6.4467536401560481499L, + -11.977031302088840261L, + -22.581360948073964469L, + -43.109479829481450573L, + -83.186290908288807424L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.55L); + } + case 12: + case 13: + //else if (m < 0.7L) + { + constexpr T coef[] = + { + 1.2707074796501497440L, + -0.56683916828786658286L, + -0.26216079343249259779L, + -0.29224417353307741931L, + -0.44039784085042318909L, + -0.77494764138139745824L, + -1.4988708379875610880L, + -3.0897083104451866665L, + -6.6675959033810010645L, + -14.894360365173190775L, + -34.181205742514490240L, + -80.158958419053973056L, + -191.34894807629849204L, + -463.59388534803420301L, + -1137.3808221693600606L, + -2820.7073786352269339L, + -7061.1382244658715621L, + -17821.809331816437058L, + -45307.849987201897801L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.65L); + } + case 14: + case 15: + //else if (m < 0.8L) + { + constexpr T coef[] = + { + 1.2110560275684595248L, + -0.63030641328745580709L, + -0.38716640952066914514L, + -0.59227823531193460257L, + -1.2375555845130498445L, + -3.0320566617452471986L, + -8.1816882215735907624L, + -23.555072173896932503L, + -71.040999358930649565L, + -221.87968531923498875L, + -712.13647932776354253L, + -2336.1253314403964072L, + -7801.9459547759646726L, + -26448.195860591919335L, + -90799.483416213652512L, + -315126.04064491634241L, + -1.1040113443115911589e6L, + -3.8998018348056769095e6L, + -1.3876249116223745041e7L, + -4.9694982823537861149e7L, + -1.7900668836197342979e8L, + -6.4817399873722371964e8L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.75L); + } + case 16: + //else if (m < 0.85L) + { + constexpr T coef[] = + { + 1.1613071521962828360L, + -0.70110028455528954752L, + -0.58055147446543736163L, + -1.2436930610777866138L, + -3.6793836134966348789L, + -12.815909243378957753L, + -49.256725307599852720L, + -202.18187354340902693L, + -869.86026993087014372L, + -3877.0058473132895713L, + -17761.707101709398174L, + -83182.690291542320614L, + -396650.45050135481698L, + -1.9200334136826344054e6L, + -9.4131321779500838352e6L, + -4.6654858837335370627e7L, + -2.3343549352617609390e8L, + -1.1776928223045913454e9L, + -5.9850851892915740401e9L, + -3.0614702984618644983e10L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.825L); + } + case 17: + //else if (m < 0.90L) + { + constexpr T coef[] = + { + 1.1246173251197522132L, + -0.77084505636090954218L, + -0.84479405364491136236L, + -2.4900973094503944527L, + -10.239717411543843601L, + -49.749005465514798660L, + -267.09866751957051961L, + -1532.6658838252299468L, + -9222.3134785260919507L, + -57502.516121403140303L, + -368596.11674161060626L, + -2.4156110887010914281e6L, + -1.6120097815816567971e7L, + -1.0920993852030899148e8L, + -7.4938075819424962198e8L, + -5.1987258467255413931e9L, + -3.6409256888121399726e10L, + -2.5711802891217393544e11L, + -1.8290904062978796996e12L, + -1.3096838781743248404e13L, + -9.4325465851415135118e13L, + -6.8291980829471896669e14L + }; + return boost::math::tools::evaluate_polynomial(coef, m - 0.875L); + } + default: + // + // All cases where m > 0.9 + // including all error handling: + // + return ellint_e_imp(k, pol, std::integral_constant()); + } +} + +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_2(T k, const Policy& pol, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + return policies::checked_narrowing_cast(detail::ellint_e_imp(static_cast(k), pol, precision_tag_type()), "boost::math::ellint_2<%1%>(%1%)"); +} + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_2(T1 k, T2 phi, const std::false_type&) +{ + return boost::math::ellint_2(k, phi, policies::policy<>()); +} + +} // detail + +// Complete elliptic integral (Legendre form) of the second kind +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_2(T k) +{ + return ellint_2(k, policies::policy<>()); +} + +// Elliptic integral (Legendre form) of the second kind +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_2(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_2(k, phi, tag_type()); +} + +template +BOOST_FORCEINLINE typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_e_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_2<%1%>(%1%,%1%)"); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_2_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_3.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_3.hpp @@ -0,0 +1,376 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the various corner cases. +// + +#ifndef BOOST_MATH_ELLINT_3_HPP +#define BOOST_MATH_ELLINT_3_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the third kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +namespace detail{ + +template +T ellint_pi_imp(T v, T k, T vc, const Policy& pol); + +// Elliptic integral (Legendre form) of the third kind +template +T ellint_pi_imp(T v, T phi, T k, T vc, const Policy& pol) +{ + // Note vc = 1-v presumably without cancellation error. + BOOST_MATH_STD_USING + + static const char* function = "boost::math::ellint_3<%1%>(%1%,%1%,%1%)"; + + + T sphi = sin(fabs(phi)); + T result = 0; + + if (k * k * sphi * sphi > 1) + { + return policies::raise_domain_error(function, + "Got k = %1%, function requires |k| <= 1", k, pol); + } + // Special cases first: + if(v == 0) + { + // A&S 17.7.18 & 19 + return (k == 0) ? phi : ellint_f_imp(phi, k, pol); + } + if((v > 0) && (1 / v < (sphi * sphi))) + { + // Complex result is a domain error: + return policies::raise_domain_error(function, + "Got v = %1%, but result is complex for v > 1 / sin^2(phi)", v, pol); + } + + if(v == 1) + { + if (k == 0) + return tan(phi); + + // http://functions.wolfram.com/08.06.03.0008.01 + T m = k * k; + result = sqrt(1 - m * sphi * sphi) * tan(phi) - ellint_e_imp(phi, k, pol); + result /= 1 - m; + result += ellint_f_imp(phi, k, pol); + return result; + } + if(phi == constants::half_pi()) + { + // Have to filter this case out before the next + // special case, otherwise we might get an infinity from + // tan(phi). + // Also note that since we can't represent PI/2 exactly + // in a T, this is a bit of a guess as to the users true + // intent... + // + return ellint_pi_imp(v, k, vc, pol); + } + if((phi > constants::half_pi()) || (phi < 0)) + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + // Xiaogang's original code used a cast to long long here + // but that fails if T has more digits than a long long, + // so rewritten to use fmod instead: + // + // See http://functions.wolfram.com/08.06.16.0002.01 + // + if(fabs(phi) > 1 / tools::epsilon()) + { + if(v > 1) + return policies::raise_domain_error( + function, + "Got v = %1%, but this is only supported for 0 <= phi <= pi/2", v, pol); + // + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + // + result = 2 * fabs(phi) * ellint_pi_imp(v, k, vc, pol) / constants::pi(); + } + else + { + T rphi = boost::math::tools::fmod_workaround(T(fabs(phi)), T(constants::half_pi())); + T m = boost::math::round((fabs(phi) - rphi) / constants::half_pi()); + int sign = 1; + if((m != 0) && (k >= 1)) + { + return policies::raise_domain_error(function, "Got k=1 and phi=%1% but the result is complex in that domain", phi, pol); + } + if(boost::math::tools::fmod_workaround(m, T(2)) > 0.5) + { + m += 1; + sign = -1; + rphi = constants::half_pi() - rphi; + } + result = sign * ellint_pi_imp(v, rphi, k, vc, pol); + if((m > 0) && (vc > 0)) + result += m * ellint_pi_imp(v, k, vc, pol); + } + return phi < 0 ? T(-result) : result; + } + if(k == 0) + { + // A&S 17.7.20: + if(v < 1) + { + T vcr = sqrt(vc); + return atan(vcr * tan(phi)) / vcr; + } + else + { + // v > 1: + T vcr = sqrt(-vc); + T arg = vcr * tan(phi); + return (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * vcr); + } + } + if((v < 0) && fabs(k) <= 1) + { + // + // If we don't shift to 0 <= v <= 1 we get + // cancellation errors later on. Use + // A&S 17.7.15/16 to shift to v > 0. + // + // Mathematica simplifies the expressions + // given in A&S as follows (with thanks to + // Rocco Romeo for figuring these out!): + // + // V = (k2 - n)/(1 - n) + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[Sqrt[(1 - V)*(1 - k2 / V)] / Sqrt[((1 - n)*(1 - k2 / n))]]] + // Result: ((-1 + k2) n) / ((-1 + n) (-k2 + n)) + // + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[k2 / (Sqrt[-n*(k2 - n) / (1 - n)] * Sqrt[(1 - n)*(1 - k2 / n)])]] + // Result : k2 / (k2 - n) + // + // Assuming[(k2 >= 0 && k2 <= 1) && n < 0, FullSimplify[Sqrt[1 / ((1 - n)*(1 - k2 / n))]]] + // Result : Sqrt[n / ((k2 - n) (-1 + n))] + // + T k2 = k * k; + T N = (k2 - v) / (1 - v); + T Nm1 = (1 - k2) / (1 - v); + T p2 = -v * N; + T t; + if(p2 <= tools::min_value()) + p2 = sqrt(-v) * sqrt(N); + else + p2 = sqrt(p2); + T delta = sqrt(1 - k2 * sphi * sphi); + if(N > k2) + { + result = ellint_pi_imp(N, phi, k, Nm1, pol); + result *= v / (v - 1); + result *= (k2 - 1) / (v - k2); + } + + if(k != 0) + { + t = ellint_f_imp(phi, k, pol); + t *= k2 / (k2 - v); + result += t; + } + t = v / ((k2 - v) * (v - 1)); + if(t > tools::min_value()) + { + result += atan((p2 / 2) * sin(2 * phi) / delta) * sqrt(t); + } + else + { + result += atan((p2 / 2) * sin(2 * phi) / delta) * sqrt(fabs(1 / (k2 - v))) * sqrt(fabs(v / (v - 1))); + } + return result; + } + if(k == 1) + { + // See http://functions.wolfram.com/08.06.03.0013.01 + result = sqrt(v) * atanh(sqrt(v) * sin(phi), pol) - log(1 / cos(phi) + tan(phi)); + result /= v - 1; + return result; + } +#if 0 // disabled but retained for future reference: see below. + if(v > 1) + { + // + // If v > 1 we can use the identity in A&S 17.7.7/8 + // to shift to 0 <= v <= 1. In contrast to previous + // revisions of this header, this identity does now work + // but appears not to produce better error rates in + // practice. Archived here for future reference... + // + T k2 = k * k; + T N = k2 / v; + T Nm1 = (v - k2) / v; + T p1 = sqrt((-vc) * (1 - k2 / v)); + T delta = sqrt(1 - k2 * sphi * sphi); + // + // These next two terms have a large amount of cancellation + // so it's not clear if this relation is useable even if + // the issues with phi > pi/2 can be fixed: + // + result = -ellint_pi_imp(N, phi, k, Nm1, pol); + result += ellint_f_imp(phi, k, pol); + // + // This log term gives the complex result when + // n > 1/sin^2(phi) + // However that case is dealt with as an error above, + // so we should always get a real result here: + // + result += log((delta + p1 * tan(phi)) / (delta - p1 * tan(phi))) / (2 * p1); + return result; + } +#endif + // + // Carlson's algorithm works only for |phi| <= pi/2, + // by the time we get here phi should already have been + // normalised above. + // + BOOST_MATH_ASSERT(fabs(phi) < constants::half_pi()); + BOOST_MATH_ASSERT(phi >= 0); + T x, y, z, p, t; + T cosp = cos(phi); + x = cosp * cosp; + t = sphi * sphi; + y = 1 - k * k * t; + z = 1; + if(v * t < 0.5) + p = 1 - v * t; + else + p = x + vc * t; + result = sphi * (ellint_rf_imp(x, y, z, pol) + v * t * ellint_rj_imp(x, y, z, p, pol) / 3); + + return result; +} + +// Complete elliptic integral (Legendre form) of the third kind +template +T ellint_pi_imp(T v, T k, T vc, const Policy& pol) +{ + // Note arg vc = 1-v, possibly without cancellation errors + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + static const char* function = "boost::math::ellint_pi<%1%>(%1%,%1%)"; + + if (abs(k) >= 1) + { + return policies::raise_domain_error(function, + "Got k = %1%, function requires |k| <= 1", k, pol); + } + if(vc <= 0) + { + // Result is complex: + return policies::raise_domain_error(function, + "Got v = %1%, function requires v < 1", v, pol); + } + + if(v == 0) + { + return (k == 0) ? boost::math::constants::pi() / 2 : boost::math::ellint_1(k, pol); + } + + if(v < 0) + { + // Apply A&S 17.7.17: + T k2 = k * k; + T N = (k2 - v) / (1 - v); + T Nm1 = (1 - k2) / (1 - v); + T result = 0; + result = boost::math::detail::ellint_pi_imp(N, k, Nm1, pol); + // This next part is split in two to avoid spurious over/underflow: + result *= -v / (1 - v); + result *= (1 - k2) / (k2 - v); + result += boost::math::ellint_1(k, pol) * k2 / (k2 - v); + return result; + } + + T x = 0; + T y = 1 - k * k; + T z = 1; + T p = vc; + T value = ellint_rf_imp(x, y, z, pol) + v * ellint_rj_imp(x, y, z, p, pol) / 3; + + return value; +} + +template +inline typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const std::false_type&) +{ + return boost::math::ellint_3(k, v, phi, policies::policy<>()); +} + +template +inline typename tools::promote_args::type ellint_3(T1 k, T2 v, const Policy& pol, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_pi_imp( + static_cast(v), + static_cast(k), + static_cast(1-v), + pol), "boost::math::ellint_3<%1%>(%1%,%1%)"); +} + +} // namespace detail + +template +inline typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise, policies::promote_double >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::ellint_pi_imp( + static_cast(v), + static_cast(phi), + static_cast(k), + static_cast(1-v), + forwarding_policy()), "boost::math::ellint_3<%1%>(%1%,%1%,%1%)"); +} + +template +typename detail::ellint_3_result::type ellint_3(T1 k, T2 v, T3 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_3(k, v, phi, tag_type()); +} + +template +inline typename tools::promote_args::type ellint_3(T1 k, T2 v) +{ + return ellint_3(k, v, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_3_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_d.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_d.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_d.hpp @@ -0,0 +1,181 @@ +// Copyright (c) 2006 Xiaogang Zhang +// Copyright (c) 2006 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to ensure +// that the code continues to work no matter how many digits +// type T has. + +#ifndef BOOST_MATH_ELLINT_D_HPP +#define BOOST_MATH_ELLINT_D_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integrals (complete and incomplete) of the second kind +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { + +template +typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol); + +namespace detail{ + +template +T ellint_d_imp(T k, const Policy& pol); + +// Elliptic integral (Legendre form) of the second kind +template +T ellint_d_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + + if(phi >= tools::max_value()) + { + // Need to handle infinity as a special case: + result = policies::raise_overflow_error("boost::math::ellint_d<%1%>(%1%,%1%)", nullptr, pol); + } + else if(phi > 1 / tools::epsilon()) + { + // Phi is so large that phi%pi is necessarily zero (or garbage), + // just return the second part of the duplication formula: + result = 2 * phi * ellint_d_imp(k, pol) / constants::pi(); + } + else + { + // Carlson's algorithm works only for |phi| <= pi/2, + // use the integrand's periodicity to normalize phi + // + T rphi = boost::math::tools::fmod_workaround(phi, T(constants::half_pi())); + T m = boost::math::round((phi - rphi) / constants::half_pi()); + int s = 1; + if(boost::math::tools::fmod_workaround(m, T(2)) > 0.5) + { + m += 1; + s = -1; + rphi = constants::half_pi() - rphi; + } + BOOST_MATH_INSTRUMENT_VARIABLE(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(m); + T sinp = sin(rphi); + T cosp = cos(rphi); + BOOST_MATH_INSTRUMENT_VARIABLE(sinp); + BOOST_MATH_INSTRUMENT_VARIABLE(cosp); + T c = 1 / (sinp * sinp); + T cm1 = cosp * cosp / (sinp * sinp); // c - 1 + T k2 = k * k; + if(k2 * sinp * sinp > 1) + { + return policies::raise_domain_error("boost::math::ellint_d<%1%>(%1%, %1%)", "The parameter k is out of range, got k = %1%", k, pol); + } + else if(rphi == 0) + { + result = 0; + } + else + { + // http://dlmf.nist.gov/19.25#E10 + result = s * ellint_rd_imp(cm1, T(c - k2), c, pol) / 3; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + if(m != 0) + result += m * ellint_d_imp(k, pol); + } + return invert ? T(-result) : result; +} + +// Complete elliptic integral (Legendre form) of the second kind +template +T ellint_d_imp(T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + + if (abs(k) >= 1) + { + return policies::raise_domain_error("boost::math::ellint_d<%1%>(%1%)", + "Got k = %1%, function requires |k| <= 1", k, pol); + } + if(fabs(k) <= tools::root_epsilon()) + return constants::pi() / 4; + + T x = 0; + T t = k * k; + T y = 1 - t; + T z = 1; + T value = ellint_rd_imp(x, y, z, pol) / 3; + + return value; +} + +template +inline typename tools::promote_args::type ellint_d(T k, const Policy& pol, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_d_imp(static_cast(k), pol), "boost::math::ellint_d<%1%>(%1%)"); +} + +// Elliptic integral (Legendre form) of the second kind +template +inline typename tools::promote_args::type ellint_d(T1 k, T2 phi, const std::false_type&) +{ + return boost::math::ellint_d(k, phi, policies::policy<>()); +} + +} // detail + +// Complete elliptic integral (Legendre form) of the second kind +template +inline typename tools::promote_args::type ellint_d(T k) +{ + return ellint_d(k, policies::policy<>()); +} + +// Elliptic integral (Legendre form) of the second kind +template +inline typename tools::promote_args::type ellint_d(T1 k, T2 phi) +{ + typedef typename policies::is_policy::type tag_type; + return detail::ellint_d(k, phi, tag_type()); +} + +template +inline typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::ellint_d_imp(static_cast(phi), static_cast(k), pol), "boost::math::ellint_2<%1%>(%1%,%1%)"); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_rc.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_rc.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_rc.hpp @@ -0,0 +1,114 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the y < 0 case. +// Updated 2015 to use Carlson's latest methods. +// + +#ifndef BOOST_MATH_ELLINT_RC_HPP +#define BOOST_MATH_ELLINT_RC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// Carlson's degenerate elliptic integral +// R_C(x, y) = R_F(x, y, y) = 0.5 * \int_{0}^{\infty} (t+x)^{-1/2} (t+y)^{-1} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +T ellint_rc_imp(T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + static const char* function = "boost::math::ellint_rc<%1%>(%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, + "Argument x must be non-negative but got %1%", x, pol); + } + if(y == 0) + { + return policies::raise_domain_error(function, + "Argument y must not be zero but got %1%", y, pol); + } + + // for y < 0, the integral is singular, return Cauchy principal value + T prefix, result; + if(y < 0) + { + prefix = sqrt(x / (x - y)); + x = x - y; + y = -y; + } + else + prefix = 1; + + if(x == 0) + { + result = constants::half_pi() / sqrt(y); + } + else if(x == y) + { + result = 1 / sqrt(x); + } + else if(y > x) + { + result = atan(sqrt((y - x) / x)) / sqrt(y - x); + } + else + { + if(y / x > 0.5) + { + T arg = sqrt((x - y) / x); + result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(x - y)); + } + else + { + result = log((sqrt(x) + sqrt(x - y)) / sqrt(y)) / sqrt(x - y); + } + } + return prefix * result; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + ellint_rc(T1 x, T2 y, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rc_imp( + static_cast(x), + static_cast(y), pol), "boost::math::ellint_rc<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + ellint_rc(T1 x, T2 y) +{ + return ellint_rc(x, y, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RC_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_rd.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_rd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_rd.hpp @@ -0,0 +1,206 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock. +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it slightly to fit into the +// Boost.Math conceptual framework better. +// Updated 2015 to use Carlson's latest methods. + +#ifndef BOOST_MATH_ELLINT_RD_HPP +#define BOOST_MATH_ELLINT_RD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the second kind +// R_D(x, y, z) = R_J(x, y, z, z) = 1.5 * \int_{0}^{\infty} [(t+x)(t+y)]^{-1/2} (t+z)^{-3/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +T ellint_rd_imp(T x, T y, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + using std::swap; + + static const char* function = "boost::math::ellint_rd<%1%>(%1%,%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, + "Argument x must be >= 0, but got %1%", x, pol); + } + if(y < 0) + { + return policies::raise_domain_error(function, + "Argument y must be >= 0, but got %1%", y, pol); + } + if(z <= 0) + { + return policies::raise_domain_error(function, + "Argument z must be > 0, but got %1%", z, pol); + } + if(x + y == 0) + { + return policies::raise_domain_error(function, + "At most one argument can be zero, but got, x + y = %1%", x + y, pol); + } + // + // Special cases from http://dlmf.nist.gov/19.20#iv + // + using std::swap; + if(x == z) + swap(x, y); + if(y == z) + { + if(x == y) + { + return 1 / (x * sqrt(x)); + } + else if(x == 0) + { + return 3 * constants::pi() / (4 * y * sqrt(y)); + } + else + { + if((std::min)(x, y) / (std::max)(x, y) > 1.3) + return 3 * (ellint_rc_imp(x, y, pol) - sqrt(x) / y) / (2 * (y - x)); + // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) + } + } + if(x == y) + { + if((std::min)(x, z) / (std::max)(x, z) > 1.3) + return 3 * (ellint_rc_imp(z, x, pol) - 1 / sqrt(z)) / (z - x); + // Otherwise fall through to avoid cancellation in the above (RC(x,y) -> 1/x^0.5 as x -> y) + } + if(y == 0) + swap(x, y); + if(x == 0) + { + // + // Special handling for common case, from + // Numerical Computation of Real or Complex Elliptic Integrals, eq.47 + // + T xn = sqrt(y); + T yn = sqrt(z); + T x0 = xn; + T y0 = yn; + T sum = 0; + T sum_pow = 0.25f; + + while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + sum_pow *= 2; + sum += sum_pow * boost::math::pow<2>(xn - yn); + } + T RF = constants::pi() / (xn + yn); + // + // This following calculation suffers from serious cancellation when y ~ z + // unless we combine terms. We have: + // + // ( ((x0 + y0)/2)^2 - z ) / (z(y-z)) + // + // Substituting y = x0^2 and z = y0^2 and simplifying we get the following: + // + T pt = (x0 + 3 * y0) / (4 * z * (x0 + y0)); + // + // Since we've moved the denominator from eq.47 inside the expression, we + // need to also scale "sum" by the same value: + // + pt -= sum / (z * (y - z)); + return pt * RF * 3; + } + + T xn = x; + T yn = y; + T zn = z; + T An = (x + y + 3 * z) / 5; + T A0 = An; + // This has an extra 1.2 fudge factor which is really only needed when x, y and z are close in magnitude: + T Q = pow(tools::epsilon() / 4, -T(1) / 8) * (std::max)((std::max)(An - x, An - y), An - z) * 1.2f; + BOOST_MATH_INSTRUMENT_VARIABLE(Q); + T lambda, rx, ry, rz; + unsigned k = 0; + T fn = 1; + T RD_sum = 0; + + for(; k < policies::get_max_series_iterations(); ++k) + { + rx = sqrt(xn); + ry = sqrt(yn); + rz = sqrt(zn); + lambda = rx * ry + rx * rz + ry * rz; + RD_sum += fn / (rz * (zn + lambda)); + An = (An + lambda) / 4; + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + fn /= 4; + Q /= 4; + BOOST_MATH_INSTRUMENT_VARIABLE(k); + BOOST_MATH_INSTRUMENT_VARIABLE(RD_sum); + BOOST_MATH_INSTRUMENT_VARIABLE(Q); + if(Q < An) + break; + } + + policies::check_series_iterations(function, k, pol); + + T X = fn * (A0 - x) / An; + T Y = fn * (A0 - y) / An; + T Z = -(X + Y) / 3; + T E2 = X * Y - 6 * Z * Z; + T E3 = (3 * X * Y - 8 * Z * Z) * Z; + T E4 = 3 * (X * Y - Z * Z) * Z * Z; + T E5 = X * Y * Z * Z * Z; + + T result = fn * pow(An, T(-3) / 2) * + (1 - 3 * E2 / 14 + E3 / 6 + 9 * E2 * E2 / 88 - 3 * E4 / 22 - 9 * E2 * E3 / 52 + 3 * E5 / 26 - E2 * E2 * E2 / 16 + + 3 * E3 * E3 / 40 + 3 * E2 * E4 / 20 + 45 * E2 * E2 * E3 / 272 - 9 * (E3 * E4 + E2 * E5) / 68); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result += 3 * RD_sum; + + return result; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rd_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rd<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z) +{ + return ellint_rd(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RD_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_rf.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_rf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_rf.hpp @@ -0,0 +1,174 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to handle +// types longer than 80-bit reals. +// Updated 2015 to use Carlson's latest methods. +// +#ifndef BOOST_MATH_ELLINT_RF_HPP +#define BOOST_MATH_ELLINT_RF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the first kind +// R_F(x, y, z) = 0.5 * \int_{0}^{\infty} [(t+x)(t+y)(t+z)]^{-1/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + + template + T ellint_rf_imp(T x, T y, T z, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math; + using std::swap; + + static const char* function = "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"; + + if(x < 0 || y < 0 || z < 0) + { + return policies::raise_domain_error(function, + "domain error, all arguments must be non-negative, " + "only sensible result is %1%.", + std::numeric_limits::quiet_NaN(), pol); + } + if(x + y == 0 || y + z == 0 || z + x == 0) + { + return policies::raise_domain_error(function, + "domain error, at most one argument can be zero, " + "only sensible result is %1%.", + std::numeric_limits::quiet_NaN(), pol); + } + // + // Special cases from http://dlmf.nist.gov/19.20#i + // + if(x == y) + { + if(x == z) + { + // x, y, z equal: + return 1 / sqrt(x); + } + else + { + // 2 equal, x and y: + if(z == 0) + return constants::pi() / (2 * sqrt(x)); + else + return ellint_rc_imp(z, x, pol); + } + } + if(x == z) + { + if(y == 0) + return constants::pi() / (2 * sqrt(x)); + else + return ellint_rc_imp(y, x, pol); + } + if(y == z) + { + if(x == 0) + return constants::pi() / (2 * sqrt(y)); + else + return ellint_rc_imp(x, y, pol); + } + if(x == 0) + swap(x, z); + else if(y == 0) + swap(y, z); + if(z == 0) + { + // + // Special case for one value zero: + // + T xn = sqrt(x); + T yn = sqrt(y); + + while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + } + return constants::pi() / (xn + yn); + } + + T xn = x; + T yn = y; + T zn = z; + T An = (x + y + z) / 3; + T A0 = An; + T Q = pow(3 * boost::math::tools::epsilon(), T(-1) / 8) * (std::max)((std::max)(fabs(An - xn), fabs(An - yn)), fabs(An - zn)); + T fn = 1; + + + // duplication + unsigned k = 1; + for(; k < boost::math::policies::get_max_series_iterations(); ++k) + { + T root_x = sqrt(xn); + T root_y = sqrt(yn); + T root_z = sqrt(zn); + T lambda = root_x * root_y + root_x * root_z + root_y * root_z; + An = (An + lambda) / 4; + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + Q /= 4; + fn *= 4; + if(Q < fabs(An)) + break; + } + // Check to see if we gave up too soon: + policies::check_series_iterations(function, k, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(k); + + T X = (A0 - x) / (An * fn); + T Y = (A0 - y) / (An * fn); + T Z = -X - Y; + + // Taylor series expansion to the 7th order + T E2 = X * Y - Z * Z; + T E3 = X * Y * Z; + return (1 + E3 * (T(1) / 14 + 3 * E3 / 104) + E2 * (T(-1) / 10 + E2 / 24 - (3 * E3) / 44 - 5 * E2 * E2 / 208 + E2 * E3 / 16)) / sqrt(An); + } + +} // namespace detail + +template +inline typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rf_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z) +{ + return ellint_rf(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RF_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_rg.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_rg.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_rg.hpp @@ -0,0 +1,136 @@ +// Copyright (c) 2015 John Maddock +// 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_ELLINT_RG_HPP +#define BOOST_MATH_ELLINT_RG_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail{ + + template + T ellint_rg_imp(T x, T y, T z, const Policy& pol) + { + BOOST_MATH_STD_USING + static const char* function = "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"; + + if(x < 0 || y < 0 || z < 0) + { + return policies::raise_domain_error(function, + "domain error, all arguments must be non-negative, " + "only sensible result is %1%.", + std::numeric_limits::quiet_NaN(), pol); + } + // + // Function is symmetric in x, y and z, but we require + // (x - z)(y - z) >= 0 to avoid cancellation error in the result + // which implies (for example) x >= z >= y + // + using std::swap; + if(x < y) + swap(x, y); + if(x < z) + swap(x, z); + if(y > z) + swap(y, z); + + BOOST_MATH_ASSERT(x >= z); + BOOST_MATH_ASSERT(z >= y); + // + // Special cases from http://dlmf.nist.gov/19.20#ii + // + if(x == z) + { + if(y == z) + { + // x = y = z + // This also works for x = y = z = 0 presumably. + return sqrt(x); + } + else if(y == 0) + { + // x = y, z = 0 + return constants::pi() * sqrt(x) / 4; + } + else + { + // x = z, y != 0 + swap(x, y); + return (x == 0) ? T(sqrt(z) / 2) : T((z * ellint_rc_imp(x, z, pol) + sqrt(x)) / 2); + } + } + else if(y == z) + { + if(x == 0) + return constants::pi() * sqrt(y) / 4; + else + return (y == 0) ? T(sqrt(x) / 2) : T((y * ellint_rc_imp(x, y, pol) + sqrt(x)) / 2); + } + else if(y == 0) + { + swap(y, z); + // + // Special handling for common case, from + // Numerical Computation of Real or Complex Elliptic Integrals, eq.46 + // + T xn = sqrt(x); + T yn = sqrt(y); + T x0 = xn; + T y0 = yn; + T sum = 0; + T sum_pow = 0.25f; + + while(fabs(xn - yn) >= 2.7 * tools::root_epsilon() * fabs(xn)) + { + T t = sqrt(xn * yn); + xn = (xn + yn) / 2; + yn = t; + sum_pow *= 2; + sum += sum_pow * boost::math::pow<2>(xn - yn); + } + T RF = constants::pi() / (xn + yn); + return ((boost::math::pow<2>((x0 + y0) / 2) - sum) * RF) / 2; + } + return (z * ellint_rf_imp(x, y, z, pol) + - (x - z) * (y - z) * ellint_rd_imp(x, y, z, pol) / 3 + + sqrt(x * y / z)) / 2; + } + +} // namespace detail + +template +inline typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rg_imp( + static_cast(x), + static_cast(y), + static_cast(z), pol), "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z) +{ + return ellint_rg(x, y, z, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RG_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/ellint_rj.hpp b/libcxx/src/third-party/boost/math/special_functions/ellint_rj.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ellint_rj.hpp @@ -0,0 +1,302 @@ +// Copyright (c) 2006 Xiaogang Zhang, 2015 John Maddock +// 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) +// +// History: +// XZ wrote the original of this file as part of the Google +// Summer of Code 2006. JM modified it to fit into the +// Boost.Math conceptual framework better, and to correctly +// handle the p < 0 case. +// Updated 2015 to use Carlson's latest methods. +// + +#ifndef BOOST_MATH_ELLINT_RJ_HPP +#define BOOST_MATH_ELLINT_RJ_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// Carlson's elliptic integral of the third kind +// R_J(x, y, z, p) = 1.5 * \int_{0}^{\infty} (t+p)^{-1} [(t+x)(t+y)(t+z)]^{-1/2} dt +// Carlson, Numerische Mathematik, vol 33, 1 (1979) + +namespace boost { namespace math { namespace detail{ + +template +T ellint_rc1p_imp(T y, const Policy& pol) +{ + using namespace boost::math; + // Calculate RC(1, 1 + x) + BOOST_MATH_STD_USING + + static const char* function = "boost::math::ellint_rc<%1%>(%1%,%1%)"; + + if(y == -1) + { + return policies::raise_domain_error(function, + "Argument y must not be zero but got %1%", y, pol); + } + + // for 1 + y < 0, the integral is singular, return Cauchy principal value + T result; + if(y < -1) + { + result = sqrt(1 / -y) * detail::ellint_rc_imp(T(-y), T(-1 - y), pol); + } + else if(y == 0) + { + result = 1; + } + else if(y > 0) + { + result = atan(sqrt(y)) / sqrt(y); + } + else + { + if(y > -0.5) + { + T arg = sqrt(-y); + result = (boost::math::log1p(arg, pol) - boost::math::log1p(-arg, pol)) / (2 * sqrt(-y)); + } + else + { + result = log((1 + sqrt(-y)) / sqrt(1 + y)) / sqrt(-y); + } + } + return result; +} + +template +T ellint_rj_imp(T x, T y, T z, T p, const Policy& pol) +{ + BOOST_MATH_STD_USING + + static const char* function = "boost::math::ellint_rj<%1%>(%1%,%1%,%1%)"; + + if(x < 0) + { + return policies::raise_domain_error(function, + "Argument x must be non-negative, but got x = %1%", x, pol); + } + if(y < 0) + { + return policies::raise_domain_error(function, + "Argument y must be non-negative, but got y = %1%", y, pol); + } + if(z < 0) + { + return policies::raise_domain_error(function, + "Argument z must be non-negative, but got z = %1%", z, pol); + } + if(p == 0) + { + return policies::raise_domain_error(function, + "Argument p must not be zero, but got p = %1%", p, pol); + } + if(x + y == 0 || y + z == 0 || z + x == 0) + { + return policies::raise_domain_error(function, + "At most one argument can be zero, " + "only possible result is %1%.", std::numeric_limits::quiet_NaN(), pol); + } + + // for p < 0, the integral is singular, return Cauchy principal value + if(p < 0) + { + // + // We must ensure that x < y < z. + // Since the integral is symmetrical in x, y and z + // we can just permute the values: + // + if(x > y) + std::swap(x, y); + if(y > z) + std::swap(y, z); + if(x > y) + std::swap(x, y); + + BOOST_MATH_ASSERT(x <= y); + BOOST_MATH_ASSERT(y <= z); + + T q = -p; + p = (z * (x + y + q) - x * y) / (z + q); + + BOOST_MATH_ASSERT(p >= 0); + + T value = (p - z) * ellint_rj_imp(x, y, z, p, pol); + value -= 3 * ellint_rf_imp(x, y, z, pol); + value += 3 * sqrt((x * y * z) / (x * y + p * q)) * ellint_rc_imp(T(x * y + p * q), T(p * q), pol); + value /= (z + q); + return value; + } + + // + // Special cases from http://dlmf.nist.gov/19.20#iii + // + if(x == y) + { + if(x == z) + { + if(x == p) + { + // All values equal: + return 1 / (x * sqrt(x)); + } + else + { + // x = y = z: + return 3 * (ellint_rc_imp(x, p, pol) - 1 / sqrt(x)) / (x - p); + } + } + else + { + // x = y only, permute so y = z: + using std::swap; + swap(x, z); + if(y == p) + { + return ellint_rd_imp(x, y, y, pol); + } + else if((std::max)(y, p) / (std::min)(y, p) > 1.2) + { + return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); + } + // Otherwise fall through to normal method, special case above will suffer too much cancellation... + } + } + if(y == z) + { + if(y == p) + { + // y = z = p: + return ellint_rd_imp(x, y, y, pol); + } + else if((std::max)(y, p) / (std::min)(y, p) > 1.2) + { + // y = z: + return 3 * (ellint_rc_imp(x, y, pol) - ellint_rc_imp(x, p, pol)) / (p - y); + } + // Otherwise fall through to normal method, special case above will suffer too much cancellation... + } + if(z == p) + { + return ellint_rd_imp(x, y, z, pol); + } + + T xn = x; + T yn = y; + T zn = z; + T pn = p; + T An = (x + y + z + 2 * p) / 5; + T A0 = An; + T delta = (p - x) * (p - y) * (p - z); + T Q = pow(tools::epsilon() / 5, -T(1) / 8) * (std::max)((std::max)(fabs(An - x), fabs(An - y)), (std::max)(fabs(An - z), fabs(An - p))); + + unsigned n; + T lambda; + T Dn; + T En; + T rx, ry, rz, rp; + T fmn = 1; // 4^-n + T RC_sum = 0; + + for(n = 0; n < policies::get_max_series_iterations(); ++n) + { + rx = sqrt(xn); + ry = sqrt(yn); + rz = sqrt(zn); + rp = sqrt(pn); + Dn = (rp + rx) * (rp + ry) * (rp + rz); + En = delta / Dn; + En /= Dn; + if((En < -0.5) && (En > -1.5)) + { + // + // Occasionally En ~ -1, we then have no means of calculating + // RC(1, 1+En) without terrible cancellation error, so we + // need to get to 1+En directly. By substitution we have + // + // 1+E_0 = 1 + (p-x)*(p-y)*(p-z)/((sqrt(p) + sqrt(x))*(sqrt(p)+sqrt(y))*(sqrt(p)+sqrt(z)))^2 + // = 2*sqrt(p)*(p+sqrt(x) * (sqrt(y)+sqrt(z)) + sqrt(y)*sqrt(z)) / ((sqrt(p) + sqrt(x))*(sqrt(p) + sqrt(y)*(sqrt(p)+sqrt(z)))) + // + // And since this is just an application of the duplication formula for RJ, the same + // expression works for 1+En if we use x,y,z,p_n etc. + // This branch is taken only once or twice at the start of iteration, + // after than En reverts to it's usual very small values. + // + T b = 2 * rp * (pn + rx * (ry + rz) + ry * rz) / Dn; + RC_sum += fmn / Dn * detail::ellint_rc_imp(T(1), b, pol); + } + else + { + RC_sum += fmn / Dn * ellint_rc1p_imp(En, pol); + } + lambda = rx * ry + rx * rz + ry * rz; + + // From here on we move to n+1: + An = (An + lambda) / 4; + fmn /= 4; + + if(fmn * Q < An) + break; + + xn = (xn + lambda) / 4; + yn = (yn + lambda) / 4; + zn = (zn + lambda) / 4; + pn = (pn + lambda) / 4; + delta /= 64; + } + + T X = fmn * (A0 - x) / An; + T Y = fmn * (A0 - y) / An; + T Z = fmn * (A0 - z) / An; + T P = (-X - Y - Z) / 2; + T E2 = X * Y + X * Z + Y * Z - 3 * P * P; + T E3 = X * Y * Z + 2 * E2 * P + 4 * P * P * P; + T E4 = (2 * X * Y * Z + E2 * P + 3 * P * P * P) * P; + T E5 = X * Y * Z * P * P; + T result = fmn * pow(An, T(-3) / 2) * + (1 - 3 * E2 / 14 + E3 / 6 + 9 * E2 * E2 / 88 - 3 * E4 / 22 - 9 * E2 * E3 / 52 + 3 * E5 / 26 - E2 * E2 * E2 / 16 + + 3 * E3 * E3 / 40 + 3 * E2 * E4 / 20 + 45 * E2 * E2 * E3 / 272 - 9 * (E3 * E4 + E2 * E5) / 68); + + result += 6 * RC_sum; + return result; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast( + detail::ellint_rj_imp( + static_cast(x), + static_cast(y), + static_cast(z), + static_cast(p), + pol), "boost::math::ellint_rj<%1%>(%1%,%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p) +{ + return ellint_rj(x, y, z, p, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_RJ_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/erf.hpp b/libcxx/src/third-party/boost/math/special_functions/erf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/erf.hpp @@ -0,0 +1,1265 @@ +// (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_ERF_HPP +#define BOOST_MATH_SPECIAL_ERF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +namespace detail +{ + +// +// Asymptotic series for large z: +// +template +struct erf_asympt_series_t +{ + erf_asympt_series_t(T z) : xx(2 * -z * z), tk(1) + { + BOOST_MATH_STD_USING + result = -exp(-z * z) / sqrt(boost::math::constants::pi()); + result /= z; + } + + typedef T result_type; + + T operator()() + { + BOOST_MATH_STD_USING + T r = result; + result *= tk / xx; + tk += 2; + if( fabs(r) < fabs(result)) + result = 0; + return r; + } +private: + T result; + T xx; + int tk; +}; +// +// How large z has to be in order to ensure that the series converges: +// +template +inline float erf_asymptotic_limit_N(const T&) +{ + return (std::numeric_limits::max)(); +} +inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 2.8F; +} +inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 4.3F; +} +inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 4.8F; +} +inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 6.5F; +} +inline float erf_asymptotic_limit_N(const std::integral_constant&) +{ + return 6.8F; +} + +template +inline T erf_asymptotic_limit() +{ + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + return erf_asymptotic_limit_N(tag_type()); +} + +template +struct erf_series_near_zero +{ + typedef T result_type; + T term; + T zz; + int k; + erf_series_near_zero(const T& z) : term(z), zz(-z * z), k(0) {} + + T operator()() + { + T result = term / (2 * k + 1); + term *= zz / ++k; + return result; + } +}; + +template +T erf_series_near_zero_sum(const T& x, const Policy& pol) +{ + // + // We need Kahan summation here, otherwise the errors grow fairly quickly. + // This method is *much* faster than the alternatives even so. + // + erf_series_near_zero sum(x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T result = constants::two_div_root_pi() * tools::kahan_sum_series(sum, tools::digits(), max_iter); + policies::check_series_iterations("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol); + return result; +} + +template +T erf_imp(T z, bool invert, const Policy& pol, const Tag& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("Generic erf_imp called"); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + if(!invert && (z > detail::erf_asymptotic_limit())) + { + detail::erf_asympt_series_t s(z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = boost::math::tools::sum_series(s, policies::get_epsilon(), max_iter, 1); + policies::check_series_iterations("boost::math::erf<%1%>(%1%, %1%)", max_iter, pol); + } + else + { + T x = z * z; + if(z < 1.3f) + { + // Compute P: + // This is actually good for z p to 2 or so, but the cutoff given seems + // to be the best compromise. Performance wise, this is way quicker than anything else... + result = erf_series_near_zero_sum(z, pol); + } + else if(x > 1 / tools::epsilon()) + { + // http://functions.wolfram.com/06.27.06.0006.02 + invert = !invert; + result = exp(-x) / (constants::root_pi() * z); + } + else + { + // Compute Q: + invert = !invert; + result = z * exp(-x); + result /= boost::math::constants::root_pi(); + result *= upper_gamma_fraction(T(0.5f), x, policies::get_epsilon()); + } + } + if(invert) + result = 1 - result; + return result; +} + +template +T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("53-bit precision erf_imp called"); + + if ((boost::math::isnan)(z)) + return policies::raise_denorm_error("boost::math::erf<%1%>(%1%)", "Expected a finite argument but got %1%", z, pol); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else if(z < -0.5) + return 2 - erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + // + // Big bunch of selection statements now to pick + // which implementation to use, + // try to put most likely options first: + // + if(z < 0.5) + { + // + // We're going to calculate erf: + // + if(z < 1e-10) + { + if(z == 0) + { + result = T(0); + } + else + { + static const T c = BOOST_MATH_BIG_CONSTANT(T, 53, 0.003379167095512573896158903121545171688); + result = static_cast(z * 1.125f + z * c); + } + } + else + { + // Maximum Deviation Found: 1.561e-17 + // Expected Error Term: 1.561e-17 + // Maximum Relative Change in Control Points: 1.155e-04 + // Max Error found at double precision = 2.961182e-17 + + static const T Y = 1.044948577880859375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0834305892146531832907), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.338165134459360935041), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0509990735146777432841), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00772758345802133288487), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000322780120964605683831), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.455004033050794024546), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0875222600142252549554), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00858571925074406212772), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000370900071787748000569), + }; + T zz = z * z; + result = z * (Y + tools::evaluate_polynomial(P, zz) / tools::evaluate_polynomial(Q, zz)); + } + } + else if(invert ? (z < 28) : (z < 5.93f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1.5f) + { + // Maximum Deviation Found: 3.702e-17 + // Expected Error Term: 3.702e-17 + // Maximum Relative Change in Control Points: 2.845e-04 + // Max Error found at double precision = 4.841816e-17 + static const T Y = 0.405935764312744140625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.098090592216281240205), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.178114665841120341155), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.191003695796775433986), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0888900368967884466578), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0195049001251218801359), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00180424538297014223957), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.84759070983002217845), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.42628004845511324508), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.578052804889902404909), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.12385097467900864233), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0113385233577001411017), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.337511472483094676155e-5), + }; + BOOST_MATH_INSTRUMENT_VARIABLE(Y); + BOOST_MATH_INSTRUMENT_VARIABLE(P[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(Q[0]); + BOOST_MATH_INSTRUMENT_VARIABLE(z); + result = Y + tools::evaluate_polynomial(P, T(z - 0.5)) / tools::evaluate_polynomial(Q, T(z - 0.5)); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + result *= exp(-z * z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if(z < 2.5f) + { + // Max Error found at double precision = 6.599585e-18 + // Maximum Deviation Found: 3.909e-18 + // Expected Error Term: 3.909e-18 + // Maximum Relative Change in Control Points: 9.886e-05 + static const T Y = 0.50672817230224609375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0243500476207698441272), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0386540375035707201728), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.04394818964209516296), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175679436311802092299), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00323962406290842133584), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000235839115596880717416), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.53991494948552447182), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.982403709157920235114), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.325732924782444448493), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0563921837420478160373), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00410369723978904575884), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.5)) / tools::evaluate_polynomial(Q, T(z - 1.5)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 4.5f) + { + // Maximum Deviation Found: 1.512e-17 + // Expected Error Term: 1.512e-17 + // Maximum Relative Change in Control Points: 2.222e-04 + // Max Error found at double precision = 2.062515e-17 + static const T Y = 0.5405750274658203125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00295276716530971662634), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0137384425896355332126), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00840807615555585383007), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00212825620914618649141), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000250269961544794627958), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.113212406648847561139e-4), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.04217814166938418171), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.442597659481563127003), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0958492726301061423444), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0105982906484876531489), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000479411269521714493907), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 3.5)) / tools::evaluate_polynomial(Q, T(z - 3.5)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Max Error found at double precision = 2.997958e-17 + // Maximum Deviation Found: 2.860e-17 + // Expected Error Term: 2.859e-17 + // Maximum Relative Change in Control Points: 1.357e-05 + static const T Y = 0.5579090118408203125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00628057170626964891937), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0175389834052493308818), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.212652252872804219852), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.687717681153649930619), + BOOST_MATH_BIG_CONSTANT(T, 53, -2.5518551727311523996), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.22729451764143718517), + BOOST_MATH_BIG_CONSTANT(T, 53, -2.8175401114513378771), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.79257750980575282228), + BOOST_MATH_BIG_CONSTANT(T, 53, 11.0567237927800161565), + BOOST_MATH_BIG_CONSTANT(T, 53, 15.930646027911794143), + BOOST_MATH_BIG_CONSTANT(T, 53, 22.9367376522880577224), + BOOST_MATH_BIG_CONSTANT(T, 53, 13.5064170191802889145), + BOOST_MATH_BIG_CONSTANT(T, 53, 5.48409182238641741584), + }; + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 26)); + hi = ldexp(hi, expon - 26); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 28 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + result = 1 - result; + } + + return result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) + + +template +T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("64-bit precision erf_imp called"); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else if(z < -0.5) + return 2 - erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + // + // Big bunch of selection statements now to pick which + // implementation to use, try to put most likely options + // first: + // + if(z < 0.5) + { + // + // We're going to calculate erf: + // + if(z == 0) + { + result = 0; + } + else if(z < 1e-10) + { + static const T c = BOOST_MATH_BIG_CONSTANT(T, 64, 0.003379167095512573896158903121545171688); + result = z * 1.125 + z * c; + } + else + { + // Max Error found at long double precision = 1.623299e-20 + // Maximum Deviation Found: 4.326e-22 + // Expected Error Term: -4.326e-22 + // Maximum Relative Change in Control Points: 1.474e-04 + static const T Y = 1.044948577880859375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0834305892146531988966), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.338097283075565413695), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509602734406067204596), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00904906346158537794396), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000489468651464798669181), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.200305626366151877759e-4), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.455817300515875172439), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0916537354356241792007), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0102722652675910031202), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000650511752687851548735), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.189532519105655496778e-4), + }; + result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z))); + } + } + else if(invert ? (z < 110) : (z < 6.6f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1.5) + { + // Max Error found at long double precision = 3.239590e-20 + // Maximum Deviation Found: 2.241e-20 + // Expected Error Term: -2.241e-20 + // Maximum Relative Change in Control Points: 5.110e-03 + static const T Y = 0.405935764312744140625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0980905922162812031672), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.159989089922969141329), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.222359821619935712378), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.127303921703577362312), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0384057530342762400273), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00628431160851156719325), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000441266654514391746428), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.266689068336295642561e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.03237474985469469291), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.78355454954969405222), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.867940326293760578231), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.248025606990021698392), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0396649631833002269861), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00279220237309449026796), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 2.5) + { + // Max Error found at long double precision = 3.686211e-21 + // Maximum Deviation Found: 1.495e-21 + // Expected Error Term: -1.494e-21 + // Maximum Relative Change in Control Points: 1.793e-04 + static const T Y = 0.50672817230224609375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.024350047620769840217), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0343522687935671451309), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0505420824305544949541), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0257479325917757388209), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00669349844190354356118), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00090807914416099524444), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.515917266698050027934e-4), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.71657861671930336344), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.26409634824280366218), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.512371437838969015941), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.120902623051120950935), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0158027197831887485261), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000897871370778031611439), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 4.5) + { + // Maximum Deviation Found: 1.107e-20 + // Expected Error Term: -1.106e-20 + // Maximum Relative Change in Control Points: 1.709e-04 + // Max Error found at long double precision = 1.446908e-20 + static const T Y = 0.5405750274658203125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0029527671653097284033), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0141853245895495604051), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0104959584626432293901), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00343963795976100077626), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00059065441194877637899), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.523435380636174008685e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.189896043050331257262e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.19352160185285642574), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.603256964363454392857), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.165411142458540585835), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0259729870946203166468), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00221657568292893699158), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.804149464190309799804e-4), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 3.5f)) / tools::evaluate_polynomial(Q, T(z - 3.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Max Error found at long double precision = 7.961166e-21 + // Maximum Deviation Found: 6.677e-21 + // Expected Error Term: 6.676e-21 + // Maximum Relative Change in Control Points: 2.319e-05 + static const T Y = 0.55825519561767578125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00593438793008050214106), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280666231009089713937), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.141597835204583050043), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.978088201154300548842), + BOOST_MATH_BIG_CONSTANT(T, 64, -5.47351527796012049443), + BOOST_MATH_BIG_CONSTANT(T, 64, -13.8677304660245326627), + BOOST_MATH_BIG_CONSTANT(T, 64, -27.1274948720539821722), + BOOST_MATH_BIG_CONSTANT(T, 64, -29.2545152747009461519), + BOOST_MATH_BIG_CONSTANT(T, 64, -16.8865774499799676937), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.72948911186645394541), + BOOST_MATH_BIG_CONSTANT(T, 64, 23.6750543147695749212), + BOOST_MATH_BIG_CONSTANT(T, 64, 60.0021517335693186785), + BOOST_MATH_BIG_CONSTANT(T, 64, 131.766251645149522868), + BOOST_MATH_BIG_CONSTANT(T, 64, 178.167924971283482513), + BOOST_MATH_BIG_CONSTANT(T, 64, 182.499390505915222699), + BOOST_MATH_BIG_CONSTANT(T, 64, 104.365251479578577989), + BOOST_MATH_BIG_CONSTANT(T, 64, 30.8365511891224291717), + }; + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 32)); + hi = ldexp(hi, expon - 32); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 110 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + result = 1 - result; + } + + return result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) + + +template +T erf_imp(T z, bool invert, const Policy& pol, const std::integral_constant& t) +{ + BOOST_MATH_STD_USING + + BOOST_MATH_INSTRUMENT_CODE("113-bit precision erf_imp called"); + + if(z < 0) + { + if(!invert) + return -erf_imp(T(-z), invert, pol, t); + else if(z < -0.5) + return 2 - erf_imp(T(-z), invert, pol, t); + else + return 1 + erf_imp(T(-z), false, pol, t); + } + + T result; + + // + // Big bunch of selection statements now to pick which + // implementation to use, try to put most likely options + // first: + // + if(z < 0.5) + { + // + // We're going to calculate erf: + // + if(z == 0) + { + result = 0; + } + else if(z < 1e-20) + { + static const T c = BOOST_MATH_BIG_CONSTANT(T, 113, 0.003379167095512573896158903121545171688); + result = z * 1.125 + z * c; + } + else + { + // Max Error found at long double precision = 2.342380e-35 + // Maximum Deviation Found: 6.124e-36 + // Expected Error Term: -6.124e-36 + // Maximum Relative Change in Control Points: 3.492e-10 + static const T Y = 1.0841522216796875f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0442269454158250738961589031215451778), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.35549265736002144875335323556961233), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0582179564566667896225454670863270393), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0112694696904802304229950538453123925), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000805730648981801146251825329609079099), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.566304966591936566229702842075966273e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169655010425186987820201021510002265e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.344448249920445916714548295433198544e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.466542092785657604666906909196052522), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.100005087012526447295176964142107611), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0128341535890117646540050072234142603), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00107150448466867929159660677016658186), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.586168368028999183607733369248338474e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.196230608502104324965623171516808796e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.313388521582925207734229967907890146e-7), + }; + result = z * (Y + tools::evaluate_polynomial(P, T(z * z)) / tools::evaluate_polynomial(Q, T(z * z))); + } + } + else if(invert ? (z < 110) : (z < 8.65f)) + { + // + // We'll be calculating erfc: + // + invert = !invert; + if(z < 1) + { + // Max Error found at long double precision = 3.246278e-35 + // Maximum Deviation Found: 1.388e-35 + // Expected Error Term: 1.387e-35 + // Maximum Relative Change in Control Points: 6.127e-05 + static const T Y = 0.371877193450927734375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0640320213544647969396032886581290455), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.200769874440155895637857443946706731), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.378447199873537170666487408805779826), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.30521399466465939450398642044975127), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.146890026406815277906781824723458196), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0464837937749539978247589252732769567), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00987895759019540115099100165904822903), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00137507575429025512038051025154301132), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0001144764551085935580772512359680516), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.436544865032836914773944382339900079e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.47651182872457465043733800302427977), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.78706486002517996428836400245547955), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.87295924621659627926365005293130693), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.829375825174365625428280908787261065), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.251334771307848291593780143950311514), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0522110268876176186719436765734722473), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00718332151250963182233267040106902368), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000595279058621482041084986219276392459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.226988669466501655990637599399326874e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.270666232259029102353426738909226413e-10), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 0.5f)) / tools::evaluate_polynomial(Q, T(z - 0.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 1.5) + { + // Max Error found at long double precision = 2.215785e-35 + // Maximum Deviation Found: 1.539e-35 + // Expected Error Term: 1.538e-35 + // Maximum Relative Change in Control Points: 6.104e-05 + static const T Y = 0.45658016204833984375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0289965858925328393392496555094848345), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0868181194868601184627743162571779226), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.169373435121178901746317404936356745), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13350446515949251201104889028133486), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0617447837290183627136837688446313313), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0185618495228251406703152962489700468), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00371949406491883508764162050169531013), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000485121708792921297742105775823900772), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.376494706741453489892108068231400061e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.133166058052466262415271732172490045e-5), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.32970330146503867261275580968135126), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.46325715420422771961250513514928746), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.55307882560757679068505047390857842), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.644274289865972449441174485441409076), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.182609091063258208068606847453955649), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0354171651271241474946129665801606795), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00454060370165285246451879969534083997), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000349871943711566546821198612518656486), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.123749319840299552925421880481085392e-4), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.0f)) / tools::evaluate_polynomial(Q, T(z - 1.0f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 2.25) + { + // Maximum Deviation Found: 1.418e-35 + // Expected Error Term: 1.418e-35 + // Maximum Relative Change in Control Points: 1.316e-04 + // Max Error found at long double precision = 1.998462e-35 + static const T Y = 0.50250148773193359375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0201233630504573402185161184151016606), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0331864357574860196516686996302305002), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0716562720864787193337475444413405461), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0545835322082103985114927569724880658), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0236692635189696678976549720784989593), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00656970902163248872837262539337601845), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00120282643299089441390490459256235021), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000142123229065182650020762792081622986), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.991531438367015135346716277792989347e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.312857043762117596999398067153076051e-6), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.13506082409097783827103424943508554), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.06399257267556230937723190496806215), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.18678481279932541314830499880691109), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.447733186643051752513538142316799562), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11505680005657879437196953047542148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.020163993632192726170219663831914034), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00232708971840141388847728782209730585), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000160733201627963528519726484608224112), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.507158721790721802724402992033269266e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.18647774409821470950544212696270639e-12), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 1.5f)) / tools::evaluate_polynomial(Q, T(z - 1.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if (z < 3) + { + // Maximum Deviation Found: 3.575e-36 + // Expected Error Term: 3.575e-36 + // Maximum Relative Change in Control Points: 7.103e-05 + // Max Error found at long double precision = 5.794737e-36 + static const T Y = 0.52896785736083984375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00902152521745813634562524098263360074), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0145207142776691539346923710537580927), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0301681239582193983824211995978678571), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0215548540823305814379020678660434461), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00864683476267958365678294164340749949), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00219693096885585491739823283511049902), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000364961639163319762492184502159894371), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.388174251026723752769264051548703059e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.241918026931789436000532513553594321e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.676586625472423508158937481943649258e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.93669171363907292305550231764920001), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69468476144051356810672506101377494), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.880023580986436640372794392579985511), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.299099106711315090710836273697708402), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0690593962363545715997445583603382337), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0108427016361318921960863149875360222), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00111747247208044534520499324234317695), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.686843205749767250666787987163701209e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.192093541425429248675532015101904262e-5), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 2.25f)) / tools::evaluate_polynomial(Q, T(z - 2.25f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 3.5) + { + // Maximum Deviation Found: 8.126e-37 + // Expected Error Term: -8.126e-37 + // Maximum Relative Change in Control Points: 1.363e-04 + // Max Error found at long double precision = 1.747062e-36 + static const T Y = 0.54037380218505859375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0033703486408887424921155540591370375), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0104948043110005245215286678898115811), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0148530118504000311502310457390417795), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00816693029245443090102738825536188916), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00249716579989140882491939681805594585), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0004655591010047353023978045800916647), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.531129557920045295895085236636025323e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.343526765122727069515775194111741049e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.971120407556888763695313774578711839e-7), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.59911256167540354915906501335919317), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.136006830764025173864831382946934), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.468565867990030871678574840738423023), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.122821824954470343413956476900662236), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0209670914950115943338996513330141633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00227845718243186165620199012883547257), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000144243326443913171313947613547085553), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.407763415954267700941230249989140046e-5), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 3.0f)) / tools::evaluate_polynomial(Q, T(z - 3.0f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 5.5) + { + // Maximum Deviation Found: 5.804e-36 + // Expected Error Term: -5.803e-36 + // Maximum Relative Change in Control Points: 2.475e-05 + // Max Error found at long double precision = 1.349545e-35 + static const T Y = 0.55000019073486328125f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00118142849742309772151454518093813615), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0072201822885703318172366893469382745), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0078782276276860110721875733778481505), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00418229166204362376187593976656261146), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00134198400587769200074194304298642705), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000283210387078004063264777611497435572), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.405687064094911866569295610914844928e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.39348283801568113807887364414008292e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.248798540917787001526976889284624449e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.929502490223452372919607105387474751e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.156161469668275442569286723236274457e-9), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.52955245103668419479878456656709381), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.06263944820093830054635017117417064), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.441684612681607364321013134378316463), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.121665258426166960049773715928906382), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0232134512374747691424978642874321434), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00310778180686296328582860464875562636), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000288361770756174705123674838640161693), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.177529187194133944622193191942300132e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.655068544833064069223029299070876623e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11005507545746069573608988651927452e-7), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 4.5f)) / tools::evaluate_polynomial(Q, T(z - 4.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 7.5) + { + // Maximum Deviation Found: 1.007e-36 + // Expected Error Term: 1.007e-36 + // Maximum Relative Change in Control Points: 1.027e-03 + // Max Error found at long double precision = 2.646420e-36 + static const T Y = 0.5574436187744140625f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000293236907400849056269309713064107674), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00225110719535060642692275221961480162), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190984458121502831421717207849429799), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000747757733460111743833929141001680706), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000170663175280949889583158597373928096), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.246441188958013822253071608197514058e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.229818000860544644974205957895688106e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.134886977703388748488480980637704864e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.454764611880548962757125070106650958e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.673002744115866600294723141176820155e-10), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.12843690320861239631195353379313367), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.569900657061622955362493442186537259), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.169094404206844928112348730277514273), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0324887449084220415058158657252147063), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00419252877436825753042680842608219552), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00036344133176118603523976748563178578), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.204123895931375107397698245752850347e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.674128352521481412232785122943508729e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.997637501418963696542159244436245077e-8), + }; + result = Y + tools::evaluate_polynomial(P, T(z - 6.5f)) / tools::evaluate_polynomial(Q, T(z - 6.5f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else if(z < 11.5) + { + // Maximum Deviation Found: 8.380e-36 + // Expected Error Term: 8.380e-36 + // Maximum Relative Change in Control Points: 2.632e-06 + // Max Error found at long double precision = 9.849522e-36 + static const T Y = 0.56083202362060546875f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000282420728751494363613829834891390121), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00175387065018002823433704079355125161), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0021344978564889819420775336322920375), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00124151356560137532655039683963075661), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000423600733566948018555157026862139644), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.914030340865175237133613697319509698e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.126999927156823363353809747017945494e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.110610959842869849776179749369376402e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.55075079477173482096725348704634529e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119735694018906705225870691331543806e-8), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69889613396167354566098060039549882), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.28824647372749624464956031163282674), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.572297795434934493541628008224078717), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.164157697425571712377043857240773164), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0315311145224594430281219516531649562), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00405588922155632380812945849777127458), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000336929033691445666232029762868642417), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.164033049810404773469413526427932109e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.356615210500531410114914617294694857e-6), + }; + result = Y + tools::evaluate_polynomial(P, T(z / 2 - 4.75f)) / tools::evaluate_polynomial(Q, T(z / 2 - 4.75f)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + else + { + // Maximum Deviation Found: 1.132e-35 + // Expected Error Term: -1.132e-35 + // Maximum Relative Change in Control Points: 4.674e-04 + // Max Error found at long double precision = 1.162590e-35 + static const T Y = 0.5632686614990234375f; + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000920922048732849448079451574171836943), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00321439044532288750501700028748922439), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.250455263029390118657884864261823431), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.906807635364090342031792404764598142), + BOOST_MATH_BIG_CONSTANT(T, 113, -8.92233572835991735876688745989985565), + BOOST_MATH_BIG_CONSTANT(T, 113, -21.7797433494422564811782116907878495), + BOOST_MATH_BIG_CONSTANT(T, 113, -91.1451915251976354349734589601171659), + BOOST_MATH_BIG_CONSTANT(T, 113, -144.1279109655993927069052125017673), + BOOST_MATH_BIG_CONSTANT(T, 113, -313.845076581796338665519022313775589), + BOOST_MATH_BIG_CONSTANT(T, 113, -273.11378811923343424081101235736475), + BOOST_MATH_BIG_CONSTANT(T, 113, -271.651566205951067025696102600443452), + BOOST_MATH_BIG_CONSTANT(T, 113, -60.0530577077238079968843307523245547), + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.49040448075464744191022350947892036), + BOOST_MATH_BIG_CONSTANT(T, 113, 34.3563592467165971295915749548313227), + BOOST_MATH_BIG_CONSTANT(T, 113, 84.4993232033879023178285731843850461), + BOOST_MATH_BIG_CONSTANT(T, 113, 376.005865281206894120659401340373818), + BOOST_MATH_BIG_CONSTANT(T, 113, 629.95369438888946233003926191755125), + BOOST_MATH_BIG_CONSTANT(T, 113, 1568.35771983533158591604513304269098), + BOOST_MATH_BIG_CONSTANT(T, 113, 1646.02452040831961063640827116581021), + BOOST_MATH_BIG_CONSTANT(T, 113, 2299.96860633240298708910425594484895), + BOOST_MATH_BIG_CONSTANT(T, 113, 1222.73204392037452750381340219906374), + BOOST_MATH_BIG_CONSTANT(T, 113, 799.359797306084372350264298361110448), + BOOST_MATH_BIG_CONSTANT(T, 113, 72.7415265778588087243442792401576737), + }; + result = Y + tools::evaluate_polynomial(P, T(1 / z)) / tools::evaluate_polynomial(Q, T(1 / z)); + T hi, lo; + int expon; + hi = floor(ldexp(frexp(z, &expon), 56)); + hi = ldexp(hi, expon - 56); + lo = z - hi; + T sq = z * z; + T err_sqr = ((hi * hi - sq) + 2 * hi * lo) + lo * lo; + result *= exp(-sq) * exp(-err_sqr) / z; + } + } + else + { + // + // Any value of z larger than 110 will underflow to zero: + // + result = 0; + invert = !invert; + } + + if(invert) + { + result = 1 - result; + } + + return result; +} // template T erf_imp(T z, bool invert, const Lanczos& l, const std::integral_constant& t) + +template +struct erf_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + boost::math::erf(static_cast(1e-12), Policy()); + boost::math::erf(static_cast(0.25), Policy()); + boost::math::erf(static_cast(1.25), Policy()); + boost::math::erf(static_cast(2.25), Policy()); + boost::math::erf(static_cast(4.25), Policy()); + boost::math::erf(static_cast(5.25), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::erf(static_cast(1e-12), Policy()); + boost::math::erf(static_cast(0.25), Policy()); + boost::math::erf(static_cast(1.25), Policy()); + boost::math::erf(static_cast(2.25), Policy()); + boost::math::erf(static_cast(4.25), Policy()); + boost::math::erf(static_cast(5.25), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::erf(static_cast(1e-22), Policy()); + boost::math::erf(static_cast(0.25), Policy()); + boost::math::erf(static_cast(1.25), Policy()); + boost::math::erf(static_cast(2.125), Policy()); + boost::math::erf(static_cast(2.75), Policy()); + boost::math::erf(static_cast(3.25), Policy()); + boost::math::erf(static_cast(5.25), Policy()); + boost::math::erf(static_cast(7.25), Policy()); + boost::math::erf(static_cast(11.25), Policy()); + boost::math::erf(static_cast(12.5), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename erf_initializer::init erf_initializer::initializer; + +} // namespace detail + +template +inline typename tools::promote_args::type erf(T z, const Policy& /* pol */) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name()); + BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name()); + BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name()); + + typedef std::integral_constant tag_type; + + BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name()); + + detail::erf_initializer::force_instantiate(); // Force constants to be initialized before main + + return policies::checked_narrowing_cast(detail::erf_imp( + static_cast(z), + false, + forwarding_policy(), + tag_type()), "boost::math::erf<%1%>(%1%, %1%)"); +} + +template +inline typename tools::promote_args::type erfc(T z, const Policy& /* pol */) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_INSTRUMENT_CODE("result_type = " << typeid(result_type).name()); + BOOST_MATH_INSTRUMENT_CODE("value_type = " << typeid(value_type).name()); + BOOST_MATH_INSTRUMENT_CODE("precision_type = " << typeid(precision_type).name()); + + typedef std::integral_constant tag_type; + + BOOST_MATH_INSTRUMENT_CODE("tag_type = " << typeid(tag_type).name()); + + detail::erf_initializer::force_instantiate(); // Force constants to be initialized before main + + return policies::checked_narrowing_cast(detail::erf_imp( + static_cast(z), + true, + forwarding_policy(), + tag_type()), "boost::math::erfc<%1%>(%1%, %1%)"); +} + +template +inline typename tools::promote_args::type erf(T z) +{ + return boost::math::erf(z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type erfc(T z) +{ + return boost::math::erfc(z, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#include + +#endif // BOOST_MATH_SPECIAL_ERF_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/expint.hpp b/libcxx/src/third-party/boost/math/special_functions/expint.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/expint.hpp @@ -0,0 +1,1666 @@ +// Copyright John Maddock 2007. +// 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_EXPINT_HPP +#define BOOST_MATH_EXPINT_HPP + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +template +inline typename tools::promote_args::type + expint(unsigned n, T z, const Policy& /*pol*/); + +namespace detail{ + +template +inline T expint_1_rational(const T& z, const std::integral_constant&) +{ + // this function is never actually called + BOOST_MATH_ASSERT(0); + return z; +} + +template +T expint_1_rational(const T& z, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 2.006e-18 + // Expected Error Term: 2.006e-18 + // Max error found at double precision: 2.760e-17 + static const T Y = 0.66373538970947265625F; + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0865197248079397976498), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0320913665303559189999), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.245088216639761496153), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0368031736257943745142), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00399167106081113256961), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000111507792921197858394) + }; + static const T Q[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.37091387659397013215), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.056770677104207528384), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00427347600017103698101), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000131049900798434683324), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.528611029520217142048e-6) + }; + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Maximum Deviation Found (interpolated): 1.444e-17 + // Max error found at double precision: 3.119e-17 + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.121013190657725568138e-18), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.999999999999998811143), + BOOST_MATH_BIG_CONSTANT(T, 53, -43.3058660811817946037), + BOOST_MATH_BIG_CONSTANT(T, 53, -724.581482791462469795), + BOOST_MATH_BIG_CONSTANT(T, 53, -6046.8250112711035463), + BOOST_MATH_BIG_CONSTANT(T, 53, -27182.6254466733970467), + BOOST_MATH_BIG_CONSTANT(T, 53, -66598.2652345418633509), + BOOST_MATH_BIG_CONSTANT(T, 53, -86273.1567711649528784), + BOOST_MATH_BIG_CONSTANT(T, 53, -54844.4587226402067411), + BOOST_MATH_BIG_CONSTANT(T, 53, -14751.4895786128450662), + BOOST_MATH_BIG_CONSTANT(T, 53, -1185.45720315201027667) + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 45.3058660811801465927), + BOOST_MATH_BIG_CONSTANT(T, 53, 809.193214954550328455), + BOOST_MATH_BIG_CONSTANT(T, 53, 7417.37624454689546708), + BOOST_MATH_BIG_CONSTANT(T, 53, 38129.5594484818471461), + BOOST_MATH_BIG_CONSTANT(T, 53, 113057.05869159631492), + BOOST_MATH_BIG_CONSTANT(T, 53, 192104.047790227984431), + BOOST_MATH_BIG_CONSTANT(T, 53, 180329.498380501819718), + BOOST_MATH_BIG_CONSTANT(T, 53, 86722.3403467334749201), + BOOST_MATH_BIG_CONSTANT(T, 53, 18455.4124737722049515), + BOOST_MATH_BIG_CONSTANT(T, 53, 1229.20784182403048905), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.776491285282330997549) + }; + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + +template +T expint_1_rational(const T& z, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 3.807e-20 + // Expected Error Term: 3.807e-20 + // Max error found at long double precision: 6.249e-20 + + static const T Y = 0.66373538970947265625F; + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0865197248079397956816), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0275114007037026844633), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.246594388074877139824), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0237624819878732642231), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00259113319641673986276), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.30853660894346057053e-4) + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.317978365797784100273), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0393622602554758722511), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00204062029115966323229), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.732512107100088047854e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.202872781770207871975e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.52779248094603709945e-7) + }; + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Maximum Deviation Found (interpolated): 2.220e-20 + // Max error found at long double precision: 1.346e-19 + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.534401189080684443046e-23), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.999999999999999999905), + BOOST_MATH_BIG_CONSTANT(T, 64, -62.1517806091379402505), + BOOST_MATH_BIG_CONSTANT(T, 64, -1568.45688271895145277), + BOOST_MATH_BIG_CONSTANT(T, 64, -21015.3431990874009619), + BOOST_MATH_BIG_CONSTANT(T, 64, -164333.011755931661949), + BOOST_MATH_BIG_CONSTANT(T, 64, -777917.270775426696103), + BOOST_MATH_BIG_CONSTANT(T, 64, -2244188.56195255112937), + BOOST_MATH_BIG_CONSTANT(T, 64, -3888702.98145335643429), + BOOST_MATH_BIG_CONSTANT(T, 64, -3909822.65621952648353), + BOOST_MATH_BIG_CONSTANT(T, 64, -2149033.9538897398457), + BOOST_MATH_BIG_CONSTANT(T, 64, -584705.537139793925189), + BOOST_MATH_BIG_CONSTANT(T, 64, -65815.2605361889477244), + BOOST_MATH_BIG_CONSTANT(T, 64, -2038.82870680427258038) + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 64.1517806091379399478), + BOOST_MATH_BIG_CONSTANT(T, 64, 1690.76044393722763785), + BOOST_MATH_BIG_CONSTANT(T, 64, 24035.9534033068949426), + BOOST_MATH_BIG_CONSTANT(T, 64, 203679.998633572361706), + BOOST_MATH_BIG_CONSTANT(T, 64, 1074661.58459976978285), + BOOST_MATH_BIG_CONSTANT(T, 64, 3586552.65020899358773), + BOOST_MATH_BIG_CONSTANT(T, 64, 7552186.84989547621411), + BOOST_MATH_BIG_CONSTANT(T, 64, 9853333.79353054111434), + BOOST_MATH_BIG_CONSTANT(T, 64, 7689642.74550683631258), + BOOST_MATH_BIG_CONSTANT(T, 64, 3385553.35146759180739), + BOOST_MATH_BIG_CONSTANT(T, 64, 763218.072732396428725), + BOOST_MATH_BIG_CONSTANT(T, 64, 73930.2995984054930821), + BOOST_MATH_BIG_CONSTANT(T, 64, 2063.86994219629165937) + }; + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + +template +T expint_1_rational(const T& z, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(z <= 1) + { + // Maximum Deviation Found: 2.477e-35 + // Expected Error Term: 2.477e-35 + // Max error found at long double precision: 6.810e-35 + + static const T Y = 0.66373538970947265625F; + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0865197248079397956434879099175975937), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0369066175910795772830865304506087759), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.24272036838415474665971599314725545), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0502166331248948515282379137550178307), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00768384138547489410285101483730424919), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000612574337702109683505224915484717162), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.380207107950635046971492617061708534e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.136528159460768830763009294683628406e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.346839106212658259681029388908658618e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.340500302777838063940402160594523429e-9) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.426568827778942588160423015589537302), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0841384046470893490592450881447510148), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0100557215850668029618957359471132995), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000799334870474627021737357294799839363), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.434452090903862735242423068552687688e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.15829674748799079874182885081231252e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.354406206738023762100882270033082198e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.369373328141051577845488477377890236e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.274149801370933606409282434677600112e-12) + }; + result = tools::evaluate_polynomial(P, z) + / tools::evaluate_polynomial(Q, z); + result += z - log(z) - Y; + } + else if(z <= 4) + { + // Max error in interpolated form: 5.614e-35 + // Max error found at long double precision: 7.979e-35 + + static const T Y = 0.70190334320068359375F; + + static const T P[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.298096656795020369955077350585959794), + BOOST_MATH_BIG_CONSTANT(T, 113, 12.9314045995266142913135497455971247), + BOOST_MATH_BIG_CONSTANT(T, 113, 226.144334921582637462526628217345501), + BOOST_MATH_BIG_CONSTANT(T, 113, 2070.83670924261732722117682067381405), + BOOST_MATH_BIG_CONSTANT(T, 113, 10715.1115684330959908244769731347186), + BOOST_MATH_BIG_CONSTANT(T, 113, 30728.7876355542048019664777316053311), + BOOST_MATH_BIG_CONSTANT(T, 113, 38520.6078609349855436936232610875297), + BOOST_MATH_BIG_CONSTANT(T, 113, -27606.0780981527583168728339620565165), + BOOST_MATH_BIG_CONSTANT(T, 113, -169026.485055785605958655247592604835), + BOOST_MATH_BIG_CONSTANT(T, 113, -254361.919204983608659069868035092282), + BOOST_MATH_BIG_CONSTANT(T, 113, -195765.706874132267953259272028679935), + BOOST_MATH_BIG_CONSTANT(T, 113, -83352.6826013533205474990119962408675), + BOOST_MATH_BIG_CONSTANT(T, 113, -19251.6828496869586415162597993050194), + BOOST_MATH_BIG_CONSTANT(T, 113, -2226.64251774578542836725386936102339), + BOOST_MATH_BIG_CONSTANT(T, 113, -109.009437301400845902228611986479816), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.51492042209561411434644938098833499) + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 46.734521442032505570517810766704587), + BOOST_MATH_BIG_CONSTANT(T, 113, 908.694714348462269000247450058595655), + BOOST_MATH_BIG_CONSTANT(T, 113, 9701.76053033673927362784882748513195), + BOOST_MATH_BIG_CONSTANT(T, 113, 63254.2815292641314236625196594947774), + BOOST_MATH_BIG_CONSTANT(T, 113, 265115.641285880437335106541757711092), + BOOST_MATH_BIG_CONSTANT(T, 113, 732707.841188071900498536533086567735), + BOOST_MATH_BIG_CONSTANT(T, 113, 1348514.02492635723327306628712057794), + BOOST_MATH_BIG_CONSTANT(T, 113, 1649986.81455283047769673308781585991), + BOOST_MATH_BIG_CONSTANT(T, 113, 1326000.828522976970116271208812099), + BOOST_MATH_BIG_CONSTANT(T, 113, 683643.09490612171772350481773951341), + BOOST_MATH_BIG_CONSTANT(T, 113, 217640.505137263607952365685653352229), + BOOST_MATH_BIG_CONSTANT(T, 113, 40288.3467237411710881822569476155485), + BOOST_MATH_BIG_CONSTANT(T, 113, 3932.89353979531632559232883283175754), + BOOST_MATH_BIG_CONSTANT(T, 113, 169.845369689596739824177412096477219), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.17607292280092201170768401876895354) + }; + T recip = 1 / z; + result = Y + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else if(z < -boost::math::tools::log_min_value()) + { + // Max error in interpolated form: 4.413e-35 + // Max error found at long double precision: 8.928e-35 + + static const T P[19] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.559148411832951463689610809550083986e-40), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999999999999999999999997), + BOOST_MATH_BIG_CONSTANT(T, 113, -166.542326331163836642960118190147367), + BOOST_MATH_BIG_CONSTANT(T, 113, -12204.639128796330005065904675153652), + BOOST_MATH_BIG_CONSTANT(T, 113, -520807.069767086071806275022036146855), + BOOST_MATH_BIG_CONSTANT(T, 113, -14435981.5242137970691490903863125326), + BOOST_MATH_BIG_CONSTANT(T, 113, -274574945.737064301247496460758654196), + BOOST_MATH_BIG_CONSTANT(T, 113, -3691611582.99810039356254671781473079), + BOOST_MATH_BIG_CONSTANT(T, 113, -35622515944.8255047299363690814678763), + BOOST_MATH_BIG_CONSTANT(T, 113, -248040014774.502043161750715548451142), + BOOST_MATH_BIG_CONSTANT(T, 113, -1243190389769.53458416330946622607913), + BOOST_MATH_BIG_CONSTANT(T, 113, -4441730126135.54739052731990368425339), + BOOST_MATH_BIG_CONSTANT(T, 113, -11117043181899.7388524310281751971366), + BOOST_MATH_BIG_CONSTANT(T, 113, -18976497615396.9717776601813519498961), + BOOST_MATH_BIG_CONSTANT(T, 113, -21237496819711.1011661104761906067131), + BOOST_MATH_BIG_CONSTANT(T, 113, -14695899122092.5161620333466757812848), + BOOST_MATH_BIG_CONSTANT(T, 113, -5737221535080.30569711574295785864903), + BOOST_MATH_BIG_CONSTANT(T, 113, -1077042281708.42654526404581272546244), + BOOST_MATH_BIG_CONSTANT(T, 113, -68028222642.1941480871395695677675137) + }; + static const T Q[20] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 168.542326331163836642960118190147311), + BOOST_MATH_BIG_CONSTANT(T, 113, 12535.7237814586576783518249115343619), + BOOST_MATH_BIG_CONSTANT(T, 113, 544891.263372016404143120911148640627), + BOOST_MATH_BIG_CONSTANT(T, 113, 15454474.7241010258634446523045237762), + BOOST_MATH_BIG_CONSTANT(T, 113, 302495899.896629522673410325891717381), + BOOST_MATH_BIG_CONSTANT(T, 113, 4215565948.38886507646911672693270307), + BOOST_MATH_BIG_CONSTANT(T, 113, 42552409471.7951815668506556705733344), + BOOST_MATH_BIG_CONSTANT(T, 113, 313592377066.753173979584098301610186), + BOOST_MATH_BIG_CONSTANT(T, 113, 1688763640223.4541980740597514904542), + BOOST_MATH_BIG_CONSTANT(T, 113, 6610992294901.59589748057620192145704), + BOOST_MATH_BIG_CONSTANT(T, 113, 18601637235659.6059890851321772682606), + BOOST_MATH_BIG_CONSTANT(T, 113, 36944278231087.2571020964163402941583), + BOOST_MATH_BIG_CONSTANT(T, 113, 50425858518481.7497071917028793820058), + BOOST_MATH_BIG_CONSTANT(T, 113, 45508060902865.0899967797848815980644), + BOOST_MATH_BIG_CONSTANT(T, 113, 25649955002765.3817331501988304758142), + BOOST_MATH_BIG_CONSTANT(T, 113, 8259575619094.6518520988612711292331), + BOOST_MATH_BIG_CONSTANT(T, 113, 1299981487496.12607474362723586264515), + BOOST_MATH_BIG_CONSTANT(T, 113, 70242279152.8241187845178443118302693), + BOOST_MATH_BIG_CONSTANT(T, 113, -37633302.9409263839042721539363416685) + }; + T recip = 1 / z; + result = 1 + tools::evaluate_polynomial(P, recip) + / tools::evaluate_polynomial(Q, recip); + result *= exp(-z) * recip; + } + else + { + result = 0; + } + return result; +} + +template +struct expint_fraction +{ + typedef std::pair result_type; + expint_fraction(unsigned n_, T z_) : b(n_ + z_), i(-1), n(n_){} + std::pair operator()() + { + std::pair result = std::make_pair(-static_cast((i+1) * (n+i)), b); + b += 2; + ++i; + return result; + } +private: + T b; + int i; + unsigned n; +}; + +template +inline T expint_as_fraction(unsigned n, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + BOOST_MATH_INSTRUMENT_VARIABLE(z) + std::uintmax_t max_iter = policies::get_max_series_iterations(); + expint_fraction f(n, z); + T result = tools::continued_fraction_b( + f, + boost::math::policies::get_epsilon(), + max_iter); + policies::check_series_iterations("boost::math::expint_continued_fraction<%1%>(unsigned,%1%)", max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + BOOST_MATH_INSTRUMENT_VARIABLE(max_iter) + result = exp(-z) / result; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + return result; +} + +template +struct expint_series +{ + typedef T result_type; + expint_series(unsigned k_, T z_, T x_k_, T denom_, T fact_) + : k(k_), z(z_), x_k(x_k_), denom(denom_), fact(fact_){} + T operator()() + { + x_k *= -z; + denom += 1; + fact *= ++k; + return x_k / (denom * fact); + } +private: + unsigned k; + T z; + T x_k; + T denom; + T fact; +}; + +template +inline T expint_as_series(unsigned n, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + BOOST_MATH_INSTRUMENT_VARIABLE(z) + + T result = 0; + T x_k = -1; + T denom = T(1) - n; + T fact = 1; + unsigned k = 0; + for(; k < n - 1;) + { + result += x_k / (denom * fact); + denom += 1; + x_k *= -z; + fact *= ++k; + } + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += pow(-z, static_cast(n - 1)) + * (boost::math::digamma(static_cast(n), pol) - log(z)) / fact; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + + expint_series s(k, z, x_k, denom, fact); + result = tools::sum_series(s, policies::get_epsilon(), max_iter, result); + policies::check_series_iterations("boost::math::expint_series<%1%>(unsigned,%1%)", max_iter, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + BOOST_MATH_INSTRUMENT_VARIABLE(max_iter) + return result; +} + +template +T expint_imp(unsigned n, T z, const Policy& pol, const Tag& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::expint<%1%>(unsigned, %1%)"; + if(z < 0) + return policies::raise_domain_error(function, "Function requires z >= 0 but got %1%.", z, pol); + if(z == 0) + return n == 1 ? policies::raise_overflow_error(function, nullptr, pol) : T(1 / (static_cast(n - 1))); + + T result; + + bool f; + if(n < 3) + { + f = z < 0.5; + } + else + { + f = z < (static_cast(n - 2) / static_cast(n - 1)); + } +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4127) // conditional expression is constant +#endif + if(n == 0) + result = exp(-z) / z; + else if((n == 1) && (Tag::value)) + { + result = expint_1_rational(z, tag); + } + else if(f) + result = expint_as_series(n, z, pol); + else + result = expint_as_fraction(n, z, pol); +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + return result; +} + +template +struct expint_i_series +{ + typedef T result_type; + expint_i_series(T z_) : k(0), z_k(1), z(z_){} + T operator()() + { + z_k *= z / ++k; + return z_k / k; + } +private: + unsigned k; + T z_k; + T z; +}; + +template +T expint_i_as_series(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + T result = log(z); // (log(z) - log(1 / z)) / 2; + result += constants::euler(); + expint_i_series s(z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + result = tools::sum_series(s, policies::get_epsilon(), max_iter, result); + policies::check_series_iterations("boost::math::expint_i_series<%1%>(%1%)", max_iter, pol); + return result; +} + +template +T expint_i_imp(T z, const Policy& pol, const Tag& tag) +{ + static const char* function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + return expint_i_as_series(z, pol); +} + +template +T expint_i_imp(T z, const Policy& pol, const std::integral_constant& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + // Maximum Deviation Found: 2.852e-18 + // Expected Error Term: 2.852e-18 + // Max Error found at double precision = Poly: 2.636335e-16 Cheb: 4.187027e-16 + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 2.98677224343598593013), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.356343618769377415068), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.780836076283730801839), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.114670926327032002811), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0499434773576515260534), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00726224593341228159561), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00115478237227804306827), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000116419523609765200999), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.798296365679269702435e-5), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.2777056254402008721e-6) + }; + static const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, -1.17090412365413911947), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.62215109846016746276), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.195114782069495403315), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0391523431392967238166), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00504800158663705747345), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000389034007436065401822), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.138972589601781706598e-4) + }; + + static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 53, 1677624236387711.0); + static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 53, 4503599627370496.0); + static const T r1 = static_cast(c1 / c2); + static const T r2 = BOOST_MATH_BIG_CONSTANT(T, 53, 0.131401834143860282009280387409357165515556574352422001206362e-16); + static const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 53, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = (z - r1) - r2; + result *= t; + if(fabs(t) < 0.1) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } + } + else if (z <= 10) + { + // Maximum Deviation Found: 6.546e-17 + // Expected Error Term: 6.546e-17 + // Max Error found at double precision = Poly: 6.890169e-17 Cheb: 6.772128e-17 + static const T Y = 1.158985137939453125F; + static const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00139324086199402804173), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0349921221823888744966), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0264095520754134848538), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00761224003005476438412), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00247496209592143627977), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000374885917942100256775), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.554086272024881826253e-4), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.396487648924804510056e-5) + }; + static const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.744625566823272107711), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.329061095011767059236), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.100128624977313872323), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0223851099128506347278), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00365334190742316650106), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000402453408512476836472), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.263649630720255691787e-4) + }; + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 20) + { + // Maximum Deviation Found: 1.843e-17 + // Expected Error Term: -1.842e-17 + // Max Error found at double precision = Poly: 4.375868e-17 Cheb: 5.860967e-17 + + static const T Y = 1.0869731903076171875F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00893891094356945667451), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0484607730127134045806), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0652810444222236895772), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0478447572647309671455), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0226059218923777094596), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00720603636917482065907), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00155941947035972031334), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000209750022660200888349), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.138652200349182596186e-4) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.97017214039061194971), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.86232465043073157508), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.09601437090337519977), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.438873285773088870812), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.122537731979686102756), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0233458478275769288159), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00278170769163303669021), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.000159150281166108755531) + }; + T t = z / 5 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 40) + { + // Maximum Deviation Found: 5.102e-18 + // Expected Error Term: 5.101e-18 + // Max Error found at double precision = Poly: 1.441088e-16 Cheb: 1.864792e-16 + + + static const T Y = 1.03937530517578125F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00356165148914447597995), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0229930320357982333406), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0449814350482277917716), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0453759383048193402336), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0272050837209380717069), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00994403059883350813295), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00207592267812291726961), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.000192178045857733706044), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.113161784705911400295e-9) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.84354408840148561131), + BOOST_MATH_BIG_CONSTANT(T, 53, 3.6599610090072393012), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.75088464344293083595), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.2985244073998398643), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.383213198510794507409), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.0651165455496281337831), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.00488071077519227853585) + }; + T t = z / 10 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else + { + // Max Error found at double precision = 3.381886e-17 + static const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 53, 2.35385266837019985407899910749034804508871617254555467236651e17)); + static const T Y= 1.013065338134765625F; + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.0130653381347656243849), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.19029710559486576682), + BOOST_MATH_BIG_CONSTANT(T, 53, 94.7365094537197236011), + BOOST_MATH_BIG_CONSTANT(T, 53, -2516.35323679844256203), + BOOST_MATH_BIG_CONSTANT(T, 53, 18932.0850014925993025), + BOOST_MATH_BIG_CONSTANT(T, 53, -38703.1431362056714134) + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 61.9733592849439884145), + BOOST_MATH_BIG_CONSTANT(T, 53, -2354.56211323420194283), + BOOST_MATH_BIG_CONSTANT(T, 53, 22329.1459489893079041), + BOOST_MATH_BIG_CONSTANT(T, 53, -70126.245140396567133), + BOOST_MATH_BIG_CONSTANT(T, 53, 54738.2833147775537106), + BOOST_MATH_BIG_CONSTANT(T, 53, 8297.16296356518409347) + }; + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +T expint_i_imp(T z, const Policy& pol, const std::integral_constant& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + // Maximum Deviation Found: 3.883e-21 + // Expected Error Term: 3.883e-21 + // Max Error found at long double precision = Poly: 3.344801e-19 Cheb: 4.989937e-19 + + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 2.98677224343598593764), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.25891613550886736592), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.789323584998672832285), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.092432587824602399339), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0514236978728625906656), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00658477469745132977921), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00124914538197086254233), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000131429679565472408551), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.11293331317982763165e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.629499283139417444244e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.177833045143692498221e-7) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.20352377969742325748), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.66707904942606479811), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.223014531629140771914), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0493340022262908008636), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00741934273050807310677), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00074353567782087939294), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.455861727069603367656e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.131515429329812837701e-5) + }; + + static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 64, 1677624236387711.0); + static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 64, 4503599627370496.0); + static const T r1 = c1 / c2; + static const T r2 = BOOST_MATH_BIG_CONSTANT(T, 64, 0.131401834143860282009280387409357165515556574352422001206362e-16); + static const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = (z - r1) - r2; + result *= t; + if(fabs(t) < 0.1) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } + } + else if (z <= 10) + { + // Maximum Deviation Found: 2.622e-21 + // Expected Error Term: -2.622e-21 + // Max Error found at long double precision = Poly: 1.208328e-20 Cheb: 1.073723e-20 + + static const T Y = 1.158985137939453125F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00139324086199409049399), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0345238388952337563247), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0382065278072592940767), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0156117003070560727392), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00383276012430495387102), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000697070540945496497992), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.877310384591205930343e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.623067256376494930067e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.377246883283337141444e-6) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.08073635708902053767), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.553681133533942532909), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.176763647137553797451), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0387891748253869928121), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0060603004848394727017), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000670519492939992806051), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.4947357050100855646e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.204339282037446434827e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.146951181174930425744e-7) + }; + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 20) + { + // Maximum Deviation Found: 3.220e-20 + // Expected Error Term: 3.220e-20 + // Max Error found at long double precision = Poly: 7.696841e-20 Cheb: 6.205163e-20 + + + static const T Y = 1.0869731903076171875F; + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00893891094356946995368), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0487562980088748775943), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0670568657950041926085), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0509577352851442932713), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.02551800927409034206), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00892913759760086687083), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00224469630207344379888), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000392477245911296982776), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.44424044184395578775e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252788029251437017959e-5) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.00323265503572414261), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.94688958187256383178), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.19733638134417472296), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.513137726038353385661), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.159135395578007264547), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0358233587351620919881), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0056716655597009417875), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000577048986213535829925), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.290976943033493216793e-4) + }; + T t = z / 5 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; + } + else if(z <= 40) + { + // Maximum Deviation Found: 2.940e-21 + // Expected Error Term: -2.938e-21 + // Max Error found at long double precision = Poly: 3.419893e-19 Cheb: 3.359874e-19 + + static const T Y = 1.03937530517578125F; + static const T P[12] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00356165148914447278177), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0240235006148610849678), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0516699967278057976119), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0586603078706856245674), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0409960120868776180825), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0185485073689590665153), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00537842101034123222417), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000920988084778273760609), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.716742618812210980263e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.504623302166487346677e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.712662196671896837736e-10), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.533769629702262072175e-11) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.13286733695729715455), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.49281223045653491929), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.84900294427622911374), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.15205199043580378211), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.802912186540269232424), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.194793170017818925388), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0280128013584653182994), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00182034930799902922549) + }; + T t = z / 10 - 3; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + } + else + { + // Maximum Deviation Found: 3.536e-20 + // Max Error found at long double precision = Poly: 1.310671e-19 Cheb: 8.630943e-11 + + static const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.35385266837019985407899910749034804508871617254555467236651e17)); + static const T Y= 1.013065338134765625F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0130653381347656250004), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.644487780349757303739), + BOOST_MATH_BIG_CONSTANT(T, 64, 143.995670348227433964), + BOOST_MATH_BIG_CONSTANT(T, 64, -13918.9322758014173709), + BOOST_MATH_BIG_CONSTANT(T, 64, 476260.975133624194484), + BOOST_MATH_BIG_CONSTANT(T, 64, -7437102.15135982802122), + BOOST_MATH_BIG_CONSTANT(T, 64, 53732298.8764767916542), + BOOST_MATH_BIG_CONSTANT(T, 64, -160695051.957997452509), + BOOST_MATH_BIG_CONSTANT(T, 64, 137839271.592778020028) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 27.2103343964943718802), + BOOST_MATH_BIG_CONSTANT(T, 64, -8785.48528692879413676), + BOOST_MATH_BIG_CONSTANT(T, 64, 397530.290000322626766), + BOOST_MATH_BIG_CONSTANT(T, 64, -7356441.34957799368252), + BOOST_MATH_BIG_CONSTANT(T, 64, 63050914.5343400957524), + BOOST_MATH_BIG_CONSTANT(T, 64, -246143779.638307701369), + BOOST_MATH_BIG_CONSTANT(T, 64, 384647824.678554961174), + BOOST_MATH_BIG_CONSTANT(T, 64, -166288297.874583961493) + }; + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +void expint_i_imp_113a(T& result, const T& z, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 1.230e-36 + // Expected Error Term: -1.230e-36 + // Max Error found at long double precision = Poly: 4.355299e-34 Cheb: 7.512581e-34 + + + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 2.98677224343598593765287235997328555), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.333256034674702967028780537349334037), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.851831522798101228384971644036708463), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0657854833494646206186773614110374948), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0630065662557284456000060708977935073), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00311759191425309373327784154659649232), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00176213568201493949664478471656026771), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.491548660404172089488535218163952295e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.207764227621061706075562107748176592e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.225445398156913584846374273379402765e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.996939977231410319761273881672601592e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.212546902052178643330520878928100847e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.154646053060262871360159325115980023e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.143971277122049197323415503594302307e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.306243138978114692252817805327426657e-13) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -1.40178870313943798705491944989231793), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.943810968269701047641218856758605284), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.405026631534345064600850391026113165), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.123924153524614086482627660399122762), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0286364505373369439591132549624317707), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00516148845910606985396596845494015963), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000738330799456364820380739850924783649), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.843737760991856114061953265870882637e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.767957673431982543213661388914587589e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.549136847313854595809952100614840031e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.299801381513743676764008325949325404e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.118419479055346106118129130945423483e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.30372295663095470359211949045344607e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.382742953753485333207877784720070523e-12) + }; + + static const T c1 = BOOST_MATH_BIG_CONSTANT(T, 113, 1677624236387711.0); + static const T c2 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T c3 = BOOST_MATH_BIG_CONSTANT(T, 113, 266514582277687.0); + static const T c4 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T c5 = BOOST_MATH_BIG_CONSTANT(T, 113, 4503599627370496.0); + static const T r1 = c1 / c2; + static const T r2 = c3 / c4 / c5; + static const T r3 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.283806480836357377069325311780969887585024578164571984232357e-31)); + static const T r = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.372507410781366634461991866580119133535689497771654051555657435242200120636201854384926049951548942392)); + T t = (z / 3) - 1; + result = tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + t = ((z - r1) - r2) - r3; + result *= t; + if(fabs(t) < 0.1) + { + result += boost::math::log1p(t / r, pol); + } + else + { + result += log(z / r); + } +} + +template +void expint_i_113b(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 7.779e-36 + // Expected Error Term: -7.779e-36 + // Max Error found at long double precision = Poly: 2.576723e-35 Cheb: 1.236001e-34 + + static const T Y = 1.158985137939453125F; + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139324086199409049282472239613554817), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0338173111691991289178779840307998955), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0555972290794371306259684845277620556), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0378677976003456171563136909186202177), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0152221583517528358782902783914356667), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00428283334203873035104248217403126905), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000922782631491644846511553601323435286), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000155513428088853161562660696055496696), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.205756580255359882813545261519317096e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.220327406578552089820753181821115181e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.189483157545587592043421445645377439e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.122426571518570587750898968123803867e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.635187358949437991465353268374523944e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.203015132965870311935118337194860863e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.384276705503357655108096065452950822e-12) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.58784732785354597996617046880946257), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.18550755302279446339364262338114098), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.55598993549661368604527040349702836), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.184290888380564236919107835030984453), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0459658051803613282360464632326866113), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0089505064268613225167835599456014705), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139042673882987693424772855926289077), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000174210708041584097450805790176479012), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.176324034009707558089086875136647376e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.142935845999505649273084545313710581e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.907502324487057260675816233312747784e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.431044337808893270797934621235918418e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.139007266881450521776529705677086902e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234715286125516430792452741830364672e-11) + }; + T t = z / 2 - 4; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +void expint_i_113c(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 1.082e-34 + // Expected Error Term: 1.080e-34 + // Max Error found at long double precision = Poly: 1.958294e-34 Cheb: 2.472261e-34 + + + static const T Y = 1.091579437255859375F; + static const T P[17] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00685089599550151282724924894258520532), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0443313550253580053324487059748497467), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.071538561252424027443296958795814874), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0622923153354102682285444067843300583), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0361631270264607478205393775461208794), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0153192826839624850298106509601033261), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00496967904961260031539602977748408242), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126989079663425780800919171538920589), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000258933143097125199914724875206326698), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.422110326689204794443002330541441956e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.546004547590412661451073996127115221e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.546775260262202177131068692199272241e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.404157632825805803833379568956559215e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.200612596196561323832327013027419284e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.502538501472133913417609379765434153e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.326283053716799774936661568391296584e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.869226483473172853557775877908693647e-15) + }; + static const T Q[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.23227220874479061894038229141871087), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.40221000361027971895657505660959863), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.65476320985936174728238416007084214), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.816828602963895720369875535001248227), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.306337922909446903672123418670921066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0902400121654409267774593230720600752), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0212708882169429206498765100993228086), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00404442626252467471957713495828165491), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0006195601618842253612635241404054589), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.755930932686543009521454653994321843e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.716004532773778954193609582677482803e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500881663076471627699290821742924233e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233593219218823384508105943657387644e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.554900353169148897444104962034267682e-9) + }; + T t = z / 4 - 3.5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +void expint_i_113d(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 3.163e-35 + // Expected Error Term: 3.163e-35 + // Max Error found at long double precision = Poly: 4.158110e-35 Cheb: 5.385532e-35 + + static const T Y = 1.051731109619140625F; + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00144552494420652573815404828020593565), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0126747451594545338365684731262912741), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.01757394877502366717526779263438073), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0126838952395506921945756139424722588), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0060045057928894974954756789352443522), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00205349237147226126653803455793107903), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000532606040579654887676082220195624207), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000107344687098019891474772069139014662), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.169536802705805811859089949943435152e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.20863311729206543881826553010120078e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.195670358542116256713560296776654385e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.133291168587253145439184028259772437e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.595500337089495614285777067722823397e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.133141358866324100955927979606981328e-10) + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.72490783907582654629537013560044682), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.44524329516800613088375685659759765), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.778241785539308257585068744978050181), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.300520486589206605184097270225725584), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0879346899691339661394537806057953957), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0200802415843802892793583043470125006), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00362842049172586254520256100538273214), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000519731362862955132062751246769469957), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.584092147914050999895178697392282665e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.501851497707855358002773398333542337e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.313085677467921096644895738538865537e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.127552010539733113371132321521204458e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.25737310826983451144405899970774587e-9) + }; + T t = z / 4 - 5.5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +void expint_i_113e(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 7.972e-36 + // Expected Error Term: 7.962e-36 + // Max Error found at long double precision = Poly: 1.711721e-34 Cheb: 3.100018e-34 + + static const T Y = 1.032726287841796875F; + static const T P[15] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00141056919297307534690895009969373233), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0123384175302540291339020257071411437), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0298127270706864057791526083667396115), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0390686759471630584626293670260768098), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0338226792912607409822059922949035589), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0211659736179834946452561197559654582), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0100428887460879377373158821400070313), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00370717396015165148484022792801682932), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0010768667551001624764329000496561659), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000246127328761027039347584096573123531), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.437318110527818613580613051861991198e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.587532682329299591501065482317771497e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.565697065670893984610852937110819467e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.350233957364028523971768887437839573e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.105428907085424234504608142258423505e-8) + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.17261315255467581204685605414005525), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.85267952971640525245338392887217426), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.74341914912439861451492872946725151), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.31108463283559911602405970817931801), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.74657006336994649386607925179848899), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.718255607416072737965933040353653244), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234037553177354542791975767960643864), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0607470145906491602476833515412605389), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0125048143774226921434854172947548724), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00201034366420433762935768458656609163), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000244823338417452367656368849303165721), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.213511655166983177960471085462540807e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.119323998465870686327170541547982932e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.322153582559488797803027773591727565e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.161635525318683508633792845159942312e-16) + }; + T t = z / 8 - 4.25; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +void expint_i_113f(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 4.469e-36 + // Expected Error Term: 4.468e-36 + // Max Error found at long double precision = Poly: 1.288958e-35 Cheb: 2.304586e-35 + + static const T Y = 1.0216197967529296875F; + static const T P[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000322999116096627043476023926572650045), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00385606067447365187909164609294113346), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00686514524727568176735949971985244415), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00606260649593050194602676772589601799), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00334382362017147544335054575436194357), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126108534260253075708625583630318043), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000337881489347846058951220431209276776), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.648480902304640018785370650254018022e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.87652644082970492211455290209092766e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.794712243338068631557849449519994144e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.434084023639508143975983454830954835e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.107839681938752337160494412638656696e-8) + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.09913805456661084097134805151524958), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.07041755535439919593503171320431849), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.26406517226052371320416108604874734), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.529689923703770353961553223973435569), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.159578150879536711042269658656115746), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0351720877642000691155202082629857131), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00565313621289648752407123620997063122), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000646920278540515480093843570291218295), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.499904084850091676776993523323213591e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233740058688179614344680531486267142e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.498800627828842754845418576305379469e-7) + }; + T t = z / 7 - 7; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +void expint_i_113g(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 5.588e-35 + // Expected Error Term: -5.566e-35 + // Max Error found at long double precision = Poly: 9.976345e-35 Cheb: 8.358865e-35 + + static const T Y = 1.015148162841796875F; + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000435714784725086961464589957142615216), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00432114324353830636009453048419094314), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0100740363285526177522819204820582424), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0116744115827059174392383504427640362), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00816145387784261141360062395898644652), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00371380272673500791322744465394211508), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00112958263488611536502153195005736563), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000228316462389404645183269923754256664), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29462181955852860250359064291292577e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.21972450610957417963227028788460299e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.720558173805289167524715527536874694e-7) + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.95918362458402597039366979529287095), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.96472247520659077944638411856748924), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.15563251550528513747923714884142131), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.64674612007093983894215359287448334), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.58695020129846594405856226787156424), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.144358385319329396231755457772362793), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.024146911506411684815134916238348063), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0026257132337460784266874572001650153), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000167479843750859222348869769094711093), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.475673638665358075556452220192497036e-5) + }; + T t = z / 14 - 5; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result *= exp(z) / z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) + result += z; + BOOST_MATH_INSTRUMENT_VARIABLE(result) +} + +template +void expint_i_113h(T& result, const T& z) +{ + BOOST_MATH_STD_USING + // Maximum Deviation Found: 4.448e-36 + // Expected Error Term: 4.445e-36 + // Max Error found at long double precision = Poly: 2.058532e-35 Cheb: 2.165465e-27 + + static const T Y= 1.00849151611328125F; + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0084915161132812500000001440233607358), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.84479378737716028341394223076147872), + BOOST_MATH_BIG_CONSTANT(T, 113, -130.431146923726715674081563022115568), + BOOST_MATH_BIG_CONSTANT(T, 113, 4336.26945491571504885214176203512015), + BOOST_MATH_BIG_CONSTANT(T, 113, -76279.0031974974730095170437591004177), + BOOST_MATH_BIG_CONSTANT(T, 113, 729577.956271997673695191455111727774), + BOOST_MATH_BIG_CONSTANT(T, 113, -3661928.69330208734947103004900349266), + BOOST_MATH_BIG_CONSTANT(T, 113, 8570600.041606912735872059184527855), + BOOST_MATH_BIG_CONSTANT(T, 113, -6758379.93672362080947905580906028645) + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -99.4868026047611434569541483506091713), + BOOST_MATH_BIG_CONSTANT(T, 113, 3879.67753690517114249705089803055473), + BOOST_MATH_BIG_CONSTANT(T, 113, -76495.82413252517165830203774900806), + BOOST_MATH_BIG_CONSTANT(T, 113, 820773.726408311894342553758526282667), + BOOST_MATH_BIG_CONSTANT(T, 113, -4803087.64956923577571031564909646579), + BOOST_MATH_BIG_CONSTANT(T, 113, 14521246.227703545012713173740895477), + BOOST_MATH_BIG_CONSTANT(T, 113, -19762752.0196769712258527849159393044), + BOOST_MATH_BIG_CONSTANT(T, 113, 8354144.67882768405803322344185185517), + BOOST_MATH_BIG_CONSTANT(T, 113, 355076.853106511136734454134915432571) + }; + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + result *= exp(z) / z; + result += z; +} + +template +T expint_i_imp(T z, const Policy& pol, const std::integral_constant& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::expint<%1%>(%1%)"; + if(z < 0) + return -expint_imp(1, T(-z), pol, tag); + if(z == 0) + return -policies::raise_overflow_error(function, nullptr, pol); + + T result; + + if(z <= 6) + { + expint_i_imp_113a(result, z, pol); + } + else if (z <= 10) + { + expint_i_113b(result, z); + } + else if(z <= 18) + { + expint_i_113c(result, z); + } + else if(z <= 26) + { + expint_i_113d(result, z); + } + else if(z <= 42) + { + expint_i_113e(result, z); + } + else if(z <= 56) + { + expint_i_113f(result, z); + } + else if(z <= 84) + { + expint_i_113g(result, z); + } + else if(z <= 210) + { + expint_i_113h(result, z); + } + else // z > 210 + { + // Maximum Deviation Found: 3.963e-37 + // Expected Error Term: 3.963e-37 + // Max Error found at long double precision = Poly: 1.248049e-36 Cheb: 2.843486e-29 + + static const T exp40 = static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2.35385266837019985407899910749034804508871617254555467236651e17)); + static const T Y= 1.00252532958984375F; + static const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00252532958984375000000000000000000085), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.16591386866059087390621952073890359), + BOOST_MATH_BIG_CONSTANT(T, 113, -67.8483431314018462417456828499277579), + BOOST_MATH_BIG_CONSTANT(T, 113, 1567.68688154683822956359536287575892), + BOOST_MATH_BIG_CONSTANT(T, 113, -17335.4683325819116482498725687644986), + BOOST_MATH_BIG_CONSTANT(T, 113, 93632.6567462673524739954389166550069), + BOOST_MATH_BIG_CONSTANT(T, 113, -225025.189335919133214440347510936787), + BOOST_MATH_BIG_CONSTANT(T, 113, 175864.614717440010942804684741336853) + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -65.6998869881600212224652719706425129), + BOOST_MATH_BIG_CONSTANT(T, 113, 1642.73850032324014781607859416890077), + BOOST_MATH_BIG_CONSTANT(T, 113, -19937.2610222467322481947237312818575), + BOOST_MATH_BIG_CONSTANT(T, 113, 124136.267326632742667972126625064538), + BOOST_MATH_BIG_CONSTANT(T, 113, -384614.251466704550678760562965502293), + BOOST_MATH_BIG_CONSTANT(T, 113, 523355.035910385688578278384032026998), + BOOST_MATH_BIG_CONSTANT(T, 113, -217809.552260834025885677791936351294), + BOOST_MATH_BIG_CONSTANT(T, 113, -8555.81719551123640677261226549550872) + }; + T t = 1 / z; + result = Y + tools::evaluate_polynomial(P, t) + / tools::evaluate_polynomial(Q, t); + if(z < 41) + result *= exp(z) / z; + else + { + // Avoid premature overflow if we can: + t = z - 40; + if(t > tools::log_max_value()) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp(z - 40) / z; + if(result > tools::max_value() / exp40) + { + result = policies::raise_overflow_error(function, nullptr, pol); + } + else + { + result *= exp40; + } + } + } + result += z; + } + return result; +} + +template +struct expint_i_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + boost::math::expint(T(5), Policy()); + boost::math::expint(T(7), Policy()); + boost::math::expint(T(18), Policy()); + boost::math::expint(T(38), Policy()); + boost::math::expint(T(45), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::expint(T(5), Policy()); + boost::math::expint(T(7), Policy()); + boost::math::expint(T(18), Policy()); + boost::math::expint(T(38), Policy()); + boost::math::expint(T(45), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::expint(T(5), Policy()); + boost::math::expint(T(7), Policy()); + boost::math::expint(T(17), Policy()); + boost::math::expint(T(25), Policy()); + boost::math::expint(T(40), Policy()); + boost::math::expint(T(50), Policy()); + boost::math::expint(T(80), Policy()); + boost::math::expint(T(200), Policy()); + boost::math::expint(T(220), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename expint_i_initializer::init expint_i_initializer::initializer; + +template +struct expint_1_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + boost::math::expint(1, T(0.5), Policy()); + boost::math::expint(1, T(2), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::expint(1, T(0.5), Policy()); + boost::math::expint(1, T(2), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::expint(1, T(0.5), Policy()); + boost::math::expint(1, T(2), Policy()); + boost::math::expint(1, T(6), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename expint_1_initializer::init expint_1_initializer::initializer; + +template +inline typename tools::promote_args::type + expint_forwarder(T z, const Policy& /*pol*/, std::true_type const&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef std::integral_constant tag_type; + + expint_i_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::expint_i_imp( + static_cast(z), + forwarding_policy(), + tag_type()), "boost::math::expint<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type +expint_forwarder(unsigned n, T z, const std::false_type&) +{ + return boost::math::expint(n, z, policies::policy<>()); +} + +} // namespace detail + +template +inline typename tools::promote_args::type + expint(unsigned n, T z, const Policy& /*pol*/) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef std::integral_constant tag_type; + + detail::expint_1_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::expint_imp( + n, + static_cast(z), + forwarding_policy(), + tag_type()), "boost::math::expint<%1%>(unsigned, %1%)"); +} + +template +inline typename detail::expint_result::type + expint(T const z, U const u) +{ + typedef typename policies::is_policy::type tag_type; + return detail::expint_forwarder(z, u, tag_type()); +} + +template +inline typename tools::promote_args::type + expint(T z) +{ + return expint(z, policies::policy<>()); +} + +}} // namespaces + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_EXPINT_HPP + + diff --git a/libcxx/src/third-party/boost/math/special_functions/expm1.hpp b/libcxx/src/third-party/boost/math/special_functions/expm1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/expm1.hpp @@ -0,0 +1,320 @@ +// (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_EXPM1_INCLUDED +#define BOOST_MATH_EXPM1_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +namespace detail +{ + // Functor expm1_series returns the next term in the Taylor series + // x^k / k! + // each time that operator() is invoked. + // + template + struct expm1_series + { + typedef T result_type; + + expm1_series(T x) + : k(0), m_x(x), m_term(1) {} + + T operator()() + { + ++k; + m_term *= m_x; + m_term /= k; + return m_term; + } + + int count()const + { + return k; + } + + private: + int k; + const T m_x; + T m_term; + expm1_series(const expm1_series&) = delete; + expm1_series& operator=(const expm1_series&) = delete; + }; + +template +struct expm1_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + template + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + expm1(T(0.5)); + } + static void do_init(const std::integral_constant&) + { + expm1(T(0.5)); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename expm1_initializer::init expm1_initializer::initializer; + +// +// Algorithm expm1 is part of C99, but is not yet provided by many compilers. +// +// This version uses a Taylor series expansion for 0.5 > |x| > epsilon. +// +template +T expm1_imp(T x, const std::integral_constant&, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T a = fabs(x); + if((boost::math::isnan)(a)) + { + return policies::raise_domain_error("boost::math::expm1<%1%>(%1%)", "expm1 requires a finite argument, but got %1%", a, pol); + } + if(a > T(0.5f)) + { + if(a >= tools::log_max_value()) + { + if(x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if(a < tools::epsilon()) + return x; + detail::expm1_series s(x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations("boost::math::expm1<%1%>(%1%)", max_iter, pol); + return result; +} + +template +T expm1_imp(T x, const std::integral_constant&, const P& pol) +{ + BOOST_MATH_STD_USING + + T a = fabs(x); + if(a > T(0.5L)) + { + if(a >= tools::log_max_value()) + { + if(x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if(a < tools::epsilon()) + return x; + + static const float Y = 0.10281276702880859e1f; + static const T n[] = { static_cast(-0.28127670288085937e-1), static_cast(0.51278186299064534e0), static_cast(-0.6310029069350198e-1), static_cast(0.11638457975729296e-1), static_cast(-0.52143390687521003e-3), static_cast(0.21491399776965688e-4) }; + static const T d[] = { 1, static_cast(-0.45442309511354755e0), static_cast(0.90850389570911714e-1), static_cast(-0.10088963629815502e-1), static_cast(0.63003407478692265e-3), static_cast(-0.17976570003654402e-4) }; + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; +} + +template +T expm1_imp(T x, const std::integral_constant&, const P& pol) +{ + BOOST_MATH_STD_USING + + T a = fabs(x); + if(a > T(0.5L)) + { + if(a >= tools::log_max_value()) + { + if(x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if(a < tools::epsilon()) + return x; + + static const float Y = 0.10281276702880859375e1f; + static const T n[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.281276702880859375e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.512980290285154286358e0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.667758794592881019644e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.131432469658444745835e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.72303795326880286965e-3), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.447441185192951335042e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.714539134024984593011e-6) + }; + static const T d[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.461477618025562520389e0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.961237488025708540713e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.116483957658204450739e-1), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.873308008461557544458e-3), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.387922804997682392562e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.807473180049193557294e-6) + }; + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; +} + +template +T expm1_imp(T x, const std::integral_constant&, const P& pol) +{ + BOOST_MATH_STD_USING + + T a = fabs(x); + if(a > T(0.5L)) + { + if(a >= tools::log_max_value()) + { + if(x > 0) + return policies::raise_overflow_error("boost::math::expm1<%1%>(%1%)", nullptr, pol); + return -1; + } + return exp(x) - T(1); + } + if(a < tools::epsilon()) + return x; + + static const float Y = 0.10281276702880859375e1f; + static const T n[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.28127670288085937499999999999999999854e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.51278156911210477556524452177540792214e0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.63263178520747096729500254678819588223e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14703285606874250425508446801230572252e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.8675686051689527802425310407898459386e-3), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.88126359618291165384647080266133492399e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.25963087867706310844432390015463138953e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.14226691087800461778631773363204081194e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.15995603306536496772374181066765665596e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.45261820069007790520447958280473183582e-10) + }; + static const T d[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.45441264709074310514348137469214538853e0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.96827131936192217313133611655555298106e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.12745248725908178612540554584374876219e-1), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.11473613871583259821612766907781095472e-2), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.73704168477258911962046591907690764416e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.34087499397791555759285503797256103259e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.11114024704296196166272091230695179724e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.23987051614110848595909588343223896577e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.29477341859111589208776402638429026517e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.13222065991022301420255904060628100924e-12) + }; + + T result = x * Y + x * tools::evaluate_polynomial(n, x) / tools::evaluate_polynomial(d, x); + return result; +} + +} // namespace detail + +template +inline typename tools::promote_args::type expm1(T x, const Policy& /* pol */) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef std::integral_constant tag_type; + + detail::expm1_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::expm1_imp( + static_cast(x), + tag_type(), forwarding_policy()), "boost::math::expm1<%1%>(%1%)"); +} + +#ifdef expm1 +# ifndef BOOST_HAS_expm1 +# define BOOST_HAS_expm1 +# endif +# undef expm1 +#endif + +#if defined(BOOST_HAS_EXPM1) && !(defined(__osf__) && defined(__DECCXX_VER)) +# ifdef BOOST_MATH_USE_C99 +inline float expm1(float x, const policies::policy<>&){ return ::expm1f(x); } +# ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline long double expm1(long double x, const policies::policy<>&){ return ::expm1l(x); } +# endif +# else +inline float expm1(float x, const policies::policy<>&){ return static_cast(::expm1(x)); } +# endif +inline double expm1(double x, const policies::policy<>&){ return ::expm1(x); } +#endif + +template +inline typename tools::promote_args::type expm1(T x) +{ + return expm1(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HYPOT_INCLUDED + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/factorials.hpp b/libcxx/src/third-party/boost/math/special_functions/factorials.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/factorials.hpp @@ -0,0 +1,269 @@ +// Copyright John Maddock 2006, 2010. +// 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_SP_FACTORIALS_HPP +#define BOOST_MATH_SP_FACTORIALS_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#ifdef _MSC_VER +#pragma warning(push) // Temporary until lexical cast fixed. +#pragma warning(disable: 4127 4701) +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif +#include +#include + +namespace boost { namespace math +{ + +template +inline T factorial(unsigned i, const Policy& pol) +{ + static_assert(!std::is_integral::value, "Type T must not be an integral type"); + // factorial(n) is not implemented + // because it would overflow integral type T for too small n + // to be useful. Use instead a floating-point type, + // and convert to an unsigned type if essential, for example: + // unsigned int nfac = static_cast(factorial(n)); + // See factorial documentation for more detail. + + BOOST_MATH_STD_USING // Aid ADL for floor. + + if(i <= max_factorial::value) + return unchecked_factorial(i); + T result = boost::math::tgamma(static_cast(i+1), pol); + if(result > tools::max_value()) + return result; // Overflowed value! (But tgamma will have signalled the error already). + return floor(result + 0.5f); +} + +template +inline T factorial(unsigned i) +{ + return factorial(i, policies::policy<>()); +} +/* +// Can't have these in a policy enabled world? +template<> +inline float factorial(unsigned i) +{ + if(i <= max_factorial::value) + return unchecked_factorial(i); + return tools::overflow_error(BOOST_CURRENT_FUNCTION); +} + +template<> +inline double factorial(unsigned i) +{ + if(i <= max_factorial::value) + return unchecked_factorial(i); + return tools::overflow_error(BOOST_CURRENT_FUNCTION); +} +*/ +template +T double_factorial(unsigned i, const Policy& pol) +{ + static_assert(!std::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING // ADL lookup of std names + if(i & 1) + { + // odd i: + if(i < max_factorial::value) + { + unsigned n = (i - 1) / 2; + return ceil(unchecked_factorial(i) / (ldexp(T(1), (int)n) * unchecked_factorial(n)) - 0.5f); + } + // + // Fallthrough: i is too large to use table lookup, try the + // gamma function instead. + // + T result = boost::math::tgamma(static_cast(i) / 2 + 1, pol) / sqrt(constants::pi()); + if(ldexp(tools::max_value(), -static_cast(i+1) / 2) > result) + return ceil(result * ldexp(T(1), static_cast(i+1) / 2) - 0.5f); + } + else + { + // even i: + unsigned n = i / 2; + T result = factorial(n, pol); + if(ldexp(tools::max_value(), -(int)n) > result) + return result * ldexp(T(1), (int)n); + } + // + // If we fall through to here then the result is infinite: + // + return policies::raise_overflow_error("boost::math::double_factorial<%1%>(unsigned)", 0, pol); +} + +template +inline T double_factorial(unsigned i) +{ + return double_factorial(i, policies::policy<>()); +} + +namespace detail{ + +template +T rising_factorial_imp(T x, int n, const Policy& pol) +{ + static_assert(!std::is_integral::value, "Type T must not be an integral type"); + if(x < 0) + { + // + // For x less than zero, we really have a falling + // factorial, modulo a possible change of sign. + // + // Note that the falling factorial isn't defined + // for negative n, so we'll get rid of that case + // first: + // + bool inv = false; + if(n < 0) + { + x += n; + n = -n; + inv = true; + } + T result = ((n&1) ? -1 : 1) * falling_factorial(-x, n, pol); + if(inv) + result = 1 / result; + return result; + } + if(n == 0) + return 1; + if(x == 0) + { + if(n < 0) + return -boost::math::tgamma_delta_ratio(x + 1, static_cast(-n), pol); + else + return 0; + } + if((x < 1) && (x + n < 0)) + { + T val = boost::math::tgamma_delta_ratio(1 - x, static_cast(-n), pol); + return (n & 1) ? T(-val) : val; + } + // + // We don't optimise this for small n, because + // tgamma_delta_ratio is already optimised for that + // use case: + // + return 1 / boost::math::tgamma_delta_ratio(x, static_cast(n), pol); +} + +template +inline T falling_factorial_imp(T x, unsigned n, const Policy& pol) +{ + static_assert(!std::is_integral::value, "Type T must not be an integral type"); + BOOST_MATH_STD_USING // ADL of std names + if(x == 0) + return 0; + if(x < 0) + { + // + // For x < 0 we really have a rising factorial + // modulo a possible change of sign: + // + return (n&1 ? -1 : 1) * rising_factorial(-x, n, pol); + } + if(n == 0) + return 1; + if(x < 0.5f) + { + // + // 1 + x below will throw away digits, so split up calculation: + // + if(n > max_factorial::value - 2) + { + // If the two end of the range are far apart we have a ratio of two very large + // numbers, split the calculation up into two blocks: + T t1 = x * boost::math::falling_factorial(x - 1, max_factorial::value - 2, pol); + T t2 = boost::math::falling_factorial(x - max_factorial::value + 1, n - max_factorial::value + 1, pol); + if(tools::max_value() / fabs(t1) < fabs(t2)) + return boost::math::sign(t1) * boost::math::sign(t2) * policies::raise_overflow_error("boost::math::falling_factorial<%1%>", 0, pol); + return t1 * t2; + } + return x * boost::math::falling_factorial(x - 1, n - 1, pol); + } + if(x <= n - 1) + { + // + // x+1-n will be negative and tgamma_delta_ratio won't + // handle it, split the product up into three parts: + // + T xp1 = x + 1; + unsigned n2 = itrunc((T)floor(xp1), pol); + if(n2 == xp1) + return 0; + T result = boost::math::tgamma_delta_ratio(xp1, -static_cast(n2), pol); + x -= n2; + result *= x; + ++n2; + if(n2 < n) + result *= falling_factorial(x - 1, n - n2, pol); + return result; + } + // + // Simple case: just the ratio of two + // (positive argument) gamma functions. + // Note that we don't optimise this for small n, + // because tgamma_delta_ratio is already optimised + // for that use case: + // + return boost::math::tgamma_delta_ratio(x + 1, -static_cast(n), pol); +} + +} // namespace detail + +template +inline typename tools::promote_args::type + falling_factorial(RT x, unsigned n) +{ + typedef typename tools::promote_args::type result_type; + return detail::falling_factorial_imp( + static_cast(x), n, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + falling_factorial(RT x, unsigned n, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::falling_factorial_imp( + static_cast(x), n, pol); +} + +template +inline typename tools::promote_args::type + rising_factorial(RT x, int n) +{ + typedef typename tools::promote_args::type result_type; + return detail::rising_factorial_imp( + static_cast(x), n, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + rising_factorial(RT x, int n, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::rising_factorial_imp( + static_cast(x), n, pol); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SP_FACTORIALS_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/fibonacci.hpp b/libcxx/src/third-party/boost/math/special_functions/fibonacci.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/fibonacci.hpp @@ -0,0 +1,92 @@ +// Copyright 2020, Madhur Chauhan + +// 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_FIBO_HPP +#define BOOST_MATH_SPECIAL_FIBO_HPP + +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost { +namespace math { + +namespace detail { + constexpr double fib_bits_phi = 0.69424191363061730173879026; + constexpr double fib_bits_deno = 1.1609640474436811739351597; +} // namespace detail + +template +inline BOOST_CXX14_CONSTEXPR T unchecked_fibonacci(unsigned long long n) noexcept(std::is_fundamental::value) { + // This function is called by the rest and computes the actual nth fibonacci number + // First few fibonacci numbers: 0 (0th), 1 (1st), 1 (2nd), 2 (3rd), ... + if (n <= 2) return n == 0 ? 0 : 1; + /* + * This is based on the following identities by Dijkstra: + * F(2*n) = F(n)^2 + F(n+1)^2 + * F(2*n+1) = (2 * F(n) + F(n+1)) * F(n+1) + * The implementation is iterative and is unrolled version of trivial recursive implementation. + */ + unsigned long long mask = 1; + for (int ct = 1; ct != std::numeric_limits::digits && (mask << 1) <= n; ++ct, mask <<= 1) + ; + T a{1}, b{1}; + for (mask >>= 1; mask; mask >>= 1) { + T t1 = a * a; + a = 2 * a * b - t1, b = b * b + t1; + if (mask & n) + t1 = b, b = b + a, a = t1; // equivalent to: swap(a,b), b += a; + } + return a; +} + +template +T inline BOOST_CXX14_CONSTEXPR fibonacci(unsigned long long n, const Policy &pol) { + // check for overflow using approximation to binet's formula: F_n ~ phi^n / sqrt(5) + if (n > 20 && n * detail::fib_bits_phi - detail::fib_bits_deno > std::numeric_limits::digits) + return policies::raise_overflow_error("boost::math::fibonacci<%1%>(unsigned long long)", "Possible overflow detected.", pol); + return unchecked_fibonacci(n); +} + +template +T inline BOOST_CXX14_CONSTEXPR fibonacci(unsigned long long n) { + return fibonacci(n, policies::policy<>()); +} + +// generator for next fibonacci number (see examples/reciprocal_fibonacci_constant.hpp) +template +class fibonacci_generator { + public: + // return next fibonacci number + T operator()() noexcept(std::is_fundamental::value) { + T ret = a; + a = b, b = b + ret; // could've simply: swap(a, b), b += a; + return ret; + } + + // after set(nth), subsequent calls to the generator returns consecutive + // fibonacci numbers starting with the nth fibonacci number + void set(unsigned long long nth) noexcept(std::is_fundamental::value) { + n = nth; + a = unchecked_fibonacci(n); + b = unchecked_fibonacci(n + 1); + } + + private: + unsigned long long n = 0; + T a = 0, b = 1; +}; + +} // namespace math +} // namespace boost + +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/fpclassify.hpp b/libcxx/src/third-party/boost/math/special_functions/fpclassify.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/fpclassify.hpp @@ -0,0 +1,638 @@ +// Copyright John Maddock 2005-2008. +// Copyright (c) 2006-2008 Johan Rade +// 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_FPCLASSIFY_HPP +#define BOOST_MATH_FPCLASSIFY_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +/*! + \file fpclassify.hpp + \brief Classify floating-point value as normal, subnormal, zero, infinite, or NaN. + \version 1.0 + \author John Maddock + */ + +/* + +1. If the platform is C99 compliant, then the native floating point +classification functions are used. However, note that we must only +define the functions which call std::fpclassify etc if that function +really does exist: otherwise a compiler may reject the code even though +the template is never instantiated. + +2. If the platform is not C99 compliant, and the binary format for +a floating point type (float, double or long double) can be determined +at compile time, then the following algorithm is used: + + If all exponent bits, the flag bit (if there is one), + and all significand bits are 0, then the number is zero. + + If all exponent bits and the flag bit (if there is one) are 0, + and at least one significand bit is 1, then the number is subnormal. + + If all exponent bits are 1 and all significand bits are 0, + then the number is infinity. + + If all exponent bits are 1 and at least one significand bit is 1, + then the number is a not-a-number. + + Otherwise the number is normal. + + This algorithm works for the IEEE 754 representation, + and also for several non IEEE 754 formats. + + Most formats have the structure + sign bit + exponent bits + significand bits. + + A few have the structure + sign bit + exponent bits + flag bit + significand bits. + The flag bit is 0 for zero and subnormal numbers, + and 1 for normal numbers and NaN. + It is 0 (Motorola 68K) or 1 (Intel) for infinity. + + To get the bits, the four or eight most significant bytes are copied + into an uint32_t or uint64_t and bit masks are applied. + This covers all the exponent bits and the flag bit (if there is one), + but not always all the significand bits. + Some of the functions below have two implementations, + depending on whether all the significand bits are copied or not. + +3. If the platform is not C99 compliant, and the binary format for +a floating point type (float, double or long double) can not be determined +at compile time, then comparison with std::numeric_limits values +is used. + +*/ + +#if defined(_MSC_VER) || defined(BOOST_BORLANDC) +#include +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +#ifdef __has_include +#if __has_include("quadmath.h") +#include "quadmath.h" +#define BOOST_MATH_HAS_QUADMATH_H +#endif +#endif +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE + namespace std{ using ::abs; using ::fabs; } +#endif + +namespace boost{ + +// +// This must not be located in any namespace under boost::math +// otherwise we can get into an infinite loop if isnan is +// a #define for "isnan" ! +// +namespace math_detail{ + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4800) +#endif + +template +inline bool is_nan_helper(T t, const std::true_type&) +{ +#ifdef isnan + return isnan(t); +#elif defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) || !defined(BOOST_HAS_FPCLASSIFY) + (void)t; + return false; +#else // BOOST_HAS_FPCLASSIFY + return (BOOST_FPCLASSIFY_PREFIX fpclassify(t) == (int)FP_NAN); +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +inline bool is_nan_helper(T, const std::false_type&) +{ + return false; +} +#if defined(BOOST_MATH_USE_FLOAT128) +#if defined(BOOST_MATH_HAS_QUADMATH_H) +inline bool is_nan_helper(__float128 f, const std::true_type&) { return ::isnanq(f); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return ::isnanq(f); } +#elif defined(BOOST_GNU_STDLIB) && BOOST_GNU_STDLIB && \ + _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +inline bool is_nan_helper(__float128 f, const std::true_type&) { return std::isnan(static_cast(f)); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return std::isnan(static_cast(f)); } +#else +inline bool is_nan_helper(__float128 f, const std::true_type&) { return boost::math::isnan(static_cast(f)); } +inline bool is_nan_helper(__float128 f, const std::false_type&) { return boost::math::isnan(static_cast(f)); } +#endif +#endif +} + +namespace math{ + +namespace detail{ + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const native_tag&) +{ + return (std::fpclassify)(t); +} +#endif + +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) +{ + BOOST_MATH_INSTRUMENT_VARIABLE(t); + + // whenever possible check for Nan's first: +#if defined(BOOST_HAS_FPCLASSIFY) && !defined(BOOST_MATH_DISABLE_STD_FPCLASSIFY) + if(::boost::math_detail::is_nan_helper(t, typename std::is_floating_point::type())) + return FP_NAN; +#elif defined(isnan) + if(boost::math_detail::is_nan_helper(t, typename std::is_floating_point::type())) + return FP_NAN; +#elif defined(_MSC_VER) || defined(BOOST_BORLANDC) + if(::_isnan(boost::math::tools::real_cast(t))) + return FP_NAN; +#endif + // std::fabs broken on a few systems especially for long long!!!! + T at = (t < T(0)) ? -t : t; + + // Use a process of exclusion to figure out + // what kind of type we have, this relies on + // IEEE conforming reals that will treat + // Nan's as unordered. Some compilers + // don't do this once optimisations are + // turned on, hence the check for nan's above. + if(at <= (std::numeric_limits::max)()) + { + if(at >= (std::numeric_limits::min)()) + return FP_NORMAL; + return (at != 0) ? FP_SUBNORMAL : FP_ZERO; + } + else if(at > (std::numeric_limits::max)()) + return FP_INFINITE; + return FP_NAN; +} + +template +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(T t, const generic_tag&) +{ +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return fpclassify_imp(t, generic_tag()); +#endif + // + // An unknown type with no numeric_limits support, + // so what are we supposed to do we do here? + // + BOOST_MATH_INSTRUMENT_VARIABLE(t); + + return t == 0 ? FP_ZERO : FP_NORMAL; +} + +template +int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_all_bits_tag) +{ + typedef typename fp_traits::type traits; + + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + typename traits::bits a; + traits::get_bits(x,a); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + a &= traits::exponent | traits::flag | traits::significand; + BOOST_MATH_INSTRUMENT_VARIABLE((traits::exponent | traits::flag | traits::significand)); + BOOST_MATH_INSTRUMENT_VARIABLE(a); + + if(a <= traits::significand) { + if(a == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if(a < traits::exponent) return FP_NORMAL; + + a &= traits::significand; + if(a == 0) return FP_INFINITE; + + return FP_NAN; +} + +template +int fpclassify_imp BOOST_NO_MACRO_EXPAND(T x, ieee_copy_leading_bits_tag) +{ + typedef typename fp_traits::type traits; + + BOOST_MATH_INSTRUMENT_VARIABLE(x); + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::flag | traits::significand; + + if(a <= traits::significand) { + if(x == 0) + return FP_ZERO; + else + return FP_SUBNORMAL; + } + + if(a < traits::exponent) return FP_NORMAL; + + a &= traits::significand; + traits::set_bits(x,a); + if(x == 0) return FP_INFINITE; + + return FP_NAN; +} + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && (defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS)) +inline int fpclassify_imp BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::fpclassify_imp(t, generic_tag()); +} +#endif + +} // namespace detail + +template +inline int fpclassify BOOST_NO_MACRO_EXPAND(T t) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + typedef typename tools::promote_args_permissive::type value_type; +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(nullptr))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); +#else + return detail::fpclassify_imp(static_cast(t), method()); +#endif +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template <> +inline int fpclassify BOOST_NO_MACRO_EXPAND(long double t) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + typedef long double value_type; +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized && detail::is_generic_tag_false(static_cast(nullptr))) + return detail::fpclassify_imp(static_cast(t), detail::generic_tag()); + return detail::fpclassify_imp(static_cast(t), method()); +#else + return detail::fpclassify_imp(static_cast(t), method()); +#endif +} +#endif + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isfinite_impl(T x, native_tag const&) + { + return (std::isfinite)(x); + } +#endif + + template + inline bool isfinite_impl(T x, generic_tag const&) + { + return x >= -(std::numeric_limits::max)() + && x <= (std::numeric_limits::max)(); + } + + template + inline bool isfinite_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isfinite_impl(x, generic_tag()); +#endif + (void)x; // warning suppression. + return true; + } + + template + inline bool isfinite_impl(T x, ieee_tag const&) + { + typedef typename detail::fp_traits::type traits; + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent; + return a != traits::exponent; + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isfinite_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isfinite_impl(t, generic_tag()); +} +#endif + +} + +template +inline bool (isfinite)(T x) +{ //!< \brief return true if floating-point type t is finite. + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isfinite_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isfinite)(long double x) +{ //!< \brief return true if floating-point type t is finite. + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isfinite_impl(static_cast(x), method()); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isnormal_impl(T x, native_tag const&) + { + return (std::isnormal)(x); + } +#endif + + template + inline bool isnormal_impl(T x, generic_tag const&) + { + if(x < 0) x = -x; + return x >= (std::numeric_limits::min)() + && x <= (std::numeric_limits::max)(); + } + + template + inline bool isnormal_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isnormal_impl(x, generic_tag()); +#endif + return !(x == 0); + } + + template + inline bool isnormal_impl(T x, ieee_tag const&) + { + typedef typename detail::fp_traits::type traits; + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::flag; + return (a != 0) && (a < traits::exponent); + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isnormal_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isnormal_impl(t, generic_tag()); +} +#endif + +} + +template +inline bool (isnormal)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + //typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isnormal_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isnormal)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isnormal_impl(static_cast(x), method()); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isinf_impl(T x, native_tag const&) + { + return (std::isinf)(x); + } +#endif + + template + inline bool isinf_impl(T x, generic_tag const&) + { + (void)x; // in case the compiler thinks that x is unused because std::numeric_limits::has_infinity is false + return std::numeric_limits::has_infinity + && ( x == std::numeric_limits::infinity() + || x == -std::numeric_limits::infinity()); + } + + template + inline bool isinf_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isinf_impl(x, generic_tag()); +#endif + (void)x; // warning suppression. + return false; + } + + template + inline bool isinf_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + return a == traits::exponent; + } + + template + inline bool isinf_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + if(a != traits::exponent) + return false; + + traits::set_bits(x,0); + return x == 0; + } + +#if defined(BOOST_MATH_USE_STD_FPCLASSIFY) && defined(BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) +inline bool isinf_impl BOOST_NO_MACRO_EXPAND(long double t, const native_tag&) +{ + return boost::math::detail::isinf_impl(t, generic_tag()); +} +#endif + +} // namespace detail + +template +inline bool (isinf)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type value_type; + return detail::isinf_impl(static_cast(x), method()); +} + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template<> +inline bool (isinf)(long double x) +{ + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + typedef long double value_type; + return detail::isinf_impl(static_cast(x), method()); +} +#endif +#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H) +template<> +inline bool (isinf)(__float128 x) +{ + return ::isinfq(x); +} +#endif + +//------------------------------------------------------------------------------ + +namespace detail { + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline bool isnan_impl(T x, native_tag const&) + { + return (std::isnan)(x); + } +#endif + + template + inline bool isnan_impl(T x, generic_tag const&) + { + return std::numeric_limits::has_infinity + ? !(x <= std::numeric_limits::infinity()) + : x != x; + } + + template + inline bool isnan_impl(T x, generic_tag const&) + { +#ifdef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + if(std::numeric_limits::is_specialized) + return isnan_impl(x, generic_tag()); +#endif + (void)x; // warning suppression + return false; + } + + template + inline bool isnan_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a &= traits::exponent | traits::significand; + return a > traits::exponent; + } + + template + inline bool isnan_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + + a &= traits::exponent | traits::significand; + if(a < traits::exponent) + return false; + + a &= traits::significand; + traits::set_bits(x,a); + return x != 0; + } + +} // namespace detail + +template +inline bool (isnan)(T x) +{ //!< \brief return true if floating-point type t is NaN (Not A Number). + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + return detail::isnan_impl(x, method()); +} + +#ifdef isnan +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(float t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +template <> inline bool isnan BOOST_NO_MACRO_EXPAND(long double t){ return ::boost::math_detail::is_nan_helper(t, std::true_type()); } +#elif defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +template<> +inline bool (isnan)(long double x) +{ //!< \brief return true if floating-point type t is NaN (Not A Number). + typedef detail::fp_traits::type traits; + typedef traits::method method; + //typedef boost::is_floating_point::type fp_tag; + return detail::isnan_impl(x, method()); +} +#endif +#if defined(BOOST_MATH_USE_FLOAT128) && defined(BOOST_MATH_HAS_QUADMATH_H) +template<> +inline bool (isnan)(__float128 x) +{ + return ::isnanq(x); +} +#endif + +} // namespace math +} // namespace boost +#endif // BOOST_MATH_FPCLASSIFY_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/gamma.hpp b/libcxx/src/third-party/boost/math/special_functions/gamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/gamma.hpp @@ -0,0 +1,2218 @@ +// Copyright John Maddock 2006-7, 2013-20. +// Copyright Paul A. Bristow 2007, 2013-14. +// Copyright Nikhar Agrawal 2013-14 +// Copyright Christopher Kormanyos 2013-14, 2020 + +// 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_SF_GAMMA_HPP +#define BOOST_MATH_SF_GAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4702) // unreachable code (return after domain_error throw). +# pragma warning(disable: 4127) // conditional expression is constant. +# pragma warning(disable: 4100) // unreferenced formal parameter. +# pragma warning(disable: 6326) // potential comparison of a constant with another constant +// Several variables made comments, +// but some difficulty as whether referenced on not may depend on macro values. +// So to be safe, 4100 warnings suppressed. +// TODO - revisit this? +#endif + +namespace boost{ namespace math{ + +namespace detail{ + +template +inline bool is_odd(T v, const std::true_type&) +{ + int i = static_cast(v); + return i&1; +} +template +inline bool is_odd(T v, const std::false_type&) +{ + // Oh dear can't cast T to int! + BOOST_MATH_STD_USING + T modulus = v - 2 * floor(v/2); + return static_cast(modulus != 0); +} +template +inline bool is_odd(T v) +{ + return is_odd(v, ::std::is_convertible()); +} + +template +T sinpx(T z) +{ + // Ad hoc function calculates x * sin(pi * x), + // taking extra care near when x is near a whole number. + BOOST_MATH_STD_USING + int sign = 1; + if(z < 0) + { + z = -z; + } + T fl = floor(z); + T dist; + if(is_odd(fl)) + { + fl += 1; + dist = fl - z; + sign = -sign; + } + else + { + dist = z - fl; + } + BOOST_MATH_ASSERT(fl >= 0); + if(dist > 0.5) + dist = 1 - dist; + T result = sin(dist*boost::math::constants::pi()); + return sign*z*result; +} // template T sinpx(T z) +// +// tgamma(z), with Lanczos support: +// +template +T gamma_imp(T z, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + T result = 1; + +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if(!b) + { + std::cout << "tgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl; + b = true; + } +#endif + static const char* function = "boost::math::tgamma<%1%>(%1%)"; + + if(z <= 0) + { + if(floor(z) == z) + return policies::raise_pole_error(function, "Evaluation of tgamma at a negative integer %1%.", z, pol); + if(z <= -20) + { + result = gamma_imp(T(-z), pol, l) * sinpx(z); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if((fabs(result) < 1) && (tools::max_value() * fabs(result) < boost::math::constants::pi())) + return -boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + result = -boost::math::constants::pi() / result; + if(result == 0) + return policies::raise_underflow_error(function, "Result of tgamma is too small to represent.", pol); + if((boost::math::fpclassify)(result) == (int)FP_SUBNORMAL) + return policies::raise_denorm_error(function, "Result of tgamma is denormalized.", result, pol); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + return result; + } + + // shift z to > 1: + while(z < 0) + { + result /= z; + z += 1; + } + } + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if((floor(z) == z) && (z < max_factorial::value)) + { + result *= unchecked_factorial(itrunc(z, pol) - 1); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else if (z < tools::root_epsilon()) + { + if (z < 1 / tools::max_value()) + result = policies::raise_overflow_error(function, nullptr, pol); + result *= 1 / z - constants::euler(); + } + else + { + result *= Lanczos::lanczos_sum(z); + T zgh = (z + static_cast(Lanczos::g()) - boost::math::constants::half()); + T lzgh = log(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + BOOST_MATH_INSTRUMENT_VARIABLE(tools::log_max_value()); + if(z * lzgh > tools::log_max_value()) + { + // we're going to overflow unless this is done with care: + BOOST_MATH_INSTRUMENT_VARIABLE(zgh); + if(lzgh * z / 2 > tools::log_max_value()) + return boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + T hp = pow(zgh, (z / 2) - T(0.25)); + BOOST_MATH_INSTRUMENT_VARIABLE(hp); + result *= hp / exp(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + if(tools::max_value() / hp < result) + return boost::math::sign(result) * policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + result *= hp; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + else + { + BOOST_MATH_INSTRUMENT_VARIABLE(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(pow(zgh, z - boost::math::constants::half())); + BOOST_MATH_INSTRUMENT_VARIABLE(exp(zgh)); + result *= pow(zgh, z - boost::math::constants::half()) / exp(zgh); + BOOST_MATH_INSTRUMENT_VARIABLE(result); + } + } + return result; +} +// +// lgamma(z) with Lanczos support: +// +template +T lgamma_imp(T z, const Policy& pol, const Lanczos& l, int* sign = nullptr) +{ +#ifdef BOOST_MATH_INSTRUMENT + static bool b = false; + if(!b) + { + std::cout << "lgamma_imp called with " << typeid(z).name() << " " << typeid(l).name() << std::endl; + b = true; + } +#endif + + BOOST_MATH_STD_USING + + static const char* function = "boost::math::lgamma<%1%>(%1%)"; + + T result = 0; + int sresult = 1; + if(z <= -tools::root_epsilon()) + { + // reflection formula: + if(floor(z) == z) + return policies::raise_pole_error(function, "Evaluation of lgamma at a negative integer %1%.", z, pol); + + T t = sinpx(z); + z = -z; + if(t < 0) + { + t = -t; + } + else + { + sresult = -sresult; + } + result = log(boost::math::constants::pi()) - lgamma_imp(z, pol, l) - log(t); + } + else if (z < tools::root_epsilon()) + { + if (0 == z) + return policies::raise_pole_error(function, "Evaluation of lgamma at %1%.", z, pol); + if (4 * fabs(z) < tools::epsilon()) + result = -log(fabs(z)); + else + result = log(fabs(1 / z - constants::euler())); + if (z < 0) + sresult = -1; + } + else if(z < 15) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + result = lgamma_small_imp(z, T(z - 1), T(z - 2), tag_type(), pol, l); + } + else if((z >= 3) && (z < 100) && (std::numeric_limits::max_exponent >= 1024)) + { + // taking the log of tgamma reduces the error, no danger of overflow here: + result = log(gamma_imp(z, pol, l)); + } + else + { + // regular evaluation: + T zgh = static_cast(z + Lanczos::g() - boost::math::constants::half()); + result = log(zgh) - 1; + result *= z - 0.5f; + // + // Only add on the lanczos sum part if we're going to need it: + // + if(result * tools::epsilon() < 20) + result += log(Lanczos::lanczos_sum_expG_scaled(z)); + } + + if(sign) + *sign = sresult; + return result; +} + +// +// Incomplete gamma functions follow: +// +template +struct upper_incomplete_gamma_fract +{ +private: + T z, a; + int k; +public: + typedef std::pair result_type; + + upper_incomplete_gamma_fract(T a1, T z1) + : z(z1-a1+1), a(a1), k(0) + { + } + + result_type operator()() + { + ++k; + z += 2; + return result_type(k * (a - k), z); + } +}; + +template +inline T upper_gamma_fraction(T a, T z, T eps) +{ + // Multiply result by z^a * e^-z to get the full + // upper incomplete integral. Divide by tgamma(z) + // to normalise. + upper_incomplete_gamma_fract f(a, z); + return 1 / (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps)); +} + +template +struct lower_incomplete_gamma_series +{ +private: + T a, z, result; +public: + typedef T result_type; + lower_incomplete_gamma_series(T a1, T z1) : a(a1), z(z1), result(1){} + + T operator()() + { + T r = result; + a += 1; + result *= z/a; + return r; + } +}; + +template +inline T lower_gamma_series(T a, T z, const Policy& pol, T init_value = 0) +{ + // Multiply result by ((z^a) * (e^-z) / a) to get the full + // lower incomplete integral. Then divide by tgamma(a) + // to get the normalised value. + lower_incomplete_gamma_series s(a, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T factor = policies::get_epsilon(); + T result = boost::math::tools::sum_series(s, factor, max_iter, init_value); + policies::check_series_iterations("boost::math::detail::lower_gamma_series<%1%>(%1%)", max_iter, pol); + return result; +} + +// +// Fully generic tgamma and lgamma use Stirling's approximation +// with Bernoulli numbers. +// +template +std::size_t highest_bernoulli_index() +{ + const float digits10_of_type = (std::numeric_limits::is_specialized + ? static_cast(std::numeric_limits::digits10) + : static_cast(boost::math::tools::digits() * 0.301F)); + + // Find the high index n for Bn to produce the desired precision in Stirling's calculation. + return static_cast(18.0F + (0.6F * digits10_of_type)); +} + +template +int minimum_argument_for_bernoulli_recursion() +{ + BOOST_MATH_STD_USING + + const float digits10_of_type = (std::numeric_limits::is_specialized + ? (float) std::numeric_limits::digits10 + : (float) (boost::math::tools::digits() * 0.301F)); + + int min_arg = (int) (digits10_of_type * 1.7F); + + if(digits10_of_type < 50.0F) + { + // The following code sequence has been modified + // within the context of issue 396. + + // The calculation of the test-variable limit has now + // been protected against overflow/underflow dangers. + + // The previous line looked like this and did, in fact, + // underflow ldexp when using certain multiprecision types. + + // const float limit = std::ceil(std::pow(1.0f / std::ldexp(1.0f, 1-boost::math::tools::digits()), 1.0f / 20.0f)); + + // The new safe version of the limit check is now here. + const float d2_minus_one = ((digits10_of_type / 0.301F) - 1.0F); + const float limit = ceil(exp((d2_minus_one * log(2.0F)) / 20.0F)); + + min_arg = (int) ((std::min)(digits10_of_type * 1.7F, limit)); + } + + return min_arg; +} + +template +T scaled_tgamma_no_lanczos(const T& z, const Policy& pol, bool islog = false) +{ + BOOST_MATH_STD_USING + // + // Calculates tgamma(z) / (z/e)^z + // Requires that our argument is large enough for Sterling's approximation to hold. + // Used internally when combining gamma's of similar magnitude without logarithms. + // + BOOST_MATH_ASSERT(minimum_argument_for_bernoulli_recursion() <= z); + + // Perform the Bernoulli series expansion of Stirling's approximation. + + const std::size_t number_of_bernoullis_b2n = policies::get_max_series_iterations(); + + T one_over_x_pow_two_n_minus_one = 1 / z; + const T one_over_x2 = one_over_x_pow_two_n_minus_one * one_over_x_pow_two_n_minus_one; + T sum = (boost::math::bernoulli_b2n(1) / 2) * one_over_x_pow_two_n_minus_one; + const T target_epsilon_to_break_loop = sum * boost::math::tools::epsilon(); + const T half_ln_two_pi_over_z = sqrt(boost::math::constants::two_pi() / z); + T last_term = 2 * sum; + + for (std::size_t n = 2U;; ++n) + { + one_over_x_pow_two_n_minus_one *= one_over_x2; + + const std::size_t n2 = static_cast(n * 2U); + + const T term = (boost::math::bernoulli_b2n(static_cast(n)) * one_over_x_pow_two_n_minus_one) / (n2 * (n2 - 1U)); + + if ((n >= 3U) && (abs(term) < target_epsilon_to_break_loop)) + { + // We have reached the desired precision in Stirling's expansion. + // Adding additional terms to the sum of this divergent asymptotic + // expansion will not improve the result. + + // Break from the loop. + break; + } + if (n > number_of_bernoullis_b2n) + return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Exceeded maximum series iterations without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol); + + sum += term; + + // Sanity check for divergence: + T fterm = fabs(term); + if(fterm > last_term) + return policies::raise_evaluation_error("scaled_tgamma_no_lanczos<%1%>()", "Series became divergent without reaching convergence, best approximation was %1%", T(exp(sum) * half_ln_two_pi_over_z), pol); + last_term = fterm; + } + + // Complete Stirling's approximation. + T scaled_gamma_value = islog ? T(sum + log(half_ln_two_pi_over_z)) : T(exp(sum) * half_ln_two_pi_over_z); + return scaled_gamma_value; +} + +// Forward declaration of the lgamma_imp template specialization. +template +T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign = nullptr); + +template +T gamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&) +{ + BOOST_MATH_STD_USING + + static const char* function = "boost::math::tgamma<%1%>(%1%)"; + + // Check if the argument of tgamma is identically zero. + const bool is_at_zero = (z == 0); + + if((boost::math::isnan)(z) || (is_at_zero) || ((boost::math::isinf)(z) && (z < 0))) + return policies::raise_domain_error(function, "Evaluation of tgamma at %1%.", z, pol); + + const bool b_neg = (z < 0); + + const bool floor_of_z_is_equal_to_z = (floor(z) == z); + + // Special case handling of small factorials: + if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial::value)) + { + return boost::math::unchecked_factorial(itrunc(z) - 1); + } + + // Make a local, unsigned copy of the input argument. + T zz((!b_neg) ? z : -z); + + // Special case for ultra-small z: + if(zz < tools::cbrt_epsilon()) + { + const T a0(1); + const T a1(boost::math::constants::euler()); + const T six_euler_squared((boost::math::constants::euler() * boost::math::constants::euler()) * 6); + const T a2((six_euler_squared - boost::math::constants::pi_sqr()) / 12); + + const T inverse_tgamma_series = z * ((a2 * z + a1) * z + a0); + + return 1 / inverse_tgamma_series; + } + + // Scale the argument up for the calculation of lgamma, + // and use downward recursion later for the final result. + const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion(); + + int n_recur; + + if(zz < min_arg_for_recursion) + { + n_recur = boost::math::itrunc(min_arg_for_recursion - zz) + 1; + + zz += n_recur; + } + else + { + n_recur = 0; + } + if (!n_recur) + { + if (zz > tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + if (log(zz) * zz / 2 > tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + } + T gamma_value = scaled_tgamma_no_lanczos(zz, pol); + T power_term = pow(zz, zz / 2); + T exp_term = exp(-zz); + gamma_value *= (power_term * exp_term); + if(!n_recur && (tools::max_value() / power_term < gamma_value)) + return policies::raise_overflow_error(function, nullptr, pol); + gamma_value *= power_term; + + // Rescale the result using downward recursion if necessary. + if(n_recur) + { + // The order of divides is important, if we keep subtracting 1 from zz + // we DO NOT get back to z (cancellation error). Further if z < epsilon + // we would end up dividing by zero. Also in order to prevent spurious + // overflow with the first division, we must save dividing by |z| till last, + // so the optimal order of divides is z+1, z+2, z+3...z+n_recur-1,z. + zz = fabs(z) + 1; + for(int k = 1; k < n_recur; ++k) + { + gamma_value /= zz; + zz += 1; + } + gamma_value /= fabs(z); + } + + // Return the result, accounting for possible negative arguments. + if(b_neg) + { + // Provide special error analysis for: + // * arguments in the neighborhood of a negative integer + // * arguments exactly equal to a negative integer. + + // Check if the argument of tgamma is exactly equal to a negative integer. + if(floor_of_z_is_equal_to_z) + return policies::raise_pole_error(function, "Evaluation of tgamma at a negative integer %1%.", z, pol); + + gamma_value *= sinpx(z); + + BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value); + + const bool result_is_too_large_to_represent = ( (abs(gamma_value) < 1) + && ((tools::max_value() * abs(gamma_value)) < boost::math::constants::pi())); + + if(result_is_too_large_to_represent) + return policies::raise_overflow_error(function, "Result of tgamma is too large to represent.", pol); + + gamma_value = -boost::math::constants::pi() / gamma_value; + BOOST_MATH_INSTRUMENT_VARIABLE(gamma_value); + + if(gamma_value == 0) + return policies::raise_underflow_error(function, "Result of tgamma is too small to represent.", pol); + + if((boost::math::fpclassify)(gamma_value) == static_cast(FP_SUBNORMAL)) + return policies::raise_denorm_error(function, "Result of tgamma is denormalized.", gamma_value, pol); + } + + return gamma_value; +} + +template +inline T log_gamma_near_1(const T& z, Policy const& pol) +{ + // + // This is for the multiprecision case where there is + // no lanczos support, use a taylor series at z = 1, + // see https://www.wolframalpha.com/input/?i=taylor+series+lgamma(x)+at+x+%3D+1 + // + BOOST_MATH_STD_USING // ADL of std names + + BOOST_MATH_ASSERT(fabs(z) < 1); + + T result = -constants::euler() * z; + + T power_term = z * z / 2; + int n = 2; + T term = 0; + + do + { + term = power_term * boost::math::polygamma(n - 1, T(1), pol); + result += term; + ++n; + power_term *= z / n; + } while (fabs(result) * tools::epsilon() < fabs(term)); + + return result; +} + +template +T lgamma_imp(T z, const Policy& pol, const lanczos::undefined_lanczos&, int* sign) +{ + BOOST_MATH_STD_USING + + static const char* function = "boost::math::lgamma<%1%>(%1%)"; + + // Check if the argument of lgamma is identically zero. + const bool is_at_zero = (z == 0); + + if(is_at_zero) + return policies::raise_domain_error(function, "Evaluation of lgamma at zero %1%.", z, pol); + if((boost::math::isnan)(z)) + return policies::raise_domain_error(function, "Evaluation of lgamma at %1%.", z, pol); + if((boost::math::isinf)(z)) + return policies::raise_overflow_error(function, nullptr, pol); + + const bool b_neg = (z < 0); + + const bool floor_of_z_is_equal_to_z = (floor(z) == z); + + // Special case handling of small factorials: + if((!b_neg) && floor_of_z_is_equal_to_z && (z < boost::math::max_factorial::value)) + { + if (sign) + *sign = 1; + return log(boost::math::unchecked_factorial(itrunc(z) - 1)); + } + + // Make a local, unsigned copy of the input argument. + T zz((!b_neg) ? z : -z); + + const int min_arg_for_recursion = minimum_argument_for_bernoulli_recursion(); + + T log_gamma_value; + + if (zz < min_arg_for_recursion) + { + // Here we simply take the logarithm of tgamma(). This is somewhat + // inefficient, but simple. The rationale is that the argument here + // is relatively small and overflow is not expected to be likely. + if (sign) + * sign = 1; + if(fabs(z - 1) < 0.25) + { + log_gamma_value = log_gamma_near_1(T(zz - 1), pol); + } + else if(fabs(z - 2) < 0.25) + { + log_gamma_value = log_gamma_near_1(T(zz - 2), pol) + log(zz - 1); + } + else if (z > -tools::root_epsilon()) + { + // Reflection formula may fail if z is very close to zero, let the series + // expansion for tgamma close to zero do the work: + if (sign) + *sign = z < 0 ? -1 : 1; + return log(abs(gamma_imp(z, pol, lanczos::undefined_lanczos()))); + } + else + { + // No issue with spurious overflow in reflection formula, + // just fall through to regular code: + T g = gamma_imp(zz, pol, lanczos::undefined_lanczos()); + if (sign) + { + *sign = g < 0 ? -1 : 1; + } + log_gamma_value = log(abs(g)); + } + } + else + { + // Perform the Bernoulli series expansion of Stirling's approximation. + T sum = scaled_tgamma_no_lanczos(zz, pol, true); + log_gamma_value = zz * (log(zz) - 1) + sum; + } + + int sign_of_result = 1; + + if(b_neg) + { + // Provide special error analysis if the argument is exactly + // equal to a negative integer. + + // Check if the argument of lgamma is exactly equal to a negative integer. + if(floor_of_z_is_equal_to_z) + return policies::raise_pole_error(function, "Evaluation of lgamma at a negative integer %1%.", z, pol); + + T t = sinpx(z); + + if(t < 0) + { + t = -t; + } + else + { + sign_of_result = -sign_of_result; + } + + log_gamma_value = - log_gamma_value + + log(boost::math::constants::pi()) + - log(t); + } + + if(sign != static_cast(nullptr)) { *sign = sign_of_result; } + + return log_gamma_value; +} + +// +// This helper calculates tgamma(dz+1)-1 without cancellation errors, +// used by the upper incomplete gamma with z < 1: +// +template +T tgammap1m1_imp(T dz, Policy const& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + + typedef typename policies::precision::type precision_type; + + typedef std::integral_constant tag_type; + + T result; + if(dz < 0) + { + if(dz < -0.5) + { + // Best method is simply to subtract 1 from tgamma: + result = boost::math::tgamma(1+dz, pol) - 1; + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // Use expm1 on lgamma: + result = boost::math::expm1(-boost::math::log1p(dz, pol) + + lgamma_small_imp(dz+2, dz + 1, dz, tag_type(), pol, l), pol); + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + else + { + if(dz < 2) + { + // Use expm1 on lgamma: + result = boost::math::expm1(lgamma_small_imp(dz+1, dz, dz-1, tag_type(), pol, l), pol); + BOOST_MATH_INSTRUMENT_CODE(result); + } + else + { + // Best method is simply to subtract 1 from tgamma: + result = boost::math::tgamma(1+dz, pol) - 1; + BOOST_MATH_INSTRUMENT_CODE(result); + } + } + + return result; +} + +template +inline T tgammap1m1_imp(T z, Policy const& pol, + const ::boost::math::lanczos::undefined_lanczos&) +{ + BOOST_MATH_STD_USING // ADL of std names + + if(fabs(z) < 0.55) + { + return boost::math::expm1(log_gamma_near_1(z, pol)); + } + return boost::math::expm1(boost::math::lgamma(1 + z, pol)); +} + +// +// Series representation for upper fraction when z is small: +// +template +struct small_gamma2_series +{ + typedef T result_type; + + small_gamma2_series(T a_, T x_) : result(-x_), x(-x_), apn(a_+1), n(1){} + + T operator()() + { + T r = result / (apn); + result *= x; + result /= ++n; + apn += 1; + return r; + } + +private: + T result, x, apn; + int n; +}; +// +// calculate power term prefix (z^a)(e^-z) used in the non-normalised +// incomplete gammas: +// +template +T full_igamma_prefix(T a, T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + + T prefix; + if (z > tools::max_value()) + return 0; + T alz = a * log(z); + + if(z >= 1) + { + if((alz < tools::log_max_value()) && (-z > tools::log_min_value())) + { + prefix = pow(z, a) * exp(-z); + } + else if(a >= 1) + { + prefix = pow(z / exp(z/a), a); + } + else + { + prefix = exp(alz - z); + } + } + else + { + if(alz > tools::log_min_value()) + { + prefix = pow(z, a) * exp(-z); + } + else if(z/a < tools::log_max_value()) + { + prefix = pow(z / exp(z/a), a); + } + else + { + prefix = exp(alz - z); + } + } + // + // This error handling isn't very good: it happens after the fact + // rather than before it... + // + if((boost::math::fpclassify)(prefix) == (int)FP_INFINITE) + return policies::raise_overflow_error("boost::math::detail::full_igamma_prefix<%1%>(%1%, %1%)", "Result of incomplete gamma function is too large to represent.", pol); + + return prefix; +} +// +// Compute (z^a)(e^-z)/tgamma(a) +// most if the error occurs in this function: +// +template +T regularised_gamma_prefix(T a, T z, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + if (z >= tools::max_value()) + return 0; + T agh = a + static_cast(Lanczos::g()) - T(0.5); + T prefix; + T d = ((z - a) - static_cast(Lanczos::g()) + T(0.5)) / agh; + + if(a < 1) + { + // + // We have to treat a < 1 as a special case because our Lanczos + // approximations are optimised against the factorials with a > 1, + // and for high precision types especially (128-bit reals for example) + // very small values of a can give rather erroneous results for gamma + // unless we do this: + // + // TODO: is this still required? Lanczos approx should be better now? + // + if(z <= tools::log_min_value()) + { + // Oh dear, have to use logs, should be free of cancellation errors though: + return exp(a * log(z) - z - lgamma_imp(a, pol, l)); + } + else + { + // direct calculation, no danger of overflow as gamma(a) < 1/a + // for small a. + return pow(z, a) * exp(-z) / gamma_imp(a, pol, l); + } + } + else if((fabs(d*d*a) <= 100) && (a > 150)) + { + // special case for large a and a ~ z. + prefix = a * boost::math::log1pmx(d, pol) + z * static_cast(0.5 - Lanczos::g()) / agh; + prefix = exp(prefix); + } + else + { + // + // general case. + // direct computation is most accurate, but use various fallbacks + // for different parts of the problem domain: + // + T alz = a * log(z / agh); + T amz = a - z; + if(((std::min)(alz, amz) <= tools::log_min_value()) || ((std::max)(alz, amz) >= tools::log_max_value())) + { + T amza = amz / a; + if(((std::min)(alz, amz)/2 > tools::log_min_value()) && ((std::max)(alz, amz)/2 < tools::log_max_value())) + { + // compute square root of the result and then square it: + T sq = pow(z / agh, a / 2) * exp(amz / 2); + prefix = sq * sq; + } + else if(((std::min)(alz, amz)/4 > tools::log_min_value()) && ((std::max)(alz, amz)/4 < tools::log_max_value()) && (z > a)) + { + // compute the 4th root of the result then square it twice: + T sq = pow(z / agh, a / 4) * exp(amz / 4); + prefix = sq * sq; + prefix *= prefix; + } + else if((amza > tools::log_min_value()) && (amza < tools::log_max_value())) + { + prefix = pow((z * exp(amza)) / agh, a); + } + else + { + prefix = exp(alz + amz); + } + } + else + { + prefix = pow(z / agh, a) * exp(amz); + } + } + prefix *= sqrt(agh / boost::math::constants::e()) / Lanczos::lanczos_sum_expG_scaled(a); + return prefix; +} +// +// And again, without Lanczos support: +// +template +T regularised_gamma_prefix(T a, T z, const Policy& pol, const lanczos::undefined_lanczos& l) +{ + BOOST_MATH_STD_USING + + if((a < 1) && (z < 1)) + { + // No overflow possible since the power terms tend to unity as a,z -> 0 + return pow(z, a) * exp(-z) / boost::math::tgamma(a, pol); + } + else if(a > minimum_argument_for_bernoulli_recursion()) + { + T scaled_gamma = scaled_tgamma_no_lanczos(a, pol); + T power_term = pow(z / a, a / 2); + T a_minus_z = a - z; + if ((0 == power_term) || (fabs(a_minus_z) > tools::log_max_value())) + { + // The result is probably zero, but we need to be sure: + return exp(a * log(z / a) + a_minus_z - log(scaled_gamma)); + } + return (power_term * exp(a_minus_z)) * (power_term / scaled_gamma); + } + else + { + // + // Usual case is to calculate the prefix at a+shift and recurse down + // to the value we want: + // + const int min_z = minimum_argument_for_bernoulli_recursion(); + long shift = 1 + ltrunc(min_z - a); + T result = regularised_gamma_prefix(T(a + shift), z, pol, l); + if (result != 0) + { + for (long i = 0; i < shift; ++i) + { + result /= z; + result *= a + i; + } + return result; + } + else + { + // + // We failed, most probably we have z << 1, try again, this time + // we calculate z^a e^-z / tgamma(a+shift), combining power terms + // as we go. And again recurse down to the result. + // + T scaled_gamma = scaled_tgamma_no_lanczos(T(a + shift), pol); + T power_term_1 = pow(z / (a + shift), a); + T power_term_2 = pow(a + shift, -shift); + T power_term_3 = exp(a + shift - z); + if ((0 == power_term_1) || (0 == power_term_2) || (0 == power_term_3) || (fabs(a + shift - z) > tools::log_max_value())) + { + // We have no test case that gets here, most likely the type T + // has a high precision but low exponent range: + return exp(a * log(z) - z - boost::math::lgamma(a, pol)); + } + result = power_term_1 * power_term_2 * power_term_3 / scaled_gamma; + for (long i = 0; i < shift; ++i) + { + result *= a + i; + } + return result; + } + } +} +// +// Upper gamma fraction for very small a: +// +template +inline T tgamma_small_upper_part(T a, T x, const Policy& pol, T* pgam = 0, bool invert = false, T* pderivative = 0) +{ + BOOST_MATH_STD_USING // ADL of std functions. + // + // Compute the full upper fraction (Q) when a is very small: + // + T result; + result = boost::math::tgamma1pm1(a, pol); + if(pgam) + *pgam = (result + 1) / a; + T p = boost::math::powm1(x, a, pol); + result -= p; + result /= a; + detail::small_gamma2_series s(a, x); + std::uintmax_t max_iter = policies::get_max_series_iterations() - 10; + p += 1; + if(pderivative) + *pderivative = p / (*pgam * exp(x)); + T init_value = invert ? *pgam : 0; + result = -p * tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter, (init_value - result) / p); + policies::check_series_iterations("boost::math::tgamma_small_upper_part<%1%>(%1%, %1%)", max_iter, pol); + if(invert) + result = -result; + return result; +} +// +// Upper gamma fraction for integer a: +// +template +inline T finite_gamma_q(T a, T x, Policy const& pol, T* pderivative = 0) +{ + // + // Calculates normalised Q when a is an integer: + // + BOOST_MATH_STD_USING + T e = exp(-x); + T sum = e; + if(sum != 0) + { + T term = sum; + for(unsigned n = 1; n < a; ++n) + { + term /= n; + term *= x; + sum += term; + } + } + if(pderivative) + { + *pderivative = e * pow(x, a) / boost::math::unchecked_factorial(itrunc(T(a - 1), pol)); + } + return sum; +} +// +// Upper gamma fraction for half integer a: +// +template +T finite_half_gamma_q(T a, T x, T* p_derivative, const Policy& pol) +{ + // + // Calculates normalised Q when a is a half-integer: + // + BOOST_MATH_STD_USING + T e = boost::math::erfc(sqrt(x), pol); + if((e != 0) && (a > 1)) + { + T term = exp(-x) / sqrt(constants::pi() * x); + term *= x; + static const T half = T(1) / 2; + term /= half; + T sum = term; + for(unsigned n = 2; n < a; ++n) + { + term /= n - half; + term *= x; + sum += term; + } + e += sum; + if(p_derivative) + { + *p_derivative = 0; + } + } + else if(p_derivative) + { + // We'll be dividing by x later, so calculate derivative * x: + *p_derivative = sqrt(x) * exp(-x) / constants::root_pi(); + } + return e; +} +// +// Asymptotic approximation for large argument, see: https://dlmf.nist.gov/8.11#E2 +// +template +struct incomplete_tgamma_large_x_series +{ + typedef T result_type; + incomplete_tgamma_large_x_series(const T& a, const T& x) + : a_poch(a - 1), z(x), term(1) {} + T operator()() + { + T result = term; + term *= a_poch / z; + a_poch -= 1; + return result; + } + T a_poch, z, term; +}; + +template +T incomplete_tgamma_large_x(const T& a, const T& x, const Policy& pol) +{ + BOOST_MATH_STD_USING + incomplete_tgamma_large_x_series s(a, x); + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations(); + T result = boost::math::tools::sum_series(s, boost::math::policies::get_epsilon(), max_iter); + boost::math::policies::check_series_iterations("boost::math::tgamma<%1%>(%1%,%1%)", max_iter, pol); + return result; +} + + +// +// Main incomplete gamma entry point, handles all four incomplete gamma's: +// +template +T gamma_incomplete_imp(T a, T x, bool normalised, bool invert, + const Policy& pol, T* p_derivative) +{ + static const char* function = "boost::math::gamma_p<%1%>(%1%, %1%)"; + if(a <= 0) + return policies::raise_domain_error(function, "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol); + if(x < 0) + return policies::raise_domain_error(function, "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol); + + BOOST_MATH_STD_USING + + typedef typename lanczos::lanczos::type lanczos_type; + + T result = 0; // Just to avoid warning C4701: potentially uninitialized local variable 'result' used + + if(a >= max_factorial::value && !normalised) + { + // + // When we're computing the non-normalized incomplete gamma + // and a is large the result is rather hard to compute unless + // we use logs. There are really two options - if x is a long + // way from a in value then we can reliably use methods 2 and 4 + // below in logarithmic form and go straight to the result. + // Otherwise we let the regularized gamma take the strain + // (the result is unlikely to underflow in the central region anyway) + // and combine with lgamma in the hopes that we get a finite result. + // + if(invert && (a * 4 < x)) + { + // This is method 4 below, done in logs: + result = a * log(x) - x; + if(p_derivative) + *p_derivative = exp(result); + result += log(upper_gamma_fraction(a, x, policies::get_epsilon())); + } + else if(!invert && (a > 4 * x)) + { + // This is method 2 below, done in logs: + result = a * log(x) - x; + if(p_derivative) + *p_derivative = exp(result); + T init_value = 0; + result += log(detail::lower_gamma_series(a, x, pol, init_value) / a); + } + else + { + result = gamma_incomplete_imp(a, x, true, invert, pol, p_derivative); + if(result == 0) + { + if(invert) + { + // Try http://functions.wolfram.com/06.06.06.0039.01 + result = 1 + 1 / (12 * a) + 1 / (288 * a * a); + result = log(result) - a + (a - 0.5f) * log(a) + log(boost::math::constants::root_two_pi()); + if(p_derivative) + *p_derivative = exp(a * log(x) - x); + } + else + { + // This is method 2 below, done in logs, we're really outside the + // range of this method, but since the result is almost certainly + // infinite, we should probably be OK: + result = a * log(x) - x; + if(p_derivative) + *p_derivative = exp(result); + T init_value = 0; + result += log(detail::lower_gamma_series(a, x, pol, init_value) / a); + } + } + else + { + result = log(result) + boost::math::lgamma(a, pol); + } + } + if(result > tools::log_max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + return exp(result); + } + + BOOST_MATH_ASSERT((p_derivative == nullptr) || normalised); + + bool is_int, is_half_int; + bool is_small_a = (a < 30) && (a <= x + 1) && (x < tools::log_max_value()); + if(is_small_a) + { + T fa = floor(a); + is_int = (fa == a); + is_half_int = is_int ? false : (fabs(fa - a) == 0.5f); + } + else + { + is_int = is_half_int = false; + } + + int eval_method; + + if(is_int && (x > 0.6)) + { + // calculate Q via finite sum: + invert = !invert; + eval_method = 0; + } + else if(is_half_int && (x > 0.2)) + { + // calculate Q via finite sum for half integer a: + invert = !invert; + eval_method = 1; + } + else if((x < tools::root_epsilon()) && (a > 1)) + { + eval_method = 6; + } + else if ((x > 1000) && ((a < x) || (fabs(a - 50) / x < 1))) + { + // calculate Q via asymptotic approximation: + invert = !invert; + eval_method = 7; + } + else if(x < 0.5) + { + // + // Changeover criterion chosen to give a changeover at Q ~ 0.33 + // + if(-0.4 / log(x) < a) + { + eval_method = 2; + } + else + { + eval_method = 3; + } + } + else if(x < 1.1) + { + // + // Changover here occurs when P ~ 0.75 or Q ~ 0.25: + // + if(x * 0.75f < a) + { + eval_method = 2; + } + else + { + eval_method = 3; + } + } + else + { + // + // Begin by testing whether we're in the "bad" zone + // where the result will be near 0.5 and the usual + // series and continued fractions are slow to converge: + // + bool use_temme = false; + if(normalised && std::numeric_limits::is_specialized && (a > 20)) + { + T sigma = fabs((x-a)/a); + if((a > 200) && (policies::digits() <= 113)) + { + // + // This limit is chosen so that we use Temme's expansion + // only if the result would be larger than about 10^-6. + // Below that the regular series and continued fractions + // converge OK, and if we use Temme's method we get increasing + // errors from the dominant erfc term as it's (inexact) argument + // increases in magnitude. + // + if(20 / a > sigma * sigma) + use_temme = true; + } + else if(policies::digits() <= 64) + { + // Note in this zone we can't use Temme's expansion for + // types longer than an 80-bit real: + // it would require too many terms in the polynomials. + if(sigma < 0.4) + use_temme = true; + } + } + if(use_temme) + { + eval_method = 5; + } + else + { + // + // Regular case where the result will not be too close to 0.5. + // + // Changeover here occurs at P ~ Q ~ 0.5 + // Note that series computation of P is about x2 faster than continued fraction + // calculation of Q, so try and use the CF only when really necessary, especially + // for small x. + // + if(x - (1 / (3 * x)) < a) + { + eval_method = 2; + } + else + { + eval_method = 4; + invert = !invert; + } + } + } + + switch(eval_method) + { + case 0: + { + result = finite_gamma_q(a, x, pol, p_derivative); + if(!normalised) + result *= boost::math::tgamma(a, pol); + break; + } + case 1: + { + result = finite_half_gamma_q(a, x, p_derivative, pol); + if(!normalised) + result *= boost::math::tgamma(a, pol); + if(p_derivative && (*p_derivative == 0)) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 2: + { + // Compute P: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if(p_derivative) + *p_derivative = result; + if(result != 0) + { + // + // If we're going to be inverting the result then we can + // reduce the number of series evaluations by quite + // a few iterations if we set an initial value for the + // series sum based on what we'll end up subtracting it from + // at the end. + // Have to be careful though that this optimization doesn't + // lead to spurious numeric overflow. Note that the + // scary/expensive overflow checks below are more often + // than not bypassed in practice for "sensible" input + // values: + // + T init_value = 0; + bool optimised_invert = false; + if(invert) + { + init_value = (normalised ? 1 : boost::math::tgamma(a, pol)); + if(normalised || (result >= 1) || (tools::max_value() * result > init_value)) + { + init_value /= result; + if(normalised || (a < 1) || (tools::max_value() / a > init_value)) + { + init_value *= -a; + optimised_invert = true; + } + else + init_value = 0; + } + else + init_value = 0; + } + result *= detail::lower_gamma_series(a, x, pol, init_value) / a; + if(optimised_invert) + { + invert = false; + result = -result; + } + } + break; + } + case 3: + { + // Compute Q: + invert = !invert; + T g; + result = tgamma_small_upper_part(a, x, pol, &g, invert, p_derivative); + invert = false; + if(normalised) + result /= g; + break; + } + case 4: + { + // Compute Q: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if(p_derivative) + *p_derivative = result; + if(result != 0) + result *= upper_gamma_fraction(a, x, policies::get_epsilon()); + break; + } + case 5: + { + // + // Use compile time dispatch to the appropriate + // Temme asymptotic expansion. This may be dead code + // if T does not have numeric limits support, or has + // too many digits for the most precise version of + // these expansions, in that case we'll be calling + // an empty function. + // + typedef typename policies::precision::type precision_type; + + typedef std::integral_constant tag_type; + + result = igamma_temme_large(a, x, pol, static_cast(nullptr)); + if(x >= a) + invert = !invert; + if(p_derivative) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 6: + { + // x is so small that P is necessarily very small too, + // use http://functions.wolfram.com/GammaBetaErf/GammaRegularized/06/01/05/01/01/ + if(!normalised) + result = pow(x, a) / (a); + else + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + result = pow(x, a) / boost::math::tgamma(a + 1, pol); +#ifndef BOOST_NO_EXCEPTIONS + } + catch (const std::overflow_error&) + { + result = 0; + } +#endif + } + result *= 1 - a * x / (a + 1); + if (p_derivative) + *p_derivative = regularised_gamma_prefix(a, x, pol, lanczos_type()); + break; + } + case 7: + { + // x is large, + // Compute Q: + result = normalised ? regularised_gamma_prefix(a, x, pol, lanczos_type()) : full_igamma_prefix(a, x, pol); + if (p_derivative) + *p_derivative = result; + result /= x; + if (result != 0) + result *= incomplete_tgamma_large_x(a, x, pol); + break; + } + } + + if(normalised && (result > 1)) + result = 1; + if(invert) + { + T gam = normalised ? 1 : boost::math::tgamma(a, pol); + result = gam - result; + } + if(p_derivative) + { + // + // Need to convert prefix term to derivative: + // + if((x < 1) && (tools::max_value() * x < *p_derivative)) + { + // overflow, just return an arbitrarily large value: + *p_derivative = tools::max_value() / 2; + } + + *p_derivative /= x; + } + + return result; +} + +// +// Ratios of two gamma functions: +// +template +T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const Lanczos& l) +{ + BOOST_MATH_STD_USING + if(z < tools::epsilon()) + { + // + // We get spurious numeric overflow unless we're very careful, this + // can occur either inside Lanczos::lanczos_sum(z) or in the + // final combination of terms, to avoid this, split the product up + // into 2 (or 3) parts: + // + // G(z) / G(L) = 1 / (z * G(L)) ; z < eps, L = z + delta = delta + // z * G(L) = z * G(lim) * (G(L)/G(lim)) ; lim = largest factorial + // + if(boost::math::max_factorial::value < delta) + { + T ratio = tgamma_delta_ratio_imp_lanczos(delta, T(boost::math::max_factorial::value - delta), pol, l); + ratio *= z; + ratio *= boost::math::unchecked_factorial(boost::math::max_factorial::value - 1); + return 1 / ratio; + } + else + { + return 1 / (z * boost::math::tgamma(z + delta, pol)); + } + } + T zgh = static_cast(z + Lanczos::g() - constants::half()); + T result; + if(z + delta == z) + { + if (fabs(delta / zgh) < boost::math::tools::epsilon()) + { + // We have: + // result = exp((constants::half() - z) * boost::math::log1p(delta / zgh, pol)); + // 0.5 - z == -z + // log1p(delta / zgh) = delta / zgh = delta / z + // multiplying we get -delta. + result = exp(-delta); + } + else + // from the pow formula below... but this may actually be wrong, we just can't really calculate it :( + result = 1; + } + else + { + if(fabs(delta) < 10) + { + result = exp((constants::half() - z) * boost::math::log1p(delta / zgh, pol)); + } + else + { + result = pow(zgh / (zgh + delta), z - constants::half()); + } + // Split the calculation up to avoid spurious overflow: + result *= Lanczos::lanczos_sum(z) / Lanczos::lanczos_sum(T(z + delta)); + } + result *= pow(constants::e() / (zgh + delta), delta); + return result; +} +// +// And again without Lanczos support this time: +// +template +T tgamma_delta_ratio_imp_lanczos(T z, T delta, const Policy& pol, const lanczos::undefined_lanczos& l) +{ + BOOST_MATH_STD_USING + + // + // We adjust z and delta so that both z and z+delta are large enough for + // Sterling's approximation to hold. We can then calculate the ratio + // for the adjusted values, and rescale back down to z and z+delta. + // + // Get the required shifts first: + // + long numerator_shift = 0; + long denominator_shift = 0; + const int min_z = minimum_argument_for_bernoulli_recursion(); + + if (min_z > z) + numerator_shift = 1 + ltrunc(min_z - z); + if (min_z > z + delta) + denominator_shift = 1 + ltrunc(min_z - z - delta); + // + // If the shifts are zero, then we can just combine scaled tgamma's + // and combine the remaining terms: + // + if (numerator_shift == 0 && denominator_shift == 0) + { + T scaled_tgamma_num = scaled_tgamma_no_lanczos(z, pol); + T scaled_tgamma_denom = scaled_tgamma_no_lanczos(T(z + delta), pol); + T result = scaled_tgamma_num / scaled_tgamma_denom; + result *= exp(z * boost::math::log1p(-delta / (z + delta), pol)) * pow((delta + z) / constants::e(), -delta); + return result; + } + // + // We're going to have to rescale first, get the adjusted z and delta values, + // plus the ratio for the adjusted values: + // + T zz = z + numerator_shift; + T dd = delta - (numerator_shift - denominator_shift); + T ratio = tgamma_delta_ratio_imp_lanczos(zz, dd, pol, l); + // + // Use gamma recurrence relations to get back to the original + // z and z+delta: + // + for (long long i = 0; i < numerator_shift; ++i) + { + ratio /= (z + i); + if (i < denominator_shift) + ratio *= (z + delta + i); + } + for (long long i = numerator_shift; i < denominator_shift; ++i) + { + ratio *= (z + delta + i); + } + return ratio; +} + +template +T tgamma_delta_ratio_imp(T z, T delta, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if((z <= 0) || (z + delta <= 0)) + { + // This isn't very sophisticated, or accurate, but it does work: + return boost::math::tgamma(z, pol) / boost::math::tgamma(z + delta, pol); + } + + if(floor(delta) == delta) + { + if(floor(z) == z) + { + // + // Both z and delta are integers, see if we can just use table lookup + // of the factorials to get the result: + // + if((z <= max_factorial::value) && (z + delta <= max_factorial::value)) + { + return unchecked_factorial((unsigned)itrunc(z, pol) - 1) / unchecked_factorial((unsigned)itrunc(T(z + delta), pol) - 1); + } + } + if(fabs(delta) < 20) + { + // + // delta is a small integer, we can use a finite product: + // + if(delta == 0) + return 1; + if(delta < 0) + { + z -= 1; + T result = z; + while(0 != (delta += 1)) + { + z -= 1; + result *= z; + } + return result; + } + else + { + T result = 1 / z; + while(0 != (delta -= 1)) + { + z += 1; + result /= z; + } + return result; + } + } + } + typedef typename lanczos::lanczos::type lanczos_type; + return tgamma_delta_ratio_imp_lanczos(z, delta, pol, lanczos_type()); +} + +template +T tgamma_ratio_imp(T x, T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if((x <= 0) || (boost::math::isinf)(x)) + return policies::raise_domain_error("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got a=%1%).", x, pol); + if((y <= 0) || (boost::math::isinf)(y)) + return policies::raise_domain_error("boost::math::tgamma_ratio<%1%>(%1%, %1%)", "Gamma function ratios only implemented for positive arguments (got b=%1%).", y, pol); + + if(x <= tools::min_value()) + { + // Special case for denorms...Ugh. + T shift = ldexp(T(1), tools::digits()); + return shift * tgamma_ratio_imp(T(x * shift), y, pol); + } + + if((x < max_factorial::value) && (y < max_factorial::value)) + { + // Rather than subtracting values, lets just call the gamma functions directly: + return boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + } + T prefix = 1; + if(x < 1) + { + if(y < 2 * max_factorial::value) + { + // We need to sidestep on x as well, otherwise we'll underflow + // before we get to factor in the prefix term: + prefix /= x; + x += 1; + while(y >= max_factorial::value) + { + y -= 1; + prefix /= y; + } + return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + } + // + // result is almost certainly going to underflow to zero, try logs just in case: + // + return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol)); + } + if(y < 1) + { + if(x < 2 * max_factorial::value) + { + // We need to sidestep on y as well, otherwise we'll overflow + // before we get to factor in the prefix term: + prefix *= y; + y += 1; + while(x >= max_factorial::value) + { + x -= 1; + prefix *= x; + } + return prefix * boost::math::tgamma(x, pol) / boost::math::tgamma(y, pol); + } + // + // Result will almost certainly overflow, try logs just in case: + // + return exp(boost::math::lgamma(x, pol) - boost::math::lgamma(y, pol)); + } + // + // Regular case, x and y both large and similar in magnitude: + // + return boost::math::tgamma_delta_ratio(x, y - x, pol); +} + +template +T gamma_p_derivative_imp(T a, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Usual error checks first: + // + if(a <= 0) + return policies::raise_domain_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument a to the incomplete gamma function must be greater than zero (got a=%1%).", a, pol); + if(x < 0) + return policies::raise_domain_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", "Argument x to the incomplete gamma function must be >= 0 (got x=%1%).", x, pol); + // + // Now special cases: + // + if(x == 0) + { + return (a > 1) ? 0 : + (a == 1) ? 1 : policies::raise_overflow_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol); + } + // + // Normal case: + // + typedef typename lanczos::lanczos::type lanczos_type; + T f1 = detail::regularised_gamma_prefix(a, x, pol, lanczos_type()); + if((x < 1) && (tools::max_value() * x < f1)) + { + // overflow: + return policies::raise_overflow_error("boost::math::gamma_p_derivative<%1%>(%1%, %1%)", nullptr, pol); + } + if(f1 == 0) + { + // Underflow in calculation, use logs instead: + f1 = a * log(x) - x - lgamma(a, pol) - log(x); + f1 = exp(f1); + } + else + f1 /= x; + + return f1; +} + +template +inline typename tools::promote_args::type + tgamma(T z, const Policy& /* pol */, const std::true_type) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast(detail::gamma_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma<%1%>(%1%)"); +} + +template +struct igamma_initializer +{ + struct init + { + init() + { + typedef typename policies::precision::type precision_type; + + typedef std::integral_constant tag_type; + + do_init(tag_type()); + } + template + static void do_init(const std::integral_constant&) + { + // If std::numeric_limits::digits is zero, we must not call + // our initialization code here as the precision presumably + // varies at runtime, and will not have been set yet. Plus the + // code requiring initialization isn't called when digits == 0. + if(std::numeric_limits::digits) + { + boost::math::gamma_p(static_cast(400), static_cast(400), Policy()); + } + } + static void do_init(const std::integral_constant&){} + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename igamma_initializer::init igamma_initializer::initializer; + +template +struct lgamma_initializer +{ + struct init + { + init() + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + do_init(tag_type()); + } + static void do_init(const std::integral_constant&) + { + boost::math::lgamma(static_cast(2.5), Policy()); + boost::math::lgamma(static_cast(1.25), Policy()); + boost::math::lgamma(static_cast(1.75), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::lgamma(static_cast(2.5), Policy()); + boost::math::lgamma(static_cast(1.25), Policy()); + boost::math::lgamma(static_cast(1.5), Policy()); + boost::math::lgamma(static_cast(1.75), Policy()); + } + static void do_init(const std::integral_constant&) + { + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename lgamma_initializer::init lgamma_initializer::initializer; + +template +inline typename tools::promote_args::type + tgamma(T1 a, T2 z, const Policy&, const std::false_type) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + igamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), false, true, + forwarding_policy(), static_cast(nullptr)), "boost::math::tgamma<%1%>(%1%, %1%)"); +} + +template +inline typename tools::promote_args::type + tgamma(T1 a, T2 z, const std::false_type& tag) +{ + return tgamma(a, z, policies::policy<>(), tag); +} + + +} // namespace detail + +template +inline typename tools::promote_args::type + tgamma(T z) +{ + return tgamma(z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + lgamma(T z, int* sign, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + detail::lgamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::lgamma_imp(static_cast(z), forwarding_policy(), evaluation_type(), sign), "boost::math::lgamma<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type + lgamma(T z, int* sign) +{ + return lgamma(z, sign, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + lgamma(T x, const Policy& pol) +{ + return ::boost::math::lgamma(x, nullptr, pol); +} + +template +inline typename tools::promote_args::type + lgamma(T x) +{ + return ::boost::math::lgamma(x, nullptr, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + tgamma1pm1(T z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast::type, forwarding_policy>(detail::tgammap1m1_imp(static_cast(z), forwarding_policy(), evaluation_type()), "boost::math::tgamma1pm1<%!%>(%1%)"); +} + +template +inline typename tools::promote_args::type + tgamma1pm1(T z) +{ + return tgamma1pm1(z, policies::policy<>()); +} + +// +// Full upper incomplete gamma: +// +template +inline typename tools::promote_args::type + tgamma(T1 a, T2 z) +{ + // + // Type T2 could be a policy object, or a value, select the + // right overload based on T2: + // + typedef typename policies::is_policy::type maybe_policy; + return detail::tgamma(a, z, maybe_policy()); +} +template +inline typename tools::promote_args::type + tgamma(T1 a, T2 z, const Policy& pol) +{ + return detail::tgamma(a, z, pol, std::false_type()); +} +// +// Full lower incomplete gamma: +// +template +inline typename tools::promote_args::type + tgamma_lower(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + detail::igamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), false, false, + forwarding_policy(), static_cast(nullptr)), "tgamma_lower<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + tgamma_lower(T1 a, T2 z) +{ + return tgamma_lower(a, z, policies::policy<>()); +} +// +// Regularised upper incomplete gamma: +// +template +inline typename tools::promote_args::type + gamma_q(T1 a, T2 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + detail::igamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), true, true, + forwarding_policy(), static_cast(nullptr)), "gamma_q<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + gamma_q(T1 a, T2 z) +{ + return gamma_q(a, z, policies::policy<>()); +} +// +// Regularised lower incomplete gamma: +// +template +inline typename tools::promote_args::type + gamma_p(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + // typedef typename lanczos::lanczos::type evaluation_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + detail::igamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast( + detail::gamma_incomplete_imp(static_cast(a), + static_cast(z), true, false, + forwarding_policy(), static_cast(nullptr)), "gamma_p<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + gamma_p(T1 a, T2 z) +{ + return gamma_p(a, z, policies::policy<>()); +} + +// ratios of gamma functions: +template +inline typename tools::promote_args::type + tgamma_delta_ratio(T1 z, T2 delta, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::tgamma_delta_ratio_imp(static_cast(z), static_cast(delta), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + tgamma_delta_ratio(T1 z, T2 delta) +{ + return tgamma_delta_ratio(z, delta, policies::policy<>()); +} +template +inline typename tools::promote_args::type + tgamma_ratio(T1 a, T2 b, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::tgamma_ratio_imp(static_cast(a), static_cast(b), forwarding_policy()), "boost::math::tgamma_delta_ratio<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + tgamma_ratio(T1 a, T2 b) +{ + return tgamma_ratio(a, b, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + gamma_p_derivative(T1 a, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast(detail::gamma_p_derivative_imp(static_cast(a), static_cast(x), forwarding_policy()), "boost::math::gamma_p_derivative<%1%>(%1%, %1%)"); +} +template +inline typename tools::promote_args::type + gamma_p_derivative(T1 a, T2 x) +{ + return gamma_p_derivative(a, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#include +#include +#include + +#endif // BOOST_MATH_SF_GAMMA_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/gegenbauer.hpp b/libcxx/src/third-party/boost/math/special_functions/gegenbauer.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/gegenbauer.hpp @@ -0,0 +1,75 @@ +// (C) Copyright Nick Thompson 2019. +// 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_GEGENBAUER_HPP +#define BOOST_MATH_SPECIAL_GEGENBAUER_HPP + +#include +#include +#include + +namespace boost { namespace math { + +template +Real gegenbauer(unsigned n, Real lambda, Real x) +{ + static_assert(!std::is_integral::value, "Gegenbauer polynomials required floating point arguments."); + if (lambda <= -1/Real(2)) { + throw std::domain_error("lambda > -1/2 is required."); + } + // The only reason to do this is because of some instability that could be present for x < 0 that is not present for x > 0. + // I haven't observed this, but then again, I haven't managed to test an exhaustive number of parameters. + // In any case, the routine is distinctly faster without this test: + //if (x < 0) { + // if (n&1) { + // return -gegenbauer(n, lambda, -x); + // } + // return gegenbauer(n, lambda, -x); + //} + + if (n == 0) { + return Real(1); + } + Real y0 = 1; + Real y1 = 2*lambda*x; + + Real yk = y1; + Real k = 2; + Real k_max = n*(1+std::numeric_limits::epsilon()); + Real gamma = 2*(lambda - 1); + while(k < k_max) + { + yk = ( (2 + gamma/k)*x*y1 - (1+gamma/k)*y0); + y0 = y1; + y1 = yk; + k += 1; + } + return yk; +} + + +template +Real gegenbauer_derivative(unsigned n, Real lambda, Real x, unsigned k) +{ + if (k > n) { + return Real(0); + } + Real gegen = gegenbauer(n-k, lambda + k, x); + Real scale = 1; + for (unsigned j = 0; j < k; ++j) { + scale *= 2*lambda; + lambda += 1; + } + return scale*gegen; +} + +template +Real gegenbauer_prime(unsigned n, Real lambda, Real x) { + return gegenbauer_derivative(n, lambda, x, 1); +} + + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/hankel.hpp b/libcxx/src/third-party/boost/math/special_functions/hankel.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hankel.hpp @@ -0,0 +1,180 @@ +// Copyright John Maddock 2012. +// 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_HANKEL_HPP +#define BOOST_MATH_HANKEL_HPP + +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +std::complex hankel_imp(T v, T x, const bessel_no_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"; + + if(x < 0) + { + bool isint_v = floor(v) == v; + T j, y; + bessel_jy(v, -x, &j, &y, need_j | need_y, pol); + std::complex cx(x), cv(v); + std::complex j_result, y_result; + if(isint_v) + { + int s = (iround(v) & 1) ? -1 : 1; + j_result = j * s; + y_result = T(s) * (y - (2 / constants::pi()) * (log(-x) - log(cx)) * j); + } + else + { + j_result = pow(cx, v) * pow(-cx, -v) * j; + T p1 = pow(-x, v); + std::complex p2 = pow(cx, v); + y_result = p1 * y / p2 + + (p2 / p1 - p1 / p2) * j / tan(constants::pi() * v); + } + // multiply y_result by i: + y_result = std::complex(-sign * y_result.imag(), sign * y_result.real()); + return j_result + y_result; + } + + if(x == 0) + { + if(v == 0) + { + // J is 1, Y is -INF + return std::complex(1, sign * -policies::raise_overflow_error(function, nullptr, pol)); + } + else + { + // At least one of J and Y is complex infinity: + return std::complex(policies::raise_overflow_error(function, nullptr, pol), sign * policies::raise_overflow_error(function, nullptr, pol)); + } + } + + T j, y; + bessel_jy(v, x, &j, &y, need_j | need_y, pol); + return std::complex(j, sign * y); +} + +template +std::complex hankel_imp(int v, T x, const bessel_int_tag&, const Policy& pol, int sign); + +template +inline std::complex hankel_imp(T v, T x, const bessel_maybe_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING // ADL of std names. + int ival = detail::iconv(v, pol); + if(0 == v - ival) + { + return hankel_imp(ival, x, bessel_int_tag(), pol, sign); + } + return hankel_imp(v, x, bessel_no_int_tag(), pol, sign); +} + +template +inline std::complex hankel_imp(int v, T x, const bessel_int_tag&, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + if((std::abs(v) < 200) && (x > 0)) + return std::complex(bessel_jn(v, x, pol), sign * bessel_yn(v, x, pol)); + return hankel_imp(static_cast(v), x, bessel_no_int_tag(), pol, sign); +} + +template +inline std::complex sph_hankel_imp(T v, T x, const Policy& pol, int sign) +{ + BOOST_MATH_STD_USING + return constants::root_half_pi() * hankel_imp(v + 0.5f, x, bessel_no_int_tag(), pol, sign) / sqrt(std::complex(x)); +} + +} // namespace detail + +template +inline std::complex::result_type> cyl_hankel_1(T1 v, T2 x, const Policy& pol) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast, Policy>(detail::hankel_imp(v, static_cast(x), tag_type(), pol, 1), "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"); +} + +template +inline std::complex >::result_type> cyl_hankel_1(T1 v, T2 x) +{ + return cyl_hankel_1(v, x, policies::policy<>()); +} + +template +inline std::complex::result_type> cyl_hankel_2(T1 v, T2 x, const Policy& pol) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename detail::bessel_traits::optimisation_tag tag_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast, Policy>(detail::hankel_imp(v, static_cast(x), tag_type(), pol, -1), "boost::math::cyl_hankel_1<%1%>(%1%,%1%)"); +} + +template +inline std::complex >::result_type> cyl_hankel_2(T1 v, T2 x) +{ + return cyl_hankel_2(v, x, policies::policy<>()); +} + +template +inline std::complex::result_type> sph_hankel_1(T1 v, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast, Policy>(detail::sph_hankel_imp(static_cast(v), static_cast(x), forwarding_policy(), 1), "boost::math::sph_hankel_1<%1%>(%1%,%1%)"); +} + +template +inline std::complex >::result_type> sph_hankel_1(T1 v, T2 x) +{ + return sph_hankel_1(v, x, policies::policy<>()); +} + +template +inline std::complex::result_type> sph_hankel_2(T1 v, T2 x, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename detail::bessel_traits::result_type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + return policies::checked_narrowing_cast, Policy>(detail::sph_hankel_imp(static_cast(v), static_cast(x), forwarding_policy(), -1), "boost::math::sph_hankel_1<%1%>(%1%,%1%)"); +} + +template +inline std::complex >::result_type> sph_hankel_2(T1 v, T2 x) +{ + return sph_hankel_2(v, x, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_HANKEL_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/hermite.hpp b/libcxx/src/third-party/boost/math/special_functions/hermite.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hermite.hpp @@ -0,0 +1,76 @@ + +// (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_HERMITE_HPP +#define BOOST_MATH_SPECIAL_HERMITE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for Hermite polynomials: +template +inline typename tools::promote_args::type + hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1) +{ + return (2 * x * Hn - 2 * n * Hnm1); +} + +namespace detail{ + +// Implement Hermite polynomials via recurrence: +template +T hermite_imp(unsigned n, T x) +{ + T p0 = 1; + T p1 = 2 * x; + + if(n == 0) + return p0; + + unsigned c = 1; + + while(c < n) + { + std::swap(p0, p1); + p1 = hermite_next(c, x, p0, p1); + ++c; + } + return p1; +} + +} // namespace detail + +template +inline typename tools::promote_args::type + hermite(unsigned n, T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::hermite_imp(n, static_cast(x)), "boost::math::hermite<%1%>(unsigned, %1%)"); +} + +template +inline typename tools::promote_args::type + hermite(unsigned n, T x) +{ + return boost::math::hermite(n, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_HERMITE_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/heuman_lambda.hpp b/libcxx/src/third-party/boost/math/special_functions/heuman_lambda.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/heuman_lambda.hpp @@ -0,0 +1,91 @@ +// Copyright (c) 2015 John Maddock +// 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_ELLINT_HL_HPP +#define BOOST_MATH_ELLINT_HL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integral the Jacobi Zeta function. + +namespace boost { namespace math { + +namespace detail{ + +// Elliptic integral - Jacobi Zeta +template +T heuman_lambda_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + const char* function = "boost::math::heuman_lambda<%1%>(%1%, %1%)"; + + if(fabs(k) > 1) + return policies::raise_domain_error(function, "We require |k| <= 1 but got k = %1%", k, pol); + + T result; + T sinp = sin(phi); + T cosp = cos(phi); + T s2 = sinp * sinp; + T k2 = k * k; + T kp = 1 - k2; + T delta = sqrt(1 - (kp * s2)); + if(fabs(phi) <= constants::half_pi()) + { + result = kp * sinp * cosp / (delta * constants::half_pi()); + result *= ellint_rf_imp(T(0), kp, T(1), pol) + k2 * ellint_rj(T(0), kp, T(1), T(1 - k2 / (delta * delta)), pol) / (3 * delta * delta); + } + else + { + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + + T rkp = sqrt(kp); + T ratio; + if(rkp == 1) + { + return policies::raise_domain_error(function, "When 1-k^2 == 1 then phi must be < Pi/2, but got phi = %1%", phi, pol); + } + else + ratio = ellint_f_imp(phi, rkp, pol) / ellint_k_imp(rkp, pol, precision_tag_type()); + result = ratio + ellint_k_imp(k, pol, precision_tag_type()) * jacobi_zeta_imp(phi, rkp, pol) / constants::half_pi(); + } + return result; +} + +} // detail + +template +inline typename tools::promote_args::type heuman_lambda(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::heuman_lambda_imp(static_cast(phi), static_cast(k), pol), "boost::math::heuman_lambda<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type heuman_lambda(T1 k, T2 phi) +{ + return boost::math::heuman_lambda(k, phi, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/hypergeometric_0F1.hpp b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_0F1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_0F1.hpp @@ -0,0 +1,118 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_0F1_HPP +#define BOOST_MATH_HYPERGEOMETRIC_0F1_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + + template + struct hypergeometric_0F1_cf + { + // + // We start this continued fraction at b on index -1 + // and treat the -1 and 0 cases as special cases. + // We do this to avoid adding the continued fraction result + // to 1 so that we can accurately evaluate for small results + // as well as large ones. See http://functions.wolfram.com/07.17.10.0002.01 + // + T b, z; + int k; + hypergeometric_0F1_cf(T b_, T z_) : b(b_), z(z_), k(-2) {} + typedef std::pair result_type; + + result_type operator()() + { + ++k; + if (k <= 0) + return std::make_pair(z / b, 1); + return std::make_pair(-z / ((k + 1) * (b + k)), 1 + z / ((k + 1) * (b + k))); + } + }; + + template + T hypergeometric_0F1_cf_imp(T b, T z, const Policy& pol, const char* function) + { + hypergeometric_0F1_cf evaluator(b, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T cf = tools::continued_fraction_b(evaluator, policies::get_epsilon(), max_iter); + policies::check_series_iterations(function, max_iter, pol); + return cf; + } + + + template + inline T hypergeometric_0F1_imp(const T& b, const T& z, const Policy& pol) + { + const char* function = "boost::math::hypergeometric_0f1<%1%,%1%>(%1%, %1%)"; + BOOST_MATH_STD_USING + + // some special cases + if (z == 0) + return T(1); + + if ((b <= 0) && (b == floor(b))) + return policies::raise_pole_error( + function, + "Evaluation of 0f1 with nonpositive integer b = %1%.", b, pol); + + if (z < -5 && b > -5) + { + // Series is alternating and divergent, need to do something else here, + // Bessel function relation is much more accurate, unless |b| is similarly + // large to |z|, otherwise the CF formula suffers from cancellation when + // the result would be very small. + if (fabs(z / b) > 4) + return hypergeometric_0F1_bessel(b, z, pol); + return hypergeometric_0F1_cf_imp(b, z, pol, function); + } + // evaluation through Taylor series looks + // more precisious than Bessel relation: + // detail::hypergeometric_0f1_bessel(b, z, pol); + return detail::hypergeometric_0F1_generic_series(b, z, pol); + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_0F1_imp( + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_0F1<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z) +{ + return hypergeometric_0F1(b, z, policies::policy<>()); +} + + +} } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F0.hpp b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F0.hpp @@ -0,0 +1,74 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_1F0_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F0_HPP + +#include +#include +#include + + +namespace boost { namespace math { namespace detail { + +template +inline T hypergeometric_1F0_imp(const T& a, const T& z, const Policy& pol) +{ + static const char* function = "boost::math::hypergeometric_1F0<%1%,%1%>(%1%, %1%)"; + BOOST_MATH_STD_USING // pow + + if (z == 1) + return policies::raise_pole_error( + function, + "Evaluation of 1F0 with z = %1%.", + z, + pol); + if (1 - z < 0) + { + if (floor(a) != a) + return policies::raise_domain_error(function, + "Result is complex when a is non-integral and z > 1, but got z = %1%", z, pol); + } + // more naive and convergent method than series + return pow(T(1 - z), T(-a)); +} + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F0_imp( + static_cast(a), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F0<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z) +{ + return hypergeometric_1F0(a, z, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_1F0_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F1.hpp b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_1F1.hpp @@ -0,0 +1,779 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_1F1_HPP +#define BOOST_MATH_HYPERGEOMETRIC_1F1_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + // check when 1F1 series can't decay to polynom + template + inline bool check_hypergeometric_1F1_parameters(const T& a, const T& b) + { + BOOST_MATH_STD_USING + + if ((b <= 0) && (b == floor(b))) + { + if ((a >= 0) || (a < b) || (a != floor(a))) + return false; + } + + return true; + } + + template + T hypergeometric_1F1_divergent_fallback(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING + const char* function = "hypergeometric_1F1_divergent_fallback<%1%>(%1%,%1%,%1%)"; + // + // We get here if either: + // 1) We decide up front that Tricomi's method won't work, or: + // 2) We've called Tricomi's method and it's failed. + // + if (b > 0) + { + // Commented out since recurrence seems to always be better? +#if 0 + if ((z < b) && (a > -50)) + // Might as well use a recurrence in preference to z-recurrence: + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + int k = 1 + itrunc(z - z_limit); + // If k is too large we destroy all the digits in the result: + T convergence_at_50 = (b - a + 50) * k / (z * 50); + if ((k > 0) && (k < 50) && (fabs(convergence_at_50) < 1) && (z > z_limit)) + { + return boost::math::detail::hypergeometric_1f1_recurrence_on_z_minus_zero(a, b, T(z - k), k, pol, log_scaling); + } +#endif + if (z < b) + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + else + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + } + else // b < 0 + { + if (a < 0) + { + if ((b < a) && (z < -b / 4)) + return hypergeometric_1F1_from_function_ratio_negative_ab(a, b, z, pol, log_scaling); + else + { + // + // Solve (a+n)z/((b+n)n) == 1 for n, the number of iterations till the series starts to converge. + // If this is well away from the origin then it's probably better to use the series to evaluate this. + // Note that if sqr is negative then we have no solution, so assign an arbitrarily large value to the + // number of iterations. + // + bool can_use_recursion = (z - b + 100 < boost::math::policies::get_max_series_iterations()) && (100 - a < boost::math::policies::get_max_series_iterations()); + T sqr = 4 * a * z + b * b - 2 * b * z + z * z; + T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a - b); + if(can_use_recursion && ((std::max)(a, b) + iterations_to_convergence > -300)) + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + // + // When a < b and if we fall through to the series, then we get divergent behaviour when b crosses the origin + // so ideally we would pick another method. Otherwise the terms immediately after b crosses the origin may + // suffer catastrophic cancellation.... + // + if((a < b) && can_use_recursion) + return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling); + } + } + else + { + // + // Start by getting the domain of the recurrence relations, we get either: + // -1 Backwards recursion is stable and the CF will converge to double precision. + // +1 Forwards recursion is stable and the CF will converge to double precision. + // 0 No man's land, we're not far enough away from the crossover point to get double precision from either CF. + // + // At higher than double precision we need to be further away from the crossover location to + // get full converge, but it's not clear how much further - indeed at quad precision it's + // basically impossible to ever get forwards iteration to work. Backwards seems to work + // OK as long as a > 1 whatever the precision tbough. + // + int domain = hypergeometric_1F1_negative_b_recurrence_region(a, b, z); + if ((domain < 0) && ((a > 1) || (boost::math::policies::digits() <= 64))) + return hypergeometric_1F1_from_function_ratio_negative_b(a, b, z, pol, log_scaling); + else if (domain > 0) + { + if (boost::math::policies::digits() <= 64) + return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling); + try + { + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + catch (const evaluation_error&) + { + // + // The series failed, try the recursions instead and hope we get at least double precision: + // + return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling); + } + } + // + // We could fall back to Tricomi's approximation if we're in the transition zone + // between the above two regions. However, I've been unable to find any examples + // where this is better than the series, and there are many cases where it leads to + // quite grievous errors. + /* + else if (allow_tricomi) + { + T aa = a < 1 ? T(1) : a; + if (z < fabs((2 * aa - b) / (sqrt(fabs(aa * b))))) + return hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + */ + } + } + + // If we get here, then we've run out of methods to try, use the checked series which will + // raise an error if the result is garbage: + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + + template + bool is_convergent_negative_z_series(const T& a, const T& b, const T& z, const T& b_minus_a) + { + BOOST_MATH_STD_USING + // + // Filter out some cases we don't want first: + // + if((b_minus_a > 0) && (b > 0)) + { + if (a < 0) + return false; + } + // + // Generic check: we have small initial divergence and are convergent after 10 terms: + // + if ((fabs(z * a / b) < 2) && (fabs(z * (a + 10) / ((b + 10) * 10)) < 1)) + { + // Double check for divergence when we cross the origin on a and b: + if (a < 0) + { + T n = 300 - floor(a); + if (fabs((a + n) * z / ((b + n) * n)) < 1) + { + if (b < 0) + { + T m = 3 - floor(b); + if (fabs((a + m) * z / ((b + m) * m)) < 1) + return true; + } + else + return true; + } + } + else if (b < 0) + { + T n = 3 - floor(b); + if (fabs((a + n) * z / ((b + n) * n)) < 1) + return true; + } + } + if ((b > 0) && (a < 0)) + { + // + // For a and z both negative, we're OK with some initial divergence as long as + // it occurs before we hit the origin, as to start with all the terms have the + // same sign. + // + // https://www.wolframalpha.com/input/?i=solve+(a%2Bn)z+%2F+((b%2Bn)n)+%3D%3D+1+for+n + // + T sqr = 4 * a * z + b * b - 2 * b * z + z * z; + T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a + b); + if (iterations_to_convergence < 0) + iterations_to_convergence = 0.5f * (sqrt(sqr) - b + z); + if (a + iterations_to_convergence < -50) + { + // Need to check for divergence when we cross the origin on a: + if (a > -1) + return true; + T n = 300 - floor(a); + if(fabs((a + n) * z / ((b + n) * n)) < 1) + return true; + } + } + return false; + } + + template + inline T cyl_bessel_i_shrinkage_rate(const T& z) + { + // Approximately the ratio I_10.5(z/2) / I_9.5(z/2), this gives us an idea of how quickly + // the Bessel terms in A&S 13.6.4 are converging: + if (z < -160) + return 1; + if (z < -40) + return 0.75f; + if (z < -20) + return 0.5f; + if (z < -7) + return 0.25f; + if (z < -2) + return 0.1f; + return 0.05f; + } + + template + inline bool hypergeometric_1F1_is_13_3_6_region(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + if(fabs(a) == 0.5) + return false; + if ((z < 0) && (fabs(10 * a / b) < 1) && (fabs(a) < 50)) + { + T shrinkage = cyl_bessel_i_shrinkage_rate(z); + // We want the first term not too divergent, and convergence by term 10: + if ((fabs((2 * a - 1) * (2 * a - b) / b) < 2) && (fabs(shrinkage * (2 * a + 9) * (2 * a - b + 10) / (10 * (b + 10))) < 0.75)) + return true; + } + return false; + } + + template + inline bool hypergeometric_1F1_need_kummer_reflection(const T& a, const T& b, const T& z) + { + BOOST_MATH_STD_USING + // + // Check to see if we should apply Kummer's relation or not: + // + if (z > 0) + return false; + if (z < -1) + return true; + // + // When z is small and negative, things get more complex. + // More often than not we do not need apply Kummer's relation and the + // series is convergent as is, but we do need to check: + // + if (a > 0) + { + if (b > 0) + { + return fabs((a + 10) * z / (10 * (b + 10))) < 1; // Is the 10'th term convergent? + } + else + { + return true; // Likely to be divergent as b crosses the origin + } + } + else // a < 0 + { + if (b > 0) + { + return false; // Terms start off all positive and then by the time a crosses the origin we *must* be convergent. + } + else + { + return true; // Likely to be divergent as b crosses the origin, but hard to rationalise about! + } + } + } + + + template + T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + + static const char* const function = "boost::math::hypergeometric_1F1<%1%,%1%,%1%>(%1%,%1%,%1%)"; + + if ((z == 0) || (a == 0)) + return T(1); + + // undefined result: + if (!detail::check_hypergeometric_1F1_parameters(a, b)) + return policies::raise_domain_error( + function, + "Function is indeterminate for negative integer b = %1%.", + b, + pol); + + // other checks: + if (a == -1) + { + T r = 1 - (z / b); + if (fabs(r) < 0.5) + r = (b - z) / b; + return r; + } + + const T b_minus_a = b - a; + + // 0f0 a == b case; + if (b_minus_a == 0) + { + if ((a < 0) && (floor(a) == a)) + { + // Special case, use the truncated series to match what Mathematica does. + if ((a < -20) && (z > 0) && (z < 1)) + { + // https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/03/01/04/02/0002/ + return exp(z) * boost::math::gamma_q(1 - a, z, pol); + } + // https://functions.wolfram.com/HypergeometricFunctions/Hypergeometric1F1/03/01/04/02/0003/ + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + long long scale = lltrunc(z, pol); + log_scaling += scale; + return exp(z - scale); + } + // Special case for b-a = -1, we don't use for small a as it throws the digits of a away and leads to large errors: + if ((b_minus_a == -1) && (fabs(a) > 0.5)) + { + // for negative small integer a it is reasonable to use truncated series - polynomial + if ((a < 0) && (a == ceil(a)) && (a > -50)) + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function); + + return (b + z) * exp(z) / b; + } + + if ((a == 1) && (b == 2)) + return boost::math::expm1(z, pol) / z; + + if ((b - a == b) && (fabs(z / b) < policies::get_epsilon())) + return 1; + // + // Special case for A&S 13.3.6: + // + if (z < 0) + { + if (hypergeometric_1F1_is_13_3_6_region(a, b, z)) + { + // a is tiny compared to b, and z < 0 + // 13.3.6 appears to be the most efficient and often the most accurate method. + T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling); + long long scale = lltrunc(z, pol); + log_scaling += scale; + return r * exp(z - scale); + } + if ((b < 0) && (fabs(a) < 1e-2)) + { + // + // This is a tricky area, potentially we have no good method at all: + // + if (b - ceil(b) == a) + { + // Fractional parts of a and b are genuinely equal, we might as well + // apply Kummer's relation and get a truncated series: + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_imp(b_minus_a, b, -z, pol, log_scaling); + log_scaling += scaling; + return r; + } + if ((b < -1) && (max_b_for_1F1_small_a_negative_b_by_ratio(z) < b)) + return hypergeometric_1F1_small_a_negative_b_by_ratio(a, b, z, pol, log_scaling); + if ((b > -1) && (b < -0.5f)) + { + // Recursion is meta-stable: + T first = hypergeometric_1F1_imp(a, T(b + 2), z, pol); + T second = hypergeometric_1F1_imp(a, T(b + 1), z, pol); + return tools::apply_recurrence_relation_backward(hypergeometric_1F1_recurrence_small_b_coefficients(a, b, z, 1), 1, first, second); + } + // + // We've got nothing left but 13.3.6, even though it may be initially divergent: + // + T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling); + long long scale = lltrunc(z, pol); + log_scaling += scale; + return r * exp(z - scale); + } + } + // + // Asymptotic expansion for large z + // TODO: check region for higher precision types. + // Use recurrence relations to move to this region when a and b are also large. + // + if (detail::hypergeometric_1F1_asym_region(a, b, z, pol)) + { + long long saved_scale = log_scaling; + try + { + return hypergeometric_1F1_asym_large_z_series(a, b, z, pol, log_scaling); + } + catch (const evaluation_error&) + { + } + // + // Very occasionally our convergence criteria don't quite go to full precision + // and we have to try another method: + // + log_scaling = saved_scale; + } + + if ((fabs(a * z / b) < 3.5) && (fabs(z * 100) < fabs(b)) && ((fabs(a) > 1e-2) || (b < -5))) + return detail::hypergeometric_1F1_rational(a, b, z, pol); + + if (hypergeometric_1F1_need_kummer_reflection(a, b, z)) + { + if (a == 1) + return detail::hypergeometric_1F1_pade(b, z, pol); + if (is_convergent_negative_z_series(a, b, z, b_minus_a)) + { + if ((boost::math::sign(b_minus_a) == boost::math::sign(b)) && ((b > 0) || (b < -200))) + { + // Series is close enough to convergent that we should be OK, + // In this domain b - a ~ b and since 1F1[a, a, z] = e^z 1F1[b-a, b, -z] + // and 1F1[a, a, -z] = e^-z the result must necessarily be somewhere near unity. + // We have to rule out b small and negative because if b crosses the origin early + // in the series (before we're pretty much converged) then all bets are off. + // Note that this can go badly wrong when b and z are both large and negative, + // in that situation the series goes in waves of large and small values which + // may or may not cancel out. Likewise the initial part of the series may or may + // not converge, and even if it does may or may not give a correct answer! + // For example 1F1[-small, -1252.5, -1043.7] can loose up to ~800 digits due to + // cancellation and is basically incalculable via this method. + return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + } + } + // Let's otherwise make z positive (almost always) + // by Kummer's transformation + // (we also don't transform if z belongs to [-1,0]) + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_imp(b_minus_a, b, -z, pol, log_scaling); + log_scaling += scaling; + return r; + } + // + // Check for initial divergence: + // + bool series_is_divergent = (a + 1) * z / (b + 1) < -1; + if (series_is_divergent && (a < 0) && (b < 0) && (a > -1)) + series_is_divergent = false; // Best off taking the series in this situation + // + // If series starts off non-divergent, and becomes divergent later + // then it's because both a and b are negative, so check for later + // divergence as well: + // + if (!series_is_divergent && (a < 0) && (b < 0) && (b > a)) + { + // + // We need to exclude situations where we're over the initial "hump" + // in the series terms (ie series has already converged by the time + // b crosses the origin: + // + //T fa = fabs(a); + //T fb = fabs(b); + T convergence_point = sqrt((a - 1) * (a - b)) - a; + if (-b < convergence_point) + { + T n = -floor(b); + series_is_divergent = (a + n) * z / ((b + n) * n) < -1; + } + } + else if (!series_is_divergent && (b < 0) && (a > 0)) + { + // Series almost always become divergent as b crosses the origin: + series_is_divergent = true; + } + if (series_is_divergent && (b < -1) && (b > -5) && (a > b)) + series_is_divergent = false; // don't bother with divergence, series will be OK + + // + // Test for alternating series due to negative a, + // in particular, see if the series is initially divergent + // If so use the recurrence relation on a: + // + if (series_is_divergent) + { + if((a < 0) && (floor(a) == a) && (-a < policies::get_max_series_iterations())) + // This works amazingly well for negative integer a: + return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling); + // + // In what follows we have to set limits on how large z can be otherwise + // the Bessel series become large and divergent and all the digits cancel out. + // The criteria are distinctly empiracle rather than based on a firm analysis + // of the terms in the series. + // + if (b > 0) + { + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + if ((z < z_limit) && hypergeometric_1F1_is_tricomi_viable_positive_b(a, b, z)) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + else // b < 0 + { + if (a < 0) + { + T z_limit = fabs((2 * a - b) / (sqrt(fabs(a)))); + // + // I hate these hard limits, but they're about the best we can do to try and avoid + // Bessel function internal failures: these will be caught and handled + // but up the expense of this function call: + // + if (((z < z_limit) || (a > -500)) && ((b > -500) || (b - 2 * a > 0)) && (z < -a)) + { + // + // Outside this domain we will probably get better accuracy from the recursive methods. + // + if(!(((a < b) && (z > -b)) || (z > z_limit))) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + // + // When b and z are both very small, we get large errors from the recurrence methods + // in the fallbacks. Tricomi seems to work well here, as does direct series evaluation + // at least some of the time. Picking the right method is not easy, and sometimes this + // is much worse than the fallback. Overall though, it's a reasonable choice that keeps + // the very worst errors under control. + // + if(b > -1) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + } + } + // + // We previously used Tricomi here, but it appears to be worse than + // the recurrence-based algorithms in hypergeometric_1F1_divergent_fallback. + /* + else + { + T aa = a < 1 ? T(1) : a; + if (z < fabs((2 * aa - b) / (sqrt(fabs(aa * b))))) + return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling); + }*/ + } + + return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scaling); + } + + if (hypergeometric_1F1_is_13_3_6_region(b_minus_a, b, T(-z))) + { + // b_minus_a is tiny compared to b, and -z < 0 + // 13.3.6 appears to be the most efficient and often the most accurate method. + return boost::math::detail::hypergeometric_1F1_AS_13_3_6(a, b, z, b_minus_a, pol, log_scaling); + } +#if 0 + if ((a > 0) && (b > 0) && (a * z / b > 2)) + { + // + // Series is initially divergent and slow to converge, see if applying + // Kummer's relation can improve things: + // + if (is_convergent_negative_z_series(b_minus_a, b, T(-z), b_minus_a)) + { + long long scaling = lltrunc(z); + T r = exp(z - scaling) * detail::hypergeometric_1F1_checked_series_impl(b_minus_a, b, T(-z), pol, log_scaling); + log_scaling += scaling; + return r; + } + + } +#endif + if ((a > 0) && (b > 0) && (a * z > 50)) + return detail::hypergeometric_1F1_large_abz(a, b, z, pol, log_scaling); + + if (b < 0) + return detail::hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling); + + return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function); + } + + template + inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + // + // Actual result will be result * e^log_scaling. + // + static const thread_local long long max_scaling = lltrunc(boost::math::tools::log_max_value()) - 2; + static const thread_local T max_scale_factor = exp(T(max_scaling)); + + while (log_scaling > max_scaling) + { + result *= max_scale_factor; + log_scaling -= max_scaling; + } + while (log_scaling < -max_scaling) + { + result /= max_scale_factor; + log_scaling += max_scaling; + } + if (log_scaling) + result *= exp(T(log_scaling)); + return result; + } + + template + inline T log_hypergeometric_1F1_imp(const T& a, const T& b, const T& z, int* sign, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + if (sign) + *sign = result < 0 ? -1 : 1; + result = log(fabs(result)) + log_scaling; + return result; + } + + template + inline T hypergeometric_1F1_regularized_imp(const T& a, const T& b, const T& z, const Policy& pol) + { + BOOST_MATH_STD_USING // exp, fabs, sqrt + long long log_scaling = 0; + T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling); + // + // Actual result will be result * e^log_scaling / tgamma(b). + // + int result_sign = 1; + T scale = log_scaling - boost::math::lgamma(b, &result_sign, pol); + + static const thread_local T max_scaling = boost::math::tools::log_max_value() - 2; + static const thread_local T max_scale_factor = exp(max_scaling); + + while (scale > max_scaling) + { + result *= max_scale_factor; + scale -= max_scaling; + } + while (scale < -max_scaling) + { + result /= max_scale_factor; + scale += max_scaling; + } + if (scale != 0) + result *= exp(scale); + return result * result_sign; + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z) +{ + return hypergeometric_1F1(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_1F1_regularized_imp( + static_cast(a), + static_cast(b), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z) +{ + return hypergeometric_1F1_regularized(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::log_hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + 0, + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z) +{ + return log_hypergeometric_1F1(a, b, z, policies::policy<>()); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::log_hypergeometric_1F1_imp( + static_cast(a), + static_cast(b), + static_cast(z), + sign, + forwarding_policy()), + "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign) +{ + return log_hypergeometric_1F1(a, b, z, sign, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/hypergeometric_2F0.hpp b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_2F0.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_2F0.hpp @@ -0,0 +1,163 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2014 Anton Bikineev +// Copyright 2014 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2014 Paul Bristow +// Distributed under 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_HYPERGEOMETRIC_2F0_HPP +#define BOOST_MATH_HYPERGEOMETRIC_2F0_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace detail { + + template + struct hypergeometric_2F0_cf + { + // + // We start this continued fraction at b on index -1 + // and treat the -1 and 0 cases as special cases. + // We do this to avoid adding the continued fraction result + // to 1 so that we can accurately evaluate for small results + // as well as large ones. See http://functions.wolfram.com/07.31.10.0002.01 + // + T a1, a2, z; + int k; + hypergeometric_2F0_cf(T a1_, T a2_, T z_) : a1(a1_), a2(a2_), z(z_), k(-2) {} + typedef std::pair result_type; + + result_type operator()() + { + ++k; + if (k <= 0) + return std::make_pair(z * a1 * a2, 1); + return std::make_pair(-z * (a1 + k) * (a2 + k) / (k + 1), 1 + z * (a1 + k) * (a2 + k) / (k + 1)); + } + }; + + template + T hypergeometric_2F0_cf_imp(T a1, T a2, T z, const Policy& pol, const char* function) + { + using namespace boost::math; + hypergeometric_2F0_cf evaluator(a1, a2, z); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + T cf = tools::continued_fraction_b(evaluator, policies::get_epsilon(), max_iter); + policies::check_series_iterations(function, max_iter, pol); + return cf; + } + + + template + inline T hypergeometric_2F0_imp(T a1, T a2, const T& z, const Policy& pol, bool asymptotic = false) + { + // + // The terms in this series go to infinity unless one of a1 and a2 is a negative integer. + // + using std::swap; + BOOST_MATH_STD_USING + + static const char* const function = "boost::math::hypergeometric_2F0<%1%,%1%,%1%>(%1%,%1%,%1%)"; + + if (z == 0) + return 1; + + bool is_a1_integer = (a1 == floor(a1)); + bool is_a2_integer = (a2 == floor(a2)); + + if (!asymptotic && !is_a1_integer && !is_a2_integer) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + if (!is_a1_integer || (a1 > 0)) + { + swap(a1, a2); + swap(is_a1_integer, is_a2_integer); + } + // + // At this point a1 must be a negative integer: + // + if(!asymptotic && (!is_a1_integer || (a1 > 0))) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + // + // Special cases first: + // + if (a1 == 0) + return 1; + if ((a1 == a2 - 0.5f) && (z < 0)) + { + // http://functions.wolfram.com/07.31.03.0083.01 + int n = static_cast(static_cast(boost::math::lltrunc(-2 * a1))); + T smz = sqrt(-z); + return pow(2 / smz, -n) * boost::math::hermite(n, 1 / smz, pol); + } + + if (is_a1_integer && is_a2_integer) + { + if ((a1 < 1) && (a2 <= a1)) + { + const unsigned int n = static_cast(static_cast(boost::math::lltrunc(-a1))); + const unsigned int m = static_cast(static_cast(boost::math::lltrunc(-a2 - n))); + + return (pow(z, T(n)) * boost::math::factorial(n, pol)) * + boost::math::laguerre(n, m, -(1 / z), pol); + } + else if ((a2 < 1) && (a1 <= a2)) + { + // function is symmetric for a1 and a2 + const unsigned int n = static_cast(static_cast(boost::math::lltrunc(-a2))); + const unsigned int m = static_cast(static_cast(boost::math::lltrunc(-a1 - n))); + + return (pow(z, T(n)) * boost::math::factorial(n, pol)) * + boost::math::laguerre(n, m, -(1 / z), pol); + } + } + + if ((a1 * a2 * z < 0) && (a2 < -5) && (fabs(a1 * a2 * z) > 0.5)) + { + // Series is alternating and maybe divergent at least for the first few terms + // (until a2 goes positive), try the continued fraction: + return hypergeometric_2F0_cf_imp(a1, a2, z, pol, function); + } + + return detail::hypergeometric_2F0_generic_series(a1, a2, z, pol); + } + +} // namespace detail + +template +inline typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy& /* pol */) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + return policies::checked_narrowing_cast( + detail::hypergeometric_2F0_imp( + static_cast(a1), + static_cast(a2), + static_cast(z), + forwarding_policy()), + "boost::math::hypergeometric_2F0<%1%>(%1%,%1%,%1%)"); +} + +template +inline typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z) +{ + return hypergeometric_2F0(a1, a2, z, policies::policy<>()); +} + + + } } // namespace boost::math + +#endif // BOOST_MATH_HYPERGEOMETRIC_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/hypergeometric_pFq.hpp b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_pFq.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypergeometric_pFq.hpp @@ -0,0 +1,194 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2018 John Maddock +// Distributed under 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_HYPERGEOMETRIC_PFQ_HPP +#define BOOST_MATH_HYPERGEOMETRIC_PFQ_HPP + +#include +#include +#include +#include + +namespace boost { + namespace math { + + namespace detail { + + struct pFq_termination_exception : public std::runtime_error + { + pFq_termination_exception(const char* p) : std::runtime_error(p) {} + }; + + struct timed_iteration_terminator + { + timed_iteration_terminator(std::uintmax_t i, double t) : max_iter(i), max_time(t), start_time(std::chrono::system_clock::now()) {} + + bool operator()(std::uintmax_t iter)const + { + if (iter > max_iter) + BOOST_MATH_THROW_EXCEPTION(boost::math::detail::pFq_termination_exception("pFq exceeded maximum permitted iterations.")); + if (std::chrono::duration(std::chrono::system_clock::now() - start_time).count() > max_time) + BOOST_MATH_THROW_EXCEPTION(boost::math::detail::pFq_termination_exception("pFq exceeded maximum permitted evaluation time.")); + return false; + } + + std::uintmax_t max_iter; + double max_time; + std::chrono::system_clock::time_point start_time; + }; + + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const Seq& aj, const Seq& bj, const Real& z, Real* p_abs_error, const Policy& pol) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + BOOST_MATH_STD_USING + + long long scale = 0; + std::pair r = boost::math::detail::hypergeometric_pFq_checked_series_impl(aj, bj, value_type(z), pol, boost::math::detail::iteration_terminator(boost::math::policies::get_max_series_iterations()), scale); + r.first *= exp(Real(scale)); + r.second *= exp(Real(scale)); + if (p_abs_error) + *p_abs_error = static_cast(r.second) * boost::math::tools::epsilon(); + return policies::checked_narrowing_cast(r.first, "boost::math::hypergeometric_pFq<%1%>(%1%,%1%,%1%)"); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const Seq& aj, const Seq& bj, const Real& z, Real* p_abs_error = 0) + { + return hypergeometric_pFq(aj, bj, z, p_abs_error, boost::math::policies::policy<>()); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, Real* p_abs_error, const Policy& pol) + { + return hypergeometric_pFq, Real, Policy>(aj, bj, z, p_abs_error, pol); + } + + template + inline typename tools::promote_args::type hypergeometric_pFq(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, Real* p_abs_error = nullptr) + { + return hypergeometric_pFq, Real>(aj, bj, z, p_abs_error); + } + + template + struct scoped_precision + { + scoped_precision(unsigned p) + { + old_p = T::default_precision(); + T::default_precision(p); + } + ~scoped_precision() + { + T::default_precision(old_p); + } + unsigned old_p; + }; + + template + Real hypergeometric_pFq_precision(const Seq& aj, const Seq& bj, Real z, unsigned digits10, double timeout, const Policy& pol) + { + unsigned current_precision = digits10 + 5; + + for (auto ai = aj.begin(); ai != aj.end(); ++ai) + { + current_precision = (std::max)(current_precision, ai->precision()); + } + for (auto bi = bj.begin(); bi != bj.end(); ++bi) + { + current_precision = (std::max)(current_precision, bi->precision()); + } + current_precision = (std::max)(current_precision, z.precision()); + + Real r, norm; + std::vector aa(aj), bb(bj); + do + { + scoped_precision p(current_precision); + for (auto ai = aa.begin(); ai != aa.end(); ++ai) + ai->precision(current_precision); + for (auto bi = bb.begin(); bi != bb.end(); ++bi) + bi->precision(current_precision); + z.precision(current_precision); + try + { + long long scale = 0; + std::pair rp = boost::math::detail::hypergeometric_pFq_checked_series_impl(aa, bb, z, pol, boost::math::detail::timed_iteration_terminator(boost::math::policies::get_max_series_iterations(), timeout), scale); + rp.first *= exp(Real(scale)); + rp.second *= exp(Real(scale)); + + r = rp.first; + norm = rp.second; + + unsigned cancellation; + try { + cancellation = itrunc(log10(abs(norm / r))); + } + catch (const boost::math::rounding_error&) + { + // Happens when r is near enough zero: + cancellation = UINT_MAX; + } + if (cancellation >= current_precision - 1) + { + current_precision *= 2; + continue; + } + unsigned precision_obtained = current_precision - 1 - cancellation; + if (precision_obtained < digits10) + { + current_precision += digits10 - precision_obtained + 5; + } + else + break; + } + catch (const boost::math::evaluation_error&) + { + current_precision *= 2; + } + catch (const detail::pFq_termination_exception& e) + { + // + // Either we have exhausted the number of series iterations, or the timeout. + // Either way we quit now. + throw boost::math::evaluation_error(e.what()); + } + } while (true); + + return r; + } + template + Real hypergeometric_pFq_precision(const Seq& aj, const Seq& bj, const Real& z, unsigned digits10, double timeout = 0.5) + { + return hypergeometric_pFq_precision(aj, bj, z, digits10, timeout, boost::math::policies::policy<>()); + } + + template + Real hypergeometric_pFq_precision(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, unsigned digits10, double timeout, const Policy& pol) + { + return hypergeometric_pFq_precision< std::initializer_list, Real>(aj, bj, z, digits10, timeout, pol); + } + template + Real hypergeometric_pFq_precision(const std::initializer_list& aj, const std::initializer_list& bj, const Real& z, unsigned digits10, double timeout = 0.5) + { + return hypergeometric_pFq_precision< std::initializer_list, Real>(aj, bj, z, digits10, timeout, boost::math::policies::policy<>()); + } + + } +} // namespaces + +#endif // BOOST_MATH_BESSEL_ITERATORS_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/hypot.hpp b/libcxx/src/third-party/boost/math/special_functions/hypot.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/hypot.hpp @@ -0,0 +1,82 @@ +// (C) Copyright John Maddock 2005-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_HYPOT_INCLUDED +#define BOOST_MATH_HYPOT_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include // for swap +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T hypot_imp(T x, T y, const Policy& pol) +{ + // + // Normalize x and y, so that both are positive and x >= y: + // + using std::fabs; using std::sqrt; // ADL of std names + + x = fabs(x); + y = fabs(y); + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4127) +#endif + // special case, see C99 Annex F: + if(std::numeric_limits::has_infinity + && ((x == std::numeric_limits::infinity()) + || (y == std::numeric_limits::infinity()))) + return policies::raise_overflow_error("boost::math::hypot<%1%>(%1%,%1%)", nullptr, pol); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + if(y > x) + (std::swap)(x, y); + + if(x * tools::epsilon() >= y) + return x; + + T rat = y / x; + return x * sqrt(1 + rat*rat); +} // template T hypot(T x, T y) + +} + +template +inline typename tools::promote_args::type + hypot(T1 x, T2 y) +{ + typedef typename tools::promote_args::type result_type; + return detail::hypot_imp( + static_cast(x), static_cast(y), policies::policy<>()); +} + +template +inline typename tools::promote_args::type + hypot(T1 x, T2 y, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::hypot_imp( + static_cast(x), static_cast(y), pol); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_HYPOT_INCLUDED + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/jacobi.hpp b/libcxx/src/third-party/boost/math/special_functions/jacobi.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/jacobi.hpp @@ -0,0 +1,69 @@ +// (C) Copyright Nick Thompson 2019. +// 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_JACOBI_HPP +#define BOOST_MATH_SPECIAL_JACOBI_HPP + +#include +#include + +namespace boost { namespace math { + +template +Real jacobi(unsigned n, Real alpha, Real beta, Real x) +{ + static_assert(!std::is_integral::value, "Jacobi polynomials do not work with integer arguments."); + + if (n == 0) { + return Real(1); + } + Real y0 = 1; + Real y1 = (alpha+1) + (alpha+beta+2)*(x-1)/Real(2); + + Real yk = y1; + Real k = 2; + Real k_max = n*(1+std::numeric_limits::epsilon()); + while(k < k_max) + { + // Hoping for lots of common subexpression elimination by the compiler: + Real denom = 2*k*(k+alpha+beta)*(2*k+alpha+beta-2); + Real gamma1 = (2*k+alpha+beta-1)*( (2*k+alpha+beta)*(2*k+alpha+beta-2)*x + alpha*alpha -beta*beta); + Real gamma0 = -2*(k+alpha-1)*(k+beta-1)*(2*k+alpha+beta); + yk = (gamma1*y1 + gamma0*y0)/denom; + y0 = y1; + y1 = yk; + k += 1; + } + return yk; +} + +template +Real jacobi_derivative(unsigned n, Real alpha, Real beta, Real x, unsigned k) +{ + if (k > n) { + return Real(0); + } + Real scale = 1; + for(unsigned j = 1; j <= k; ++j) { + scale *= (alpha + beta + n + j)/2; + } + + return scale*jacobi(n-k, alpha + k, beta+k, x); +} + +template +Real jacobi_prime(unsigned n, Real alpha, Real beta, Real x) +{ + return jacobi_derivative(n, alpha, beta, x, 1); +} + +template +Real jacobi_double_prime(unsigned n, Real alpha, Real beta, Real x) +{ + return jacobi_derivative(n, alpha, beta, x, 2); +} + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/jacobi_elliptic.hpp b/libcxx/src/third-party/boost/math/special_functions/jacobi_elliptic.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/jacobi_elliptic.hpp @@ -0,0 +1,321 @@ +// Copyright John Maddock 2012. +// 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_JACOBI_ELLIPTIC_HPP +#define BOOST_MATH_JACOBI_ELLIPTIC_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +T jacobi_recurse(const T& x, const T& k, T anm1, T bnm1, unsigned N, T* pTn, const Policy& pol) +{ + BOOST_MATH_STD_USING + ++N; + T Tn; + T cn = (anm1 - bnm1) / 2; + T an = (anm1 + bnm1) / 2; + if(cn < policies::get_epsilon()) + { + Tn = ldexp(T(1), (int)N) * x * an; + } + else + Tn = jacobi_recurse(x, k, an, sqrt(anm1 * bnm1), N, 0, pol); + if(pTn) + *pTn = Tn; + return (Tn + asin((cn / an) * sin(Tn))) / 2; +} + +template +T jacobi_imp(const T& x, const T& k, T* cn, T* dn, const Policy& pol, const char* function) +{ + BOOST_MATH_STD_USING + if(k < 0) + { + *cn = policies::raise_domain_error(function, "Modulus k must be positive but got %1%.", k, pol); + *dn = *cn; + return *cn; + } + if(k > 1) + { + T xp = x * k; + T kp = 1 / k; + T snp, cnp, dnp; + snp = jacobi_imp(xp, kp, &cnp, &dnp, pol, function); + *cn = dnp; + *dn = cnp; + return snp * kp; + } + // + // Special cases first: + // + if(x == 0) + { + *cn = *dn = 1; + return 0; + } + if(k == 0) + { + *cn = cos(x); + *dn = 1; + return sin(x); + } + if(k == 1) + { + *cn = *dn = 1 / cosh(x); + return tanh(x); + } + // + // Asymptotic forms from A&S 16.13: + // + if(k < tools::forth_root_epsilon()) + { + T su = sin(x); + T cu = cos(x); + T m = k * k; + *dn = 1 - m * su * su / 2; + *cn = cu + m * (x - su * cu) * su / 4; + return su - m * (x - su * cu) * cu / 4; + } + /* Can't get this to work to adequate precision - disabled for now... + // + // Asymptotic forms from A&S 16.15: + // + if(k > 1 - tools::root_epsilon()) + { + T tu = tanh(x); + T su = sinh(x); + T cu = cosh(x); + T sec = 1 / cu; + T kp = 1 - k; + T m1 = 2 * kp - kp * kp; + *dn = sec + m1 * (su * cu + x) * tu * sec / 4; + *cn = sec - m1 * (su * cu - x) * tu * sec / 4; + T sn = tu; + T sn2 = m1 * (x * sec * sec - tu) / 4; + T sn3 = (72 * x * cu + 4 * (8 * x * x - 5) * su - 19 * sinh(3 * x) + sinh(5 * x)) * sec * sec * sec * m1 * m1 / 512; + return sn + sn2 - sn3; + }*/ + T T1; + T kc = 1 - k; + T k_prime = k < 0.5 ? T(sqrt(1 - k * k)) : T(sqrt(2 * kc - kc * kc)); + T T0 = jacobi_recurse(x, k, T(1), k_prime, 0, &T1, pol); + *cn = cos(T0); + *dn = cos(T0) / cos(T1 - T0); + return sin(T0); +} + +} // namespace detail + +template +inline typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&) +{ + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_elliptic<%1%>(%1%)"; + + value_type sn, cn, dn; + sn = detail::jacobi_imp(static_cast(theta), static_cast(k), &cn, &dn, forwarding_policy(), function); + if(pcn) + *pcn = policies::checked_narrowing_cast(cn, function); + if(pdn) + *pdn = policies::checked_narrowing_cast(dn, function); + return policies::checked_narrowing_cast(sn, function); +} + +template +inline typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn) +{ + return jacobi_elliptic(k, theta, pcn, pdn, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sn(U k, T theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), static_cast(nullptr), pol); +} + +template +inline typename tools::promote_args::type jacobi_sn(U k, T theta) +{ + return jacobi_sn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cn(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return cn; +} + +template +inline typename tools::promote_args::type jacobi_cn(T k, U theta) +{ + return jacobi_cn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_dn(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type dn; + jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return dn; +} + +template +inline typename tools::promote_args::type jacobi_dn(T k, U theta) +{ + return jacobi_dn(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cd(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn, dn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, &dn, pol); + return cn / dn; +} + +template +inline typename tools::promote_args::type jacobi_cd(T k, U theta) +{ + return jacobi_cd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_dc(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type cn, dn; + jacobi_elliptic(static_cast(k), static_cast(theta), &cn, &dn, pol); + return dn / cn; +} + +template +inline typename tools::promote_args::type jacobi_dc(T k, U theta) +{ + return jacobi_dc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_ns(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return 1 / jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), static_cast(nullptr), pol); +} + +template +inline typename tools::promote_args::type jacobi_ns(T k, U theta) +{ + return jacobi_ns(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sd(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, dn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return sn / dn; +} + +template +inline typename tools::promote_args::type jacobi_sd(T k, U theta) +{ + return jacobi_sd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_ds(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, dn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), static_cast(nullptr), &dn, pol); + return dn / sn; +} + +template +inline typename tools::promote_args::type jacobi_ds(T k, U theta) +{ + return jacobi_ds(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_nc(T k, U theta, const Policy& pol) +{ + return 1 / jacobi_cn(k, theta, pol); +} + +template +inline typename tools::promote_args::type jacobi_nc(T k, U theta) +{ + return jacobi_nc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_nd(T k, U theta, const Policy& pol) +{ + return 1 / jacobi_dn(k, theta, pol); +} + +template +inline typename tools::promote_args::type jacobi_nd(T k, U theta) +{ + return jacobi_nd(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_sc(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, cn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return sn / cn; +} + +template +inline typename tools::promote_args::type jacobi_sc(T k, U theta) +{ + return jacobi_sc(k, theta, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_cs(T k, U theta, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + result_type sn, cn; + sn = jacobi_elliptic(static_cast(k), static_cast(theta), &cn, static_cast(nullptr), pol); + return cn / sn; +} + +template +inline typename tools::promote_args::type jacobi_cs(T k, U theta) +{ + return jacobi_cs(k, theta, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_JACOBI_ELLIPTIC_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/jacobi_theta.hpp b/libcxx/src/third-party/boost/math/special_functions/jacobi_theta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/jacobi_theta.hpp @@ -0,0 +1,835 @@ +// Jacobi theta functions +// Copyright Evan Miller 2020 +// +// 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) +// +// Four main theta functions with various flavors of parameterization, +// floating-point policies, and bonus "minus 1" versions of functions 3 and 4 +// designed to preserve accuracy for small q. Twenty-four C++ functions are +// provided in all. +// +// The functions take a real argument z and a parameter known as q, or its close +// relative tau. +// +// The mathematical functions are best understood in terms of their Fourier +// series. Using the q parameterization, and summing from n = 0 to INF: +// +// theta_1(z,q) = 2 SUM (-1)^n * q^(n+1/2)^2 * sin((2n+1)z) +// theta_2(z,q) = 2 SUM q^(n+1/2)^2 * cos((2n+1)z) +// theta_3(z,q) = 1 + 2 SUM q^n^2 * cos(2nz) +// theta_4(z,q) = 1 + 2 SUM (-1)^n * q^n^2 * cos(2nz) +// +// Appropriately multiplied and divided, these four theta functions can be used +// to implement the famous Jacabi elliptic functions - but this is not really +// recommended, as the existing Boost implementations are likely faster and +// more accurate. More saliently, setting z = 0 on the fourth theta function +// will produce the limiting CDF of the Kolmogorov-Smirnov distribution, which +// is this particular implementation's raison d'etre. +// +// Separate C++ functions are provided for q and for tau. The main q functions are: +// +// template inline T jacobi_theta1(T z, T q); +// template inline T jacobi_theta2(T z, T q); +// template inline T jacobi_theta3(T z, T q); +// template inline T jacobi_theta4(T z, T q); +// +// The parameter q, also known as the nome, is restricted to the domain (0, 1), +// and will throw a domain error otherwise. +// +// The equivalent functions that use tau instead of q are: +// +// template inline T jacobi_theta1tau(T z, T tau); +// template inline T jacobi_theta2tau(T z, T tau); +// template inline T jacobi_theta3tau(T z, T tau); +// template inline T jacobi_theta4tau(T z, T tau); +// +// Mathematically, q and tau are related by: +// +// q = exp(i PI*Tau) +// +// However, the tau in the equation above is *not* identical to the tau in the function +// signature. Instead, `tau` is the imaginary component of tau. Mathematically, tau can +// be complex - but practically, most applications call for a purely imaginary tau. +// Rather than provide a full complex-number API, the author decided to treat the +// parameter `tau` as an imaginary number. So in computational terms, the +// relationship between `q` and `tau` is given by: +// +// q = exp(-constants::pi() * tau) +// +// The tau versions are provided for the sake of accuracy, as well as conformance +// with common notation. If your q is an exponential, you are better off using +// the tau versions, e.g. +// +// jacobi_theta1(z, exp(-a)); // rather poor accuracy +// jacobi_theta1tau(z, a / constants::pi()); // better accuracy +// +// Similarly, if you have a precise (small positive) value for the complement +// of q, you can obtain a more precise answer overall by passing the result of +// `log1p` to the tau parameter: +// +// jacobi_theta1(z, 1-q_complement); // precision lost in subtraction +// jacobi_theta1tau(z, -log1p(-q_complement) / constants::pi()); // better! +// +// A third quartet of functions are provided for improving accuracy in cases +// where q is small, specifically |q| < exp(-PI) = 0.04 (or, equivalently, tau +// greater than unity). In this domain of q values, the third and fourth theta +// functions always return values close to 1. So the following "m1" functions +// are provided, similar in spirit to `expm1`, which return one less than their +// regular counterparts: +// +// template inline T jacobi_theta3m1(T z, T q); +// template inline T jacobi_theta4m1(T z, T q); +// template inline T jacobi_theta3m1tau(T z, T tau); +// template inline T jacobi_theta4m1tau(T z, T tau); +// +// Note that "m1" versions of the first and second theta would not be useful, +// as their ranges are not confined to a neighborhood around 1 (see the Fourier +// transform representations above). +// +// Finally, the twelve functions above are each available with a third Policy +// argument, which can be used to define a custom epsilon value. These Policy +// versions bring the total number of functions provided by jacobi_theta.hpp +// to twenty-four. +// +// See: +// https://mathworld.wolfram.com/JacobiThetaFunctions.html +// https://dlmf.nist.gov/20 + +#ifndef BOOST_MATH_JACOBI_THETA_HPP +#define BOOST_MATH_JACOBI_THETA_HPP + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ + +// Simple functions - parameterized by q +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q); + +// Simple functions - parameterized by tau (assumed imaginary) +// q = exp(i*PI*TAU) +// tau = -log(q)/PI +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau); + +// Minus one versions for small q / large tau +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q); +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau); +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau); + +// Policied versions - parameterized by q +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy& pol); + +// Policied versions - parameterized by tau +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy& pol); + +// Policied m1 functions +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy& pol); +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy& pol); + +// Compare the non-oscillating component of the delta to the previous delta. +// Both are assumed to be non-negative. +template +inline bool +_jacobi_theta_converged(RealType last_delta, RealType delta, RealType eps) { + return delta == 0.0 || delta < eps*last_delta; +} + +template +inline RealType +_jacobi_theta_sum(RealType tau, RealType z_n, RealType z_increment, RealType eps) { + BOOST_MATH_STD_USING + RealType delta = 0, partial_result = 0; + RealType last_delta = 0; + + do { + last_delta = delta; + delta = exp(-tau*z_n*z_n/constants::pi()); + partial_result += delta; + z_n += z_increment; + } while (!_jacobi_theta_converged(last_delta, delta, eps)); + + return partial_result; +} + +// The following _IMAGINARY theta functions assume imaginary z and are for +// internal use only. They are designed to increase accuracy and reduce the +// number of iterations required for convergence for large |q|. The z argument +// is scaled by tau, and the summations are rewritten to be double-sided +// following DLMF 20.13.4 and 20.13.5. The return values are scaled by +// exp(-tau*z^2/Pi)/sqrt(tau). +// +// These functions are triggered when tau < 1, i.e. |q| > exp(-Pi) = 0.043 +// +// Note that jacobi_theta4 uses the imaginary version of jacobi_theta2 (and +// vice-versa). jacobi_theta1 and jacobi_theta3 use the imaginary versions of +// themselves, following DLMF 20.7.30 - 20.7.33. +template +inline RealType +_IMAGINARY_jacobi_theta1tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = RealType(0); + + // n>=0 even + result -= _jacobi_theta_sum(tau, RealType(z + constants::half_pi()), constants::two_pi(), eps); + // n>0 odd + result += _jacobi_theta_sum(tau, RealType(z + constants::half_pi() + constants::pi()), constants::two_pi(), eps); + // n<0 odd + result += _jacobi_theta_sum(tau, RealType(z - constants::half_pi()), RealType (-constants::two_pi()), eps); + // n<0 even + result -= _jacobi_theta_sum(tau, RealType(z - constants::half_pi() - constants::pi()), RealType (-constants::two_pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta2tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = RealType(0); + + // n>=0 + result += _jacobi_theta_sum(tau, RealType(z + constants::half_pi()), constants::pi(), eps); + // n<0 + result += _jacobi_theta_sum(tau, RealType(z - constants::half_pi()), RealType (-constants::pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta3tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = 0; + + // n=0 + result += exp(-z*z*tau/constants::pi()); + // n>0 + result += _jacobi_theta_sum(tau, RealType(z + constants::pi()), constants::pi(), eps); + // n<0 + result += _jacobi_theta_sum(tau, RealType(z - constants::pi()), RealType(-constants::pi()), eps); + + return result * sqrt(tau); +} + +template +inline RealType +_IMAGINARY_jacobi_theta4tau(RealType z, RealType tau, const Policy&) { + BOOST_MATH_STD_USING + RealType eps = policies::get_epsilon(); + RealType result = 0; + + // n = 0 + result += exp(-z*z*tau/constants::pi()); + + // n > 0 odd + result -= _jacobi_theta_sum(tau, RealType(z + constants::pi()), constants::two_pi(), eps); + // n < 0 odd + result -= _jacobi_theta_sum(tau, RealType(z - constants::pi()), RealType (-constants::two_pi()), eps); + // n > 0 even + result += _jacobi_theta_sum(tau, RealType(z + constants::two_pi()), constants::two_pi(), eps); + // n < 0 even + result += _jacobi_theta_sum(tau, RealType(z - constants::two_pi()), RealType (-constants::two_pi()), eps); + + return result * sqrt(tau); +} + +// First Jacobi theta function (Parameterized by tau - assumed imaginary) +// = 2 * SUM (-1)^n * exp(i*Pi*Tau*(n+1/2)^2) * sin((2n+1)z) +template +inline RealType +jacobi_theta1tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + unsigned n = 0; + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + + if (tau <= 0.0) + return policies::raise_domain_error(function, + "tau must be greater than 0 but got %1%.", tau, pol); + + if (abs(z) == 0.0) + return result; + + if (tau < 1.0) { + z = fmod(z, constants::two_pi()); + while (z > constants::pi()) { + z -= constants::two_pi(); + } + while (z < -constants::pi()) { + z += constants::two_pi(); + } + + return _IMAGINARY_jacobi_theta1tau(z, RealType(1/tau), pol); + } + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n + 0.5)*RealType(n + 0.5) ); + delta = q_n * sin(RealType(2*n+1)*z); + if (n%2) + delta = -delta; + + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// First Jacobi theta function (Parameterized by q) +// = 2 * SUM (-1)^n * q^(n+1/2)^2 * sin((2n+1)z) +template +inline RealType +jacobi_theta1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta1tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Second Jacobi theta function (Parameterized by tau - assumed imaginary) +// = 2 * SUM exp(i*Pi*Tau*(n+1/2)^2) * cos((2n+1)z) +template +inline RealType +jacobi_theta2tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + unsigned n = 0; + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + + if (tau <= 0.0) { + return policies::raise_domain_error(function, + "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta4tau(z, 1/tau, pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.31 + z = fmod(z, constants::two_pi()); + while (z > constants::pi()) { + z -= constants::two_pi(); + } + while (z < -constants::pi()) { + z += constants::two_pi(); + } + + return _IMAGINARY_jacobi_theta4tau(z, RealType(1/tau), pol); + } + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n + 0.5)*RealType(n + 0.5)); + delta = q_n * cos(RealType(2*n+1)*z); + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Second Jacobi theta function, parameterized by q +// = 2 * SUM q^(n+1/2)^2 * cos((2n+1)z) +template +inline RealType +jacobi_theta2_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta2tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Third Jacobi theta function, minus one (Parameterized by tau - assumed imaginary) +// This function preserves accuracy for small values of q (i.e. |q| < exp(-Pi) = 0.043) +// For larger values of q, the minus one version usually won't help. +// = 2 * SUM exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta3m1tau_imp(RealType z, RealType tau, const Policy& pol) +{ + BOOST_MATH_STD_USING + + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + unsigned n = 1; + + if (tau < 1.0) + return jacobi_theta3tau(z, tau, pol) - RealType(1); + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n)*RealType(n)); + delta = q_n * cos(RealType(2*n)*z); + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Third Jacobi theta function, parameterized by tau +// = 1 + 2 * SUM exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta3tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + if (tau <= 0.0) { + return policies::raise_domain_error(function, + "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta3tau(z, RealType(1/tau), pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.32 + z = fmod(z, constants::pi()); + while (z > constants::half_pi()) { + z -= constants::pi(); + } + while (z < -constants::half_pi()) { + z += constants::pi(); + } + return _IMAGINARY_jacobi_theta3tau(z, RealType(1/tau), pol); + } + return RealType(1) + jacobi_theta3m1tau_imp(z, tau, pol); +} + +// Third Jacobi theta function, minus one (parameterized by q) +// = 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta3m1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta3m1tau_imp(z, RealType (-log(q)/constants::pi()), pol); +} + +// Third Jacobi theta function (parameterized by q) +// = 1 + 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta3_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta3tau_imp(z, RealType (-log(q)/constants::pi()), pol, function); +} + +// Fourth Jacobi theta function, minus one (Parameterized by tau) +// This function preserves accuracy for small values of q (i.e. tau > 1) +// = 2 * SUM (-1)^n exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta4m1tau_imp(RealType z, RealType tau, const Policy& pol) +{ + BOOST_MATH_STD_USING + + RealType eps = policies::get_epsilon(); + RealType q_n = 0, last_q_n, delta, result = 0; + unsigned n = 1; + + if (tau < 1.0) + return jacobi_theta4tau(z, tau, pol) - RealType(1); + + do { + last_q_n = q_n; + q_n = exp(-tau * constants::pi() * RealType(n)*RealType(n)); + delta = q_n * cos(RealType(2*n)*z); + if (n%2) + delta = -delta; + + result += delta + delta; + n++; + } while (!_jacobi_theta_converged(last_q_n, q_n, eps)); + + return result; +} + +// Fourth Jacobi theta function (Parameterized by tau) +// = 1 + 2 * SUM (-1)^n exp(i*Pi*Tau*(n)^2) * cos(2nz) +template +inline RealType +jacobi_theta4tau_imp(RealType z, RealType tau, const Policy& pol, const char *function) +{ + BOOST_MATH_STD_USING + if (tau <= 0.0) { + return policies::raise_domain_error(function, + "tau must be greater than 0 but got %1%.", tau, pol); + } else if (tau < 1.0 && abs(z) == 0.0) { + return jacobi_theta2tau(z, 1/tau, pol) / sqrt(tau); + } else if (tau < 1.0) { // DLMF 20.7.33 + z = fmod(z, constants::pi()); + while (z > constants::half_pi()) { + z -= constants::pi(); + } + while (z < -constants::half_pi()) { + z += constants::pi(); + } + return _IMAGINARY_jacobi_theta2tau(z, RealType(1/tau), pol); + } + + return RealType(1) + jacobi_theta4m1tau_imp(z, tau, pol); +} + +// Fourth Jacobi theta function, minus one (Parameterized by q) +// This function preserves accuracy for small values of q +// = 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta4m1_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "q must be greater than 0 and less than 1 but got %1%.", q, pol); + } + return jacobi_theta4m1tau_imp(z, RealType (-log(q)/constants::pi()), pol); +} + +// Fourth Jacobi theta function, parameterized by q +// = 1 + 2 * SUM q^n^2 * cos(2nz) +template +inline RealType +jacobi_theta4_imp(RealType z, RealType q, const Policy& pol, const char *function) { + BOOST_MATH_STD_USING + if (q <= 0.0 || q >= 1.0) { + return policies::raise_domain_error(function, + "|q| must be greater than zero and less than 1, but got %1%.", q, pol); + } + return jacobi_theta4tau_imp(z, RealType(-log(q)/constants::pi()), pol, function); +} + +// Begin public API + +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta1tau_imp(static_cast(z), static_cast(tau), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta1tau(T z, U tau) { + return jacobi_theta1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta1<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta1_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta1(T z, U q) { + return jacobi_theta1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta2tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta2tau_imp(static_cast(z), static_cast(tau), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta2tau(T z, U tau) { + return jacobi_theta2tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta2<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta2_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta2(T z, U q) { + return jacobi_theta2(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3m1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta3m1tau_imp(static_cast(z), static_cast(tau), + forwarding_policy()), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau) { + return jacobi_theta3m1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta3tau_imp(static_cast(z), static_cast(tau), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3tau(T z, U tau) { + return jacobi_theta3tau(z, tau, policies::policy<>()); +} + + +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3m1<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta3m1_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3m1(T z, U q) { + return jacobi_theta3m1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta3<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta3_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta3(T z, U q) { + return jacobi_theta3(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4m1tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta4m1tau_imp(static_cast(z), static_cast(tau), + forwarding_policy()), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau) { + return jacobi_theta4m1tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4tau<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta4tau_imp(static_cast(z), static_cast(tau), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4tau(T z, U tau) { + return jacobi_theta4tau(z, tau, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4m1<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta4m1_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4m1(T z, U q) { + return jacobi_theta4m1(z, q, policies::policy<>()); +} + +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy&) { + BOOST_FPU_EXCEPTION_GUARD + typedef typename tools::promote_args::type result_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + static const char* function = "boost::math::jacobi_theta4<%1%>(%1%)"; + + return policies::checked_narrowing_cast( + jacobi_theta4_imp(static_cast(z), static_cast(q), + forwarding_policy(), function), function); +} + +template +inline typename tools::promote_args::type jacobi_theta4(T z, U q) { + return jacobi_theta4(z, q, policies::policy<>()); +} + +}} + +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/jacobi_zeta.hpp b/libcxx/src/third-party/boost/math/special_functions/jacobi_zeta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/jacobi_zeta.hpp @@ -0,0 +1,81 @@ +// Copyright (c) 2015 John Maddock +// 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_ELLINT_JZ_HPP +#define BOOST_MATH_ELLINT_JZ_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +// Elliptic integral the Jacobi Zeta function. + +namespace boost { namespace math { + +namespace detail{ + +// Elliptic integral - Jacobi Zeta +template +T jacobi_zeta_imp(T phi, T k, const Policy& pol) +{ + BOOST_MATH_STD_USING + using namespace boost::math::tools; + using namespace boost::math::constants; + + bool invert = false; + if(phi < 0) + { + phi = fabs(phi); + invert = true; + } + + T result; + T sinp = sin(phi); + T cosp = cos(phi); + T s2 = sinp * sinp; + T k2 = k * k; + T kp = 1 - k2; + if(k == 1) + result = sinp * (boost::math::sign)(cosp); // We get here by simplifying JacobiZeta[w, 1] in Mathematica, and the fact that 0 <= phi. + else + { + typedef std::integral_constant::value&& std::numeric_limits::digits && (std::numeric_limits::digits <= 54) ? 0 : + std::is_floating_point::value && std::numeric_limits::digits && (std::numeric_limits::digits <= 64) ? 1 : 2 + > precision_tag_type; + result = k2 * sinp * cosp * sqrt(1 - k2 * s2) * ellint_rj_imp(T(0), kp, T(1), T(1 - k2 * s2), pol) / (3 * ellint_k_imp(k, pol, precision_tag_type())); + } + return invert ? T(-result) : result; +} + +} // detail + +template +inline typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::jacobi_zeta_imp(static_cast(phi), static_cast(k), pol), "boost::math::jacobi_zeta<%1%>(%1%,%1%)"); +} + +template +inline typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi) +{ + return boost::math::jacobi_zeta(k, phi, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ELLINT_D_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/laguerre.hpp b/libcxx/src/third-party/boost/math/special_functions/laguerre.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/laguerre.hpp @@ -0,0 +1,139 @@ + +// (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_LAGUERRE_HPP +#define BOOST_MATH_SPECIAL_LAGUERRE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for Laguerre polynomials: +template +inline typename tools::promote_args::type + laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * n + 1 - result_type(x)) * result_type(Ln) - n * result_type(Lnm1)) / (n + 1); +} + +namespace detail{ + +// Implement Laguerre polynomials via recurrence: +template +T laguerre_imp(unsigned n, T x) +{ + T p0 = 1; + T p1 = 1 - x; + + if(n == 0) + return p0; + + unsigned c = 1; + + while(c < n) + { + std::swap(p0, p1); + p1 = laguerre_next(c, x, p0, p1); + ++c; + } + return p1; +} + +template +inline typename tools::promote_args::type +laguerre(unsigned n, T x, const Policy&, const std::true_type&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::laguerre_imp(n, static_cast(x)), "boost::math::laguerre<%1%>(unsigned, %1%)"); +} + +template +inline typename tools::promote_args::type + laguerre(unsigned n, unsigned m, T x, const std::false_type&) +{ + return boost::math::laguerre(n, m, x, policies::policy<>()); +} + +} // namespace detail + +template +inline typename tools::promote_args::type + laguerre(unsigned n, T x) +{ + return laguerre(n, x, policies::policy<>()); +} + +// Recurrence for associated polynomials: +template +inline typename tools::promote_args::type + laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * n + l + 1 - result_type(x)) * result_type(Pl) - (n + l) * result_type(Plm1)) / (n+1); +} + +namespace detail{ +// Laguerre Associated Polynomial: +template +T laguerre_imp(unsigned n, unsigned m, T x, const Policy& pol) +{ + // Special cases: + if(m == 0) + return boost::math::laguerre(n, x, pol); + + T p0 = 1; + + if(n == 0) + return p0; + + T p1 = m + 1 - x; + + unsigned c = 1; + + while(c < n) + { + std::swap(p0, p1); + p1 = laguerre_next(c, m, x, p0, p1); + ++c; + } + return p1; +} + +} + +template +inline typename tools::promote_args::type + laguerre(unsigned n, unsigned m, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::laguerre_imp(n, m, static_cast(x), pol), "boost::math::laguerre<%1%>(unsigned, unsigned, %1%)"); +} + +template +inline typename laguerre_result::type + laguerre(unsigned n, T1 m, T2 x) +{ + typedef typename policies::is_policy::type tag_type; + return detail::laguerre(n, m, x, tag_type()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_LAGUERRE_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/lambert_w.hpp b/libcxx/src/third-party/boost/math/special_functions/lambert_w.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/lambert_w.hpp @@ -0,0 +1,2183 @@ +// Copyright John Maddock 2017. +// Copyright Paul A. Bristow 2016, 2017, 2018. +// Copyright Nicholas Thompson 2018 + +// Distributed under 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_SF_LAMBERT_W_HPP +#define BOOST_MATH_SF_LAMBERT_W_HPP + +#ifdef _MSC_VER +#pragma warning(disable : 4127) +#endif + +/* +Implementation of an algorithm for the Lambert W0 and W-1 real-only functions. + +This code is based in part on the algorithm by +Toshio Fukushima, +"Precise and fast computation of Lambert W-functions without transcendental function evaluations", +J.Comp.Appl.Math. 244 (2013) 77-89, +and on a C/C++ version by Darko Veberic, darko.veberic@ijs.si +based on the Fukushima algorithm and Toshio Fukushima's FORTRAN version of his algorithm. + +First derivative of Lambert_w is derived from +Princeton Companion to Applied Mathematics, 'The Lambert-W function', Section 1.3: Series and Generating Functions. + +*/ + +/* +TODO revise this list of macros. +Some macros that will show some (or much) diagnostic values if #defined. +//[boost_math_instrument_lambert_w_macros + +// #define-able macros +BOOST_MATH_INSTRUMENT_LAMBERT_W_HALLEY // Halley refinement diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_W_PRECISION // Precision. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1 // W1 branch diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_HALLEY // Halley refinement diagnostics only for W-1 branch. +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY // K > 64, z > -1.0264389699511303e-26 +BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP // Show results from W-1 lookup table. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER // Schroeder refinement diagnostics. +BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS // Number of terms used for near-singularity series. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES // Show evaluation of series near branch singularity. +BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES +BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS // Show evaluation of series for small z. +//] [/boost_math_instrument_lambert_w_macros] +*/ + +#include +#include +#include +#include +#include // for log (1 + x) +#include // For exp_minus_one == 3.67879441171442321595523770161460867e-01. +#include // powers with compile time exponent, used in arbitrary precision code. +#include // series functor. +//#include // polynomial. +#include // evaluate_polynomial. +#include // boost::math::tools::max_value(). +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +#include +#include +#include +#include +#include +#include + +// Needed for testing and diagnostics only. +#include +#include +#include // For float_distance. + +using lookup_t = double; // Type for lookup table (double or float, or even long double?) + +//#include "J:\Cpp\Misc\lambert_w_lookup_table_generator\lambert_w_lookup_table.ipp" +// #include "lambert_w_lookup_table.ipp" // Boost.Math version. +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost { +namespace math { +namespace lambert_w_detail { + +//! \brief Applies a single Halley step to make a better estimate of Lambert W. +//! \details Used the simplified formulae obtained from +//! http://www.wolframalpha.com/input/?i=%5B2(z+exp(z)-w)+d%2Fdx+(z+exp(z)-w)%5D+%2F+%5B2+(d%2Fdx+(z+exp(z)-w))%5E2+-+(z+exp(z)-w)+d%5E2%2Fdx%5E2+(z+exp(z)-w)%5D +//! [2(z exp(z)-w) d/dx (z exp(z)-w)] / [2 (d/dx (z exp(z)-w))^2 - (z exp(z)-w) d^2/dx^2 (z exp(z)-w)] + +//! \tparam T floating-point (or fixed-point) type. +//! \param w_est Lambert W estimate. +//! \param z Argument z for Lambert_w function. +//! \returns New estimate of Lambert W, hopefully improved. +//! +template +inline T lambert_w_halley_step(T w_est, const T z) +{ + BOOST_MATH_STD_USING + T e = exp(w_est); + w_est -= 2 * (w_est + 1) * (e * w_est - z) / (z * (w_est + 2) + e * (w_est * (w_est + 2) + 2)); + return w_est; +} // template lambert_w_halley_step(T w_est, T z) + +//! \brief Halley iterate to refine Lambert_w estimate, +//! taking at least one Halley_step. +//! Repeat Halley steps until the *last step* had fewer than half the digits wrong, +//! the step we've just taken should have been sufficient to have completed the iteration. + +//! \tparam T floating-point (or fixed-point) type. +//! \param z Argument z for Lambert_w function. +//! \param w_est Lambert w estimate. +template +inline T lambert_w_halley_iterate(T w_est, const T z) +{ + BOOST_MATH_STD_USING + static const T max_diff = boost::math::tools::root_epsilon() * fabs(w_est); + + T w_new = lambert_w_halley_step(w_est, z); + T diff = fabs(w_est - w_new); + while (diff > max_diff) + { + w_est = w_new; + w_new = lambert_w_halley_step(w_est, z); + diff = fabs(w_est - w_new); + } + return w_new; +} // template lambert_w_halley_iterate(T w_est, T z) + +// Two Halley function versions that either +// single step (if std::false_type) or iterate (if std::true_type). +// Selected at compile-time using parameter 3. +template +inline T lambert_w_maybe_halley_iterate(T z, T w, std::false_type const&) +{ + return lambert_w_halley_step(z, w); // Single step. +} + +template +inline T lambert_w_maybe_halley_iterate(T z, T w, std::true_type const&) +{ + return lambert_w_halley_iterate(z, w); // Iterate steps. +} + +//! maybe_reduce_to_double function, +//! Two versions that have a compile-time option to +//! reduce argument z to double precision (if true_type). +//! Version is selected at compile-time using parameter 2. + +template +inline double maybe_reduce_to_double(const T& z, const std::true_type&) +{ + return static_cast(z); // Reduce to double precision. +} + +template +inline T maybe_reduce_to_double(const T& z, const std::false_type&) +{ // Don't reduce to double. + return z; +} + +template +inline double must_reduce_to_double(const T& z, const std::true_type&) +{ + return static_cast(z); // Reduce to double precision. +} + +template +inline double must_reduce_to_double(const T& z, const std::false_type&) +{ // try a lexical_cast and hope for the best: +#ifndef BOOST_MATH_STANDALONE + return boost::lexical_cast(z); +#else + static_assert(sizeof(T) == 0, "Unsupported in standalone mode: don't know how to cast your number type to a double."); + return 0.0; +#endif +} + +//! \brief Schroeder method, fifth-order update formula, +//! \details See T. Fukushima page 80-81, and +//! A. Householder, The Numerical Treatment of a Single Nonlinear Equation, +//! McGraw-Hill, New York, 1970, section 4.4. +//! Fukushima algorithm switches to @c schroeder_update after pre-computed bisections, +//! chosen to ensure that the result will be achieve the +/- 10 epsilon target. +//! \param w Lambert w estimate from bisection or series. +//! \param y bracketing value from bisection. +//! \returns Refined estimate of Lambert w. + +// Schroeder refinement, called unless NOT required by precision policy. +template +inline T schroeder_update(const T w, const T y) +{ + // Compute derivatives using 5th order Schroeder refinement. + // Since this is the final step, it will always use the highest precision type T. + // Example of Call: + // result = schroeder_update(w, y); + //where + // w is estimate of Lambert W (from bisection or series). + // y is z * e^-w. + + BOOST_MATH_STD_USING // Aid argument dependent lookup of abs. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + using boost::math::float_distance; + T fd = float_distance(w, y); + std::cout << "Schroder "; + if (abs(fd) < 214748000.) + { + std::cout << " Distance = "<< static_cast(fd); + } + else + { + std::cout << "Difference w - y = " << (w - y) << "."; + } + std::cout << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + // Fukushima equation 18, page 6. + const T f0 = w - y; // f0 = w - y. + const T f1 = 1 + y; // f1 = df/dW + const T f00 = f0 * f0; + const T f11 = f1 * f1; + const T f0y = f0 * y; + const T result = + w - 4 * f0 * (6 * f1 * (f11 + f0y) + f00 * y) / + (f11 * (24 * f11 + 36 * f0y) + + f00 * (6 * y * y + 8 * f1 * y + f0y)); // Fukushima Page 81, equation 21 from equation 20. + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + std::cout << "Schroeder refined " << w << " " << y << ", difference " << w-y << ", change " << w - result << ", to result " << result << std::endl; + std::cout.precision(saved_precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER + + return result; +} // template T schroeder_update(const T w, const T y) + + //! \brief Series expansion used near the singularity/branch point z = -exp(-1) = -3.6787944. + //! Wolfram InverseSeries[Series[sqrt[2(p Exp[1 + p] + 1)], {p,-1, 20}]] + //! Wolfram command used to obtain 40 series terms at 50 decimal digit precision was + //! N[InverseSeries[Series[Sqrt[2(p Exp[1 + p] + 1)], { p,-1,40 }]], 50] + //! -1+p-p^2/3+(11 p^3)/72-(43 p^4)/540+(769 p^5)/17280-(221 p^6)/8505+(680863 p^7)/43545600 ... + //! Decimal values of specifications for built-in floating-point types below + //! are at least 21 digits precision == max_digits10 for long double. + //! Longer decimal digits strings are rationals evaluated using Wolfram. + +template +T lambert_w_singularity_series(const T p) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES + std::size_t saved_precision = std::cout.precision(3); + std::cout << "Singularity_series Lambert_w p argument = " << p << std::endl; + std::cout + //<< "Argument Type = " << typeid(T).name() + //<< ", max_digits10 = " << std::numeric_limits::max_digits10 + //<< ", epsilon = " << std::numeric_limits::epsilon() + << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES + + static const T q[] = + { + -static_cast(1), // j0 + +T(1), // j1 + -T(1) / 3, // 1/3 j2 + +T(11) / 72, // 0.152777777777777778, // 11/72 j3 + -T(43) / 540, // 0.0796296296296296296, // 43/540 j4 + +T(769) / 17280, // 0.0445023148148148148, j5 + -T(221) / 8505, // 0.0259847148736037625, j6 + //+T(0.0156356325323339212L), // j7 + //+T(0.015635632532333921222810111699000587889476778365667L), // j7 from Wolfram N[680863/43545600, 50] + +T(680863uLL) / 43545600uLL, // +0.0156356325323339212, j7 + //-T(0.00961689202429943171L), // j8 + -T(1963uLL) / 204120uLL, // 0.00961689202429943171, j8 + //-T(0.0096168920242994317068391142465216539290613364687439L), // j8 from Wolfram N[1963/204120, 50] + +T(226287557uLL) / 37623398400uLL, // 0.00601454325295611786, j9 + -T(5776369uLL) / 1515591000uLL, // 0.00381129803489199923, j10 + //+T(0.00244087799114398267L), j11 0.0024408779911439826658968585286437530215699919795550 + +T(169709463197uLL) / 69528040243200uLL, // j11 + // -T(0.00157693034468678425L), // j12 -0.0015769303446867842539234095399314115973161850314723 + -T(1118511313uLL) / 709296588000uLL, // j12 + +T(667874164916771uLL) / 650782456676352000uLL, // j13 + //+T(0.00102626332050760715L), // j13 0.0010262633205076071544375481533906861056468041465973 + -T(500525573uLL) / 744761417400uLL, // j14 + // -T(0.000672061631156136204L), j14 + //+T(1003663334225097487uLL) / 234281684403486720000uLL, // j15 0.00044247306181462090993020760858473726479232802068800 error C2177: constant too big + //+T(0.000442473061814620910L, // j15 + BOOST_MATH_BIG_CONSTANT(T, 64, +0.000442473061814620910), // j15 + // -T(0.000292677224729627445L), // j16 + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000292677224729627445), // j16 + //+T(0.000194387276054539318L), // j17 + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000194387276054539318), // j17 + //-T(0.000129574266852748819L), // j18 + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000129574266852748819), // j18 + //+T(0.0000866503580520812717L), // j19 N[+1150497127780071399782389/13277465363600276402995200000, 50] 0.000086650358052081271660451590462390293190597827783288 + BOOST_MATH_BIG_CONSTANT(T, 64, +0.0000866503580520812717), // j19 + //-T(0.0000581136075044138168L) // j20 N[2853534237182741069/49102686267859224000000, 50] 0.000058113607504413816772205464778828177256611844221913 + // -T(2853534237182741069uLL) / 49102686267859224000000uLL // j20 // error C2177: constant too big, + // so must use BOOST_MATH_BIG_CONSTANT(T, ) format in hope of using suffix Q for quad or decimal digits string for others. + //-T(0.000058113607504413816772205464778828177256611844221913L), // j20 N[2853534237182741069/49102686267859224000000, 50] 0.000058113607504413816772205464778828177256611844221913 + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000058113607504413816772205464778828177256611844221913) // j20 - last used by Fukushima + // More terms don't seem to give any improvement (worse in fact) and are not use for many z values. + //BOOST_MATH_BIG_CONSTANT(T, +0.000039076684867439051635395583044527492132109160553593), // j21 + //BOOST_MATH_BIG_CONSTANT(T, -0.000026338064747231098738584082718649443078703982217219), // j22 + //BOOST_MATH_BIG_CONSTANT(T, +0.000017790345805079585400736282075184540383274460464169), // j23 + //BOOST_MATH_BIG_CONSTANT(T, -0.000012040352739559976942274116578992585158113153190354), // j24 + //BOOST_MATH_BIG_CONSTANT(T, +8.1635319824966121713827512573558687050675701559448E-6), // j25 + //BOOST_MATH_BIG_CONSTANT(T, -5.5442032085673591366657251660804575198155559225316E-6) // j26 + // -T(5.5442032085673591366657251660804575198155559225316E-6L) // j26 + // 21 to 26 Added for long double. + }; // static const T q[] + + /* + // Temporary copy of original double values for comparison; these are reproduced well. + static const T q[] = + { + -1L, // j0 + +1L, // j1 + -0.333333333333333333L, // 1/3 j2 + +0.152777777777777778L, // 11/72 j3 + -0.0796296296296296296L, // 43/540 + +0.0445023148148148148L, + -0.0259847148736037625L, + +0.0156356325323339212L, + -0.00961689202429943171L, + +0.00601454325295611786L, + -0.00381129803489199923L, + +0.00244087799114398267L, + -0.00157693034468678425L, + +0.00102626332050760715L, + -0.000672061631156136204L, + +0.000442473061814620910L, + -0.000292677224729627445L, + +0.000194387276054539318L, + -0.000129574266852748819L, + +0.0000866503580520812717L, + -0.0000581136075044138168L // j20 + }; + */ + + // Decide how many series terms to use, increasing as z approaches the singularity, + // balancing run-time versus computational noise from round-off. + // In practice, we truncate the series expansion at a certain order. + // If the order is too large, not only does the amount of computation increase, + // but also the round-off errors accumulate. + // See Fukushima equation 35, page 85 for logic of choice of number of series terms. + + BOOST_MATH_STD_USING // Aid argument dependent lookup (ADL) of abs. + + const T absp = abs(p); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS + { + int terms = 20; // Default to using all terms. + if (absp < 0.01159) + { // Very near singularity. + terms = 6; + } + else if (absp < 0.0766) + { // Near singularity. + terms = 10; + } + std::streamsize saved_precision = std::cout.precision(3); + std::cout << "abs(p) = " << absp << ", terms = " << terms << std::endl; + std::cout.precision(saved_precision); + } +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS + + if (absp < 0.01159) + { // Only 6 near-singularity series terms are useful. + return + -1 + + p * (1 + + p * (q[2] + + p * (q[3] + + p * (q[4] + + p * (q[5] + + p * q[6] + ))))); + } + else if (absp < 0.0766) // Use 10 near-singularity series terms. + { // Use 10 near-singularity series terms. + return + -1 + + p * (1 + + p * (q[2] + + p * (q[3] + + p * (q[4] + + p * (q[5] + + p * (q[6] + + p * (q[7] + + p * (q[8] + + p * (q[9] + + p * q[10] + ))))))))); + } + else + { // Use all 20 near-singularity series terms. + return + -1 + + p * (1 + + p * (q[2] + + p * (q[3] + + p * (q[4] + + p * (q[5] + + p * (q[6] + + p * (q[7] + + p * (q[8] + + p * (q[9] + + p * (q[10] + + p * (q[11] + + p * (q[12] + + p * (q[13] + + p * (q[14] + + p * (q[15] + + p * (q[16] + + p * (q[17] + + p * (q[18] + + p * (q[19] + + p * q[20] // Last Fukushima term. + ))))))))))))))))))); + // + // more terms for more precise T: long double ... + //// but makes almost no difference, so don't use more terms? + // p*q[21] + + // p*q[22] + + // p*q[23] + + // p*q[24] + + // p*q[25] + // ))))))))))))))))))); + } +} // template T lambert_w_singularity_series(const T p) + + + ///////////////////////////////////////////////////////////////////////////////////////////// + + //! \brief Series expansion used near zero (abs(z) < 0.05). + //! \details + //! Coefficients of the inverted series expansion of the Lambert W function around z = 0. + //! Tosio Fukushima always uses all 17 terms of a Taylor series computed using Wolfram with + //! InverseSeries[Series[z Exp[z],{z,0,17}]] + //! Tosio Fukushima / Journal of Computational and Applied Mathematics 244 (2013) page 86. + + //! Decimal values of specifications for built-in floating-point types below + //! are 21 digits precision == max_digits10 for long double. + //! Care! Some coefficients might overflow some fixed_point types. + + //! This version is intended to allow use by user-defined types + //! like Boost.Multiprecision quad and cpp_dec_float types. + //! The three specializations below for built-in float, double + //! (and perhaps long double) will be chosen in preference for these types. + + //! This version uses rationals computed by Wolfram as far as possible, + //! limited by maximum size of uLL integers. + //! For higher term, uses decimal digit strings computed by Wolfram up to the maximum possible using uLL rationals, + //! and then higher coefficients are computed as necessary using function lambert_w0_small_z_series_term + //! until the precision required by the policy is achieved. + //! InverseSeries[Series[z Exp[z],{z,0,34}]] also computed. + + // Series evaluation for LambertW(z) as z -> 0. + // See http://functions.wolfram.com/ElementaryFunctions/ProductLog/06/01/01/0003/ + // http://functions.wolfram.com/ElementaryFunctions/ProductLog/06/01/01/0003/MainEq1.L.gif + + //! \brief lambert_w0_small_z uses a tag_type to select a variant depending on the size of the type. + //! The Lambert W is computed by lambert_w0_small_z for small z. + //! The cutoff for z smallness determined by Tosio Fukushima by trial and error is (abs(z) < 0.05), + //! but the optimum might be a function of the size of the type of z. + + //! \details + //! The tag_type selection is based on the value @c std::numeric_limits::max_digits10. + //! This allows distinguishing between long double types that commonly vary between 64 and 80-bits, + //! and also compilers that have a float type using 64 bits and/or long double using 128-bits. + //! It assumes that max_digits10 is defined correctly or this might fail to make the correct selection. + //! causing very small differences in computing lambert_w that would be very difficult to detect and diagnose. + //! Cannot switch on @c std::numeric_limits<>::max() because comparison values may overflow the compiler limit. + //! Cannot switch on @c std::numeric_limits::max_exponent10() + //! because both 80 and 128 bit floating-point implementations use 11 bits for the exponent. + //! So must rely on @c std::numeric_limits::max_digits10. + + //! Specialization of float zero series expansion used for small z (abs(z) < 0.05). + //! Specializations of lambert_w0_small_z for built-in types. + //! These specializations should be chosen in preference to T version. + //! For example: lambert_w0_small_z(0.001F) should use the float version. + //! (Parameter Policy is not used by built-in types when all terms are used during an inline computation, + //! but for the tag_type selection to work, they all must include Policy in their signature. + + // Forward declaration of variants of lambert_w0_small_z. +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for float (32-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for double (64-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for long double (double extended 80-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for long double (128-bit) type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // for float128 quadmath Q type. + +template +T lambert_w0_small_z(T x, const Policy&, std::integral_constant const&); // Generic multiprecision T. + // Set tag_type depending on max_digits10. +template +T lambert_w0_small_z(T x, const Policy& pol) +{ //std::numeric_limits::max_digits10 == 36 ? 3 : // 128-bit long double. + using tag_type = std::integral_constant::is_specialized == 0 ? 5 : +#ifndef BOOST_NO_CXX11_NUMERIC_LIMITS + std::numeric_limits::max_digits10 <= 9 ? 0 : // for float 32-bit. + std::numeric_limits::max_digits10 <= 17 ? 1 : // for double 64-bit. + std::numeric_limits::max_digits10 <= 22 ? 2 : // for 80-bit double extended. + std::numeric_limits::max_digits10 < 37 ? 4 // for both 128-bit long double (3) and 128-bit quad suffix Q type (4). +#else + std::numeric_limits::radix != 2 ? 5 : + std::numeric_limits::digits <= 24 ? 0 : // for float 32-bit. + std::numeric_limits::digits <= 53 ? 1 : // for double 64-bit. + std::numeric_limits::digits <= 64 ? 2 : // for 80-bit double extended. + std::numeric_limits::digits <= 113 ? 4 // for both 128-bit long double (3) and 128-bit quad suffix Q type (4). +#endif + : 5>; // All Generic multiprecision types. + // std::cout << "\ntag type = " << tag_type << std::endl; // error C2275: 'tag_type': illegal use of this type as an expression. + return lambert_w0_small_z(x, pol, tag_type()); +} // template T lambert_w0_small_z(T x) + + //! Specialization of float (32-bit) series expansion used for small z (abs(z) < 0.05). + // Only 9 Coefficients are computed to 21 decimal digits precision, ample for 32-bit float used by most platforms. + // Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction + // N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], + // as proposed by Tosio Fukushima and implemented by Darko Veberic. + +template +T lambert_w0_small_z(T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize prec = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 0 float lambert_w0_small_z called with z = " << z << " using " << 9 << " terms of precision " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1 - // j1 z^1 term = 1 + z * (1 - // j2 z^2 term = -1 + z * (static_cast(3uLL) / 2uLL - // 3/2 // j3 z^3 term = 1.5. + z * (2.6666666666666666667F - // 8/3 // j4 + z * (5.2083333333333333333F - // -125/24 // j5 + z * (10.8F - // j6 + z * (23.343055555555555556F - // j7 + z * (52.012698412698412698F - // j8 + z * 118.62522321428571429F)))))))); // j9 + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // template T lambert_w0_small_z(T x, std::integral_constant const&) + + //! Specialization of double (64-bit double) series expansion used for small z (abs(z) < 0.05). + // 17 Coefficients are computed to 21 decimal digits precision suitable for 64-bit double used by most platforms. + // Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction + // N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], as proposed by Tosio Fukushima and implemented by Veberic. + +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize prec = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 1 double lambert_w0_small_z called with z = " << z << " using " << 17 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1. - // j1 z^1 + z * (1. - // j2 z^2 + z * (1.5 - // 3/2 // j3 z^3 + z * (2.6666666666666666667 - // 8/3 // j4 + z * (5.2083333333333333333 - // -125/24 // j5 + z * (10.8 - // j6 + z * (23.343055555555555556 - // j7 + z * (52.012698412698412698 - // j8 + z * (118.62522321428571429 - // j9 + z * (275.57319223985890653 - // j10 + z * (649.78717234347442681 - // j11 + z * (1551.1605194805194805 - // j12 + z * (3741.4497029592385495 - // j13 + z * (9104.5002411580189358 - // j14 + z * (22324.308512706601434 - // j15 + z * (55103.621972903835338 - // j16 + z * 136808.86090394293563)))))))))))))))); // j17 z^17 + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) + + //! Specialization of long double (80-bit double extended) series expansion used for small z (abs(z) < 0.05). + // 21 Coefficients are computed to 21 decimal digits precision suitable for 80-bit long double used by some + // platforms including GCC and Clang when generating for Intel X86 floating-point processors with 80-bit operations enabled (the default). + // (This is NOT used by Microsoft Visual Studio where double and long always both use only 64-bit type. + // Nor used for 128-bit float128.) +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 2 long double (80-bit double extended) lambert_w0_small_z called with z = " << z << " using " << 21 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES +// T result = +// z * (1.L - // j1 z^1 +// z * (1.L - // j2 z^2 +// z * (1.5L - // 3/2 // j3 +// z * (2.6666666666666666667L - // 8/3 // j4 +// z * (5.2083333333333333333L - // -125/24 // j5 +// z * (10.800000000000000000L - // j6 +// z * (23.343055555555555556L - // j7 +// z * (52.012698412698412698L - // j8 +// z * (118.62522321428571429L - // j9 +// z * (275.57319223985890653L - // j10 +// z * (649.78717234347442681L - // j11 +// z * (1551.1605194805194805L - // j12 +// z * (3741.4497029592385495L - // j13 +// z * (9104.5002411580189358L - // j14 +// z * (22324.308512706601434L - // j15 +// z * (55103.621972903835338L - // j16 +// z * (136808.86090394293563L - // j17 z^17 last term used by Fukushima double. +// z * (341422.050665838363317L - // z^18 +// z * (855992.9659966075514633L - // z^19 +// z * (2.154990206091088289321e6L - // z^20 +// z * 5.4455529223144624316423e6L // z^21 +// )))))))))))))))))))); +// + + T result = +z * (1.L - // z j1 +z * (1.L - // z^2 +z * (1.500000000000000000000000000000000L - // z^3 +z * (2.666666666666666666666666666666666L - // z ^ 4 +z * (5.208333333333333333333333333333333L - // z ^ 5 +z * (10.80000000000000000000000000000000L - // z ^ 6 +z * (23.34305555555555555555555555555555L - // z ^ 7 +z * (52.01269841269841269841269841269841L - // z ^ 8 +z * (118.6252232142857142857142857142857L - // z ^ 9 +z * (275.5731922398589065255731922398589L - // z ^ 10 +z * (649.7871723434744268077601410934744L - // z ^ 11 +z * (1551.160519480519480519480519480519L - // z ^ 12 +z * (3741.449702959238549516327294105071L - //z ^ 13 +z * (9104.500241158018935796713574491352L - // z ^ 14 +z * (22324.308512706601434280005708577137L - // z ^ 15 +z * (55103.621972903835337697771560205422L - // z ^ 16 +z * (136808.86090394293563342215789305736L - // z ^ 17 +z * (341422.05066583836331735491399356945L - // z^18 +z * (855992.9659966075514633630250633224L - // z^19 +z * (2.154990206091088289321708745358647e6L // z^20 distance -5 without term 20 +)))))))))))))))))))); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + return result; +} // long double lambert_w0_small_z(const T z, std::integral_constant const&) + +//! Specialization of 128-bit long double series expansion used for small z (abs(z) < 0.05). +// 34 Taylor series coefficients used are computed by Wolfram to 50 decimal digits using instruction +// N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], +// and are suffixed by L as they are assumed of type long double. +// (This is NOT used for 128-bit quad boost::multiprecision::float128 type which required a suffix Q +// nor multiprecision type cpp_bin_float_quad that can only be initialised at full precision of the type +// constructed with a decimal digit string like "2.6666666666666666666666666666666666666666666666667".) + +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 3 long double (128-bit) lambert_w0_small_z called with z = " << z << " using " << 17 << " terms of precision, " + << std::numeric_limits::max_digits10 << " decimal digits. " << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1.L - // j1 + z * (1.L - // j2 + z * (1.5L - // 3/2 // j3 + z * (2.6666666666666666666666666666666666L - // 8/3 // j4 + z * (5.2052083333333333333333333333333333L - // -125/24 // j5 + z * (10.800000000000000000000000000000000L - // j6 + z * (23.343055555555555555555555555555555L - // j7 + z * (52.0126984126984126984126984126984126L - // j8 + z * (118.625223214285714285714285714285714L - // j9 + z * (275.57319223985890652557319223985890L - // * z ^ 10 - // j10 + z * (649.78717234347442680776014109347442680776014109347L - // j11 + z * (1551.1605194805194805194805194805194805194805194805L - // j12 + z * (3741.4497029592385495163272941050718828496606274384L - // j13 + z * (9104.5002411580189357967135744913522691300469078247L - // j14 + z * (22324.308512706601434280005708577137148565719994291L - // j15 + z * (55103.621972903835337697771560205422639285073147507L - // j16 + z * 136808.86090394293563342215789305736395683485630576L // j17 + )))))))))))))))); + +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) + +//! Specialization of 128-bit quad series expansion used for small z (abs(z) < 0.05). +// 34 Taylor series coefficients used were computed by Wolfram to 50 decimal digits using instruction +// N[InverseSeries[Series[z Exp[z],{z,0,34}]],50], +// and are suffixed by Q as they are assumed of type quad. +// This could be used for 128-bit quad (which requires a suffix Q for full precision). +// But experiments with GCC 7.2.0 show that while this gives full 128-bit precision +// when the -f-ext-numeric-literals option is in force and the libquadmath library available, +// over the range -0.049 to +0.049, +// it is slightly slower than getting a double approximation followed by a single Halley step. + +#ifdef BOOST_HAS_FLOAT128 +template +T lambert_w0_small_z(const T z, const Policy&, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "\ntag_type 4 128-bit quad float128 lambert_w0_small_z called with z = " << z << " using " << 34 << " terms of precision, " + << std::numeric_limits::max_digits10 << " max decimal digits." << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + T result = + z * (1.Q - // z j1 + z * (1.Q - // z^2 + z * (1.500000000000000000000000000000000Q - // z^3 + z * (2.666666666666666666666666666666666Q - // z ^ 4 + z * (5.208333333333333333333333333333333Q - // z ^ 5 + z * (10.80000000000000000000000000000000Q - // z ^ 6 + z * (23.34305555555555555555555555555555Q - // z ^ 7 + z * (52.01269841269841269841269841269841Q - // z ^ 8 + z * (118.6252232142857142857142857142857Q - // z ^ 9 + z * (275.5731922398589065255731922398589Q - // z ^ 10 + z * (649.7871723434744268077601410934744Q - // z ^ 11 + z * (1551.160519480519480519480519480519Q - // z ^ 12 + z * (3741.449702959238549516327294105071Q - //z ^ 13 + z * (9104.500241158018935796713574491352Q - // z ^ 14 + z * (22324.308512706601434280005708577137Q - // z ^ 15 + z * (55103.621972903835337697771560205422Q - // z ^ 16 + z * (136808.86090394293563342215789305736Q - // z ^ 17 + z * (341422.05066583836331735491399356945Q - // z^18 + z * (855992.9659966075514633630250633224Q - // z^19 + z * (2.154990206091088289321708745358647e6Q - // 20 + z * (5.445552922314462431642316420035073e6Q - // 21 + z * (1.380733000216662949061923813184508e7Q - // 22 + z * (3.511704498513923292853869855945334e7Q - // 23 + z * (8.956800256102797693072819557780090e7Q - // 24 + z * (2.290416846187949813964782641734774e8Q - // 25 + z * (5.871035041171798492020292225245235e8Q - // 26 + z * (1.508256053857792919641317138812957e9Q - // 27 + z * (3.882630161293188940385873468413841e9Q - // 28 + z * (1.001394313665482968013913601565723e10Q - // 29 + z * (2.587356736265760638992878359024929e10Q - // 30 + z * (6.696209709358073856946120522333454e10Q - // 31 + z * (1.735711659599198077777078238043644e11Q - // 32 + z * (4.505680465642353886756098108484670e11Q - // 33 + z * (1.171223178256487391904047636564823e12Q //z^34 + )))))))))))))))))))))))))))))))))); + + + #ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "return w = " << result << std::endl; + std::cout.precision(precision); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + return result; +} // T lambert_w0_small_z(const T z, std::integral_constant const&) float128 + +#else + +template +inline T lambert_w0_small_z(const T z, const Policy& pol, std::integral_constant const&) +{ + return lambert_w0_small_z(z, pol, std::integral_constant()); +} + +#endif // BOOST_HAS_FLOAT128 + +//! Series functor to compute series term using pow and factorial. +//! \details Functor is called after evaluating polynomial with the coefficients as rationals below. +template +struct lambert_w0_small_z_series_term +{ + using result_type = T; + //! \param _z Lambert W argument z. + //! \param -term -pow<18>(z) / 6402373705728000uLL + //! \param _k number of terms == initially 18 + + // Note *after* evaluating N terms, its internal state has k = N and term = (-1)^N z^N. + + lambert_w0_small_z_series_term(T _z, T _term, int _k) + : k(_k), z(_z), term(_term) { } + + T operator()() + { // Called by sum_series until needs precision set by factor (policy::get_epsilon). + using std::pow; + ++k; + term *= -z / k; + //T t = pow(z, k) * pow(T(k), -1 + k) / factorial(k); // (z^k * k(k-1)^k) / k! + T result = term * pow(T(k), -1 + k); // term * k^(k-1) + // std::cout << " k = " << k << ", term = " << term << ", result = " << result << std::endl; + return result; // + } +private: + int k; + T z; + T term; +}; // template struct lambert_w0_small_z_series_term + + //! Generic variant for T a User-defined types like Boost.Multiprecision. +template +inline T lambert_w0_small_z(T z, const Policy& pol, std::integral_constant const&) +{ +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::streamsize precision = std::cout.precision(std::numeric_limits::max_digits10); // Save. + std::cout << "Generic lambert_w0_small_z called with z = " << z << " using as many terms needed for precision." << std::endl; + std::cout << "Argument z is of type " << typeid(T).name() << std::endl; +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + // First several terms of the series are tabulated and evaluated as a polynomial: + // this will save us a bunch of expensive calls to pow. + // Then our series functor is initialized "as if" it had already reached term 18, + // enough evaluation of built-in 64-bit double and float (and 80-bit long double?) types. + + // Coefficients should be stored such that the coefficients for the x^i terms are in poly[i]. + static const T coeff[] = + { + 0, // z^0 Care: zeroth term needed by tools::evaluate_polynomial, but not in the Wolfram equation, so indexes are one different! + 1, // z^1 term. + -1, // z^2 term + static_cast(3uLL) / 2uLL, // z^3 term. + -static_cast(8uLL) / 3uLL, // z^4 + static_cast(125uLL) / 24uLL, // z^5 + -static_cast(54uLL) / 5uLL, // z^6 + static_cast(16807uLL) / 720uLL, // z^7 + -static_cast(16384uLL) / 315uLL, // z^8 + static_cast(531441uLL) / 4480uLL, // z^9 + -static_cast(156250uLL) / 567uLL, // z^10 + static_cast(2357947691uLL) / 3628800uLL, // z^11 + -static_cast(2985984uLL) / 1925uLL, // z^12 + static_cast(1792160394037uLL) / 479001600uLL, // z^13 + -static_cast(7909306972uLL) / 868725uLL, // z^14 + static_cast(320361328125uLL) / 14350336uLL, // z^15 + -static_cast(35184372088832uLL) / 638512875uLL, // z^16 + static_cast(2862423051509815793uLL) / 20922789888000uLL, // z^17 term + -static_cast(5083731656658uLL) / 14889875uLL, + // z^18 term. = 136808.86090394293563342215789305735851647769682393 + + // z^18 is biggest that can be computed as rational using the largest possible uLL integers, + // so higher terms cannot be potentially compiler-computed as uLL rationals. + // Wolfram (5083731656658 z ^ 18) / 14889875 or + // -341422.05066583836331735491399356945575432970390954 z^18 + + // See note below calling the functor to compute another term, + // sufficient for 80-bit long double precision. + // Wolfram -341422.05066583836331735491399356945575432970390954 z^19 term. + // (5480386857784802185939 z^19)/6402373705728000 + // But now this variant is not used to compute long double + // as specializations are provided above. + }; // static const T coeff[] + + /* + Table of 19 computed coefficients: + + #0 0 + #1 1 + #2 -1 + #3 1.5 + #4 -2.6666666666666666666666666666666665382713370408509 + #5 5.2083333333333333333333333333333330765426740817019 + #6 -10.800000000000000000000000000000000616297582203915 + #7 23.343055555555555555555555555555555076212991619177 + #8 -52.012698412698412698412698412698412659282693193402 + #9 118.62522321428571428571428571428571146835390992496 + #10 -275.57319223985890652557319223985891400375196748314 + #11 649.7871723434744268077601410934743969785223845882 + #12 -1551.1605194805194805194805194805194947599566007429 + #13 3741.4497029592385495163272941050719510009019331763 + #14 -9104.5002411580189357967135744913524243896052869184 + #15 22324.308512706601434280005708577137322392070452582 + #16 -55103.621972903835337697771560205423203318720697224 + #17 136808.86090394293563342215789305735851647769682393 + 136808.86090394293563342215789305735851647769682393 == Exactly same as Wolfram computed value. + #18 -341422.05066583836331735491399356947486381600607416 + 341422.05066583836331735491399356945575432970390954 z^19 Wolfram value differs at 36 decimal digit, as expected. + */ + + using boost::math::policies::get_epsilon; // for type T. + using boost::math::tools::sum_series; + using boost::math::tools::evaluate_polynomial; + // http://www.boost.org/doc/libs/release/libs/math/doc/html/math_toolkit/roots/rational.html + + // std::streamsize prec = std::cout.precision(std::numeric_limits ::max_digits10); + + T result = evaluate_polynomial(coeff, z); + // template + // V evaluate_polynomial(const T(&poly)[N], const V& val); + // Size of coeff found from N + //std::cout << "evaluate_polynomial(coeff, z); == " << result << std::endl; + //std::cout << "result = " << result << std::endl; + // It's an artefact of the way I wrote the functor: *after* evaluating N + // terms, its internal state has k = N and term = (-1)^N z^N. So after + // evaluating 18 terms, we initialize the functor to the term we've just + // evaluated, and then when it's called, it increments itself to the next term. + // So 18!is 6402373705728000, which is where that comes from. + + // The 19th coefficient of the polynomial is actually, 19 ^ 18 / 19!= + // 104127350297911241532841 / 121645100408832000 which after removing GCDs + // reduces down to Wolfram rational 5480386857784802185939 / 6402373705728000. + // Wolfram z^19 term +(5480386857784802185939 z^19) /6402373705728000 + // +855992.96599660755146336302506332246623424823099755 z^19 + + //! Evaluate Functor. + lambert_w0_small_z_series_term s(z, -pow<18>(z) / 6402373705728000uLL, 18); + + // Temporary to list the coefficients. + //std::cout << " Table of coefficients" << std::endl; + //std::streamsize saved_precision = std::cout.precision(50); + //for (size_t i = 0; i != 19; i++) + //{ + // std::cout << "#" << i << " " << coeff[i] << std::endl; + //} + //std::cout.precision(saved_precision); + + std::uintmax_t max_iter = policies::get_max_series_iterations(); // Max iterations from policy. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + std::cout << "max iter from policy = " << max_iter << std::endl; + // // max iter from policy = 1000000 is default. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES + + result = sum_series(s, get_epsilon(), max_iter, result); + // result == evaluate_polynomial. + //sum_series(Functor& func, int bits, std::uintmax_t& max_terms, const U& init_value) + // std::cout << "sum_series(s, get_epsilon(), max_iter, result); = " << result << std::endl; + + //T epsilon = get_epsilon(); + //std::cout << "epsilon from policy = " << epsilon << std::endl; + // epsilon from policy = 1.93e-34 for T == quad + // 5.35e-51 for t = cpp_bin_float_50 + + // std::cout << " get eps = " << get_epsilon() << std::endl; // quad eps = 1.93e-34, bin_float_50 eps = 5.35e-51 + policies::check_series_iterations("boost::math::lambert_w0_small_z<%1%>(%1%)", max_iter, pol); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS + std::cout << "z = " << z << " needed " << max_iter << " iterations." << std::endl; + std::cout.precision(prec); // Restore. +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS + return result; +} // template inline T lambert_w0_small_z_series(T z, const Policy& pol) + +// Approximate lambert_w0 (used for z values that are outside range of lookup table or rational functions) +// Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. +template +inline T lambert_w0_approx(T z) +{ + BOOST_MATH_STD_USING + T lz = log(z); + T llz = log(lz); + T w = lz - llz + (llz / lz); // Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. + return w; + // std::cout << "w max " << max_w << std::endl; // double 703.227 +} + + ////////////////////////////////////////////////////////////////////////////////////////// + +//! \brief Lambert_w0 implementations for float, double and higher precisions. +//! 3rd parameter used to select which version is used. + +//! /details Rational polynomials are provided for several range of argument z. +//! For very small values of z, and for z very near the branch singularity at -e^-1 (~= -0.367879), +//! two other series functions are used. + +//! float precision polynomials are used for 32-bit (usually float) precision (for speed) +//! double precision polynomials are used for 64-bit (usually double) precision. +//! For higher precisions, a 64-bit double approximation is computed first, +//! and then refined using Halley iterations. + +template +inline T do_get_near_singularity_param(T z) +{ + BOOST_MATH_STD_USING + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + return p; +} +template +inline T get_near_singularity_param(T z, const Policy) +{ + using value_type = typename policies::evaluation::type; + return static_cast(do_get_near_singularity_param(static_cast(z))); +} + +// Forward declarations: + +//template T lambert_w0_small_z(T z, const Policy& pol); +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 32 bit usually float. +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 64 bit usually double. +//template +//T lambert_w0_imp(T w, const Policy& pol, const std::integral_constant&); // 80-bit long double. + +template +T lambert_w_positive_rational_float(T z) +{ + BOOST_MATH_STD_USING + if (z < 2) + { + if (z < 0.5) + { // 0.05 < z < 0.5 + // Maximum Deviation Found: 2.993e-08 + // Expected Error Term : 2.993e-08 + // Maximum Relative Change in Control Points : 7.555e-04 Y offset : -8.196592331e-01 + static const T Y = 8.196592331e-01f; + static const T P[] = { + 1.803388345e-01f, + -4.820256838e-01f, + -1.068349741e+00f, + -3.506624319e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.871703469e+00f, + 1.690949264e+00f, + }; + return z * (Y + boost::math::tools::evaluate_polynomial(P, z) / boost::math::tools::evaluate_polynomial(Q, z)); + } + else + { // 0.5 < z < 2 + // Max error in interpolated form: 1.018e-08 + static const T Y = 5.503368378e-01f; + static const T P[] = { + 4.493332766e-01f, + 2.543432707e-01f, + -4.808788799e-01f, + -1.244425316e-01f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.780661241e+00f, + 1.830840318e+00f, + 2.407221031e-01f, + }; + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + } + else if (z < 6) + { + // 2 < z < 6 + // Max error in interpolated form: 2.944e-08 + static const T Y = 1.162393570e+00f; + static const T P[] = { + -1.144183394e+00f, + -4.712732855e-01f, + 1.563162512e-01f, + 1.434010911e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 1.192626340e+00f, + 2.295580708e-01f, + 5.477869455e-03f, + }; + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 18) + { + // 6 < z < 18 + // Max error in interpolated form: 5.893e-08 + static const T Y = 1.809371948e+00f; + static const T P[] = { + -1.689291769e+00f, + -3.337812742e-01f, + 3.151434873e-02f, + 1.134178734e-03f, + }; + static const T Q[] = { + 1.000000000e+00f, + 5.716915685e-01f, + 4.489521292e-02f, + 4.076716763e-04f, + }; + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 9897.12905874) // 2.8 < log(z) < 9.2 + { + // Max error in interpolated form: 1.771e-08 + static const T Y = -1.402973175e+00f; + static const T P[] = { + 1.966174312e+00f, + 2.350864728e-01f, + -5.098074353e-02f, + -1.054818339e-02f, + }; + static const T Q[] = { + 1.000000000e+00f, + 4.388208264e-01f, + 8.316639634e-02f, + 3.397187918e-03f, + -1.321489743e-05f, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } + else if (z < 7.896296e+13) // 9.2 < log(z) <= 32 + { + // Max error in interpolated form: 5.821e-08 + static const T Y = -2.735729218e+00f; + static const T P[] = { + 3.424903470e+00f, + 7.525631787e-02f, + -1.427309584e-02f, + -1.435974178e-05f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.514005579e-01f, + 6.118994652e-03f, + -1.357889535e-05f, + 7.312865624e-08f, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } + else // 32 < log(z) < 100 + { + // Max error in interpolated form: 1.491e-08 + static const T Y = -4.012863159e+00f; + static const T P[] = { + 4.431629226e+00f, + 2.756690487e-01f, + -2.992956930e-03f, + -4.912259384e-05f, + }; + static const T Q[] = { + 1.000000000e+00f, + 2.015434591e-01f, + 4.949426142e-03f, + 1.609659944e-05f, + -5.111523436e-09f, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_polynomial(P, log_w) / boost::math::tools::evaluate_polynomial(Q, log_w); + } +} + +template +T lambert_w_negative_rational_float(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + if (z > -0.27) + { + if (z < -0.051) + { + // -0.27 < z < -0.051 + // Max error in interpolated form: 5.080e-08 + static const T Y = 1.255809784e+00f; + static const T P[] = { + -2.558083412e-01f, + -2.306524098e+00f, + -5.630887033e+00f, + -3.803974556e+00f, + }; + static const T Q[] = { + 1.000000000e+00f, + 5.107680783e+00f, + 7.914062868e+00f, + 3.501498501e+00f, + }; + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else + { + // Very small z so use a series function. + return lambert_w0_small_z(z, pol); + } + } + else if (z > -0.3578794411714423215955237701) + { // Very close to branch singularity. + // Max error in interpolated form: 5.269e-08 + static const T Y = 1.220928431e-01f; + static const T P[] = { + -1.221787446e-01f, + -6.816155875e+00f, + 7.144582035e+01f, + 1.128444390e+03f, + }; + static const T Q[] = { + 1.000000000e+00f, + 6.480326790e+01f, + 1.869145243e+02f, + -1.361804274e+03f, + 1.117826726e+03f, + }; + T d = z + 0.367879441171442321595523770161460867445811f; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + else + { + // z is very close (within 0.01) of the singularity at e^-1. + return lambert_w_singularity_series(get_near_singularity_param(z, pol)); + } +} + +//! Lambert_w0 @b 'float' implementation, selected when T is 32-bit precision. +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; // For error messages. + BOOST_MATH_STD_USING // Aid ADL of std functions. + + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected a value > -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if ((boost::math::isinf)(z)) + { + return boost::math::policies::raise_overflow_error(function, "Expected a finite value but got %1%.", z, pol); + } + + if (z >= 0.05) // Fukushima switch point. + // if (z >= 0.045) // 34 terms makes 128-bit 'exact' below 0.045. + { // Normal ranges using several rational polynomials. + return lambert_w_positive_rational_float(z); + } + else if (z <= -0.3678794411714423215955237701614608674458111310f) + { + if (z < -0.3678794411714423215955237701614608674458111310f) + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + return -1; + } + else // z < 0.05 + { + return lambert_w_negative_rational_float(z, pol); + } +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) for 32-bit usually float. + +template +T lambert_w_positive_rational_double(T z) +{ + BOOST_MATH_STD_USING + if (z < 2) + { + if (z < 0.5) + { + // Max error in interpolated form: 2.255e-17 + static const T offset = 8.19659233093261719e-01; + static const T P[] = { + 1.80340766906685177e-01, + 3.28178241493119307e-01, + -2.19153620687139706e+00, + -7.24750929074563990e+00, + -7.28395876262524204e+00, + -2.57417169492512916e+00, + -2.31606948888704503e-01 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 7.36482529307436604e+00, + 2.03686007856430677e+01, + 2.62864592096657307e+01, + 1.59742041380858333e+01, + 4.03760534788374589e+00, + 2.91327346750475362e-01 + }; + return z * (offset + boost::math::tools::evaluate_polynomial(P, z) / boost::math::tools::evaluate_polynomial(Q, z)); + } + else + { + // Max error in interpolated form: 3.806e-18 + static const T offset = 5.50335884094238281e-01; + static const T P[] = { + 4.49664083944098322e-01, + 1.90417666196776909e+00, + 1.99951368798255994e+00, + -6.91217310299270265e-01, + -1.88533935998617058e+00, + -7.96743968047750836e-01, + -1.02891726031055254e-01, + -3.09156013592636568e-03 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 6.45854489419584014e+00, + 1.54739232422116048e+01, + 1.72606164253337843e+01, + 9.29427055609544096e+00, + 2.29040824649748117e+00, + 2.21610620995418981e-01, + 5.70597669908194213e-03 + }; + return z * (offset + boost::math::tools::evaluate_rational(P, Q, z)); + } + } + else if (z < 6) + { + // 2 < z < 6 + // Max error in interpolated form: 1.216e-17 + static const T Y = 1.16239356994628906e+00; + static const T P[] = { + -1.16230494982099475e+00, + -3.38528144432561136e+00, + -2.55653717293161565e+00, + -3.06755172989214189e-01, + 1.73149743765268289e-01, + 3.76906042860014206e-02, + 1.84552217624706666e-03, + 1.69434126904822116e-05, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 3.77187616711220819e+00, + 4.58799960260143701e+00, + 2.24101228462292447e+00, + 4.54794195426212385e-01, + 3.60761772095963982e-02, + 9.25176499518388571e-04, + 4.43611344705509378e-06, + }; + return Y + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 18) + { + // 6 < z < 18 + // Max error in interpolated form: 1.985e-19 + static const T offset = 1.80937194824218750e+00; + static const T P[] = + { + -1.80690935424793635e+00, + -3.66995929380314602e+00, + -1.93842957940149781e+00, + -2.94269984375794040e-01, + 1.81224710627677778e-03, + 2.48166798603547447e-03, + 1.15806592415397245e-04, + 1.43105573216815533e-06, + 3.47281483428369604e-09 + }; + static const T Q[] = { + 1.00000000000000000e+00, + 2.57319080723908597e+00, + 1.96724528442680658e+00, + 5.84501352882650722e-01, + 7.37152837939206240e-02, + 3.97368430940416778e-03, + 8.54941838187085088e-05, + 6.05713225608426678e-07, + 8.17517283816615732e-10 + }; + return offset + boost::math::tools::evaluate_rational(P, Q, z); + } + else if (z < 9897.12905874) // 2.8 < log(z) < 9.2 + { + // Max error in interpolated form: 1.195e-18 + static const T Y = -1.40297317504882812e+00; + static const T P[] = { + 1.97011826279311924e+00, + 1.05639945701546704e+00, + 3.33434529073196304e-01, + 3.34619153200386816e-02, + -5.36238353781326675e-03, + -2.43901294871308604e-03, + -2.13762095619085404e-04, + -4.85531936495542274e-06, + -2.02473518491905386e-08, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 8.60107275833921618e-01, + 4.10420467985504373e-01, + 1.18444884081994841e-01, + 2.16966505556021046e-02, + 2.24529766630769097e-03, + 9.82045090226437614e-05, + 1.36363515125489502e-06, + 3.44200749053237945e-09, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else if (z < 7.896296e+13) // 9.2 < log(z) <= 32 + { + // Max error in interpolated form: 6.529e-18 + static const T Y = -2.73572921752929688e+00; + static const T P[] = { + 3.30547638424076217e+00, + 1.64050071277550167e+00, + 4.57149576470736039e-01, + 4.03821227745424840e-02, + -4.99664976882514362e-04, + -1.28527893803052956e-04, + -2.95470325373338738e-06, + -1.76662025550202762e-08, + -1.98721972463709290e-11, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 6.91472559412458759e-01, + 2.48154578891676774e-01, + 4.60893578284335263e-02, + 3.60207838982301946e-03, + 1.13001153242430471e-04, + 1.33690948263488455e-06, + 4.97253225968548872e-09, + 3.39460723731970550e-12, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else if (z < 2.6881171e+43) // 32 < log(z) < 100 + { + // Max error in interpolated form: 2.015e-18 + static const T Y = -4.01286315917968750e+00; + static const T P[] = { + 5.07714858354309672e+00, + -3.32994414518701458e+00, + -8.61170416909864451e-01, + -4.01139705309486142e-02, + -1.85374201771834585e-04, + 1.08824145844270666e-05, + 1.17216905810452396e-07, + 2.97998248101385990e-10, + 1.42294856434176682e-13, + }; + static const T Q[] = { + 1.00000000000000000e+00, + -4.85840770639861485e-01, + -3.18714850604827580e-01, + -3.20966129264610534e-02, + -1.06276178044267895e-03, + -1.33597828642644955e-05, + -6.27900905346219472e-08, + -9.35271498075378319e-11, + -2.60648331090076845e-14, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } + else // 100 < log(z) < 710 + { + // Max error in interpolated form: 5.277e-18 + static const T Y = -5.70115661621093750e+00; + static const T P[] = { + 6.42275660145116698e+00, + 1.33047964073367945e+00, + 6.72008923401652816e-02, + 1.16444069958125895e-03, + 7.06966760237470501e-06, + 5.48974896149039165e-09, + -7.00379652018853621e-11, + -1.89247635913659556e-13, + -1.55898770790170598e-16, + -4.06109208815303157e-20, + -2.21552699006496737e-24, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 3.34498588416632854e-01, + 2.51519862456384983e-02, + 6.81223810622416254e-04, + 7.94450897106903537e-06, + 4.30675039872881342e-08, + 1.10667669458467617e-10, + 1.31012240694192289e-13, + 6.53282047177727125e-17, + 1.11775518708172009e-20, + 3.78250395617836059e-25, + }; + T log_w = log(z); + return log_w + Y + boost::math::tools::evaluate_rational(P, Q, log_w); + } +} + +template +T lambert_w_negative_rational_double(T z, const Policy& pol) +{ + BOOST_MATH_STD_USING + if (z > -0.1) + { + if (z < -0.051) + { + // -0.1 < z < -0.051 + // Maximum Deviation Found: 4.402e-22 + // Expected Error Term : 4.240e-22 + // Maximum Relative Change in Control Points : 4.115e-03 + static const T Y = 1.08633995056152344e+00; + static const T P[] = { + -8.63399505615014331e-02, + -1.64303871814816464e+00, + -7.71247913918273738e+00, + -1.41014495545382454e+01, + -1.02269079949257616e+01, + -2.17236002836306691e+00, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 7.44775406945739243e+00, + 2.04392643087266541e+01, + 2.51001961077774193e+01, + 1.31256080849023319e+01, + 2.11640324843601588e+00, + }; + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else + { + // Very small z > 0.051: + return lambert_w0_small_z(z, pol); + } + } + else if (z > -0.2) + { + // -0.2 < z < -0.1 + // Maximum Deviation Found: 2.898e-20 + // Expected Error Term : 2.873e-20 + // Maximum Relative Change in Control Points : 3.779e-04 + static const T Y = 1.20359611511230469e+00; + static const T P[] = { + -2.03596115108465635e-01, + -2.95029082937201859e+00, + -1.54287922188671648e+01, + -3.81185809571116965e+01, + -4.66384358235575985e+01, + -2.59282069989642468e+01, + -4.70140451266553279e+00, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 9.57921436074599929e+00, + 3.60988119290234377e+01, + 6.73977699505546007e+01, + 6.41104992068148823e+01, + 2.82060127225153607e+01, + 4.10677610657724330e+00, + }; + return z * (Y + boost::math::tools::evaluate_rational(P, Q, z)); + } + else if (z > -0.3178794411714423215955237) + { + // Max error in interpolated form: 6.996e-18 + static const T Y = 3.49680423736572266e-01; + static const T P[] = { + -3.49729841718749014e-01, + -6.28207407760709028e+01, + -2.57226178029669171e+03, + -2.50271008623093747e+04, + 1.11949239154711388e+05, + 1.85684566607844318e+06, + 4.80802490427638643e+06, + 2.76624752134636406e+06, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 1.82717661215113000e+02, + 8.00121119810280100e+03, + 1.06073266717010129e+05, + 3.22848993926057721e+05, + -8.05684814514171256e+05, + -2.59223192927265737e+06, + -5.61719645211570871e+05, + 6.27765369292636844e+04, + }; + T d = z + 0.367879441171442321595523770161460867445811; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + else if (z > -0.3578794411714423215955237701) + { + // Max error in interpolated form: 1.404e-17 + static const T Y = 5.00126481056213379e-02; + static const T P[] = { + -5.00173570682372162e-02, + -4.44242461870072044e+01, + -9.51185533619946042e+03, + -5.88605699015429386e+05, + -1.90760843597427751e+06, + 5.79797663818311404e+08, + 1.11383352508459134e+10, + 5.67791253678716467e+10, + 6.32694500716584572e+10, + }; + static const T Q[] = { + 1.00000000000000000e+00, + 9.08910517489981551e+02, + 2.10170163753340133e+05, + 1.67858612416470327e+07, + 4.90435561733227953e+08, + 4.54978142622939917e+09, + 2.87716585708739168e+09, + -4.59414247951143131e+10, + -1.72845216404874299e+10, + }; + T d = z + 0.36787944117144232159552377016146086744581113103176804; + return -d / (Y + boost::math::tools::evaluate_polynomial(P, d) / boost::math::tools::evaluate_polynomial(Q, d)); + } + else + { // z is very close (within 0.01) of the singularity at -e^-1, + // so use a series expansion from R. M. Corless et al. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + return lambert_w_detail::lambert_w_singularity_series(p); + } +} + +//! Lambert_w0 @b 'double' implementation, selected when T is 64-bit precision. +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; + BOOST_MATH_STD_USING // Aid ADL of std functions. + + // Detect unusual case of 32-bit double with a wider/64-bit long double + static_assert(std::numeric_limits::digits >= 53, + "Our double precision coefficients will be truncated, " + "please file a bug report with details of your platform's floating point types " + "- or possibly edit the coefficients to have " + "an appropriate size-suffix for 64-bit floats on your platform - L?"); + + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected a value > -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if ((boost::math::isinf)(z)) + { + return boost::math::policies::raise_overflow_error(function, "Expected a finite value but got %1%.", z, pol); + } + + if (z >= 0.05) + { + return lambert_w_positive_rational_double(z); + } + else if (z <= -0.36787944117144232159552377016146086744581113103176804) // Precision is max_digits10(cpp_bin_float_50). + { + if (z < -0.36787944117144232159552377016146086744581113103176804) + { + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + return -1; + } + else + { + return lambert_w_negative_rational_double(z, pol); + } +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) 64-bit precision, usually double. + +//! lambert_W0 implementation for extended precision types including +//! long double (80-bit and 128-bit), ??? +//! quad float128, Boost.Multiprecision types like cpp_bin_float_quad, cpp_bin_float_50... + +template +inline T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) +{ + static const char* function = "boost::math::lambert_w0<%1%>"; + BOOST_MATH_STD_USING // Aid ADL of std functions. + + // Filter out special cases first: + if ((boost::math::isnan)(z)) + { + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + if (fabs(z) <= 0.05f) + { + // Very small z: + return lambert_w0_small_z(z, pol); + } + if (z > (std::numeric_limits::max)()) + { + if ((boost::math::isinf)(z)) + { + return policies::raise_overflow_error(function, nullptr, pol); + // Or might return infinity if available else max_value, + // but other Boost.Math special functions raise overflow. + } + // z is larger than the largest double, so cannot use the polynomial to get an approximation, + // so use the asymptotic approximation and Halley iterate: + + T w = lambert_w0_approx(z); // Make an inline function as also used elsewhere. + //T lz = log(z); + //T llz = log(lz); + //T w = lz - llz + (llz / lz); // Corless equation 4.19, page 349, and Chapeau-Blondeau equation 20, page 2162. + return lambert_w_halley_iterate(w, z); + } + if (z < -0.3578794411714423215955237701) + { // Very close to branch point so rational polynomials are not usable. + if (z <= -boost::math::constants::exp_minus_one()) + { + if (z == -boost::math::constants::exp_minus_one()) + { // Exactly at the branch point singularity. + return -1; + } + return boost::math::policies::raise_domain_error(function, "Expected z >= -e^-1 (-0.367879...) but got %1%.", z, pol); + } + // z is very close (within 0.01) of the branch singularity at -e^-1 + // so use a series approximation proposed by Corless et al. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + const T p = sqrt(p2); + T w = lambert_w_detail::lambert_w_singularity_series(p); + return lambert_w_halley_iterate(w, z); + } + + // Phew! If we get here we are in the normal range of the function, + // so get a double precision approximation first, then iterate to full precision of T. + // We define a tag_type that is: + // true_type if there are so many digits precision wanted that iteration is necessary. + // false_type if a single Halley step is sufficient. + + using precision_type = typename policies::precision::type; + using tag_type = std::integral_constant 113) ? + true // Unknown at compile-time, variable/arbitrary, or more than float128 or cpp_bin_quad 128-bit precision. + : false // float, double, float128, cpp_bin_quad 128-bit, so single Halley step. + >; + + // For speed, we also cast z to type double when that is possible + // if (std::is_constructible() == true). + T w = lambert_w0_imp(maybe_reduce_to_double(z, std::is_constructible()), pol, std::integral_constant()); + + return lambert_w_maybe_halley_iterate(w, z, tag_type()); + +} // T lambert_w0_imp(T z, const Policy& pol, const std::integral_constant&) all extended precision types. + + // Lambert w-1 implementation +// ============================================================================================== + + //! Lambert W for W-1 branch, -max(z) < z <= -1/e. + // TODO is -max(z) allowed? +template +T lambert_wm1_imp(const T z, const Policy& pol) +{ + // Catch providing an integer value as parameter x to lambert_w, for example, lambert_w(1). + // Need to ensure it is a floating-point type (of the desired type, float 1.F, double 1., or long double 1.L), + // or static_casted integer, for example: static_cast(1) or static_cast(1). + // Want to allow fixed_point types too, so do not just test for floating-point. + // Integral types should be promoted to double by user Lambert w functions. + // If integral type provided to user function lambert_w0 or lambert_wm1, + // then should already have been promoted to double. + static_assert(!std::is_integral::value, + "Must be floating-point or fixed type (not integer type), for example: lambert_wm1(1.), not lambert_wm1(1)!"); + + BOOST_MATH_STD_USING // Aid argument dependent lookup (ADL) of abs. + + const char* function = "boost::math::lambert_wm1()"; // Used for error messages. + + // Check for edge and corner cases first: + if ((boost::math::isnan)(z)) + { + return policies::raise_domain_error(function, + "Argument z is NaN!", + z, pol); + } // isnan + + if ((boost::math::isinf)(z)) + { + return policies::raise_domain_error(function, + "Argument z is infinite!", + z, pol); + } // isinf + + if (z == static_cast(0)) + { // z is exactly zero so return -std::numeric_limits::infinity(); + if (std::numeric_limits::has_infinity) + { + return -std::numeric_limits::infinity(); + } + else + { + return -tools::max_value(); + } + } + if (std::numeric_limits::has_denorm) + { // All real types except arbitrary precision. + if (!(boost::math::isnormal)(z)) + { // Almost zero - might also just return infinity like z == 0 or max_value? + return policies::raise_overflow_error(function, + "Argument z = %1% is denormalized! (must be z > (std::numeric_limits::min)() or z == 0)", + z, pol); + } + } + + if (z > static_cast(0)) + { // + return policies::raise_domain_error(function, + "Argument z = %1% is out of range (z <= 0) for Lambert W-1 branch! (Try Lambert W0 branch?)", + z, pol); + } + if (z > -boost::math::tools::min_value()) + { // z is denormalized, so cannot be computed. + // -std::numeric_limits::min() is smallest for type T, + // for example, for double: lambert_wm1(-2.2250738585072014e-308) = -714.96865723796634 + return policies::raise_overflow_error(function, + "Argument z = %1% is too small (z < -std::numeric_limits::min so denormalized) for Lambert W-1 branch!", + z, pol); + } + if (z == -boost::math::constants::exp_minus_one()) // == singularity/branch point z = -exp(-1) = -3.6787944. + { // At singularity, so return exactly -1. + return -static_cast(1); + } + // z is too negative for the W-1 (or W0) branch. + if (z < -boost::math::constants::exp_minus_one()) // > singularity/branch point z = -exp(-1) = -3.6787944. + { + return policies::raise_domain_error(function, + "Argument z = %1% is out of range (z < -exp(-1) = -3.6787944... <= 0) for Lambert W-1 (or W0) branch!", + z, pol); + } + if (z < static_cast(-0.35)) + { // Close to singularity/branch point z = -0.3678794411714423215955237701614608727 but on W-1 branch. + const T p2 = 2 * (boost::math::constants::e() * z + 1); + if (p2 == 0) + { // At the singularity at branch point. + return -1; + } + if (p2 > 0) + { + T w_series = lambert_w_singularity_series(T(-sqrt(p2))); + if (boost::math::tools::digits() > 53) + { // Multiprecision, so try a Halley refinement. + w_series = lambert_w_detail::lambert_w_halley_iterate(w_series, z); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Lambert W-1 Halley updated to " << w_series << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + } + return w_series; + } + // Should not get here. + return policies::raise_domain_error(function, + "Argument z = %1% is out of range for Lambert W-1 branch. (Should not get here - please report!)", + z, pol); + } // if (z < -0.35) + + using lambert_w_lookup::wm1es; + using lambert_w_lookup::wm1zs; + using lambert_w_lookup::noof_wm1zs; // size == 64 + + // std::cout <<" Wm1zs[63] (== G[64]) = " << " " << wm1zs[63] << std::endl; // Wm1zs[63] (== G[64]) = -1.0264389699511283e-26 + // Check that z argument value is not smaller than lookup_table G[64] + // std::cout << "(z > wm1zs[63]) = " << std::boolalpha << (z > wm1zs[63]) << std::endl; + + if (z >= wm1zs[63]) // wm1zs[63] = -1.0264389699511282259046957018510946438e-26L W = 64.00000000000000000 + { // z >= -1.0264389699511303e-26 (but z != 0 and z >= std::numeric_limits::min() and so NOT denormalized). + + // Some info on Lambert W-1 values for extreme values of z. + // std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + // std::cout << "-std::numeric_limits::min() = " << -(std::numeric_limits::min)() << std::endl; + // std::cout << "-std::numeric_limits::min() = " << -(std::numeric_limits::min)() << std::endl; + // -std::numeric_limits::min() = -1.1754943508222875e-38 + // -std::numeric_limits::min() = -2.2250738585072014e-308 + // N[productlog(-1, -1.1754943508222875 * 10^-38 ), 50] = -91.856775324595479509567756730093823993834155027858 + // N[productlog(-1, -2.2250738585072014e-308 * 10^-308 ), 50] = -1424.8544521230553853558132180518404363617968042942 + // N[productlog(-1, -1.4325445274604020119111357113179868158* 10^-27), 37] = -65.99999999999999999999999999999999955 + + // R.M.Corless, G.H.Gonnet, D.E.G.Hare, D.J.Jeffrey, and D.E.Knuth, + // On the Lambert W function, Adv.Comput.Math., vol. 5, pp. 329, 1996. + // Francois Chapeau-Blondeau and Abdelilah Monir + // Numerical Evaluation of the Lambert W Function + // IEEE Transactions On Signal Processing, VOL. 50, NO. 9, Sep 2002 + // https://pdfs.semanticscholar.org/7a5a/76a9369586dd0dd34dda156d8f2779d1fd59.pdf + // Estimate Lambert W using ln(-z) ... + // This is roughly the power of ten * ln(10) ~= 2.3. n ~= 10^n + // and improve by adding a second term -ln(ln(-z)) + T guess; // bisect lowest possible Gk[=64] (for lookup_t type) + T lz = log(-z); + T llz = log(-lz); + guess = lz - llz + (llz / lz); // Chapeau-Blondeau equation 20, page 2162. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "z = " << z << ", guess = " << guess << ", ln(-z) = " << lz << ", ln(-ln(-z) = " << llz << ", llz/lz = " << (llz / lz) << std::endl; + // z = -1.0000000000000001e-30, guess = -73.312782616731482, ln(-z) = -69.077552789821368, ln(-ln(-z) = 4.2352298269101114, llz/lz = -0.061311231447304194 + // z = -9.9999999999999999e-91, guess = -212.56650048504233, ln(-z) = -207.23265836946410, ln(-ln(-z) = 5.3338421155782205, llz/lz = -0.025738424423764311 + // >z = -2.2250738585072014e-308, guess = -714.95942238244606, ln(-z) = -708.39641853226408, ln(-ln(-z) = 6.5630038501819854, llz/lz = -0.0092645920821846622 + int d10 = policies::digits_base10(); // policy template parameter digits10 + int d2 = policies::digits(); // digits base 2 from policy. + std::cout << "digits10 = " << d10 << ", digits2 = " << d2 // For example: digits10 = 1, digits2 = 5 + << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_TINY + if (policies::digits() < 12) + { // For the worst case near w = 64, the error in the 'guess' is ~0.008, ratio ~ 0.0001 or 1 in 10,000 digits 10 ~= 4, or digits2 ~= 12. + return guess; + } + T result = lambert_w_detail::lambert_w_halley_iterate(guess, z); + return result; + + // Was Fukushima + // G[k=64] == g[63] == -1.02643897e-26 + //return policies::raise_domain_error(function, + // "Argument z = %1% is too small (< -1.02643897e-26) ! (Should not occur, please report.", + // z, pol); + } // Z too small so use approximation and Halley. + // Else Use a lookup table to find the nearest integer part of Lambert W-1 as starting point for Bisection. + + if (boost::math::tools::digits() > 53) + { // T is more precise than 64-bit double (or long double, or ?), + // so compute an approximate value using only one Schroeder refinement, + // (avoiding any double-precision Halley refinement from policy double_digits2<50> 53 - 3 = 50 + // because are next going to use Halley refinement at full/high precision using this as an approximation). + using boost::math::policies::precision; + using boost::math::policies::digits10; + using boost::math::policies::digits2; + using boost::math::policies::policy; + // Compute a 50-bit precision approximate W0 in a double (no Halley refinement). + T double_approx(static_cast(lambert_wm1_imp(must_reduce_to_double(z, std::is_constructible()), policy>()))); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_NOT_BUILTIN + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Lambert_wm1 Argument Type " << typeid(T).name() << " approximation double = " << double_approx << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + // Perform additional Halley refinement(s) to ensure that + // get a near as possible to correct result (usually +/- one epsilon). + T result = lambert_w_halley_iterate(double_approx, z); +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Result " << typeid(T).name() << " precision Halley refinement = " << result << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1 + return result; + } // digits > 53 - higher precision than double. + else // T is double or less precision. + { // Use a lookup table to find the nearest integer part of Lambert W as starting point for Bisection. + using namespace boost::math::lambert_w_detail::lambert_w_lookup; + // Bracketing sequence n = (2, 4, 8, 16, 32, 64) for W-1 branch. (0 is -infinity) + // Since z is probably quite small, start with lowest n (=2). + int n = 2; + if (wm1zs[n - 1] > z) + { + goto bisect; + } + for (int j = 1; j <= 5; ++j) + { + n *= 2; + if (wm1zs[n - 1] > z) + { + goto overshot; + } + } + // else z < g[63] == -1.0264389699511303e-26, so Lambert W-1 integer part > 64. + // This should not now occur (should be caught by test and code above) so should be a logic_error? + return policies::raise_domain_error(function, + "Argument z = %1% is too small (< -1.026439e-26) (logic error - please report!)", + z, pol); + overshot: + { + int nh = n / 2; + for (int j = 1; j <= 5; ++j) + { + nh /= 2; // halve step size. + if (nh <= 0) + { + break; // goto bisect; + } + if (wm1zs[n - nh - 1] > z) + { + n -= nh; + } + } + } + bisect: + --n; + // g[n] now holds lambert W of floor integer n and g[n+1] the ceil part; + // these are used as initial values for bisection. +#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP + std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); + std::cout << "Result lookup W-1(" << z << ") bisection between wm1zs[" << n - 1 << "] = " << wm1zs[n - 1] << " and wm1zs[" << n << "] = " << wm1zs[n] + << ", bisect mean = " << (wm1zs[n - 1] + wm1zs[n]) / 2 << std::endl; + std::cout.precision(saved_precision); +#endif // BOOST_MATH_INSTRUMENT_LAMBERT_WM1_LOOKUP + + // Compute bisections is the number of bisections computed from n, + // such that a single application of the fifth-order Schroeder update formula + // after the bisections is enough to evaluate Lambert W-1 with (near?) 53-bit accuracy. + // Fukushima established these by trial and error? + int bisections = 11; // Assume maximum number of bisections will be needed (most common case). + if (n >= 8) + { + bisections = 8; + } + else if (n >= 3) + { + bisections = 9; + } + else if (n >= 2) + { + bisections = 10; + } + // Bracketing, Fukushima section 2.3, page 82: + // (Avoiding using exponential function for speed). + // Only use @c lookup_t precision, default double, for bisection (again for speed), + // and use later Halley refinement for higher precisions. + using lambert_w_lookup::halves; + using lambert_w_lookup::sqrtwm1s; + + using calc_type = typename std::conditional::value, lookup_t, T>::type; + + calc_type w = -static_cast(n); // Equation 25, + calc_type y = static_cast(z * wm1es[n - 1]); // Equation 26, + // Perform the bisections fractional bisections for necessary precision. + for (int j = 0; j < bisections; ++j) + { // Equation 27. + calc_type wj = w - halves[j]; // Subtract 1/2, 1/4, 1/8 ... + calc_type yj = y * sqrtwm1s[j]; // Multiply by sqrt(1/e), ... + if (wj < yj) + { + w = wj; + y = yj; + } + } // for j + return static_cast(schroeder_update(w, y)); // Schroeder 5th order method refinement. + +// else // Perform additional Halley refinement(s) to ensure that +// // get a near as possible to correct result (usually +/- epsilon). +// { +// // result = lambert_w_halley_iterate(result, z); +// result = lambert_w_halley_step(result, z); // Just one Halley step should be enough. +//#ifdef BOOST_MATH_INSTRUMENT_LAMBERT_WM1_HALLEY +// std::streamsize saved_precision = std::cout.precision(std::numeric_limits::max_digits10); +// std::cout << "Halley refinement estimate = " << result << std::endl; +// std::cout.precision(saved_precision); +//#endif // BOOST_MATH_INSTRUMENT_LAMBERT_W1_HALLEY +// return result; // Halley +// } // Schroeder or Schroeder and Halley. + } + } // template T lambert_wm1_imp(const T z) +} // namespace lambert_w_detail + +///////////////////////////// User Lambert w functions. ////////////////////////////// + +//! Lambert W0 using User-defined policy. + template + inline + typename boost::math::tools::promote_args::type + lambert_w0(T z, const Policy& pol) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + + // Work out what precision has been selected, + // based on the Policy and the number type. + using precision_type = typename policies::precision::type; + // and then select the correct implementation based on that precision (not the type T): + using tag_type = std::integral_constant 53) ? + 0 // either variable precision (0), or greater than 64-bit precision. + : (precision_type::value <= 24) ? 1 // 32-bit (probably float) precision. + : 2 // 64-bit (probably double) precision. + >; + + return lambert_w_detail::lambert_w0_imp(result_type(z), pol, tag_type()); // + } // lambert_w0(T z, const Policy& pol) + + //! Lambert W0 using default policy. + template + inline + typename tools::promote_args::type + lambert_w0(T z) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + + // Work out what precision has been selected, based on the Policy and the number type. + // For the default policy version, we want the *default policy* precision for T. + using precision_type = typename policies::precision>::type; + // and then select the correct implementation based on that (not the type T): + using tag_type = std::integral_constant 53) ? + 0 // either variable precision (0), or greater than 64-bit precision. + : (precision_type::value <= 24) ? 1 // 32-bit (probably float) precision. + : 2 // 64-bit (probably double) precision. + >; + return lambert_w_detail::lambert_w0_imp(result_type(z), policies::policy<>(), tag_type()); + } // lambert_w0(T z) using default policy. + + //! W-1 branch (-max(z) < z <= -1/e). + + //! Lambert W-1 using User-defined policy. + template + inline + typename tools::promote_args::type + lambert_wm1(T z, const Policy& pol) + { + // Promote integer or expression template arguments to double, + // without doing any other internal promotion like float to double. + using result_type = typename tools::promote_args::type; + return lambert_w_detail::lambert_wm1_imp(result_type(z), pol); // + } + + //! Lambert W-1 using default policy. + template + inline + typename tools::promote_args::type + lambert_wm1(T z) + { + using result_type = typename tools::promote_args::type; + return lambert_w_detail::lambert_wm1_imp(result_type(z), policies::policy<>()); + } // lambert_wm1(T z) + + // First derivative of Lambert W0 and W-1. + template + inline typename tools::promote_args::type + lambert_w0_prime(T z, const Policy& pol) + { + using result_type = typename tools::promote_args::type; + using std::numeric_limits; + if (z == 0) + { + return static_cast(1); + } + // This is the sensible choice if we regard the Lambert-W function as complex analytic. + // Of course on the real line, it's just undefined. + if (z == - boost::math::constants::exp_minus_one()) + { + return numeric_limits::has_infinity ? numeric_limits::infinity() : boost::math::tools::max_value(); + } + // if z < -1/e, we'll let lambert_w0 do the error handling: + result_type w = lambert_w0(result_type(z), pol); + // If w ~ -1, then presumably this can get inaccurate. + // Is there an accurate way to evaluate 1 + W(-1/e + eps)? + // Yes: This is discussed in the Princeton Companion to Applied Mathematics, + // 'The Lambert-W function', Section 1.3: Series and Generating Functions. + // 1 + W(-1/e + x) ~ sqrt(2ex). + // Nick is not convinced this formula is more accurate than the naive one. + // However, for z != -1/e, we never get rounded to w = -1 in any precision I've tested (up to cpp_bin_float_100). + return w / (z * (1 + w)); + } // lambert_w0_prime(T z) + + template + inline typename tools::promote_args::type + lambert_w0_prime(T z) + { + return lambert_w0_prime(z, policies::policy<>()); + } + + template + inline typename tools::promote_args::type + lambert_wm1_prime(T z, const Policy& pol) + { + using std::numeric_limits; + using result_type = typename tools::promote_args::type; + //if (z == 0) + //{ + // return static_cast(1); + //} + //if (z == - boost::math::constants::exp_minus_one()) + if (z == 0 || z == - boost::math::constants::exp_minus_one()) + { + return numeric_limits::has_infinity ? -numeric_limits::infinity() : -boost::math::tools::max_value(); + } + + result_type w = lambert_wm1(z, pol); + return w/(z*(1+w)); + } // lambert_wm1_prime(T z) + + template + inline typename tools::promote_args::type + lambert_wm1_prime(T z) + { + return lambert_wm1_prime(z, policies::policy<>()); + } + +}} //boost::math namespaces + +#endif // #ifdef BOOST_MATH_SF_LAMBERT_W_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/lanczos.hpp b/libcxx/src/third-party/boost/math/special_functions/lanczos.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/lanczos.hpp @@ -0,0 +1,2709 @@ +// (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 +#define BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace lanczos{ + +// +// Individual lanczos approximations start here. +// +// Optimal values for G for each N are taken from +// http://web.mala.bc.ca/pughg/phdThesis/phdThesis.pdf, +// as are the theoretical error bounds. +// +// Constants calculated using the method described by Godfrey +// http://my.fit.edu/~gabdo/gamma.txt and elaborated by Toth at +// http://www.rskey.org/gamma.htm using NTL::RR at 1000 bit precision. +// +// Begin with a small helper to force initialization of constants prior +// to main. This makes the constant initialization thread safe, even +// when called with a user-defined number type. +// +template +struct lanczos_initializer +{ + struct init + { + init() + { + T t(1); + Lanczos::lanczos_sum(t); + Lanczos::lanczos_sum_expG_scaled(t); + Lanczos::lanczos_sum_near_1(t); + Lanczos::lanczos_sum_near_2(t); + Lanczos::g(); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; +template +typename lanczos_initializer::init const lanczos_initializer::initializer; + +// +// Non-member helper which allows us to have a different g() value for the +// near_1 and near_2 approximations. This is a big help in reducing error +// rates for multiprecision types at large digit counts. +// Default version assumes all g() values are the same. +// +template +inline double lanczos_g_near_1_and_2(const L&) +{ + return L::g(); +} + + +// +// Lanczos Coefficients for N=6 G=5.581 +// Max experimental error (with arbitrary precision arithmetic) 9.516e-12 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos6 : public std::integral_constant +{ + // + // Produces slightly better than float precision when evaluated at + // double precision: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[6] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 8706.349592549009182288174442774377925882)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 8523.650341121874633477483696775067709735)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 3338.029219476423550899999750161289306564)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 653.6424994294008795995653541449610986791)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 63.99951844938187085666201263218840287667)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.506628274631006311133031631822390264407)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[6] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 32.81244541029783471623665933780748627823)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 32.12388941444332003446077108933558534361)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 12.58034729455216106950851080138931470954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.463444478353241423633780693218408889251)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.2412010548258800231126240760264822486599)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.009446967704539249494420221613134244048319)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[5] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.044879010930422922760429926121241330235)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -2.751366405578505366591317846728753993668)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 1.02282965224225004296750609604264824677)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -0.09786124911582813985028889636665335893627)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.0009829742267506615183144364420540766510112)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[5] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 5.748142489536043490764289256167080091892)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -7.734074268282457156081021756682138251825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 2.875167944990511006997713242805893543947)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, -0.2750873773533504542306766137703788781776)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 35, 0.002763134585812698552178368447708846850353)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 5.581000000000000405009359383257105946541; } +}; + +// +// Lanczos Coefficients for N=11 G=10.900511 +// Max experimental error (with arbitrary precision arithmetic) 2.16676e-19 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos11 : public std::integral_constant +{ + // + // Produces slightly better than double precision when evaluated at + // extended-double precision: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[11] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 38474670393.31776828316099004518914832218)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 36857665043.51950660081971227404959150474)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 15889202453.72942008945006665994637853242)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4059208354.298834770194507810788393801607)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 680547661.1834733286087695557084801366446)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 78239755.00312005289816041245285376206263)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 6246580.776401795264013335510453568106366)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 341986.3488721347032223777872763188768288)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 12287.19451182455120096222044424100527629)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 261.6140441641668190791708576058805625502)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 2.506628274631000502415573855452633787834)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[11] = { + static_cast(0u), + static_cast(362880u), + static_cast(1026576u), + static_cast(1172700u), + static_cast(723680u), + static_cast(269325u), + static_cast(63273u), + static_cast(9450u), + static_cast(870u), + static_cast(45u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[11] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 709811.662581657956893540610814842699825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 679979.847415722640161734319823103390728)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 293136.785721159725251629480984140341656)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 74887.5403291467179935942448101441897121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 12555.29058241386295096255111537516768137)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 1443.42992444170669746078056942194198252)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 115.2419459613734722083208906727972935065)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 6.30923920573262762719523981992008976989)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.2266840463022436475495508977579735223818)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.004826466289237661857584712046231435101741)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.4624429436045378766270459638520555557321e-4)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[11] = { + static_cast(0u), + static_cast(362880u), + static_cast(1026576u), + static_cast(1172700u), + static_cast(723680u), + static_cast(269325u), + static_cast(63273u), + static_cast(9450u), + static_cast(870u), + static_cast(45u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[10] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4.005853070677940377969080796551266387954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -13.17044315127646469834125159673527183164)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 17.19146865350790353683895137079288129318)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -11.36446409067666626185701599196274701126)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 4.024801119349323770107694133829772634737)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.7445703262078094128346501724255463005006)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.06513861351917497265045550019547857713172)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.00217899958561830354633560009312512312758)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.17655204574495137651670832229571934738e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.1036282091079938047775645941885460820853e-7)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[10] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 19.05889633808148715159575716844556056056)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -62.66183664701721716960978577959655644762)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 81.7929198065004751699057192860287512027)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -54.06941772964234828416072865069196553015)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 19.14904664790693019642068229478769661515)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -3.542488556926667589704590409095331790317)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.3099140334815639910894627700232804503017)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.01036716187296241640634252431913030440825)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, 0.8399926504443119927673843789048514017761e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 60, -0.493038376656195010308610694048822561263e-7)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 10.90051099999999983936049829935654997826; } +}; + +// +// Lanczos Coefficients for N=13 G=13.144565 +// Max experimental error (with arbitrary precision arithmetic) 9.2213e-23 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos13 : public std::integral_constant +{ + // + // Produces slightly better than extended-double precision when evaluated at + // higher precision: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[13] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 44012138428004.60895436261759919070125699)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 41590453358593.20051581730723108131357995)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 18013842787117.99677796276038389462742949)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 4728736263475.388896889723995205703970787)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 837910083628.4046470415724300225777912264)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 105583707273.4299344907359855510105321192)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 9701363618.494999493386608345339104922694)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 654914397.5482052641016767125048538245644)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 32238322.94213356530668889463945849409184)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1128514.219497091438040721811544858643121)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 26665.79378459858944762533958798805525125)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 381.8801248632926870394389468349331394196)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 2.506628274631000502415763426076722427007)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[13] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 86091529.53418537217994842267760536134841)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 81354505.17858011242874285785316135398567)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 35236626.38815461910817650960734605416521)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 9249814.988024471294683815872977672237195)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1639024.216687146960253839656643518985826)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 206530.8157641225032631778026076868855623)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 18976.70193530288915698282139308582105936)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1281.068909912559479885759622791374106059)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 63.06093343420234536146194868906771599354)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 2.207470909792527638222674678171050209691)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.05216058694613505427476207805814960742102)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.0007469903808915448316510079585999893674101)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.4903180573459871862552197089738373164184e-5)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[12] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 4.832115561461656947793029596285626840312)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -19.86441536140337740383120735104359034688)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 33.9927422807443239927197864963170585331)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -31.41520692249765980987427413991250886138)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 17.0270866009599345679868972409543597821)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -5.5077216950865501362506920516723682167)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 1.037811741948214855286817963800439373362)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.106640468537356182313660880481398642811)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.005276450526660653288757565778182586742831)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0001000935625597121545867453746252064770029)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.462590910138598083940803704521211569234e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.1735307814426389420248044907765671743012e-9)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[12] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 26.96979819614830698367887026728396466395)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -110.8705424709385114023884328797900204863)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 189.7258846119231466417015694690434770085)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -175.3397202971107486383321670769397356553)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 95.03437648691551457087250340903980824948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -30.7406022781665264273675797983497141978)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 5.792405601630517993355102578874590410552)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.5951993240669148697377539518639997795831)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.02944979359164017509944724739946255067671)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.0005586586555377030921194246330399163602684)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, 0.2581888478270733025288922038673392636029e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 72, -0.9685385411006641478305219367315965391289e-9)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 13.1445650000000000545696821063756942749; } +}; + +// +// Lanczos Coefficients for N=6 G=1.428456135094165802001953125 +// Max experimental error (with arbitrary precision arithmetic) 8.111667e-8 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos6m24 : public std::integral_constant +{ + // + // Use for float precision, when evaluated as a float: + // + template + static T lanczos_sum(const T& z) + { + static const T num[6] = { + static_cast(58.52061591769095910314047740215847630266L), + static_cast(182.5248962595894264831189414768236280862L), + static_cast(211.0971093028510041839168287718170827259L), + static_cast(112.2526547883668146736465390902227161763L), + static_cast(27.5192015197455403062503721613097825345L), + static_cast(2.50662858515256974113978724717473206342L) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[6] = { + static_cast(14.0261432874996476619570577285003839357L), + static_cast(43.74732405540314316089531289293124360129L), + static_cast(50.59547402616588964511581430025589038612L), + static_cast(26.90456680562548195593733429204228910299L), + static_cast(6.595765571169314946316366571954421695196L), + static_cast(0.6007854010515290065101128585795542383721L) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint16_t) denom[6] = { + static_cast(0u), + static_cast(24u), + static_cast(50u), + static_cast(35u), + static_cast(10u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[5] = { + static_cast(0.4922488055204602807654354732674868442106L), + static_cast(0.004954497451132152436631238060933905650346L), + static_cast(-0.003374784572167105840686977985330859371848L), + static_cast(0.001924276018962061937026396537786414831385L), + static_cast(-0.00056533046336427583708166383712907694434L), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[5] = { + static_cast(0.6534966888520080645505805298901130485464L), + static_cast(0.006577461728560758362509168026049182707101L), + static_cast(-0.004480276069269967207178373559014835978161L), + static_cast(0.00255461870648818292376982818026706528842L), + static_cast(-0.000750517993690428370380996157470900204524L), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 1.428456135094165802001953125; } +}; + +// +// Lanczos Coefficients for N=13 G=6.024680040776729583740234375 +// Max experimental error (with arbitrary precision arithmetic) 1.196214e-17 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos13m53 : public std::integral_constant +{ + // + // Use for double precision, when evaluated as a double: + // + template + static T lanczos_sum(const T& z) + { + static const T num[13] = { + static_cast(23531376880.41075968857200767445163675473L), + static_cast(42919803642.64909876895789904700198885093L), + static_cast(35711959237.35566804944018545154716670596L), + static_cast(17921034426.03720969991975575445893111267L), + static_cast(6039542586.35202800506429164430729792107L), + static_cast(1439720407.311721673663223072794912393972L), + static_cast(248874557.8620541565114603864132294232163L), + static_cast(31426415.58540019438061423162831820536287L), + static_cast(2876370.628935372441225409051620849613599L), + static_cast(186056.2653952234950402949897160456992822L), + static_cast(8071.672002365816210638002902272250613822L), + static_cast(210.8242777515793458725097339207133627117L), + static_cast(2.506628274631000270164908177133837338626L) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[13] = { + static_cast(56906521.91347156388090791033559122686859L), + static_cast(103794043.1163445451906271053616070238554L), + static_cast(86363131.28813859145546927288977868422342L), + static_cast(43338889.32467613834773723740590533316085L), + static_cast(14605578.08768506808414169982791359218571L), + static_cast(3481712.15498064590882071018964774556468L), + static_cast(601859.6171681098786670226533699352302507L), + static_cast(75999.29304014542649875303443598909137092L), + static_cast(6955.999602515376140356310115515198987526L), + static_cast(449.9445569063168119446858607650988409623L), + static_cast(19.51992788247617482847860966235652136208L), + static_cast(0.5098416655656676188125178644804694509993L), + static_cast(0.006061842346248906525783753964555936883222L) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint32_t) denom[13] = { + static_cast(0u), + static_cast(39916800u), + static_cast(120543840u), + static_cast(150917976u), + static_cast(105258076u), + static_cast(45995730u), + static_cast(13339535u), + static_cast(2637558u), + static_cast(357423u), + static_cast(32670u), + static_cast(1925u), + static_cast(66u), + static_cast(1u) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[12] = { + static_cast(2.208709979316623790862569924861841433016L), + static_cast(-3.327150580651624233553677113928873034916L), + static_cast(1.483082862367253753040442933770164111678L), + static_cast(-0.1993758927614728757314233026257810172008L), + static_cast(0.004785200610085071473880915854204301886437L), + static_cast(-0.1515973019871092388943437623825208095123e-5L), + static_cast(-0.2752907702903126466004207345038327818713e-7L), + static_cast(0.3075580174791348492737947340039992829546e-7L), + static_cast(-0.1933117898880828348692541394841204288047e-7L), + static_cast(0.8690926181038057039526127422002498960172e-8L), + static_cast(-0.2499505151487868335680273909354071938387e-8L), + static_cast(0.3394643171893132535170101292240837927725e-9L), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[12] = { + static_cast(6.565936202082889535528455955485877361223L), + static_cast(-9.8907772644920670589288081640128194231L), + static_cast(4.408830289125943377923077727900630927902L), + static_cast(-0.5926941084905061794445733628891024027949L), + static_cast(0.01422519127192419234315002746252160965831L), + static_cast(-0.4506604409707170077136555010018549819192e-5L), + static_cast(-0.8183698410724358930823737982119474130069e-7L), + static_cast(0.9142922068165324132060550591210267992072e-7L), + static_cast(-0.5746670642147041587497159649318454348117e-7L), + static_cast(0.2583592566524439230844378948704262291927e-7L), + static_cast(-0.7430396708998719707642735577238449585822e-8L), + static_cast(0.1009141566987569892221439918230042368112e-8L), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 6.024680040776729583740234375; } +}; + +// +// Lanczos Coefficients for N=17 G=12.2252227365970611572265625 +// Max experimental error (with arbitrary precision arithmetic) 2.7699e-26 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos17m64 : public std::integral_constant +{ + // + // Use for extended-double precision, when evaluated as an extended-double: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[17] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 553681095419291969.2230556393350368550504)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 731918863887667017.2511276782146694632234)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 453393234285807339.4627124634539085143364)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 174701893724452790.3546219631779712198035)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 46866125995234723.82897281620357050883077)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9281280675933215.169109622777099699054272)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1403600894156674.551057997617468721789536)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 165345984157572.7305349809894046783973837)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 15333629842677.31531822808737907246817024)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1123152927963.956626161137169462874517318)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 64763127437.92329018717775593533620578237)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2908830362.657527782848828237106640944457)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 99764700.56999856729959383751710026787811)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2525791.604886139959837791244686290089331)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 44516.94034970167828580039370201346554872)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 488.0063567520005730476791712814838113252)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2.50662827463100050241576877135758834683)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint64_t) denom[17] = { + BOOST_MATH_INT_VALUE_SUFFIX(0, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(120, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1, uLL) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[17] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2715894658327.717377557655133124376674911)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 3590179526097.912105038525528721129550434)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 2223966599737.814969312127353235818710172)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 856940834518.9562481809925866825485883417)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 229885871668.749072933597446453399395469)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 45526171687.54610815813502794395753410032)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 6884887713.165178784550917647709216424823)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 811048596.1407531864760282453852372777439)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 75213915.96540822314499613623119501704812)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 5509245.417224265151697527957954952830126)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 317673.5368435419126714931842182369574221)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 14268.27989845035520147014373320337523596)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 489.3618720403263670213909083601787814792)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 12.38941330038454449295883217865458609584)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2183627389504614963941574507281683147897)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.002393749522058449186690627996063983095463)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1229541408909435212800785616808830746135e-4)) + }; + static const BOOST_MATH_INT_TABLE_TYPE(T, std::uint64_t) denom[17] = { + BOOST_MATH_INT_VALUE_SUFFIX(0, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1307674368000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4339163001600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6165817614720, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(5056995703824, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(2706813345600, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1009672107080, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(272803210680, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(54631129553, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(8207628000, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(928095740, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(78558480, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(4899622, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(218400, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(6580, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(120, uLL), + BOOST_MATH_INT_VALUE_SUFFIX(1, uLL) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[16] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 4.493645054286536365763334986866616581265)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -16.95716370392468543800733966378143997694)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 26.19196892983737527836811770970479846644)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -21.3659076437988814488356323758179283908)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 9.913992596774556590710751047594507535764)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -2.62888300018780199210536267080940382158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.3807056693542503606384861890663080735588)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.02714647489697685807340312061034730486958)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.0007815484715461206757220527133967191796747)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.6108630817371501052576880554048972272435e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.5037380238864836824167713635482801545086e-8)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1483232144262638814568926925964858237006e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1346609158752142460943888149156716841693e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.660492688923978805315914918995410340796e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.1472114697343266749193617793755763792681e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1410901942033374651613542904678399264447e-16)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[16] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 23.56409085052261327114594781581930373708)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -88.92116338946308797946237246006238652361)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 137.3472822086847596961177383569603988797)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -112.0400438263562152489272966461114852861)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 51.98768915202973863076166956576777843805)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -13.78552090862799358221343319574970124948)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 1.996371068830872830250406773917646121742)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.1423525874909934506274738563671862576161)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.004098338646046865122459664947239111298524)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3203286637326511000882086573060433529094e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.2641536751640138646146395939004587594407e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7777876663062235617693516558976641009819e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7061443477097101636871806229515157914789e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.3463537849537988455590834887691613484813e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, 0.7719578215795234036320348283011129450595e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 64, -0.7398586479708476329563577384044188912075e-16)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 12.2252227365970611572265625; } +}; + +// +// Lanczos Coefficients for N=24 G=20.3209821879863739013671875 +// Max experimental error (with arbitrary precision arithmetic) 1.0541e-38 +// Generated with compiler: Microsoft Visual C++ version 8.0 on Win32 at Mar 23 2006 +// +struct lanczos24m113 : public std::integral_constant +{ + // + // Use for long-double precision, when evaluated as an long-double: + // + template + static T lanczos_sum(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2029889364934367661624137213253.22102954656825019111612712252027267955023987678816620961507)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2338599599286656537526273232565.2727349714338768161421882478417543004440597874814359063158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1288527989493833400335117708406.3953711906175960449186720680201425446299360322830739180195)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 451779745834728745064649902914.550539158066332484594436145043388809847364393288132164411521)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 113141284461097964029239556815.291212318665536114012605167994061291631013303788706545334708)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 21533689802794625866812941616.7509064680880468667055339259146063256555368135236149614592432)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3235510315314840089932120340.71494940111731241353655381919722177496659303550321056514776757)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 393537392344185475704891959.081297108513472083749083165179784098220158201055270548272414314)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 39418265082950435024868801.5005452240816902251477336582325944930252142622315101857742955673)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3290158764187118871697791.05850632319194734270969161036889516414516566453884272345518372696)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 230677110449632078321772.618245845856640677845629174549731890660612368500786684333975350954)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 13652233645509183190158.5916189185218250859402806777406323001463296297553612462737044693697)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 683661466754325350495.216655026531202476397782296585200982429378069417193575896602446904762)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 28967871782219334117.0122379171041074970463982134039409352925258212207710168851968215545064)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1036104088560167006.2022834098572346459442601718514554488352117620272232373622553429728555)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 31128490785613152.8380102669349814751268126141105475287632676569913936040772990253369753962)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 779327504127342.536207878988196814811198475410572992436243686674896894543126229424358472541)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 16067543181294.643350688789124777020407337133926174150582333950666044399234540521336771876)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 268161795520.300916569439413185778557212729611517883948634711190170998896514639936969855484)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3533216359.10528191668842486732408440112703691790824611391987708562111396961696753452085068)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 35378979.5479656110614685178752543826919239614088343789329169535932709470588426584501652577)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253034.881362204346444503097491737872930637147096453940375713745904094735506180552724766444)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1151.61895453463992438325318456328526085882924197763140514450975619271382783957699017875304)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2.50662827463100050241576528481104515966515623051532908941425544355490413900497467936202516)) + }; + static const T denom[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T num[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3035162425359883494754.02878223286972654682199012688209026810841953293372712802258398358538)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3496756894406430103600.16057175075063458536101374170860226963245118484234495645518505519827)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1926652656689320888654.01954015145958293168365236755537645929361841917596501251362171653478)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 675517066488272766316.083023742440619929434602223726894748181327187670231286180156444871912)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 169172853104918752780.086262749564831660238912144573032141700464995906149421555926000038492)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 32197935167225605785.6444116302160245528783954573163541751756353183343357329404208062043808)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4837849542714083249.37587447454818124327561966323276633775195138872820542242539845253171632)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 588431038090493242.308438203986649553459461798968819276505178004064031201740043314534404158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 58939585141634058.6206417889192563007809470547755357240808035714047014324843817783741669733)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4919561837722192.82991866530802080996138070630296720420704876654726991998309206256077395868)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 344916580244240.407442753122831512004021081677987651622305356145640394384006997569631719101)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 20413302960687.8250598845969238472629322716685686993835561234733641729957841485003560103066)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1022234822943.78400752460970689311934727763870970686747383486600540378889311406851534545789)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43313787191.9821354846952908076307094286897439975815501673706144217246093900159173598852503)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1549219505.59667418528481770869280437577581951167003505825834192510436144666564648361001914)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 46544421.1998761919380541579358096705925369145324466147390364674998568485110045455014967149)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1165278.06807504975090675074910052763026564833951579556132777702952882101173607903881127542)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 24024.759267256769471083727721827405338569868270177779485912486668586611981795179894572115)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 400.965008113421955824358063769761286758463521789765880962939528760888853281920872064838918)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 5.28299015654478269617039029170846385138134929147421558771949982217659507918482272439717603)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0528999024412510102409256676599360516359062802002483877724963720047531347449011629466149805)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.000378346710654740685454266569593414561162134092347356968516522170279688139165340746957511115)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.172194142179211139195966608011235161516824700287310869949928393345257114743230967204370963e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.374799931707148855771381263542708435935402853962736029347951399323367765509988401336565436e-8)) + }; + static const T denom[24] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.112400072777760768e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.414847677933545472e22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6756146673770930688000.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 6548684852703068697600.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4280722865357147142912.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2021687376910682741568.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 720308216440924653696.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 199321978221066137360.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 43714229649594412832.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7707401101297361068.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1103230881185949736.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 129006659818331295.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 12363045847086207.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 971250460939913.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 62382416421941.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 3256091103430.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 136717357942.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4546047198.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 116896626.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2240315.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 30107.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 253.0)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1.0)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[23] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 7.4734083002469026177867421609938203388868806387315406134072298925733950040583068760685908)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -50.4225805042247530267317342133388132970816607563062253708655085754357843064134941138154171)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 152.288200621747008570784082624444625293884063492396162110698238568311211546361189979357019)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -271.894959539150384169327513139846971255640842175739337449692360299099322742181325023644769)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 319.240102980202312307047586791116902719088581839891008532114107693294261542869734803906793)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -259.493144143048088289689500935518073716201741349569864988870534417890269467336454358361499)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 149.747518319689708813209645403067832020714660918583227716408482877303972685262557460145835)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -61.9261301009341333289187201425188698128684426428003249782448828881580630606817104372760037)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 18.3077524177286961563937379403377462608113523887554047531153187277072451294845795496072365)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -3.82011322251948043097070160584761236869363471824695092089556195047949392738162970152230254)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.549382685505691522516705902336780999493262538301283190963770663549981309645795228539620711)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.0524814679715180697633723771076668718265358076235229045603747927518423453658004287459638024)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.00315392664003333528534120626687784812050217700942910879712808180705014754163256855643360698)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000110098373127648510519799564665442121339511198561008748083409549601095293123407080388658329)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.19809382866681658224945717689377373458866950897791116315219376038432014207446832310901893e-5)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.152278977408600291408265615203504153130482270424202400677280558181047344681214058227949755e-7)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.364344768076106268872239259083188037615571711218395765792787047015406264051536972018235217e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.148897510480440424971521542520683536298361220674662555578951242811522959610991621951203526e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.261199241161582662426512749820666625442516059622425213340053324061794752786482115387573582e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.780072664167099103420998436901014795601783313858454665485256897090476089641613851903791529e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.303465867587106629530056603454807425512962762653755513440561256044986695349304176849392735e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.615420597971283870342083342286977366161772327800327789325710571275345878439656918541092056e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.499641233843540749369110053005439398774706583601830828776209650445427083113181961630763702e-26)), + }; + T result = 0; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(k*dz + k*k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + lanczos_initializer::force_instantiate(); // Ensure our constants get initialized before main() + static const T d[23] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 61.4165001061101455341808888883960361969557848005400286332291451422461117307237198559485365)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -414.372973678657049667308134761613915623353625332248315105320470271523320700386200587519147)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1251.50505818554680171298972755376376836161706773644771875668053742215217922228357204561873)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -2234.43389421602399514176336175766511311493214354568097811220122848998413358085613880612158)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 2623.51647746991904821899989145639147785427273427135380151752779100215839537090464785708684)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -2132.51572435428751962745870184529534443305617818870214348386131243463614597272260797772423)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 1230.62572059218405766499842067263311220019173335523810725664442147670956427061920234820189)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -508.90919151163744999377586956023909888833335885805154492270846381061182696305011395981929)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 150.453184562246579758706538566480316921938628645961177699894388251635886834047343195475395)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -31.3937061525822497422230490071156186113405446381476081565548185848237169870395131828731397)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 4.51482916590287954234936829724231512565732528859217337795452389161322923867318809206313688)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.431292919341108177524462194102701868233551186625103849565527515201492276412231365776131952)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.0259189820815586225636729971503340447445001375909094681698918294680345547092233915092128323)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.000904788882557558697594884691337532557729219389814315972435534723829065673966567231504429712)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.162793589759218213439218473348810982422449144393340433592232065020562974405674317564164312e-4)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.125142926178202562426432039899709511761368233479483128438847484617555752948755923647214487e-6)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.299418680048132583204152682950097239197934281178261879500770485862852229898797687301941982e-9)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.122364035267809278675627784883078206654408225276233049012165202996967011873995261617995421e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.21465364366598631597052073538883430194257709353929022544344097235100199405814005393447785e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.641064035802907518396608051803921688237330857546406669209280666066685733941549058513986818e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.249388374622173329690271566855185869111237201309011956145463506483151054813346819490278951e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, -0.505752900177513489906064295001851463338022055787536494321532352380960774349054239257683149e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 113, 0.410605371184590959139968810080063542546949719163227555918846829816144878123034347778284006e-25)), + }; + T result = 0; + T z = dz + 2; + for(unsigned k = 1; k <= sizeof(d)/sizeof(d[0]); ++k) + { + result += (-d[k-1]*dz)/(z + k*z + k*k - 1); + } + return result; + } + + static double g(){ return 20.3209821879863739013671875; } +}; + +// +// Lanczos Coefficients for N=27 G=2.472513680905104038743047567550092935562134e+01 +// Max experimental error (with MP precision arithmetic) 0.000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 23 2021 +// Type precision was 134 bits or 42 max_digits10 +// +struct lanczos27MP : public std::integral_constant +{ + template + static T lanczos_sum(const T& z) + { + static const T num[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.532923291341302819860952064783714673718970e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.715272050979243637524956158081893927075092e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.399396313336459710065708403038293278484916e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.615805213483907585030394968151583590083805e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.094287593119694642121339924355455488336630e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.985179143643083871895846729884916046817583e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.864723387203319421361199873281888626383507e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.374651939493419385833371654981557918551584e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.304504350810987437240912594601486056121725e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.724892917231894382998818728699010291796660e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.909901039551708500588401626148435467434009e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.145381204249362220411918333792713760478856e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.902980366355225260615014098246446681081078e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.620997933261144559370948440813656891792187e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.003441440382636640319535096309665505136930e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.309721390821762354780404195884829522953769e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.381514076593540726655991152770953882150136e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.275266040978137565809877941293859174071955e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.690398430937632687996992361090819887063422e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.142411407304237744553849404860811146407986e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.174971623395676312463521417132401487856454e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.384092119107453943335286646923309490786229e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.296932429990667045419860753608558102709582e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.299378037650538629629318998114044963408825e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.792561328661952922209314899668849919321249e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.580741273679785112052701460119954412080073e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.506628274631000502415765284811045253005320e+00)) + }; + static const T denom[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 0.000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.551121004333098598400000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.919012881170120359936000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.004801715483511615488000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.023395306017446756725760000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.087414531983767267719680000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.577035564590760682636262400000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.374646821796792697868000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.144457803247115877036800000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.001369304512841374110000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.969281004511108202428800000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.188201437529851278250000000000000000000000e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.284218746244111474800000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.805445587427335451250000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.514594692699448186500000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.557372853474553750000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.349615694227860500000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.297275331854287500000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.956673043671350000000000000000000000000000e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.256393782500000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.968295763000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.724710487500000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.336854950000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.858750000000000000000000000000000000000000e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.005000000000000000000000000000000000000000e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.250000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.630539114451826442425094380936505531231478e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.963898228350662244301785145431331232866294e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.558292778812387748738731408569861630189290e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.438339470758124934572462000795083198080916e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.000511235267926346573212315280041509763731e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.629185970715063928416526096935558921044815e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.237116237146422484431753186953979152997281e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.169337167415775727114018906990954798102547e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.041097534463262894898495303906833076469281e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.981486521549315574859643064948741979243976e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.491567035847004398885838650781864506656075e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.093917524216073202169716871304960622121045e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.079147622499629876874169792116583887362096e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.791551915666662583520458128259897770660473e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.834431723470453391466841656396291574724498e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.050635015489291434258728317621551605496937e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.715072384266421431637543951156767586591045e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.159505514655385281007353699906486901798470e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.574706336771416438731056639147393961539411e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.488547033239016552342729952719496931402330e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.148012961586177396403312787979484589898276e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.530314564772178162122057449947469958774484e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.370974425637913452858480025228307253546963e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.700056764080375263450528442694493496437080e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.761474446005270789145652778771406388702068e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.889816806780013044430000551700375309307825e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.582468135039046226997146555551548992616343e-11)) + }; + static const T denom[27] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 0.000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.551121004333098598400000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.919012881170120359936000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.004801715483511615488000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.023395306017446756725760000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.087414531983767267719680000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.577035564590760682636262400000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.374646821796792697868000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.144457803247115877036800000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.001369304512841374110000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.969281004511108202428800000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.188201437529851278250000000000000000000000e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.284218746244111474800000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.805445587427335451250000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.514594692699448186500000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.557372853474553750000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.349615694227860500000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.297275331854287500000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.956673043671350000000000000000000000000000e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.256393782500000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.968295763000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.724710487500000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.336854950000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.858750000000000000000000000000000000000000e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.005000000000000000000000000000000000000000e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.250000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[34] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 6.264579889722939745225908247624593169040293e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -3.470545597111704235784909052092266897169254e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 8.398164226943527197542310295220360303173237e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.166490739555248669771075340695671987349622e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.028101937812836112448434230485371426845812e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.003050880354706854567842055875605768028585e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.355206767355338215012383892758889890708805e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.173166763225116428638036856999036700963277e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.055748115088123667349396984075505516234940e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.127784364612243323022358484127515048080935e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.013011055366411613813518259345336997226641e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.271137289000937686705998821090835222190159e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.195172534910278451113805217678979457290834e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.421890451863814077221239932785029648679973e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.066311611137421591999312557597869716741027e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.797948012646761974584234409950319937184538e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -5.274002995605577985657965320478056380380290e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.270091452696164640108774677242731307730848e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -6.933040546739252731034872986511694993372995e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.405071936614348906224568346156522897751303e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.105092450748689398417350156762592106638543e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.573335807137266819877752062372030042747590e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.690602407074901259448169161354115161602278e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.445091932555604281164557526008785529455861e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.932804556880430674197633802977544778784320e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.320001406610629373227596309759263536640140e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -7.699733918513786660891771237627803608806010e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.776870859236169815307382842451635095251495e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.526154769745297076196084765279504608995696e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.939458578626915680695594094484224178207306e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.229538969055131478930409285699348366508295e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.207569067702627873429089508800955397620386e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.542428477414786133402832964643707382175743e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.409458057545117569935733339065832415295665e-25)) + }; + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[34] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.391991857844535020743473289228849738381662e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -2.433141291692735004291785549611375831426138e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 5.887812040849956173864447000497922705559488e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -8.178070869177285054991117755136346786974125e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.207850198088647199855281811058606257270817e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.208638257131458956367681504789416772705762e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.651195950543217389263490876246883903526458e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.327903648523876358512872196882929451369963e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.401672908678997114468388150043974540095678e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -7.906706968342945744899907670199667000072243e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 4.916704391410548803397953511596928808893685e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.592256249729202493268939584019491192080080e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.240081857804364904696255913500139170039349e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -9.968635402954290441376528527568797927543768e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 7.475731807209447934074840206826861054997914e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.961594409606987475034042150632670295904917e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -3.697515016601028609216707527257479621172555e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.591523031442252914289458638424672100510104e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -4.860638409502590149748648713304503849363893e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.850723614235842081434077716825371111986246e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.475844999417373489569601576817086030522522e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.804122560714365990744061859839148408328067e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.886336206511766947905039498619940334834436e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.714212931833249115161397417081604581762608e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.355056847554880232469037060291577918972607e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.254308400931922182743462783124793743058980e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -5.398154269396277345367516583851274647578103e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 2.647900793652290520419156346839352858087685e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.069961504286664892352397126472100106281531e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 3.462971538614891132079878533424998572755101e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -8.620091428399885297009840750915836982112365e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 1.547689636281132331592940788973245529484744e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, -1.782453950387991004107321678322483537333246e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 134, 9.881473972208065873607436095608077625677024e-25)), + }; + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + static double g() { return 2.472513680905104038743047567550092935562134e+01; } +}; + +inline double lanczos_g_near_1_and_2(const lanczos27MP&) +{ + return 17.03623256087303; +} + +// +// Lanczos Coefficients for N=35 G=2.96640371531248092651367187500000000000000000000000000e+01 +// Max experimental error (with 50 digit precision arithmetic) 67eps +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019 +// Type precision was 168 bits or 53 max_digits10 +// +struct lanczos35MP : public std::integral_constant +{ + template + static T lanczos_sum(const T& z) + { + static const T num[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.17215050716253100021302249837728942659410271586236104e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.51055117651708470336913962553466820524801246971658127e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40813458996718289733677017073036013655624930344397267e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.10569518324826607478187974291222641098997506635019681e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34502197565331471178368569687788687058240547971732391e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.74311603169690571192608960963509140372217014888512918e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.50656021978234091874071935392175934984492682009447097e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.12703102551730381018400796362603958419580969330315139e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.02844698442195350077632196816248435420923619452768200e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.90106767379334717236568166816961185224083190775430842e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.86371531667026447746284883480888667804130713757839681e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.34808948517797782155274346690360992144536507118093783e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.83232124439938458545786668616393415008373341980153072e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.62895707563068512468013948922815298700909218398406635e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.30384063116420066671650072267242339695473078925159324e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.76258309689585811716178198120267186946262194080905971e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51837231299916455171135124843484994848995300472356341e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.46324357690180919340289798257560253430931750807924001e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.75333853376321853646128997503611223620394342435525484e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01719517877315910652307531002686423847077617217874485e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.27861878894319497853745513558138184450369083409359360e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.89640024726662067702004632718605032785787967237099607e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.81537701811791870172286588846619085013138846074815251e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.03090758312551459302562064161308518889144037164899961e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.60538569869661647274451913615710409703905629234367906e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.18176163448730621246454091850022844174919234685832508e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.56586635256765282348264053213197702964352373258511008e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.58289895656990946427745668670352144404744258615044371e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.19373478903102411154024309088124853938046967389531861e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.54192605870424877025476980158698548681325282029269310e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.73027427579217615249706012469272147499107562412573337e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.82675918536460865549992482360500962016208597062710654e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.21869956201943834772161655315196962519434419814106818e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50897418653428667959996348205296461689142907811767371e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.50662827463100050241576528481104525300698674060984055e+00)) + }; + static const T denom[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.84421398435712762388902267099927585742388886580864424e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28731583799033736725852757551292030085556435695468295e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.84381150359300352571680869181416248982215282642834936e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.68539753215772969226355064737523321566208288321687448e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.76117184320624276162478300964159399462275652881271996e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.59183627116994441494601110756468114877940946273012852e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.90089018057779871758440184258134151304912092733579104e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.02273473587728940068021671629793244969348874651645551e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.20304883823127369598764418881022021049206245678741573e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.03625836242722113759123056762610636251641913153595812e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.67794913334462808923359541498599600753842936204419932e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.69338859264140114791649895977363900871692586779302150e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.70864158121145435408364940074910197916145829346031858e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.13295647753179115743895667847873122731507276407230715e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.08730493440263847356723847541024859440843056640671533e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.92672649809905793239714364398097142490510744815940192e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.98815678372776973689475889094271298156568135487559824e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.15357141696015228406471054927723105303656292491717836e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29582156512528703674984172534752222415664014582498353e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.56951562180494343732211791410530161839249714612303326e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.67422350715677024140556410421772283993277946880053914e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.79254663081905790190270601146772274854974105071798035e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.61465496276608608941993297108655885737613121720232292e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.34987044168298086318822469739196823360923972361455073e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.10209211537761991333937729340544738747931371426736883e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.85679879496413826670691454915567101976631415248412906e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.35974553231926272707704478737590721340254406209650188e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.38204802486455055334129565820015244464343854444712513e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.87247644413155087645140975008088533286977710080244249e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.01899805954981363917258740277358024893572331522514601e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.14314215799519834172753514406176454576793263619287700e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.01075867159821346256470334018168931185179114379271616e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.59576526838074751422330690168945437827562833198707558e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28525092722679899458094768960179796663588010298597603e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28217919006153582429216342066702743329957749672852350e-13)) + }; + static const T denom[35] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 0.00000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.68331761881188649551819440128000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.55043336733310191803732770947072000000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.55728779174162547080350866368102400000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.37352350419052295388404251629977600000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.72117566475005542296335706764492800000000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.28417720643003773414159612967554252800000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.45822739485943139719482682477713244160000000000000000e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.16476527817201997988283152951021977600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.49225481668254064104679479029764121600000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.57726463942545496998486904826347776000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.20859297660335343156864734965859840000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.23364307820330543590375511999050240000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.80750015058176473779293385245398400000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.28183125026789051815954180232544000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.49437224233918151570015089338400000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.37000480501772121324931003824000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.96258640868140652967646352465000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.41894262447739018035536664650000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.96452376168568744680811480000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.94875410890088264440962800000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.38478815149246067334598000000000000000000000000000000e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00124085806115519088380000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.65117470518809938644000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.15145312544238764840000000000000000000000000000000000e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.12192419709374919000000000000000000000000000000000000e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.22038661704031100000000000000000000000000000000000000e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.40979763670090400000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.29191290647440000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.04437176604000000000000000000000000000000000000000000e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.21763644400000000000000000000000000000000000000000000e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.60169360000000000000000000000000000000000000000000000e+07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.51096000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.61000000000000000000000000000000000000000000000000000e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.00000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[42] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.2258008829795701933757823508857131818190413131511363e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.1680809698202901664719598422224259984110345848176138e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.0937956909159916126016144892534179459545368045658870e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.2570860117223597345299309707009980433696777143916823e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.7808407045434705509914139521956838552432057817709310e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.5355182201018147597112724614545263772722036922648575e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.8474340895549068665467127190441982794533803160633534e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.9687073432491586288948383529096081854867384409828362e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.4457539281218595159502905008069838638140685905208109e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.0724321926101376768201888687693227423632630755627070e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.1941554220476109189863208161993450668341832413951177e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.0469416499468520752326008902894754184436051369514739e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.0254471406496505041361077191383344271915106887055424e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.9743975328123868311047848806382369109187457702980947e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.6326975883294075748535457727960259872733702003969396e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8276395425975110081829250599527615065306178329307764e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.4994926214942760944619799278085799215984014361562132e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.1685212562684580327244208091708941173130794374261284e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.0566129445336641178978472923139566421562362783155822e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -6.6744193557172228303189080097715371728193237070211608e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.3116377246238995291497495503598572469502355628188604e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.7791795131683583370183641939988202673347172514688534e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.6372242277604226411817535739257869758194674562641039e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.7502495488892655715569603094708394381657045801526069e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.0501577132014302973783965458067331883116843242885033e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.0246214059191840597181314245134333087378581123342727e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4016071303078853730266134475467378117726380022343630e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.6214830666337247122639245651193515459936309025504988e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.6312853482448038567407561706085851388360060108080568e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.4458785355627609495060506977643541320437284829970271e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.1331287575394227733315016732552406681866623847709417e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -7.8351635033967037250982310034619565150687081453609992e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.7520885958378593874310858129100278585054737696926701e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.5058409122183022757924336573867978222207111500077203e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.1353898614924597482474648262273645405650282912119167e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.3531153377666279783383214654257629384565834244973196e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.3839135182642184911017974189326632232475070566724497e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.5479558181723745255902653783884759401621303982915322e-29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.0441825447107352322817077249008075090725287665933142e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.0157887327297754418593987114368959771100770274203800e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 9.4607280988529299025458955706898751267120992042268667e-32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.2702032336418528894772149178970767164510337389404370e-33)) + }; + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[42] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 7.3782193657165970743894979068466124765194827248379940e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.5325256602067816772285455933211570612342576586214891e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.8780522570799869937961476290263461833002660531646012e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8184384596766268378888212415693303553880671796724735e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.1851863962133477520750252664910607723762372771833722e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -4.9651417912803026185477059393373316779106801664686922e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.4509968222802070571038728168526976259879110509473673e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.7658529366356277958293590921029620586497540226150778e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.6785479743985639684438881535624244315638292743993560e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.8588900406390499925005060563245955316983471925301184e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 3.7619921996662567540276653040387614527561121386327888e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.4238684621351227134322239416053684476498738936970880e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.4045887339956612618258661862314001628281850888893694e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.5648780296066214471224136948413423004282323597057130e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4644654223878248996887367583334112564695286627087816e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.4332418933955508302078477926243914098802666261366678e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.0358676398914795323109452992079597262040795201720992e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.9450781456519433542572418782578042705818718277820822e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 2.7416614067965791526251519843473783727166050306987362e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -5.9866912469474631311384623900742191091588854047124831e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.7643298058164570865040068204832109970445542816595386e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.4928145473701388663847838847907869194628008362147191e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.6442105079571407791997926495585104881317603986245265e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.4668655090053572169091092679046557243825245275372519e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 5.4267531441890485644063141608998212380717408586417687e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -9.1904503977518246823477462773596622658428222241396033e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.2571863845333234910026102012663485977044671519503762e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.4544064381831932921238058900083969277495893492892409e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.4631986986621358205011740516995928067691739105999606e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -1.2968960911316058263225162731552440661464077730310616e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.0163718599154085420173689991270137222141149005433561e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -7.0278330240079354003556694314544898753730575016426382e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 4.2624362787531585897289168590458242934350512724487489e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -2.2476405895248242769628910185593849817270999749433590e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.0183999810930941402072961555627198647985838184285745e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.9045729824028673594421184017022743317479187113896743e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 1.2413159115073860802650598534057774896614268826143102e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.1823766097367740928881247634568036933183255409575449e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 6.3183542619623422719031481991659628332908631907371078e-29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -9.1112247985618590949970839428497941653776549519221927e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, 8.4859004327675283792859615082199609974336399587796249e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 168, -3.8302040910318742925508017945893539585506545571212821e-32)), + }; + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + static double g() { return 2.96640371531248092651367187500000000000000000000000000e+01; } +}; + +inline double lanczos_g_near_1_and_2(const lanczos35MP&) +{ + return 22.36563469469547; +} +// +// Lanczos Coefficients for N=48 G=2.880805098265409469604492187500000000000000000000000000000000000e+01 +// Max experimental error (with 60-digit precision arithmetic) 51eps +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at Oct 14 2019 +// Type precision was 201 bits or 63 max_digits10 +// +struct lanczos48MP : public std::integral_constant +{ + template + static T lanczos_sum(const T& z) + { + static const T num[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.761757987425932419978923296640371540367427757167447418730589877e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.723233313564421930629677035555276136256253817229396631458438691e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.460052620548943146316510839385235752729444155384745952604400014e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.118620599704657143233902039524163888476114389296433891234019212e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.103553323924588863191816202847384353588419783622786374048756587e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.051624469576894078907076790635986076815810433950937821174281248e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.865434054315747674202246332480484800778071304068935338977820344e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.291785980379681713553231795767203835753576510251486784293089714e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.073927196464385740270105346713079967925505577692095446860826790e+67)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.884317172328855613403642857232246924724496526520223674336243586e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.515983058669346491005379681336434957516572863544374020968683717e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.791988252541273516986153564408477102509671668999707480365384945e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.645764905652320236264233988360776875326874810201273735655153182e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.144135487589921315512939394666974184673239886993573956770438389e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.444700846549614719681016920231266383188819427952261902403138865e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.721099093953481665535866508692670759355705777392277743203856663e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.100969797434901880312682514502493221610943693861105392844971160e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.418121506159806547634040503980950792234471035467217702752406105e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.417864259432558812733518752689742288284271989351444645566759428e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.665995533734965936996397899459612023184583125575089834552055942e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.444766925649844009950058690449625999301860892596426461258095232e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.053637791492838551734963920042182131006240650838206322215619662e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.150696853422753584935226676401667305978026730065639035499393518e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.985976091763077924792684854305586783380530313659602423780141188e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.269589095786672590317833654141210781129738119237951536741077115e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.718300118825405526804849893058410300716988331091767076237827497e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.001037055130874457401651655102738871459032839441218104652569066e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.475842513986568687160423191409256650108932454810648362428602348e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.620452049086499203878684285356863241396518483154492676811559133e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.169661026157169583693125067814111812572434991018171004040405784e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.227918466522161929152413190031319328201533237960827483146218740e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.876388843752351291646654793076860108915313255758699513365393870e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.145947758366681136606104191450792163942386660344907590963820717e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.853323303407534484800459250019301328433169196161471441696806506e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.154628006575221227908667538321556179086649067527404327882584768e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.357526820024103486396860374714568600536209103260198100884104997e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.431529899588725297356982438015035066854198997921929156832870645e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.345565129287503320724079046959642760096964859126850291147857935e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.118851309483567225684739040233675455708538654675741148330404763e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.153371780240325463304870847387326315142505274277395976930776452e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.146212685927632120682088036018035709941745020823689824280902727e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.771109638413640784841091904266004758198074452790973613270876444e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.247775743837944205683004431867637625466576857881195465700397478e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.570311375510395966207715903995528566489264305503840005145629111e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.307932649387240491969419239876926639445902586258953887216911993e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.743144608535924824275750439447323876880302369055576390115394778e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.749690888961891063146468955091435916957208840312184463551812828e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.506628274631000502415765284811045253006986740609938316629929233e+00)) + }; + static const T denom[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.775732062655417998910881298714821053061055705608286949609421120e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.688437299644448784121592662352787426980194425446481703306505899e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.990941408817264621124181941423397180231807676408175000011574647e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.611362716446299768312931282360230566955098878347512701289885826e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.401071382066693821667231534775770086983519477562699643517826070e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.404885497858970433702192998314287586471872015950314081905843790e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.115877029354588030985670444733795075439494699793733843615128537e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.981190790128533233774351539949086864384527026303253658346042487e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.391693345003088328615594164751621620795026048184784616056424156e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.889256530644592752851605934648543064680013184446459552930302708e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.083600502252557317792851907104175947655615832167024966482957198e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.168663303100387254423547467716347840589509950430146037235024663e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.123598327107617380847613820395680616677588511868146055764672247e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.689997752127767317102012222013845618089045780981297513260591263e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.534390868711924145397558028431517797916157184545344400315049888e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.304302698603539256283286371502868034443493795813215278491516590e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.393109140624987047793401361048831961769792029208766436336102130e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.978018543190809154654104033779556195143800802618966016721119650e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.053360999285885098804414279382371819392475408561904784568215676e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.134477518753880004346650767299407142912151189519394755303948278e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.294423222517027804991661400849986263936601088969957809227734095e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.411090410120803602405769061472811786006792830932395177026805674e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.546364324011365762789375386661337991434000702963811196005801731e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.228448949533845774618310075362255075191314754073111861819975658e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.912781600174900095022672513908490962899309128877584272045832513e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.145953154225327686809754524860534768156895534588187817885425867e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.085123669861365984774838320924008647858451270384142925874188908e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.630367231261397170650842427640465271470437848007390468680241668e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.732182596346604787991836614669276692020582495778773122326853797e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.604810530255586389021528105443008249789929772232910820974558737e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.866283281281868197964883431828004811500103664332499479032936741e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.194674953754173153419535571352963617418336620849047024493757781e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.894136566262225941799684575793203365634052117390221232065529506e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.728530091896234109430773225830735206267902257956559214561779937e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.558479853180206010560597094150305393424259777860361999786422123e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.183799294403182487629551851184805610521945574359855930862189385e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.411871423439005125979602342436157376541872925894678545707600871e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.146934230284030660663814250662713645615827253848318877256260252e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.448218665084135299794121636822853382005896647323977605040284573e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.512810104228409918190743070957013357446861162954554120244345275e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.586025460907685522041021408846741988415862331430490056017676558e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.540359114012197595748944623835295064565126012703153392373623351e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.845554430040583564794301575257907183920519062724643766057340299e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.408536849955106342184570268692357634552350288861587703063273018e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.030953654039823541442226125506893371879437951634029024402619056e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.454172918244607114802676127860508419821673596398248024962237789e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155627562127299657410444702080985966726894475302009989071093439e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.725246714864934496649491688787278190129598018071339049048385845e-13)) + }; + static const T denom[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 0.000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.502622159812088949850305428800254892961651752960000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.430336111272256671478593169569751383305061494947840000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.920361290698585974808779016476219830728024276336640000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.149178946896205138947217427059336370288899808821248000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.374105269656119699331051574067858017333550280343552000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.521316226597066883749849655326023294027593332332429312000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.808864152650289891915479515152146571014320216782405632000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.514810409642252571378917003183814999063638859346214912000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.583350992233550434239775839017811699814141926043903590400000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.478403249251559174520099458337662519939088809134875607040000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.848344883280695333961708798743230793633983609036568330240000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.943873277267014936040757307088314776495222166971439104000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.331069721888505257142927693659482094449571844495257600000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.196124539826947758881834650235619760202156354268084224000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.723744838816127002822609734027860811982593574672547840000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.205691767196054136766333529400075228162139411801728000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.517213632743192166819003098472340901249838381523200000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.571722144655713179046526371841394014407124514352640000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.359512744028577584409389641902976782871564427046400000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.949188285585060392916084953872833077002135851920000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.452967188675463645529736303316005271151737332000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.790015208782962556675223159728484084908850744000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.970673071264242753610155919125826961862567840000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.299166890445957751586491053313346243255473500000000000000000000e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.652735578141047520337049888545244673386975000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.508428802270485256066710729742536448661900000000000000000000000e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.093294777021479729147119238554967297499000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.155176275192359061296447275633302204250000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.907505708457079284974986712721395225000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.195848283940498442888394846136646210000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.305934675041764670409270520636101000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.238840089027488915014959267151000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.846167161648076059624793804150000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.707826341119682695847826052600000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 6.648183019818072129964867660000000000000000000000000000000000000e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059080011923383455919277000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.490144286132397218940500000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.838362455658776519186000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.970532718044669378600000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.814183952293757550000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.413370614847675000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 9.134958017031000000000000000000000000000000000000000000000000000e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.765795079100000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.928125650000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.675250000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.081000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[47] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.059629332377126683204423480567078764834299559082175332563440691e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.045539783916612448318159279915745234781500064405838259582295756e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.784116147862702971548198855631720823614071322755242269800139953e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.347627123899697763041970836639890836066182746484603984701614322e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.616287350264343765684251764154979472791739226517501453422663702e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.713882062539651653939339395399443747287004395732955159091898814e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.991169606573224259776909844091992693404451938778998047720606365e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.317302161605094814956529918647229867233820698992970037871348037e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.160243421312714521088457044577429625205805822189897013706603525e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.109943233027050100899811890306430189301581767622560123811853152e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.510589694767723034579229465791750718722450232983242500655372350e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.447631000703120050516586541372187152390222336990410786008441418e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.650513815713423478665128697883383003943391843803280033790640056e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.169833252147741984016531016457108860830636610643268300442548571e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.082891222574188256195988224106955541928146669677565424595939508e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.236107424816170540654753273736991964308279435358993150196240041e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.042295614972976540486053879488442847688158698802215145729595300e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -6.301008161384761854991230670333450694872613042265540662425668275e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.626174700692043436308812511757112824553679923076031241653340508e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.165638597797307942127436742547456896168876912136407736672893749e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.193760947891421842393017150194414897043594152709554867681454093e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.102566205604210639065160857917396944102487766555058309172771685e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.915816623470797626925445072607835810426224865943397673652473644e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.588275837841705058968991523347781566219989845111381889185487327e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.200550301285945062259329336559146630395284987411539369061121774e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.164333226683698411437894680594408940426530663957731548446585176e-23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.066415481671710192926882432742434212829003971627792457166443068e-28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.794259516500627365643093960688415401054083199354112116216326548e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.109766027021453750770079684473469373477285891593627979028234104e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 7.857040454431507009464118652247309465880198950544005451066913133e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.257636833252205356462338019252188768182918234805529456629813332e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.657386968948568677903872677704817552898314429680193647771915640e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.807368757318279512579151153998249666772948741065806312921477647e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.661046240741398691824399424582067048482718145278248186045239803e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.310274358393495831279259654715581878034928245769119610060724565e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.979289812994200254512860775692570111131240734486735844065571645e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -5.374132043246630393307108400571746261019561481928368054130159659e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.807680467889122570534300256450516518962725443297886143108832476e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.273791157694681089776609329544693948790210894828257493359951461e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.971177216154470328027539744763226999793762414262864963697237346e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.645869582759689501568146144102914403686604774258048281344406053e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.533836765077295478897031652308024155740827573708543095934776509e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.011071482407693628614243045457397049948479637840391111641112292e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.753334959707221495336088007359122169612976692723773645699626150e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.217604773736938924265403811396189809599754278055061061653740309e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.819104328189909539214493755590516594857915205552841395610714917e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.261124772729210946163851510369531392121538686694430629664292782e-42)) + }; + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[47] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.201442621036266842137537764128372139686555918574926377003612763e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.185467427150643969519910927764836582205108528009141221591420898e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.424388386017623557963301151646679462091516489317860889362683594e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.527983998220780910263892115033927387104053611029099941633323011e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.966432728352315714505545454293409301356907573727621630702827634e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.210921746972897898551337991192707389898034825880579655985363009e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.525319492963037163576188790739239848749059077112768508582824310e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.761266399512640929192286468240357629226481512485264527650043412e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.449355108314973517543246836489412427594992113516547680523282212e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.258490177973741431378782429416242097479994678322390199981700552e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.114255088752286384038861754183366335220682008583459292808501983e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.641371685961506906939690430062582517060728808639566257675679493e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.139072742579462987548668350779672609568514018384674745960251434e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.129392978890804438983060711164783076784089453197491087525720250e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.227817717944841986447189375517242505918979312023367060292099051e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.401539292067249253713639886818857395065226008969910929456090178e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.181789081601278618540976740818676551399023595924451938057596056e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -7.144290488450459735914078985115746320918090890348935029860425141e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.977643331768050273059868974450773270172308183228656321879824795e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.124636941696344229278652214634921673116603924841964381194849043e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.353525462444406600575359080915245707387262742058104197063680358e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.250125861423094782405286690199652039727315544398975014264972834e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.573714720964717327652547152474097356959063887913062262865877352e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -9.737669879005051560419153179757554889911318336987864449783329044e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 4.762722217636305077074994367900679148917691897585712642440813437e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -3.587825185218585020252537180920386716805319681061835516115435092e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.209136980512837161314713015292452549173388035330975386269996826e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.034390508507134900778125110328032318737425888723900242108805840e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -4.659788018772143666295222723749466460348336784193790467337277007e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 8.908571128342935499766722474863105091718059244706787068658556651e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.425950044120254934054607924023969978647876123112048584684333719e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.879199908120536747953526966437055347446296944118172532473563579e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.049254197314637745167349860869170443784687973315125511356920644e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.883348910945891785870183207161008885784794173754432580579430117e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.485632203001929498321635338807138918181560966989477820879657556e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.018101439657813295290872898460623215815148336073781084176896879e-33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -6.093367832078140478972419022586567008505333455627897676553352131e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 3.183440545955440848970303491445824299419388286256245840846211512e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.444266348988579122529259208173467560400718346248315966198898381e-34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.636484383471871096369253024129613184534143941833907586683970329e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.866141116496477515961611479835778926021343627571438400431425496e-35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 5.140613382384541819628458619521408963917801187880958447868987984e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -1.146386132171160390143187663792496413753249459594650450672610453e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 1.987988898740147227778865012441676866493607979490727350027458052e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -2.514393298082843730831623322496784440966181704206301582735570257e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, 2.062560373914843383483799612278119836498689222815662595453851079e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 201, -8.232902310328177520527925464546117674377821202617522000849431630e-41)), + }; + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + static double g() { return 2.880805098265409469604492187500000000000000000000000000000000000e+01; } +}; +// +// Lanczos Coefficients for N=49 G=3.531905273437499914734871708787977695465087890625000000000000000000000000e+01 +// Max experimental error (with MP precision arithmetic) 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 23 2021 +// Type precision was 234 bits or 72 max_digits10 +// +struct lanczos49MP : public std::integral_constant +{ + template + static T lanczos_sum(const T& z) + { + static const T num[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.019754080776483553135944314398390557182640085494778723336498544843678485e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.676059842235360762770131859925648183945167646928679564649946220888559950e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.735650057396761011129552305882284776566019938011364428733911563803428382e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.344111322348095681337661934126816558843997557802467558098296633193647235e+74)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.279680216265226689865713732197298481387164441051031689408254603978998739e+74)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.534520884978570988754896701605114795240254179745381857143817149573644190e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.094111428842887690996413081740290562974159836498138544655694952917058279e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.810579629726532069935485995735078752851873354363515145898406449827612179e+72)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.558918434547693216059693184449337082460551934950816980580247364223027781e+71)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.135873934032978624782044873078145389831812962597897650459872577452106819e+70)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.371686637133152315568960647279607142944608875215381633194517073295482279e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.210709791290211789451664416279176396010610028867877916229859938579263979e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.728493971517374186383948573740973812742868532549695728659376828743835354e+67)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.082196640005602972025690170863702787506422900608580581233509996818990072e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.434296904963427729210616126543061543796855074189151534322145897294331943e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.956561957668034323532429269801091280845027370525277092791205986418388937e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.088465031117387833989029481250197681372395074774197408003458965955199114e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.638006253255673292005995366039132327048285444095672469721651872147026836e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.251091350064240218784436940525650498454117574503185703454335896105827459e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.438965470269742797671507642697325276853822736866823134892262314489634493e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.171096428020164782492194583597894107448038723781192404665010946856416728e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.967964763783296071512049792468354332039332869323402055488486515880211228e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.691239511306362286583973595898917873397629545053239582674237238671075149e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.371351678345135454487045322888974392983710298168736348320865063481886470e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.399139456864000364822305296187724318277750756512114883045860699513780982e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.335644907596902422235465624341780552277299385700659659374735347476790554e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.541494306852766687136536628805359613169443442681232300932385167150904206e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.454056970723993494338669836718832149990196703371093557999871225274488103e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.122804036582476347394286398036300142213667443126058369432667730381406969e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.350437044906396962588019269622122085882249454809361766675217669398941902e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.350870345849974415762276588597695308720927596639430565914494820338490132e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.751385019528115548010259296564491721747559138159547937603014471132985302e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.476113159838159765344429146854859477076267913220368138623944281045558949e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.294398437121931983845715884547145127710330599817550100565429763115048575e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.839781945206891229035081139535266037057033378415390353746447012903101485e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.711123560991297649877080280435694393772679378388200862936651880878974513e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.629549637595714724789129505098155944312207076674498749184233965222505036e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.574490956477982663124058935512682291631619753616365947349506147258465402e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.813448512582564107136706674347542806763477703915847701777955330517207527e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.794883897023788035285405896000621807947409236640451176090748912226153397e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.960479107645842137800504870276268649357196518321705636965540139043447991e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.584873693858658935208259218348427715203386574579073396812006362138544628e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.245936834930690813978996898166861135901321349975150652784783993349872251e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.773017141345068472510554017030953209437181800565207451480397068178339458e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.641092177320087625773994531564401851985558319657745034892144486195046163e+11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.105900602857710093040451403979744395599050533242553243284994146810134883e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.764831079995208797424885873124263386851285031310243195313947355076198006e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.390800780998954208500039666019609185743083611214630479125238184115750385e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.506628274631000502415765284811045253006986740609938316629923576327386304e+00)) + }; + static const T denom[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.586232415111681806429643551536119799691976323891200000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.147760594457772724544789095126583405046340554378444800000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.336873167741057974874912069439520834275222024827699200000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.939317717948202275053279980882650292343063152909352960000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.587321266207338310075066414082486631849657629849681920000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.708759679197182632355739853743909528366304368999677296640000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.853793140116069180377738686747691213170064352110549401600000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.712847307796887697739638943011607706661342285570961571840000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.289323070446191229806483814370209648903283093834096836608000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.773184626371587855448424329320482554352785932897781894348800000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.435061276344423987072041299926950982073631843385358712832000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.038454928643566553335326814205831024316152779380233211904000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.839990097014298964461251746728788062040820983609914982400000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.354892309375504992458915625473361082395092049509521612800000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.297725282262744672148100400166565576520346155229059072000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.209049614463758144562437732220821438434464881014066944000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.403659584108905732081564809222007746403637980496076800000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.460430771262504410833767704612689276896332359898060800000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.366143204159002782577065768878538489390347732147072000000000000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.152069768627836143111498892510529224478160293107040000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.778134072359739526905845579458057851415301312320000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.054274336803456047167091188388392791058897181680000000000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.785217864372490349864295597961987080566291959200000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.147675745636024418606666386969855430516329329000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.106702410770888109717062552947599620817425600000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.181697115208175590688403931524236804258068000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.204691425427143998305817115095088274690720000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.522623270425567317240421434031487657474000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.991703958167186325234691030612357960000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.527992642977421966550442489563632412000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.749637581210127837980751990835613680000000000000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.178189516884684460466301376197071000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.691582574877344639525149014665600000000000000000000000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.588845541974326926673272048872000000000000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.832472360434176596931313852800000000000000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.162585907585797437278546956000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.759447826405610148821312000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.354174640292022182957920000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.764512833139771127128000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.823199175622735427100000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.478468141272164800000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.842713641648132000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.137488170420800000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.672014134600000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.194862400000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.183320000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.128000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.256115936295239128792053510340342045264892843178101822334871337037830072e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.226382973449509462464247401218271019985727521806127065773488938845990367e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.954125855720840120393676022050001333138789037332565663424594891457273557e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.365654586155298475098646391183374531128854691159534781627889669107191405e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.044730374864121201936514442517987939299764008179567577221682561782183421e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.536356651078758500509516730725625323443004425012359430385110182685573948e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.014086778674585662580239648780048641118590040590185584314710995851825637e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.297512615100351568281310997196097430272736169985311846063847409602541101e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.172699484909110833455814713100736399837181820940085502574724938707290372e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.437106278000765568297205273500695563702563420274384149002742312586130286e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.545174371038470657228461270859888251519093095798232203286784662979129719e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.471402006255895070535216946049289412987253853074246902793428565040300946e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.250412452299054568666234182931337401773386777590706330586351790579683785e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.542277292811232416618979097150690892713986488440887554977845301225180167e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.573086578098175124839634461979173468237189761083032074786971884241523043e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.104607420271440962257749252277010146224322860594339170999893725175800398e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.331938462909285706991247107187321645123045527742414883815000495606636547e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.208943799307442534797422457740696336724404643783689597868534121046756796e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.733493346199244389057953770564978235470425412393741328222813802783023596e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.492565577437473684677047557246888601845840521959370888739670894941330993e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.949686666262532681847746981577965659951530620900061798663932175932503947e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.651553737747111429808666993553840522239787479567412806226997545642698201e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.233339502372167653077823100186702309252932859938068579827741608727620372e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.836417632015534931979173072268670137192644539820843175043472436022533106e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.099476078371695988128239701316213720767789442435824569996795481661867708e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.903495249944998411669955533495843613032560579446280190215596256375769138e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.064350138053898858268455142115215057417819864153422362951139202939062254e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.582922994233975143266417356893351025577967930478759984258796518122317112e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.264234026390622585348908134631186844315412961960282698027228844566912117e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.188774153889105680535092985608022230760508397240005354866271201170463092e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.077355341399798609786211120408446935756994848842131485074396331912972263e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.719182300108746375704686202821491852452619639378413670885143111968297622e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.509589596583338412898049035294868361167322854043341291672085090640104583e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.342872197271389972201661238004898097226547537612646678471852083509061055e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.051089551701679946626603411942133093477647785693757342688765248578133558e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.450407423742747934005020832364099630124534867513398798024857849571995697e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.413023778896356322547226273989314105826233010702360664846872922408122652e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.929512168994516762673517469057078217752079550440541815733308359698355209e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.122462776963280343259527700358220850883119067227711325233658329309622143e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.197396290684303702682694949348422316362810937601334045965871833844532390e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.356726450420886407112529306259506900505875228060535982041959265851381932e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.263148912218322814862431970673685825699419657740452507847522864799628960e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.320663245567314255422944457710191091603773917350053498982455870821336578e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.270816501767199044429825237923512258332267743288560304635568302760089360e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.960034133400021433681975737071902053498506976351095156717280432287769760e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.650907660437171004901238983264357806498757360812524606971708594836581635e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.725344352001816640635025885398718044955247687225228912342703408863775468e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.012213341659767638341287600182102653785253052492980766472349845276996656e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.148735984247176123115370642724455566337349193609892794757225210307646070e-15)) + }; + static const T denom[49] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 0.000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.586232415111681806429643551536119799691976323891200000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.147760594457772724544789095126583405046340554378444800000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.336873167741057974874912069439520834275222024827699200000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.939317717948202275053279980882650292343063152909352960000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.587321266207338310075066414082486631849657629849681920000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.708759679197182632355739853743909528366304368999677296640000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.853793140116069180377738686747691213170064352110549401600000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.712847307796887697739638943011607706661342285570961571840000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.289323070446191229806483814370209648903283093834096836608000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.773184626371587855448424329320482554352785932897781894348800000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.435061276344423987072041299926950982073631843385358712832000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.038454928643566553335326814205831024316152779380233211904000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.839990097014298964461251746728788062040820983609914982400000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.354892309375504992458915625473361082395092049509521612800000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.297725282262744672148100400166565576520346155229059072000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.209049614463758144562437732220821438434464881014066944000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.403659584108905732081564809222007746403637980496076800000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.460430771262504410833767704612689276896332359898060800000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.366143204159002782577065768878538489390347732147072000000000000000000000e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.152069768627836143111498892510529224478160293107040000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.778134072359739526905845579458057851415301312320000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.054274336803456047167091188388392791058897181680000000000000000000000000e+47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.785217864372490349864295597961987080566291959200000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.147675745636024418606666386969855430516329329000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.106702410770888109717062552947599620817425600000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.181697115208175590688403931524236804258068000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.204691425427143998305817115095088274690720000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.522623270425567317240421434031487657474000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.991703958167186325234691030612357960000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.527992642977421966550442489563632412000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.749637581210127837980751990835613680000000000000000000000000000000000000e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.178189516884684460466301376197071000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.691582574877344639525149014665600000000000000000000000000000000000000000e+32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.588845541974326926673272048872000000000000000000000000000000000000000000e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.832472360434176596931313852800000000000000000000000000000000000000000000e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.162585907585797437278546956000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.759447826405610148821312000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.354174640292022182957920000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.764512833139771127128000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.823199175622735427100000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.478468141272164800000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.842713641648132000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.137488170420800000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.672014134600000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.194862400000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.183320000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.128000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.233965513689195496302526816415068018137532804347903252026160914018410959e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.432567696701419045483804034990696504881298696037704685583731202573594084e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.800990151010204780591569831451389602736047219596430673280355834870101274e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.648373417629954217779547889047207255669324591553480603234009701221311635e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.284437059737535030909183878223579768026497336818714964176813046702885009e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.107670081863262975759677889098250504331506870772724719160419469778560968e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.504360049237893454280746661699303420195288960483588101185311510511921407e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.611963690317610801367925234041815344408602188860817148261094946859641055e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.384196825969374886217890731633708081987015968697189525652444057097652970e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -9.622790278065968351142661698209916105231451436587332112667311309898112907e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.449580263451402816852387882691399098166718792531955596134468390704873784e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.521891259305373384442177581056279631601936059906718384076120380236152660e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.540905879286304237452585078525021002948388724011947750659051968465604420e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.945234350579576646146368625320015500721771847656877764914364796999018932e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.387416831492605275144126841246803690906548552137287238128485938487779304e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.495798927786732788454640929952042349030889163403974404914516146280530443e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.422943482445615791699986810123527175351383953692494761445061153868299970e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.102903565532198274392276413606953369815588940855811878456066484772851432e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.094535028891646496546262084074169534843273855151767819779938179094208188e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.358095366769232988323350838247191988585424776577310286935330610243011743e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.340530976890392038064297300042596231921772020705486053763028541479656280e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.516126555541810552632615941497264105370152230590961486150754875983890898e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.581070770182358530034488215134552244420314579258249233845063889274308385e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.004041803560396287949218893554883846494476801309699018606217164405518118e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.544940513373792201443764129828570298376651506143103507977578771056330357e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.379886756316120706725450388823927894039691498002769785120646242635823255e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.045944766231461555774689284231476775257484866624431880423176393512207387e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.148008349481903710728852060629194581596537318553456161574664356163226596e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.275939213508899016428747078031525836021120921513924955762486505940940452e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.002074313199153828387282409848698339315167131865367803807278126600553143e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.312111841788085794021549817149806212210409562054999023338937587332395908e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.626943187621427535665396572257733498961554813667830477603994486170242725e-38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.301342661659868689654008011518619781951990528882947953585638647826710208e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.943206436729179344584590804980950978078020765463364229230497237642990035e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.427985516258891942239250982488681113868086410604389604401061682071089711e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.507315406936486999900039292673781706696418133992677762607195734544800586e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.128602212783277628616662270027724563712726585388232543952969868791288808e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.491772665541813784561971549986243397968726526748411110109050933398474269e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.703534948980953284999107504304646577995487754638088095508324603995172100e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.254734374358011114570777363031532176229997594050978074992481078060588238e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.744400882431682663010546719169103111178937911186079762496396144974231758e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.962681142344559707919656870822506290159603512929253279249408502104315114e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.676028721091677637759913537058723470799950761402802553076562435074866681e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.784145301171889911387402141919770031244273301985414474074193734901497838e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.609382025715763421062067113377305459236198785081684246167946524325632358e-44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -8.390549764136377795654766730143252213193890014751189315315457960953487009e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.892571860428412953244204670046307154753124542150699703190076405369134986e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.750996769906711001487027901108989269217518777400665423098451353536180397e-47)) + }; + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[48] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.614127734928823683399031924928203896697519780457812139739363243361356121e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.873915620620241270111954934939697069495813017577862172724257417200307532e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.020433263568799913803105156119729477192007677199414299858195073560627451e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.464288862550385816890047588667703388387049707546055857832236105882063068e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.220557255453323997837181773609238378313171107809994660932186398177260086e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.448922988893760252035044756495535237100474172953062930583429032976738764e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.967825884804576295373543809345485166700533400342174877153161242305801190e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.108580240999530194943835615053920860235079936071561387017856553284307741e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.810642568703399030220299393722324927217417866857948859237865608524037352e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.258739608434628125323282855631713548863857229929349389847042534864564944e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 7.128496339139347963949841917163532287235353252857530075762245657435637432e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.298839862995292241245807816785011319551976707839297599695370993581498944e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.248028459892634227909925496833936295152351078572924268478121601580013392e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.852607223132643180520259993802350485519940462836224552121831884016060957e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.663344935420648740647632834149137036410170363282848810726789852512040974e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.956627238308290890004850312580119602770863155061517303602115059073018915e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.169408084580850119987259593698335014334975914638255180200227109093248923e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.058851441448441752395908342271882717629330686791993331066549580482119207e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.047904711622988136321913253467026391205138759157051345098701122533901641e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.084581449711468658856874852797634685668605539676219540421511092086784257e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.753524069615947925605286028020036313127948537531901833841745089038345419e-03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.215544327537876774584851905154058374732203881621234998864896154317725107e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.068169776809028066872463505146223239383722607505095101927453621607143258e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.929532177536816530254915957100118239727512976366989010196601003141928983e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 4.637071893688824301043677755554700799944720607401583032240419889530137613e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.113086368090515818656083953394041201305628629939937324183681568207995992e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.052475329075586591944149534403412432330839345810529801140374324740860043e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.501688739492061913271178171928421774535209059448213231063121542726735922e-17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 6.901359655394917555561825304708227606591126162154019191593957327845941711e-21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -6.543121984804052902464306048576584437634232699686221158393201347605610557e-25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 5.640594686585611716813857202286477090235259523435190405734068397561049518e-30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.360501538535076761830231649645320930651740695652757112015168140991871811e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.702262550718545671102818966852852449667460777654069395734978498316238097e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -2.541872823365472358451692936741339351955915607098512711275660224596475692e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 3.176003476857354088823169817786505980377842772003301806663816129924483628e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.279773456918425628141724849602711155924011970103858226014129388572719403e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.784385649492108496180681575852127700091310578360977342260193352159187181e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.951360558254817806983487356566692526413661637802019026539779594905551108e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 1.138493498985334706374097781200574458692873800531006014767134080212447095e-39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -5.565540270144127561133019747139820473778629043608866511009741796439135919e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.281818911412862056602174736820614290615384940807745468773991962352596562e-40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -7.799674220733213250330301520376602557698625350979839820580611411813901622e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 2.192382536820850868749995412323169490150589703968805623276375892630104761e-41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -4.949971304595638285364920838869349221534754917093372730956379282259345856e-42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 8.645611826340683772044616248727903964535937439036743879074020086333544390e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -1.097552479007470044347986004697357054639788223386746160457893283010512693e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, 9.016047273189589762707582112298788030798897468010511171850691914431226857e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 234, -3.598528593988298984798384438686079221879557020145063999565131046963034260e-46)), + }; + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + static double g() { return 3.531905273437499914734871708787977695465087890625000000000000000000000000e+01; } +}; + +inline double lanczos_g_near_1_and_2(const lanczos49MP&) +{ + return 33.54638671875000; +} + +// +// Lanczos Coefficients for N=52 G=4.9921416015624998863131622783839702606201171875000000000000000000000000000000000000e+01 +// Max experimental error (with MP precision arithmetic) 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00 +// Generated with compiler: Microsoft Visual C++ version 14.2 on Win32 at May 22 2021 +// Type precision was 267 bits or 82 max_digits10 +// +struct lanczos52MP : public std::integral_constant +{ + template + static T lanczos_sum(const T& z) + { + static const T num[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2155666558597192337239536765115831322604714024167432764126799013946738944179064162e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.4127424062560995063147129656553600039438028633959646865531341376543275935920940510e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2432219642804430367752303997394644425738553439619047355470691880100895245432999409e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0716287209474721369403884015994122665163651602768597920624758793936677215462844844e+86)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6014675657079399574912415792629561012344641595734333223485162579517263855066064448e+85)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.9469676695440316675866392095745726625355531618465991865275205877617243118858829897e+84)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.6725271559955312030697432949232367888201769834554225137624859446813736913045818789e+83)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.9780497929717466762906957902715326245615108291247102827737801883575021795143342955e+82)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1101996681004003890634693624249367763382356608502270377869975360325542360496573703e+82)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0730494939748425861290791265310097852481749101609248058586423168275758843014930972e+81)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.1172053614337336389459663390209768009612090987295451850767107564157925998672033369e+79)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.8745706482859815560001340912167784132864948819270481387088631069414787418480398968e+78)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.6357176185157048005266104227745750047123126912102898052446617690907900639513363491e+77)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8133959284164525780065088214012765730887094925955713435258703832914376223639644932e+76)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5448240429477602353083070839059087571962149587434416045281607922549720081768160509e+75)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.7087163798498299832185901789792446192843546181020939291287863440328666852365937976e+73)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5087881343681529988104227139117041222747015656224230641710513581568311157611360164e+72)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4613990031561986058105893353533330535471171288800176856715938119122276074192401252e+71)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.5842870550209699690118875938391296069620575640884684638841925128818533345720622707e+69)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9620974233284411294099207169175001352700074635064713292874723705223947089062735699e+68)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3508670578887212089913735806070046196943428333276779526487779234259460474649929457e+66)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8965656059697746722951241391165378222796048954133067890004635351203115571283351365e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.2318932193708961851167812069245962898666936025147808964284039760031905048392189838e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3345087899695578368548637479429057252399026780996532026306572668368481753083446035e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1496377806602727082710361157715063723084394483433707624016834119253720339362659524e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.8813988021021593903128761372635593523664342047294885462297735355749747492567917846e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3920956168650489448209669451137968296707297452484593173253158710325555644182737609e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6075799130233642952967048487438119546115615639287311948474085370143960495152991553e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5215062065032735365892761801093050964342794846560150713881139044884954246649618411e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.2544625196666558309461059934941389307783421507071758131936839820683873609174384275e+51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0762146929190267795931737389984769617036500590695127135611707890269647516827819385e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4748530311527356370488285932357594780386892716488623785717991900210848418789146683e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8647515097879595082625933421641550420004206477055484917914396725134286781971556627e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1719649433541326415406560692060639805792580579388667358862336598215919709516402950e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3261545166351967601378626266818200343311913249759151579277193749871910741821474852e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2856597199911108057679518458817252978491416960383076400280909448497251424577297828e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0550442252418806202988575468283015522717243147245311227478147425985867569431393246e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6853992677311201643273807677942992750803865734634293875367989072577697582186788546e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2561436609157539906689091056055983931948431067099841829117491622768568140084478954e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.4705206401662673954957473131998048608819946981033942322942114785407455940229233196e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.1407133281903210341367420024686210845937006762879607281383052013961468193494392782e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.7901285852211406723998154843259068960125192963338996339928284868353890653815257694e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3438998631585891046402379167404007265944767353624748363650936091693896699924614422e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.6902706401090767936392657986442523138728548699749092883267263725876049498265301615e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0929659841192947874271802260842934838560431084502779238527946412041140734245143884e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5862712170406726646812829026907981494912831615106789457689818325123973212320279526e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7379005522986464990683100411983090503131358664627225315444053238030719367736285441e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.7401492854176051649551304067922101744785432102294852270917872876250420006402939364e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3052097444388598287826452442622724171650622602495079541553039504582845036611195233e+09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.8093796662195533917872631136981728293723308532958487302137409818490410036072819019e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.3192906485096381210566149918556620595525679738152760526187454875638091923687554946e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5066282746310005024157652848110452530069867406099383166299235763422936546004304390e+00)) + }; + static const T denom[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0414093201713378043612608166064768844377641568960512000000000000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3683925049359750564345782687270252191318781054337155072000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8312047394413543873001574618939688475496532684433218600960000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6266290361540649084000356943724186480051615706407501824000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2578261522689833134479268958172001145701798207577980403712000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2001844261052005486660334218376501837226733355004196185702400000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1681037008119350981332433342566749327534832358109654944841728000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0293361153311185534392570196926631029364162024577328008396800000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7968291458361430782020246122299560311802074147902210076049408000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4212998306869600977887871207212578754682594793002122395254784000000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4006322967557247180769968530346138316658911433773347563153653760000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1334912462852682149761710693821775975226278702191992823808000000000000000000000000e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1263921790865468343839418571823409266633338824655665334886400000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0548002159482240692664043366538929906734975613031337827840000000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6095781466700764043324234378972985924892034584990590768742400000000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1887214284827766716471402753528692603931747042835394432000000000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6644926572075096083148238618984385847884240529010940198400000000000000000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9154102380883742873084802432628398856163736124576909120000000000000000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8768151045628896730547232493410634338494669305466040192000000000000000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5674503027583263140245049650089911892130421780961760000000000000000000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0774565729992714117801952876016228015049549176491224000000000000000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5271995659293168127377699172748774995796493494870600000000000000000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0217297271367563021376459886512004721472442416486880000000000000000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2295402510227377004563262212164474005108576587500000000000000000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4652078765044198452095090589463630638929867781650000000000000000000000000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7599751702378955591170076678443001141850220448750000000000000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.1661954970720573655661780303655361431161958585000000000000000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4624589782073664468902246801624082962588775000000000000000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3415303241063823936930939721131813816093940000000000000000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7484118887814252101652801793318408875609500000000000000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5345701242523770267594030980609724717749800000000000000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5242293875075726230709587746676742825000000000000000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2153799706792737162996155167868591485000000000000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9704836232659058554494106146940431250000000000000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5926306456751344865378122278650335000000000000000000000000000000000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3255133142885196993084362383550000000000000000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4074634262098477202456261501600000000000000000000000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9362537824702021303895557050000000000000000000000000000000000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7695574975175958167624223800000000000000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5430949131153796097540000000000000000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.7427444047045863749135000000000000000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.9163115009072256171250000000000000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9274383168492884295000000000000000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.0731790610548750000000000000000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9491312919646000000000000000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1366198225750000000000000000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.3570498490000000000000000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1862250000000000000000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9135000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2750000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + template + static T lanczos_sum_expG_scaled(const T& z) + { + static const T num[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2968364952374867351881152115042817894191583875220489481700563388077315440993668645e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3379758994539627857606593702434364057385206718035611620158459666404856221820703129e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.7667661507089657936560642518188013126674666141084536651063996312630940638352438169e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2358817974531517479015567958773172164495426366469934483861648449503257164430597676e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4277884337482721045863559292777143585727342521289738221346249419373476553706960477e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0321517843552558179026592998573667333331808062275687745076218349815677074985963362e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6008215787076020416349896191435806440785263359504290408274535992043818825469757467e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0818534880683055883178218002277669005830432150690130666222387190067193078388546735e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3163575041638782544481444410280012073460223217514438140658322833554580013590099428e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2388461455413602821779255933063678852868399289922539164611151211712717693487661387e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9022440433706121764851738708000810548525373575286185895490944900856672029848122464e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4343332795539887118781806263726922877784774015269102474184340994778721415926159254e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.6721153873219058826376914786734034750310419590675042405183247501763477751707551977e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.8699628167986487178009534272364155924157279822557444996249799757685987843467799627e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2231722520846745745100754786781488061001048923809737738337722261187091800649653747e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6083722187098822924476598339806607838145759265459316214837904824198871273160389130e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.3208522386531907691637761481331075921814846045082743370064300808114976199945037122e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0491114749931089548713463433723654679587396917777106103842119656518486449033314603e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1651242201716492163343440840407055970036142959703118121095709130441296636187948680e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.0937853081905503955154539906393844955264076759979726863680373891843152853217317289e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3250660210211249438634406634827812076838178133500698949898645633350310552370070845e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9570575453729198045577937136948643736522682229986841993417806493265120889607818521e+43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0915995985127530070498760979124015775616748288243587047367665303776535820627821806e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.7843635148151485646319955417265990806303645948936943738048724343049029864512194310e+40)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5715089981189796608580098957107087883056675964697423692398096552244865201126563742e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4357579282713452366310121777478478833619311278663562587227576970753556113485917320e+37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9045145853415845950075255530781663873014618840017618405203106705648527948595759022e+35)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4405414384364870662900944749199576151689786973539596080446881216688775114111401244e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.4338208995125086931437020109275839003754703899452696411395381222142064582727164193e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5135951828248789401437398422210292739440102976394266807495518051141687446206426902e+30)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2454501218684993019799803589484969919745689383924985827556442495293105857928357346e+28)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0771824063818140076215034706980442595962662610399835096143334152833816531221628660e+26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.8906795572088352821870480514365587413988764084322141604846302060067104077934035979e+24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5316598805398286987903918997966274192433403859480290402541541527289805994033568970e+22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8533661333839969582529636915290426021792269810841946250308753325085094758818317464e+20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7688764431225908123092120518561018783609436337842987641148647520393460757258932651e+18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.2877126063932361367573287637428749753108811218139980724742491890986894871059180965e+16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5164730755154849065370365582371664006783859248354506763822538105452920154803662025e+14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6208599037402680475080806960664748732421517587082652352333314249266933718172853538e+12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7673175927530323929887314159232706831613273850912577130092484125942772196619237882e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0725755228231653548395606930605822556041123469753556193146323302002970112193491322e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.8214170582643892131251904381692606071847290625764371754232909841174413907293095377e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8039573621910762166001861467061356387294777080327106241940313632291985560896860294e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1872369877837204032074079418146123055615124618000942960799358353269625124323889098e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.3668338250989578832466315465536077672534713261875481920848252453271529995224516632e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3741815275584317532245789502116967720634823787379160467839166784058598703361284195e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6260135014231198723283200126807995474827979567257597700738272144468899515236872878e-07)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.8035718374820798318368374097127140964803349360705519156103446564446533105562174708e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3155399273220963343988533731471377905809634204429087235409329216539588313353641052e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6293749415061585604836546051163481302110136557722031417335367202114639560092787049e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3184778139696006596104645792244972612333458493576785210966728195969324996631733257e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.2299125832253333486600023635817464870204660970908989075481425992405717273229096642e-22)) + }; + static const T denom[52] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0414093201713378043612608166064768844377641568960512000000000000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3683925049359750564345782687270252191318781054337155072000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8312047394413543873001574618939688475496532684433218600960000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6266290361540649084000356943724186480051615706407501824000000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2578261522689833134479268958172001145701798207577980403712000000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.2001844261052005486660334218376501837226733355004196185702400000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1681037008119350981332433342566749327534832358109654944841728000000000000000000000e+65)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0293361153311185534392570196926631029364162024577328008396800000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7968291458361430782020246122299560311802074147902210076049408000000000000000000000e+64)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4212998306869600977887871207212578754682594793002122395254784000000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4006322967557247180769968530346138316658911433773347563153653760000000000000000000e+63)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1334912462852682149761710693821775975226278702191992823808000000000000000000000000e+62)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1263921790865468343839418571823409266633338824655665334886400000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0548002159482240692664043366538929906734975613031337827840000000000000000000000000e+61)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6095781466700764043324234378972985924892034584990590768742400000000000000000000000e+60)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1887214284827766716471402753528692603931747042835394432000000000000000000000000000e+59)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6644926572075096083148238618984385847884240529010940198400000000000000000000000000e+58)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9154102380883742873084802432628398856163736124576909120000000000000000000000000000e+57)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.8768151045628896730547232493410634338494669305466040192000000000000000000000000000e+56)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5674503027583263140245049650089911892130421780961760000000000000000000000000000000e+55)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0774565729992714117801952876016228015049549176491224000000000000000000000000000000e+54)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5271995659293168127377699172748774995796493494870600000000000000000000000000000000e+53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0217297271367563021376459886512004721472442416486880000000000000000000000000000000e+52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.2295402510227377004563262212164474005108576587500000000000000000000000000000000000e+50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4652078765044198452095090589463630638929867781650000000000000000000000000000000000e+49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.7599751702378955591170076678443001141850220448750000000000000000000000000000000000e+48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.1661954970720573655661780303655361431161958585000000000000000000000000000000000000e+46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.4624589782073664468902246801624082962588775000000000000000000000000000000000000000e+45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3415303241063823936930939721131813816093940000000000000000000000000000000000000000e+44)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.7484118887814252101652801793318408875609500000000000000000000000000000000000000000e+42)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.5345701242523770267594030980609724717749800000000000000000000000000000000000000000e+41)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.5242293875075726230709587746676742825000000000000000000000000000000000000000000000e+39)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2153799706792737162996155167868591485000000000000000000000000000000000000000000000e+38)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9704836232659058554494106146940431250000000000000000000000000000000000000000000000e+36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5926306456751344865378122278650335000000000000000000000000000000000000000000000000e+34)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3255133142885196993084362383550000000000000000000000000000000000000000000000000000e+33)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4074634262098477202456261501600000000000000000000000000000000000000000000000000000e+31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9362537824702021303895557050000000000000000000000000000000000000000000000000000000e+29)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7695574975175958167624223800000000000000000000000000000000000000000000000000000000e+27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5430949131153796097540000000000000000000000000000000000000000000000000000000000000e+25)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.7427444047045863749135000000000000000000000000000000000000000000000000000000000000e+23)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.9163115009072256171250000000000000000000000000000000000000000000000000000000000000e+21)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9274383168492884295000000000000000000000000000000000000000000000000000000000000000e+19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.0731790610548750000000000000000000000000000000000000000000000000000000000000000000e+17)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9491312919646000000000000000000000000000000000000000000000000000000000000000000000e+15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1366198225750000000000000000000000000000000000000000000000000000000000000000000000e+13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.3570498490000000000000000000000000000000000000000000000000000000000000000000000000e+10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1862250000000000000000000000000000000000000000000000000000000000000000000000000000e+08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9135000000000000000000000000000000000000000000000000000000000000000000000000000000e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2750000000000000000000000000000000000000000000000000000000000000000000000000000000e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000e+00)) + }; + return boost::math::tools::evaluate_rational(num, denom, z); + } + + + template + static T lanczos_sum_near_1(const T& dz) + { + static const T d[56] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4249481633301349696310814410227012806541100102720500928500445853537331413655453290e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9263209672927829270913652941762375058727326960303110137656951784697992824730035351e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2326134462101140657073655882621393643823409472993225649429843685598155061860815843e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.9662801801612054404095225935108977904002486830482176026791636595192650184999106786e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4138906470545941456294493142170199869989528110729651897652377168498087934667952997e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0258375230969759913527502498295624381557778356817817750999982139142785355759733840e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.0558030423043855628646211274492485894483342086566824594162146024985516781169314244e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.7626679132766782666656123523498939281680490327213627146988312255304416262392894908e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.3671346711777066286093979449135095463576878628561846047759456811238250487006378990e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.6153175690992245402186127652781399642963298842199508872954793356226534605339323333e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.9373755602608411416894250529851681229919578866115774473369305562033628341735461195e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0800169087178819510009898255169517991710412699732186488007608833012065028092686003e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.6113163429881357240014185384821233436360839107514932109343845514870210427965645190e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -7.0800055208994526950912019754052939899262033086446277779400918426435279835354194130e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.6124888869258097801249338962341633267998552553797818622228028001697157538310910762e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.0821345203062947277822243784585588745042841720677807798397954250617939305106506107e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0897234684613304316686535121178451999373954297009955842614973223259353042645941321e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.4950083481830885847356672064097545823284701899839135264776743195466249025042048810e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.9937323326320843218449977911798288651196634496462091472078054583251005505547883394e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.1659790383945267871585567047493689107693027444469426401770619301894048344984407423e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.3811750187329199929662456874823737031712476205965338135458988288637511665389967467e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.3126057597099554726738230571307233576246752870932752732642137542414937991213738675e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.8603278118738070120786476302797971799214428999935477462676132231556636610008100990e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -5.7497497499750147559650543128496209797619661773802614023013669364107360500260024694e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.5455669051693660429433444114100199274899990967149528799831986363426701813268631682e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.3264707731119706730021053355613906861401420453549875829176477978488700910763350933e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.9452716333766656109625805591981088427443890665155986807469770654997947109460588842e-09)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.1107270143427404085533822649150071785436589803547989849458232547054059840123879700e-11)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2247407103283988605835624937345007318815870047594787786390767998944461846883100894e-13)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.0188429331847134597398824340892444962476368435762668313929678602451262836436731615e-15)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.9431143198672109701045920614322844783143358661530851155605617982604226639477903946e-18)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.1511473493622067561750500375000264321547190996454590396416983138367840485620637483e-20)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.6282967029324804059233959451615215356643254329321661581764544172041721688288262211e-24)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.5217584051959451141711566663295724419583710296958056943098481375601920843969902641e-27)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7686779496951341450129898316334506462294006086177935245787611395642697303462481134e-32)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.8183279898437068462121010262051285364082674967144808177521395570040237794774928143e-37)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.2301356317533360807190133199588525842189842444453020346114472115201441728418314131e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0538087755476779873724252308339637373681982420524344896439951953765025296864700289e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.7368861518094102628071448870890238982875711317443189777819779346097156832497387210e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.2127031296187719256650789211253726767816659542004125362087789737915250037588745613e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.2845218026163010098046208410081722573197086178079121337275774350592686815176989662e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9013371187879239559027439498823204927228357549709009148789220121477613502450061401e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.2089862298013055403993867290116144511841012233395353799752061257869549127164945780e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4527554216741432380141011585082087141319941270266854468232919279949735902352803053e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.2837166837027744593760237442711271028335526295415770894642075176684832265233618094e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.1059350216220761035803511769514044782618497241929104348673618588819476720900045601e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7687314351211090978609979306272584841117647148823431923713385159635722296908466519e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.5969462796000208210556070606779102539560199436191964981433237450523523642860510077e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.1139078862715122066066654151520960142401928001906787354175105139384536625985592872e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.7479750622279993094858160487261517850737208803407757126835554161719741165140561935e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.3023257271883644155548861805986381464362072120660374852325331311980696768011868477e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.3944877765920457854470382189260552086188360983214813092431218719428924850775816044e-50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.4340311277195491754628728769381617236158442845382974748650525927232846582643581377e-51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.6046447704173152191387256911138439680611975514728905319266554977285611063458373730e-52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.4634008445755689570224291035627638546740260971523702032261365019321949141711275488e-53)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.2246731300220072906782081133065950352668949898418513030190006777980796985877588993e-55)) + }; + T result = 0; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (k * dz + k * k); + } + return result; + } + + template + static T lanczos_sum_near_2(const T& dz) + { + static const T d[56] = { + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1359871474796665853092357455924330354587340093067807143261699873815704783987359772e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.8875414095359657817766255009397774415784763914903057809977502598124862632510767554e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.8476787764422274017528261804071971508619123082396685980448133660376964287516316704e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -7.4444186171772165373465718949072340109367841198406244729719893501352272283072463708e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1194120093410237139270201027497804988299179344758829377397770385486861046469631203e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.5357088952571626888790834841289410266972526362527135768453266364708511931775492144e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.5786127498932741985489606333645851990301122033327283854824446437684628190530769575e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.0137191034145345260388746496030657014468720426439135322862142167063250610782207818e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1043282398857092560432546685968118908647431787644471096079379813564778477126420342e+06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -9.9163139177426012658354764048015319057833754923450432555380434933570665536720208880e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 7.4010907978229491816684804764341724977655263945662331641124141340242633003517508734e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.6169234084041844689042685434707229435012900685910183054712320472809843835362299874e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.4153517213588660353769404140539796364318846647922938442928982516763682295297524025e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.0612877847699383856310204418767999963941175773527544927951233517414654065993562292e+05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.9161022337583429443319078749411063125143924304273472659235111671109967684138896371e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2115062080034682817602956663792443265985654149672855657063890194977099012713284199e+04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.1324805949350810193947943179103430601921304099416931772402636138580376468344900971e+03)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -6.7379854977281995958474241831424455939028898406040636148869222006236410315246590813e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1982547830365481876880107367272973441376153376561639433022240961322166151300388030e+02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7477942737376629095840094280792553329439356352076603742418189295402785845496828618e+01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.0703715155075453775002558378654461695986020593253642834916629665157095201951753511e+00)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9675866846243159020907742164534290169104130230063615572789631974066350817947062221e-01)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.4780561158714357685758956261017689353220221023341472401836356861114284203430539079e-02)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -8.6188339219787319686113112867608363101891398970645607178011869309209804235190901119e-04)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.8157866597647120851117681906042345217930339391652255480834165995078338419417330285e-05)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2481320382678181695580703583602390565135442535050898393382403247198998298046344360e-06)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.9159483230174733349570293758760922152980844047473628166544981799492351078480622954e-08)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.6629576379996951454117430064764364032095890196838102664116218770332578145496215211e-10)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8338633562069325240602901391334379837235954960205324388722028354858275502279946625e-12)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.0262311774099493927119217222064229499121659914970978765047236920420564019570051218e-14)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.0407678912374899180410563256969325940215095079830235805022567411720384237429934979e-16)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.7255616775185743686583950617043659309702235282144322436444914063380593981448767314e-19)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.1434762424301802086970046614089097993428600914262940192954247147222512140342020251e-22)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.2811050104947718753668138286684667456060595320836882460657390484001848305710926658e-26)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.6472071585409775242391978767682093973522869636260937895265262698161653967448170294e-31)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.7256607055318261608651300407042778032797661723154154620044497458638616772687293939e-36)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2336914691939376212057695014798607076719945066572302277992040650923577371403732374e-43)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.0786447260639215447891518190226750925343851277049431943886851989702400712288529676e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.1025728477854679597292503557220243198932574654689944030312971203381791545284070615e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.8158191084622128024881877808372136805034582816867095109911304441480739442791111504e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -4.9234747877490011456140079812669308237793558885580849786063897631770733025035207671e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 4.3490836759659078559291835803157452697088321139262167213210146255834532556301891370e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.3112546247213856964589957649093570444521154190936715486464158458810486032666803106e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 2.1776700296770363161098741319363506481285657595677761712371712460328658791045355723e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.2417232307174566390298057341943116719841715593695502126267674406446096534743228763e-45)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 6.1547673524314003744185487198857922344498908431160001720400958944740800214791613435e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -2.6513158232596442320093540701345954468693696224501434722041096230050093398371645003e-46)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 9.8887754856348531434071033903412118519453856283236928328635658056271487149248163047e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.1687328649763305634603605974128554276109745864508580830005398092245895954643537734e-47)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 8.6161736776863672083691176367303804395378775987877354282547095064819083181262752062e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -1.9521769890951289875720183789100014523337064918766622763963203875214061068994800866e-48)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 3.5893201221052508883479696840784788679013550155716308694609078334579681197829045250e-49)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -5.1475882011819285876938214420399142925361432312238692258191602240316479716676925358e-50)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 5.4033368363711826759446617519812384260206693934532562051784267615057052651438166096e-51)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, -3.6926203201715401183464726950807528731521709827951454941037337126228208878967951308e-52)), + static_cast(BOOST_MATH_BIG_CONSTANT(T, 267, 1.2328726440751392123787631395330686880390176572387043105330275032212649717981066795e-53)), + }; + T result = 0; + T z = dz + 2; + for (unsigned k = 1; k <= sizeof(d) / sizeof(d[0]); ++k) + { + result += (-d[k - 1] * dz) / (z + k * z + k * k - 1); + } + return result; + } + + static double g() { return 4.9921416015624998863131622783839702606201171875000000000000000000000000000000000000e+01; } +}; + +inline double lanczos_g_near_1_and_2(const lanczos52MP&) +{ + return 38.73733398437500; +} + + +// +// placeholder for no lanczos info available: +// +struct undefined_lanczos : public std::integral_constant::max)() - 1> { }; + +template +struct lanczos +{ + static constexpr auto target_precision = policies::precision::type::value <= 0 ? (std::numeric_limits::max)()-2 : + policies::precision::type::value; + + using type = typename std::conditional<(target_precision <= lanczos6m24::value), lanczos6m24, + typename std::conditional<(target_precision <= lanczos13m53::value), lanczos13m53, + typename std::conditional<(target_precision <= lanczos11::value), lanczos11, + typename std::conditional<(target_precision <= lanczos17m64::value), lanczos17m64, + typename std::conditional<(target_precision <= lanczos24m113::value), lanczos24m113, + typename std::conditional<(target_precision <= lanczos27MP::value), lanczos27MP, + typename std::conditional<(target_precision <= lanczos35MP::value), lanczos35MP, + typename std::conditional<(target_precision <= lanczos48MP::value), lanczos48MP, + typename std::conditional<(target_precision <= lanczos49MP::value), lanczos49MP, + typename std::conditional<(target_precision <= lanczos52MP::value), lanczos52MP, undefined_lanczos>::type + >::type>::type>::type>::type>::type>::type>::type>::type + >::type; +}; + +} // namespace lanczos +} // namespace math +} // namespace boost + +#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) +#if ((defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) || defined(_M_AMD64) || defined(_M_X64)) && !defined(_MANAGED) +#include +#endif +#endif + +#endif // BOOST_MATH_SPECIAL_FUNCTIONS_LANCZOS diff --git a/libcxx/src/third-party/boost/math/special_functions/legendre.hpp b/libcxx/src/third-party/boost/math/special_functions/legendre.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/legendre.hpp @@ -0,0 +1,387 @@ +// (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_LEGENDRE_HPP +#define BOOST_MATH_SPECIAL_LEGENDRE_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +// Recurrence relation for legendre P and Q polynomials: +template +inline typename tools::promote_args::type + legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * l + 1) * result_type(x) * result_type(Pl) - l * result_type(Plm1)) / (l + 1); +} + +namespace detail{ + +// Implement Legendre P and Q polynomials via recurrence: +template +T legendre_imp(unsigned l, T x, const Policy& pol, bool second = false) +{ + static const char* function = "boost::math::legrendre_p<%1%>(unsigned, %1%)"; + // Error handling: + if((x < -1) || (x > 1)) + return policies::raise_domain_error( + function, + "The Legendre Polynomial is defined for" + " -1 <= x <= 1, but got x = %1%.", x, pol); + + T p0, p1; + if(second) + { + // A solution of the second kind (Q): + p0 = (boost::math::log1p(x, pol) - boost::math::log1p(-x, pol)) / 2; + p1 = x * p0 - 1; + } + else + { + // A solution of the first kind (P): + p0 = 1; + p1 = x; + } + if(l == 0) + return p0; + + unsigned n = 1; + + while(n < l) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + } + return p1; +} + +template +T legendre_p_prime_imp(unsigned l, T x, const Policy& pol, T* Pn +#ifdef BOOST_NO_CXX11_NULLPTR + = 0 +#else + = nullptr +#endif +) +{ + static const char* function = "boost::math::legrendre_p_prime<%1%>(unsigned, %1%)"; + // Error handling: + if ((x < -1) || (x > 1)) + return policies::raise_domain_error( + function, + "The Legendre Polynomial is defined for" + " -1 <= x <= 1, but got x = %1%.", x, pol); + + if (l == 0) + { + if (Pn) + { + *Pn = 1; + } + return 0; + } + T p0 = 1; + T p1 = x; + T p_prime; + bool odd = ((l & 1) == 1); + // If the order is odd, we sum all the even polynomials: + if (odd) + { + p_prime = p0; + } + else // Otherwise we sum the odd polynomials * (2n+1) + { + p_prime = 3*p1; + } + + unsigned n = 1; + while(n < l - 1) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + if (odd) + { + p_prime += (2*n+1)*p1; + odd = false; + } + else + { + odd = true; + } + } + // This allows us to evaluate the derivative and the function for the same cost. + if (Pn) + { + std::swap(p0, p1); + *Pn = boost::math::legendre_next(n, x, p0, p1); + } + return p_prime; +} + +template +struct legendre_p_zero_func +{ + int n; + const Policy& pol; + + legendre_p_zero_func(int n_, const Policy& p) : n(n_), pol(p) {} + + std::pair operator()(T x) const + { + T Pn; + T Pn_prime = detail::legendre_p_prime_imp(n, x, pol, &Pn); + return std::pair(Pn, Pn_prime); + } +}; + +template +std::vector legendre_p_zeros_imp(int n, const Policy& pol) +{ + using std::cos; + using std::sin; + using std::ceil; + using std::sqrt; + using boost::math::constants::pi; + using boost::math::constants::half; + using boost::math::tools::newton_raphson_iterate; + + BOOST_MATH_ASSERT(n >= 0); + std::vector zeros; + if (n == 0) + { + // There are no zeros of P_0(x) = 1. + return zeros; + } + int k; + if (n & 1) + { + zeros.resize((n-1)/2 + 1, std::numeric_limits::quiet_NaN()); + zeros[0] = 0; + k = 1; + } + else + { + zeros.resize(n/2, std::numeric_limits::quiet_NaN()); + k = 0; + } + T half_n = ceil(n*half()); + + while (k < (int)zeros.size()) + { + // Bracket the root: Szego: + // Gabriel Szego, Inequalities for the Zeros of Legendre Polynomials and Related Functions, Transactions of the American Mathematical Society, Vol. 39, No. 1 (1936) + T theta_nk = ((half_n - half()*half() - static_cast(k))*pi())/(static_cast(n)+half()); + T lower_bound = cos( (half_n - static_cast(k))*pi()/static_cast(n + 1)); + T cos_nk = cos(theta_nk); + T upper_bound = cos_nk; + // First guess follows from: + // F. G. Tricomi, Sugli zeri dei polinomi sferici ed ultrasferici, Ann. Mat. Pura Appl., 31 (1950), pp. 93-97; + T inv_n_sq = 1/static_cast(n*n); + T sin_nk = sin(theta_nk); + T x_nk_guess = (1 - inv_n_sq/static_cast(8) + inv_n_sq /static_cast(8*n) - (inv_n_sq*inv_n_sq/384)*(39 - 28 / (sin_nk*sin_nk) ) )*cos_nk; + + std::uintmax_t number_of_iterations = policies::get_max_root_iterations(); + + legendre_p_zero_func f(n, pol); + + const T x_nk = newton_raphson_iterate(f, x_nk_guess, + lower_bound, upper_bound, + policies::digits(), + number_of_iterations); + + BOOST_MATH_ASSERT(lower_bound < x_nk); + BOOST_MATH_ASSERT(upper_bound > x_nk); + zeros[k] = x_nk; + ++k; + } + return zeros; +} + +} // namespace detail + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p(int l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + static const char* function = "boost::math::legendre_p<%1%>(unsigned, %1%)"; + if(l < 0) + return policies::checked_narrowing_cast(detail::legendre_imp(-l-1, static_cast(x), pol, false), function); + return policies::checked_narrowing_cast(detail::legendre_imp(l, static_cast(x), pol, false), function); +} + + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p_prime(int l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + static const char* function = "boost::math::legendre_p_prime<%1%>(unsigned, %1%)"; + if(l < 0) + return policies::checked_narrowing_cast(detail::legendre_p_prime_imp(-l-1, static_cast(x), pol), function); + return policies::checked_narrowing_cast(detail::legendre_p_prime_imp(l, static_cast(x), pol), function); +} + +template +inline typename tools::promote_args::type + legendre_p(int l, T x) +{ + return boost::math::legendre_p(l, x, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + legendre_p_prime(int l, T x) +{ + return boost::math::legendre_p_prime(l, x, policies::policy<>()); +} + +template +inline std::vector legendre_p_zeros(int l, const Policy& pol) +{ + if(l < 0) + return detail::legendre_p_zeros_imp(-l-1, pol); + + return detail::legendre_p_zeros_imp(l, pol); +} + + +template +inline std::vector legendre_p_zeros(int l) +{ + return boost::math::legendre_p_zeros(l, policies::policy<>()); +} + +template +inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_q(unsigned l, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::legendre_imp(l, static_cast(x), pol, true), "boost::math::legendre_q<%1%>(unsigned, %1%)"); +} + +template +inline typename tools::promote_args::type + legendre_q(unsigned l, T x) +{ + return boost::math::legendre_q(l, x, policies::policy<>()); +} + +// Recurrence for associated polynomials: +template +inline typename tools::promote_args::type + legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1) +{ + typedef typename tools::promote_args::type result_type; + return ((2 * l + 1) * result_type(x) * result_type(Pl) - (l + m) * result_type(Plm1)) / (l + 1 - m); +} + +namespace detail{ +// Legendre P associated polynomial: +template +T legendre_p_imp(int l, int m, T x, T sin_theta_power, const Policy& pol) +{ + BOOST_MATH_STD_USING + // Error handling: + if((x < -1) || (x > 1)) + return policies::raise_domain_error( + "boost::math::legendre_p<%1%>(int, int, %1%)", + "The associated Legendre Polynomial is defined for" + " -1 <= x <= 1, but got x = %1%.", x, pol); + // Handle negative arguments first: + if(l < 0) + return legendre_p_imp(-l-1, m, x, sin_theta_power, pol); + if ((l == 0) && (m == -1)) + { + return sqrt((1 - x) / (1 + x)); + } + if ((l == 1) && (m == 0)) + { + return x; + } + if (-m == l) + { + return pow((1 - x * x) / 4, T(l) / 2) / boost::math::tgamma(l + 1, pol); + } + if(m < 0) + { + int sign = (m&1) ? -1 : 1; + return sign * boost::math::tgamma_ratio(static_cast(l+m+1), static_cast(l+1-m), pol) * legendre_p_imp(l, -m, x, sin_theta_power, pol); + } + // Special cases: + if(m > l) + return 0; + if(m == 0) + return boost::math::legendre_p(l, x, pol); + + T p0 = boost::math::double_factorial(2 * m - 1, pol) * sin_theta_power; + + if(m&1) + p0 *= -1; + if(m == l) + return p0; + + T p1 = x * (2 * m + 1) * p0; + + int n = m + 1; + + while(n < l) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, m, x, p0, p1); + ++n; + } + return p1; +} + +template +inline T legendre_p_imp(int l, int m, T x, const Policy& pol) +{ + BOOST_MATH_STD_USING + // TODO: we really could use that mythical "pow1p" function here: + return legendre_p_imp(l, m, x, static_cast(pow(1 - x*x, T(abs(m))/2)), pol); +} + +} + +template +inline typename tools::promote_args::type + legendre_p(int l, int m, T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::legendre_p_imp(l, m, static_cast(x), pol), "boost::math::legendre_p<%1%>(int, int, %1%)"); +} + +template +inline typename tools::promote_args::type + legendre_p(int l, int m, T x) +{ + return boost::math::legendre_p(l, m, x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_LEGENDRE_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/legendre_stieltjes.hpp b/libcxx/src/third-party/boost/math/special_functions/legendre_stieltjes.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/legendre_stieltjes.hpp @@ -0,0 +1,234 @@ +// Copyright Nick Thompson 2017. +// 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_LEGENDRE_STIELTJES_HPP +#define BOOST_MATH_SPECIAL_LEGENDRE_STIELTJES_HPP + +/* + * Constructs the Legendre-Stieltjes polynomial of degree m. + * The Legendre-Stieltjes polynomials are used to create extensions for Gaussian quadratures, + * commonly called "Gauss-Konrod" quadratures. + * + * References: + * Patterson, TNL. "The optimum addition of points to quadrature formulae." Mathematics of Computation 22.104 (1968): 847-856. + */ + +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +template +class legendre_stieltjes +{ +public: + legendre_stieltjes(size_t m) + { + if (m == 0) + { + throw std::domain_error("The Legendre-Stieltjes polynomial is defined for order m > 0.\n"); + } + m_m = static_cast(m); + std::ptrdiff_t n = m - 1; + std::ptrdiff_t q; + std::ptrdiff_t r; + if ((n & 1) == 1) + { + q = 1; + r = (n-1)/2 + 2; + } + else + { + q = 0; + r = n/2 + 1; + } + m_a.resize(r + 1); + // We'll keep the ones-based indexing at the cost of storing a superfluous element + // so that we can follow Patterson's notation exactly. + m_a[r] = static_cast(1); + // Make sure using the zero index is a bug: + m_a[0] = std::numeric_limits::quiet_NaN(); + + for (std::ptrdiff_t k = 1; k < r; ++k) + { + Real ratio = 1; + m_a[r - k] = 0; + for (std::ptrdiff_t i = r + 1 - k; i <= r; ++i) + { + // See Patterson, equation 12 + std::ptrdiff_t num = (n - q + 2*(i + k - 1))*(n + q + 2*(k - i + 1))*(n-1-q+2*(i-k))*(2*(k+i-1) -1 -q -n); + std::ptrdiff_t den = (n - q + 2*(i - k))*(2*(k + i - 1) - q - n)*(n + 1 + q + 2*(k - i))*(n - 1 - q + 2*(i + k)); + ratio *= static_cast(num)/static_cast(den); + m_a[r - k] -= ratio*m_a[i]; + } + } + } + + + Real norm_sq() const + { + Real t = 0; + bool odd = ((m_m & 1) == 1); + for (size_t i = 1; i < m_a.size(); ++i) + { + if(odd) + { + t += 2*m_a[i]*m_a[i]/static_cast(4*i-1); + } + else + { + t += 2*m_a[i]*m_a[i]/static_cast(4*i-3); + } + } + return t; + } + + + Real operator()(Real x) const + { + // Trivial implementation: + // Em += m_a[i]*legendre_p(2*i - 1, x); m odd + // Em += m_a[i]*legendre_p(2*i - 2, x); m even + size_t r = m_a.size() - 1; + Real p0 = 1; + Real p1 = x; + + Real Em; + bool odd = ((m_m & 1) == 1); + if (odd) + { + Em = m_a[1]*p1; + } + else + { + Em = m_a[1]*p0; + } + + unsigned n = 1; + for (size_t i = 2; i <= r; ++i) + { + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + if (!odd) + { + Em += m_a[i]*p1; + } + std::swap(p0, p1); + p1 = boost::math::legendre_next(n, x, p0, p1); + ++n; + if(odd) + { + Em += m_a[i]*p1; + } + } + return Em; + } + + + Real prime(Real x) const + { + Real Em_prime = 0; + + for (size_t i = 1; i < m_a.size(); ++i) + { + if(m_m & 1) + { + Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast(2*i - 1), x, policies::policy<>()); + } + else + { + Em_prime += m_a[i]*detail::legendre_p_prime_imp(static_cast(2*i - 2), x, policies::policy<>()); + } + } + return Em_prime; + } + + std::vector zeros() const + { + using boost::math::constants::half; + + std::vector stieltjes_zeros; + std::vector legendre_zeros = legendre_p_zeros(m_m - 1); + int k; + if (m_m & 1) + { + stieltjes_zeros.resize(legendre_zeros.size() + 1, std::numeric_limits::quiet_NaN()); + stieltjes_zeros[0] = 0; + k = 1; + } + else + { + stieltjes_zeros.resize(legendre_zeros.size(), std::numeric_limits::quiet_NaN()); + k = 0; + } + + while (k < (int)stieltjes_zeros.size()) + { + Real lower_bound; + Real upper_bound; + if (m_m & 1) + { + lower_bound = legendre_zeros[k - 1]; + if (k == (int)legendre_zeros.size()) + { + upper_bound = 1; + } + else + { + upper_bound = legendre_zeros[k]; + } + } + else + { + lower_bound = legendre_zeros[k]; + if (k == (int)legendre_zeros.size() - 1) + { + upper_bound = 1; + } + else + { + upper_bound = legendre_zeros[k+1]; + } + } + + // The root bracketing is not very tight; to keep weird stuff from happening + // in the Newton's method, let's tighten up the tolerance using a few bisections. + boost::math::tools::eps_tolerance tol(6); + auto g = [&](Real t) { return this->operator()(t); }; + auto p = boost::math::tools::bisect(g, lower_bound, upper_bound, tol); + + Real x_nk_guess = p.first + (p.second - p.first)*half(); + std::uintmax_t number_of_iterations = 500; + + auto f = [&] (Real x) { Real Pn = this->operator()(x); + Real Pn_prime = this->prime(x); + return std::pair(Pn, Pn_prime); }; + + const Real x_nk = boost::math::tools::newton_raphson_iterate(f, x_nk_guess, + p.first, p.second, + tools::digits(), + number_of_iterations); + + BOOST_MATH_ASSERT(p.first < x_nk); + BOOST_MATH_ASSERT(x_nk < p.second); + stieltjes_zeros[k] = x_nk; + ++k; + } + return stieltjes_zeros; + } + +private: + // Coefficients of Legendre expansion + std::vector m_a; + int m_m; +}; + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/log1p.hpp b/libcxx/src/third-party/boost/math/special_functions/log1p.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/log1p.hpp @@ -0,0 +1,483 @@ +// (C) Copyright John Maddock 2005-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_LOG1P_INCLUDED +#define BOOST_MATH_LOG1P_INCLUDED + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ + +namespace detail +{ + // Functor log1p_series returns the next term in the Taylor series + // pow(-1, k-1)*pow(x, k) / k + // each time that operator() is invoked. + // + template + struct log1p_series + { + typedef T result_type; + + log1p_series(T x) + : k(0), m_mult(-x), m_prod(-1){} + + T operator()() + { + m_prod *= m_mult; + return m_prod / ++k; + } + + int count()const + { + return k; + } + + private: + int k; + const T m_mult; + T m_prod; + log1p_series(const log1p_series&) = delete; + log1p_series& operator=(const log1p_series&) = delete; + }; + +// Algorithm log1p is part of C99, but is not yet provided by many compilers. +// +// This version uses a Taylor series expansion for 0.5 > x > epsilon, which may +// require up to std::numeric_limits::digits+1 terms to be calculated. +// It would be much more efficient to use the equivalence: +// log(1+x) == (log(1+x) * x) / ((1-x) - 1) +// Unfortunately many optimizing compilers make such a mess of this, that +// it performs no better than log(1+x): which is to say not very well at all. +// +template +T log1p_imp(T const & x, const Policy& pol, const std::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + + static const char* function = "boost::math::log1p<%1%>(%1%)"; + + if((x < -1) || (boost::math::isnan)(x)) + return policies::raise_domain_error( + function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + result_type a = abs(result_type(x)); + if(a > result_type(0.5f)) + return log(1 + result_type(x)); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + detail::log1p_series s(x); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + result_type result = tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return result; +} + +template +T log1p_imp(T const& x, const Policy& pol, const std::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + static const char* function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error( + function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 1.846e-017 + // Expected Error Term: 1.843e-017 + // Maximum Relative Change in Control Points: 8.138e-004 + // Max Error found at double precision = 3.250766e-016 + static const T P[] = { + 0.15141069795941984e-16L, + 0.35495104378055055e-15L, + 0.33333333333332835L, + 0.99249063543365859L, + 1.1143969784156509L, + 0.58052937949269651L, + 0.13703234928513215L, + 0.011294864812099712L + }; + static const T Q[] = { + 1L, + 3.7274719063011499L, + 5.5387948649720334L, + 4.159201143419005L, + 1.6423855110312755L, + 0.31706251443180914L, + 0.022665554431410243L, + -0.29252538135177773e-5L + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +template +T log1p_imp(T const& x, const Policy& pol, const std::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + static const char* function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error( + function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 8.089e-20 + // Expected Error Term: 8.088e-20 + // Maximum Relative Change in Control Points: 9.648e-05 + // Max Error found at long double precision = 2.242324e-19 + static const T P[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.807533446680736736712e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.490881544804798926426e-18), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.333333333333333373941), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.17141290782087994162), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.62790522814926264694), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.13156411870766876113), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.408087379932853785336), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0706537026422828914622), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00441709903782239229447) + }; + static const T Q[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.26423872346263928361), + BOOST_MATH_BIG_CONSTANT(T, 64, 7.48189472704477708962), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.94757016732904280913), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.6493508622280767304), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.06884863623790638317), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.158292216998514145947), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00885295524069924328658), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.560026216133415663808e-6) + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +template +T log1p_imp(T const& x, const Policy& pol, const std::integral_constant&) +{ // The function returns the natural logarithm of 1 + x. + BOOST_MATH_STD_USING + + static const char* function = "boost::math::log1p<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error( + function, "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + T a = fabs(x); + if(a > 0.5f) + return log(1 + x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return x; + + // Maximum Deviation Found: 6.910e-08 + // Expected Error Term: 6.910e-08 + // Maximum Relative Change in Control Points: 2.509e-04 + // Max Error found at double precision = 6.910422e-08 + // Max Error found at float precision = 8.357242e-08 + static const T P[] = { + -0.671192866803148236519e-7L, + 0.119670999140731844725e-6L, + 0.333339469182083148598L, + 0.237827183019664122066L + }; + static const T Q[] = { + 1L, + 1.46348272586988539733L, + 0.497859871350117338894L, + -0.00471666268910169651936L + }; + + T result = 1 - x / 2 + tools::evaluate_polynomial(P, x) / tools::evaluate_polynomial(Q, x); + result *= x; + + return result; +} + +template +struct log1p_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + template + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + boost::math::log1p(static_cast(0.25), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename log1p_initializer::init log1p_initializer::initializer; + + +} // namespace detail + +template +inline typename tools::promote_args::type log1p(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + typedef std::integral_constant tag_type; + + detail::log1p_initializer::force_instantiate(); + + return policies::checked_narrowing_cast( + detail::log1p_imp(static_cast(x), forwarding_policy(), tag_type()), "boost::math::log1p<%1%>(%1%)"); +} + +#ifdef log1p +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# undef log1p +#endif + +#if defined(BOOST_HAS_LOG1P) && !(defined(__osf__) && defined(__DECCXX_VER)) +# ifdef BOOST_MATH_USE_C99 +template +inline float log1p(float x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + return ::log1pf(x); +} +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +template +inline long double log1p(long double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + return ::log1pl(x); +} +#endif +#else +template +inline float log1p(float x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + return ::log1p(x); +} +#endif +template +inline double log1p(double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + return ::log1p(x); +} +#elif defined(_MSC_VER) && (BOOST_MSVC >= 1400) +// +// You should only enable this branch if you are absolutely sure +// that your compilers optimizer won't mess this code up!! +// Currently tested with VC8 and Intel 9.1. +// +template +inline double log1p(double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + double u = 1+x; + if(u == 1.0) + return x; + else + return ::log(u)*(x/(u-1.0)); +} +template +inline float log1p(float x, const Policy& pol) +{ + return static_cast(boost::math::log1p(static_cast(x), pol)); +} +#ifndef _WIN32_WCE +// +// For some reason this fails to compile under WinCE... +// Needs more investigation. +// +template +inline long double log1p(long double x, const Policy& pol) +{ + if(x < -1) + return policies::raise_domain_error( + "log1p<%1%>(%1%)", "log1p(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + "log1p<%1%>(%1%)", nullptr, pol); + long double u = 1+x; + if(u == 1.0) + return x; + else + return ::logl(u)*(x/(u-1.0)); +} +#endif +#endif + +template +inline typename tools::promote_args::type log1p(T x) +{ + return boost::math::log1p(x, policies::policy<>()); +} +// +// Compute log(1+x)-x: +// +template +inline typename tools::promote_args::type + log1pmx(T x, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + static const char* function = "boost::math::log1pmx<%1%>(%1%)"; + + if(x < -1) + return policies::raise_domain_error( + function, "log1pmx(x) requires x > -1, but got x = %1%.", x, pol); + if(x == -1) + return -policies::raise_overflow_error( + function, nullptr, pol); + + result_type a = abs(result_type(x)); + if(a > result_type(0.95f)) + return log(1 + result_type(x)) - result_type(x); + // Note that without numeric_limits specialisation support, + // epsilon just returns zero, and our "optimisation" will always fail: + if(a < tools::epsilon()) + return -x * x / 2; + boost::math::detail::log1p_series s(x); + s(); + std::uintmax_t max_iter = policies::get_max_series_iterations(); + + T result = boost::math::tools::sum_series(s, policies::get_epsilon(), max_iter); + + policies::check_series_iterations(function, max_iter, pol); + return result; +} + +template +inline typename tools::promote_args::type log1pmx(T x) +{ + return log1pmx(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_LOG1P_INCLUDED + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/logaddexp.hpp b/libcxx/src/third-party/boost/math/special_functions/logaddexp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/logaddexp.hpp @@ -0,0 +1,41 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#include +#include +#include +#include + +namespace boost { namespace math { + +// Calculates log(exp(x1) + exp(x2)) +template +Real logaddexp(Real x1, Real x2) noexcept +{ + using std::log1p; + using std::exp; + using std::abs; + + // Validate inputs first + if (!(boost::math::isfinite)(x1)) + { + return x1; + } + else if (!(boost::math::isfinite)(x2)) + { + return x2; + } + + const Real temp = x1 - x2; + + if (temp > 0) + { + return x1 + log1p(exp(-temp)); + } + + return x2 + log1p(exp(temp)); +} + +}} // Namespace boost::math diff --git a/libcxx/src/third-party/boost/math/special_functions/logsumexp.hpp b/libcxx/src/third-party/boost/math/special_functions/logsumexp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/logsumexp.hpp @@ -0,0 +1,60 @@ +// (C) Copyright Matt Borland 2022. +// 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) + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { + +// https://nhigham.com/2021/01/05/what-is-the-log-sum-exp-function/ +// See equation (#) +template ::value_type> +Real logsumexp(ForwardIterator first, ForwardIterator last) +{ + using std::exp; + using std::log1p; + + const auto elem = std::max_element(first, last); + const Real max_val = *elem; + + Real arg = 0; + while (first != last) + { + if (first != elem) + { + arg += exp(*first - max_val); + } + + ++first; + } + + return max_val + log1p(arg); +} + +template +inline Real logsumexp(const Container& c) +{ + return logsumexp(std::begin(c), std::end(c)); +} + +template ::type, + typename std::enable_if::value, bool>::type = true> +inline Real logsumexp(Args&& ...args) +{ + std::initializer_list list {std::forward(args)...}; + + if(list.size() == 2) + { + return logaddexp(*list.begin(), *std::next(list.begin())); + } + return logsumexp(list.begin(), list.end()); +} + +}} // Namespace boost::math diff --git a/libcxx/src/third-party/boost/math/special_functions/math_fwd.hpp b/libcxx/src/third-party/boost/math/special_functions/math_fwd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/math_fwd.hpp @@ -0,0 +1,1818 @@ +// math_fwd.hpp + +// TODO revise completely for new distribution classes. + +// Copyright Paul A. Bristow 2006. +// 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) + +// Omnibus list of forward declarations of math special functions. + +// IT = Integer type. +// RT = Real type (built-in floating-point types, float, double, long double) & User Defined Types +// AT = Integer or Real type + +#ifndef BOOST_MATH_SPECIAL_MATH_FWD_HPP +#define BOOST_MATH_SPECIAL_MATH_FWD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include // for argument promotion. +#include + +#define BOOST_NO_MACRO_EXPAND /**/ + +namespace boost +{ + namespace math + { // Math functions (in roughly alphabetic order). + + // Beta functions. + template + typename tools::promote_args::type + beta(RT1 a, RT2 b); // Beta function (2 arguments). + + template + typename tools::promote_args::type + beta(RT1 a, RT2 b, A x); // Beta function (3 arguments). + + template + typename tools::promote_args::type + beta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Beta function (3 arguments). + + template + typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x); + + template + typename tools::promote_args::type + betac(RT1 a, RT2 b, RT3 x, const Policy& pol); + + template + typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x); // Incomplete beta function. + + template + typename tools::promote_args::type + ibeta(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta function. + + template + typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x); // Incomplete beta complement function. + + template + typename tools::promote_args::type + ibetac(RT1 a, RT2 b, RT3 x, const Policy& pol); // Incomplete beta complement function. + + template + typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py); + + template + typename tools::promote_args::type + ibeta_inv(T1 a, T2 b, T3 p, T4* py, const Policy& pol); + + template + typename tools::promote_args::type + ibeta_inv(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibeta_inv(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibeta_inva(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibeta_inva(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 b, RT3 p); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibeta_invb(RT1 a, RT2 b, RT3 p, const Policy&); // Incomplete beta inverse function. + + template + typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py); + + template + typename tools::promote_args::type + ibetac_inv(T1 a, T2 b, T3 q, T4* py, const Policy& pol); + + template + typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibetac_inv(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibetac_inva(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibetac_inva(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 b, RT3 q); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibetac_invb(RT1 a, RT2 b, RT3 q, const Policy&); // Incomplete beta complement inverse function. + + template + typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x); // derivative of incomplete beta + + template + typename tools::promote_args::type + ibeta_derivative(RT1 a, RT2 b, RT3 x, const Policy& pol); // derivative of incomplete beta + + // Binomial: + template + T binomial_coefficient(unsigned n, unsigned k, const Policy& pol); + template + T binomial_coefficient(unsigned n, unsigned k); + + // erf & erfc error functions. + template // Error function. + typename tools::promote_args::type erf(RT z); + template // Error function. + typename tools::promote_args::type erf(RT z, const Policy&); + + template // Error function complement. + typename tools::promote_args::type erfc(RT z); + template // Error function complement. + typename tools::promote_args::type erfc(RT z, const Policy&); + + template // Error function inverse. + typename tools::promote_args::type erf_inv(RT z); + template // Error function inverse. + typename tools::promote_args::type erf_inv(RT z, const Policy& pol); + + template // Error function complement inverse. + typename tools::promote_args::type erfc_inv(RT z); + template // Error function complement inverse. + typename tools::promote_args::type erfc_inv(RT z, const Policy& pol); + + // Polynomials: + template + typename tools::promote_args::type + legendre_next(unsigned l, T1 x, T2 Pl, T3 Plm1); + + template + typename tools::promote_args::type + legendre_p(int l, T x); + template + typename tools::promote_args::type + legendre_p_prime(int l, T x); + + + template + inline std::vector legendre_p_zeros(int l, const Policy& pol); + + template + inline std::vector legendre_p_zeros(int l); + + template + typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p(int l, T x, const Policy& pol); + template + inline typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_p_prime(int l, T x, const Policy& pol); + + template + typename tools::promote_args::type + legendre_q(unsigned l, T x); + + template + typename std::enable_if::value, typename tools::promote_args::type>::type + legendre_q(unsigned l, T x, const Policy& pol); + + template + typename tools::promote_args::type + legendre_next(unsigned l, unsigned m, T1 x, T2 Pl, T3 Plm1); + + template + typename tools::promote_args::type + legendre_p(int l, int m, T x); + + template + typename tools::promote_args::type + legendre_p(int l, int m, T x, const Policy& pol); + + template + typename tools::promote_args::type + laguerre_next(unsigned n, T1 x, T2 Ln, T3 Lnm1); + + template + typename tools::promote_args::type + laguerre_next(unsigned n, unsigned l, T1 x, T2 Pl, T3 Plm1); + + template + typename tools::promote_args::type + laguerre(unsigned n, T x); + + template + typename tools::promote_args::type + laguerre(unsigned n, unsigned m, T x, const Policy& pol); + + template + struct laguerre_result + { + using type = typename std::conditional< + policies::is_policy::value, + typename tools::promote_args::type, + typename tools::promote_args::type + >::type; + }; + + template + typename laguerre_result::type + laguerre(unsigned n, T1 m, T2 x); + + template + typename tools::promote_args::type + hermite(unsigned n, T x); + + template + typename tools::promote_args::type + hermite(unsigned n, T x, const Policy& pol); + + template + typename tools::promote_args::type + hermite_next(unsigned n, T1 x, T2 Hn, T3 Hnm1); + + template + typename tools::promote_args::type chebyshev_next(T1 const & x, T2 const & Tn, T3 const & Tn_1); + + template + typename tools::promote_args::type + chebyshev_t(unsigned n, Real const & x, const Policy&); + template + typename tools::promote_args::type chebyshev_t(unsigned n, Real const & x); + + template + typename tools::promote_args::type + chebyshev_u(unsigned n, Real const & x, const Policy&); + template + typename tools::promote_args::type chebyshev_u(unsigned n, Real const & x); + + template + typename tools::promote_args::type + chebyshev_t_prime(unsigned n, Real const & x, const Policy&); + template + typename tools::promote_args::type chebyshev_t_prime(unsigned n, Real const & x); + + template + Real chebyshev_clenshaw_recurrence(const Real* const c, size_t length, const T2& x); + + template + std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi); + + template + std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi); + + template + typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi); + + template + typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol); + + // Elliptic integrals: + template + typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z); + + template + typename tools::promote_args::type + ellint_rf(T1 x, T2 y, T3 z, const Policy& pol); + + template + typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z); + + template + typename tools::promote_args::type + ellint_rd(T1 x, T2 y, T3 z, const Policy& pol); + + template + typename tools::promote_args::type + ellint_rc(T1 x, T2 y); + + template + typename tools::promote_args::type + ellint_rc(T1 x, T2 y, const Policy& pol); + + template + typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p); + + template + typename tools::promote_args::type + ellint_rj(T1 x, T2 y, T3 z, T4 p, const Policy& pol); + + template + typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z); + + template + typename tools::promote_args::type + ellint_rg(T1 x, T2 y, T3 z, const Policy& pol); + + template + typename tools::promote_args::type ellint_2(T k); + + template + typename tools::promote_args::type ellint_2(T1 k, T2 phi); + + template + typename tools::promote_args::type ellint_2(T1 k, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type ellint_1(T k); + + template + typename tools::promote_args::type ellint_1(T1 k, T2 phi); + + template + typename tools::promote_args::type ellint_1(T1 k, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type ellint_d(T k); + + template + typename tools::promote_args::type ellint_d(T1 k, T2 phi); + + template + typename tools::promote_args::type ellint_d(T1 k, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi); + + template + typename tools::promote_args::type jacobi_zeta(T1 k, T2 phi, const Policy& pol); + + template + typename tools::promote_args::type heuman_lambda(T1 k, T2 phi); + + template + typename tools::promote_args::type heuman_lambda(T1 k, T2 phi, const Policy& pol); + + namespace detail{ + + template + struct ellint_3_result + { + using type = typename std::conditional< + policies::is_policy::value, + typename tools::promote_args::type, + typename tools::promote_args::type + >::type; + }; + + } // namespace detail + + + template + typename detail::ellint_3_result::type ellint_3(T1 k, T2 v, T3 phi); + + template + typename tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi, const Policy& pol); + + template + typename tools::promote_args::type ellint_3(T1 k, T2 v); + + // Factorial functions. + // Note: not for integral types, at present. + template + struct max_factorial; + template + RT factorial(unsigned int); + template + RT factorial(unsigned int, const Policy& pol); + template + RT unchecked_factorial(unsigned int BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(RT)); + template + RT double_factorial(unsigned i); + template + RT double_factorial(unsigned i, const Policy& pol); + + template + typename tools::promote_args::type falling_factorial(RT x, unsigned n); + + template + typename tools::promote_args::type falling_factorial(RT x, unsigned n, const Policy& pol); + + template + typename tools::promote_args::type rising_factorial(RT x, int n); + + template + typename tools::promote_args::type rising_factorial(RT x, int n, const Policy& pol); + + // Gamma functions. + template + typename tools::promote_args::type tgamma(RT z); + + template + typename tools::promote_args::type tgamma1pm1(RT z); + + template + typename tools::promote_args::type tgamma1pm1(RT z, const Policy& pol); + + template + typename tools::promote_args::type tgamma(RT1 a, RT2 z); + + template + typename tools::promote_args::type tgamma(RT1 a, RT2 z, const Policy& pol); + + template + typename tools::promote_args::type lgamma(RT z, int* sign); + + template + typename tools::promote_args::type lgamma(RT z, int* sign, const Policy& pol); + + template + typename tools::promote_args::type lgamma(RT x); + + template + typename tools::promote_args::type lgamma(RT x, const Policy& pol); + + template + typename tools::promote_args::type tgamma_lower(RT1 a, RT2 z); + + template + typename tools::promote_args::type tgamma_lower(RT1 a, RT2 z, const Policy&); + + template + typename tools::promote_args::type gamma_q(RT1 a, RT2 z); + + template + typename tools::promote_args::type gamma_q(RT1 a, RT2 z, const Policy&); + + template + typename tools::promote_args::type gamma_p(RT1 a, RT2 z); + + template + typename tools::promote_args::type gamma_p(RT1 a, RT2 z, const Policy&); + + template + typename tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta); + + template + typename tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta, const Policy&); + + template + typename tools::promote_args::type tgamma_ratio(T1 a, T2 b); + + template + typename tools::promote_args::type tgamma_ratio(T1 a, T2 b, const Policy&); + + template + typename tools::promote_args::type gamma_p_derivative(T1 a, T2 x); + + template + typename tools::promote_args::type gamma_p_derivative(T1 a, T2 x, const Policy&); + + // gamma inverse. + template + typename tools::promote_args::type gamma_p_inv(T1 a, T2 p); + + template + typename tools::promote_args::type gamma_p_inva(T1 a, T2 p, const Policy&); + + template + typename tools::promote_args::type gamma_p_inva(T1 a, T2 p); + + template + typename tools::promote_args::type gamma_p_inv(T1 a, T2 p, const Policy&); + + template + typename tools::promote_args::type gamma_q_inv(T1 a, T2 q); + + template + typename tools::promote_args::type gamma_q_inv(T1 a, T2 q, const Policy&); + + template + typename tools::promote_args::type gamma_q_inva(T1 a, T2 q); + + template + typename tools::promote_args::type gamma_q_inva(T1 a, T2 q, const Policy&); + + // digamma: + template + typename tools::promote_args::type digamma(T x); + + template + typename tools::promote_args::type digamma(T x, const Policy&); + + // trigamma: + template + typename tools::promote_args::type trigamma(T x); + + template + typename tools::promote_args::type trigamma(T x, const Policy&); + + // polygamma: + template + typename tools::promote_args::type polygamma(int n, T x); + + template + typename tools::promote_args::type polygamma(int n, T x, const Policy&); + + // Hypotenuse function sqrt(x ^ 2 + y ^ 2). + template + typename tools::promote_args::type + hypot(T1 x, T2 y); + + template + typename tools::promote_args::type + hypot(T1 x, T2 y, const Policy&); + + // cbrt - cube root. + template + typename tools::promote_args::type cbrt(RT z); + + template + typename tools::promote_args::type cbrt(RT z, const Policy&); + + // log1p is log(x + 1) + template + typename tools::promote_args::type log1p(T); + + template + typename tools::promote_args::type log1p(T, const Policy&); + + // log1pmx is log(x + 1) - x + template + typename tools::promote_args::type log1pmx(T); + + template + typename tools::promote_args::type log1pmx(T, const Policy&); + + // Exp (x) minus 1 functions. + template + typename tools::promote_args::type expm1(T); + + template + typename tools::promote_args::type expm1(T, const Policy&); + + // Power - 1 + template + typename tools::promote_args::type + powm1(const T1 a, const T2 z); + + template + typename tools::promote_args::type + powm1(const T1 a, const T2 z, const Policy&); + + // sqrt(1+x) - 1 + template + typename tools::promote_args::type sqrt1pm1(const T& val); + + template + typename tools::promote_args::type sqrt1pm1(const T& val, const Policy&); + + // sinus cardinals: + template + typename tools::promote_args::type sinc_pi(T x); + + template + typename tools::promote_args::type sinc_pi(T x, const Policy&); + + template + typename tools::promote_args::type sinhc_pi(T x); + + template + typename tools::promote_args::type sinhc_pi(T x, const Policy&); + + // inverse hyperbolics: + template + typename tools::promote_args::type asinh(T x); + + template + typename tools::promote_args::type asinh(T x, const Policy&); + + template + typename tools::promote_args::type acosh(T x); + + template + typename tools::promote_args::type acosh(T x, const Policy&); + + template + typename tools::promote_args::type atanh(T x); + + template + typename tools::promote_args::type atanh(T x, const Policy&); + + namespace detail{ + + typedef std::integral_constant bessel_no_int_tag; // No integer optimisation possible. + typedef std::integral_constant bessel_maybe_int_tag; // Maybe integer optimisation. + typedef std::integral_constant bessel_int_tag; // Definite integer optimisation. + + template + struct bessel_traits + { + using result_type = typename std::conditional< + std::is_integral::value, + typename tools::promote_args::type, + typename tools::promote_args::type + >::type; + + typedef typename policies::precision::type precision_type; + + using optimisation_tag = typename std::conditional< + (precision_type::value <= 0 || precision_type::value > 64), + bessel_no_int_tag, + typename std::conditional< + std::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + + using optimisation_tag128 = typename std::conditional< + (precision_type::value <= 0 || precision_type::value > 113), + bessel_no_int_tag, + typename std::conditional< + std::is_integral::value, + bessel_int_tag, + bessel_maybe_int_tag + >::type + >::type; + }; + } // detail + + // Bessel functions: + template + typename detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x, const Policy& pol); + template + typename detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_bessel_j(T1 v, T2 x); + template + typename detail::bessel_traits >::result_type cyl_bessel_j_prime(T1 v, T2 x); + + template + typename detail::bessel_traits::result_type sph_bessel(unsigned v, T x, const Policy& pol); + template + typename detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type sph_bessel(unsigned v, T x); + template + typename detail::bessel_traits >::result_type sph_bessel_prime(unsigned v, T x); + + template + typename detail::bessel_traits::result_type cyl_bessel_i(T1 v, T2 x, const Policy& pol); + template + typename detail::bessel_traits::result_type cyl_bessel_i_prime(T1 v, T2 x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_bessel_i(T1 v, T2 x); + template + typename detail::bessel_traits >::result_type cyl_bessel_i_prime(T1 v, T2 x); + + template + typename detail::bessel_traits::result_type cyl_bessel_k(T1 v, T2 x, const Policy& pol); + template + typename detail::bessel_traits::result_type cyl_bessel_k_prime(T1 v, T2 x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_bessel_k(T1 v, T2 x); + template + typename detail::bessel_traits >::result_type cyl_bessel_k_prime(T1 v, T2 x); + + template + typename detail::bessel_traits::result_type cyl_neumann(T1 v, T2 x, const Policy& pol); + template + typename detail::bessel_traits::result_type cyl_neumann_prime(T1 v, T2 x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_neumann(T1 v, T2 x); + template + typename detail::bessel_traits >::result_type cyl_neumann_prime(T1 v, T2 x); + + template + typename detail::bessel_traits::result_type sph_neumann(unsigned v, T x, const Policy& pol); + template + typename detail::bessel_traits::result_type sph_neumann_prime(unsigned v, T x, const Policy& pol); + + template + typename detail::bessel_traits >::result_type sph_neumann(unsigned v, T x); + template + typename detail::bessel_traits >::result_type sph_neumann_prime(unsigned v, T x); + + template + typename detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_bessel_j_zero(T v, int m); + + template + OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + + template + OutputIterator cyl_bessel_j_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + typename detail::bessel_traits::result_type cyl_neumann_zero(T v, int m, const Policy& pol); + + template + typename detail::bessel_traits >::result_type cyl_neumann_zero(T v, int m); + + template + OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + + template + OutputIterator cyl_neumann_zero(T v, + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + std::complex >::result_type> cyl_hankel_1(T1 v, T2 x); + + template + std::complex::result_type> cyl_hankel_1(T1 v, T2 x, const Policy& pol); + + template + std::complex::result_type> cyl_hankel_2(T1 v, T2 x, const Policy& pol); + + template + std::complex >::result_type> cyl_hankel_2(T1 v, T2 x); + + template + std::complex::result_type> sph_hankel_1(T1 v, T2 x, const Policy& pol); + + template + std::complex >::result_type> sph_hankel_1(T1 v, T2 x); + + template + std::complex::result_type> sph_hankel_2(T1 v, T2 x, const Policy& pol); + + template + std::complex >::result_type> sph_hankel_2(T1 v, T2 x); + + template + typename tools::promote_args::type airy_ai(T x, const Policy&); + + template + typename tools::promote_args::type airy_ai(T x); + + template + typename tools::promote_args::type airy_bi(T x, const Policy&); + + template + typename tools::promote_args::type airy_bi(T x); + + template + typename tools::promote_args::type airy_ai_prime(T x, const Policy&); + + template + typename tools::promote_args::type airy_ai_prime(T x); + + template + typename tools::promote_args::type airy_bi_prime(T x, const Policy&); + + template + typename tools::promote_args::type airy_bi_prime(T x); + + template + T airy_ai_zero(int m); + template + T airy_ai_zero(int m, const Policy&); + + template + OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + template + OutputIterator airy_ai_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + T airy_bi_zero(int m); + template + T airy_bi_zero(int m, const Policy&); + + template + OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it); + template + OutputIterator airy_bi_zero( + int start_index, + unsigned number_of_zeros, + OutputIterator out_it, + const Policy&); + + template + typename tools::promote_args::type sin_pi(T x, const Policy&); + + template + typename tools::promote_args::type sin_pi(T x); + + template + typename tools::promote_args::type cos_pi(T x, const Policy&); + + template + typename tools::promote_args::type cos_pi(T x); + + template + int fpclassify BOOST_NO_MACRO_EXPAND(T t); + + template + bool isfinite BOOST_NO_MACRO_EXPAND(T z); + + template + bool isinf BOOST_NO_MACRO_EXPAND(T t); + + template + bool isnan BOOST_NO_MACRO_EXPAND(T t); + + template + bool isnormal BOOST_NO_MACRO_EXPAND(T t); + + template + int signbit BOOST_NO_MACRO_EXPAND(T x); + + template + int sign BOOST_NO_MACRO_EXPAND(const T& z); + + template + typename tools::promote_args_permissive::type copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y); + + template + typename tools::promote_args_permissive::type changesign BOOST_NO_MACRO_EXPAND(const T& z); + + // Exponential integrals: + namespace detail{ + + template + struct expint_result + { + typedef typename std::conditional< + policies::is_policy::value, + typename tools::promote_args::type, + typename tools::promote_args::type + >::type type; + }; + + } // namespace detail + + template + typename tools::promote_args::type expint(unsigned n, T z, const Policy&); + + template + typename detail::expint_result::type expint(T const z, U const u); + + template + typename tools::promote_args::type expint(T z); + + // Zeta: + template + typename tools::promote_args::type zeta(T s, const Policy&); + + // Owen's T function: + template + typename tools::promote_args::type owens_t(T1 h, T2 a, const Policy& pol); + + template + typename tools::promote_args::type owens_t(T1 h, T2 a); + + // Jacobi Functions: + template + typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn, V* pdn, const Policy&); + + template + typename tools::promote_args::type jacobi_elliptic(T k, U theta, V* pcn = 0, V* pdn = 0); + + template + typename tools::promote_args::type jacobi_sn(U k, T theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_sn(U k, T theta); + + template + typename tools::promote_args::type jacobi_cn(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_cn(T k, U theta); + + template + typename tools::promote_args::type jacobi_dn(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_dn(T k, U theta); + + template + typename tools::promote_args::type jacobi_cd(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_cd(T k, U theta); + + template + typename tools::promote_args::type jacobi_dc(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_dc(T k, U theta); + + template + typename tools::promote_args::type jacobi_ns(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_ns(T k, U theta); + + template + typename tools::promote_args::type jacobi_sd(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_sd(T k, U theta); + + template + typename tools::promote_args::type jacobi_ds(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_ds(T k, U theta); + + template + typename tools::promote_args::type jacobi_nc(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_nc(T k, U theta); + + template + typename tools::promote_args::type jacobi_nd(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_nd(T k, U theta); + + template + typename tools::promote_args::type jacobi_sc(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_sc(T k, U theta); + + template + typename tools::promote_args::type jacobi_cs(T k, U theta, const Policy& pol); + + template + typename tools::promote_args::type jacobi_cs(T k, U theta); + + // Jacobi Theta Functions: + template + typename tools::promote_args::type jacobi_theta1(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta1(T z, U q); + + template + typename tools::promote_args::type jacobi_theta2(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta2(T z, U q); + + template + typename tools::promote_args::type jacobi_theta3(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta3(T z, U q); + + template + typename tools::promote_args::type jacobi_theta4(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta4(T z, U q); + + template + typename tools::promote_args::type jacobi_theta1tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta1tau(T z, U tau); + + template + typename tools::promote_args::type jacobi_theta2tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta2tau(T z, U tau); + + template + typename tools::promote_args::type jacobi_theta3tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta3tau(T z, U tau); + + template + typename tools::promote_args::type jacobi_theta4tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta4tau(T z, U tau); + + template + typename tools::promote_args::type jacobi_theta3m1(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta3m1(T z, U q); + + template + typename tools::promote_args::type jacobi_theta4m1(T z, U q, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta4m1(T z, U q); + + template + typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta3m1tau(T z, U tau); + + template + typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau, const Policy& pol); + + template + typename tools::promote_args::type jacobi_theta4m1tau(T z, U tau); + + + template + typename tools::promote_args::type zeta(T s); + + // pow: + template + BOOST_CXX14_CONSTEXPR typename tools::promote_args::type pow(T base, const Policy& policy); + + template + BOOST_CXX14_CONSTEXPR typename tools::promote_args::type pow(T base); + + // next: + template + typename tools::promote_args::type nextafter(const T&, const U&, const Policy&); + template + typename tools::promote_args::type nextafter(const T&, const U&); + template + typename tools::promote_args::type float_next(const T&, const Policy&); + template + typename tools::promote_args::type float_next(const T&); + template + typename tools::promote_args::type float_prior(const T&, const Policy&); + template + typename tools::promote_args::type float_prior(const T&); + template + typename tools::promote_args::type float_distance(const T&, const U&, const Policy&); + template + typename tools::promote_args::type float_distance(const T&, const U&); + template + typename tools::promote_args::type float_advance(T val, int distance, const Policy& pol); + template + typename tools::promote_args::type float_advance(const T& val, int distance); + + template + typename tools::promote_args::type ulp(const T& val, const Policy& pol); + template + typename tools::promote_args::type ulp(const T& val); + + template + typename tools::promote_args::type relative_difference(const T&, const U&); + template + typename tools::promote_args::type epsilon_difference(const T&, const U&); + + template + BOOST_MATH_CONSTEXPR_TABLE_FUNCTION T unchecked_bernoulli_b2n(const std::size_t n); + template + T bernoulli_b2n(const int i, const Policy &pol); + template + T bernoulli_b2n(const int i); + template + OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol); + template + OutputIterator bernoulli_b2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it); + template + T tangent_t2n(const int i, const Policy &pol); + template + T tangent_t2n(const int i); + template + OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it, + const Policy& pol); + template + OutputIterator tangent_t2n(const int start_index, + const unsigned number_of_bernoullis_b2n, + OutputIterator out_it); + + // Lambert W: + template + typename boost::math::tools::promote_args::type lambert_w0(T z, const Policy& pol); + template + typename boost::math::tools::promote_args::type lambert_w0(T z); + template + typename boost::math::tools::promote_args::type lambert_wm1(T z, const Policy& pol); + template + typename boost::math::tools::promote_args::type lambert_wm1(T z); + template + typename boost::math::tools::promote_args::type lambert_w0_prime(T z, const Policy& pol); + template + typename boost::math::tools::promote_args::type lambert_w0_prime(T z); + template + typename boost::math::tools::promote_args::type lambert_wm1_prime(T z, const Policy& pol); + template + typename boost::math::tools::promote_args::type lambert_wm1_prime(T z); + + // Hypergeometrics: + template typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z); + template typename tools::promote_args::type hypergeometric_1F0(T1 a, T2 z, const Policy&); + + template typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z); + template typename tools::promote_args::type hypergeometric_0F1(T1 b, T2 z, const Policy&); + + template typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z); + template typename tools::promote_args::type hypergeometric_2F0(T1 a1, T2 a2, T3 z, const Policy&); + + template typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z); + template typename tools::promote_args::type hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy&); + + + } // namespace math +} // namespace boost + +#define BOOST_MATH_DETAIL_LL_FUNC(Policy)\ + \ + template \ + inline T modf(const T& v, long long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + inline long long lltrunc(const T& v){ using boost::math::lltrunc; return lltrunc(v, Policy()); }\ + \ + template \ + inline long long llround(const T& v){ using boost::math::llround; return llround(v, Policy()); }\ + +# define BOOST_MATH_DETAIL_11_FUNC(Policy)\ + template \ + inline typename boost::math::tools::promote_args::type hypergeometric_1F1(const T& a, const U& b, const V& z)\ + { return boost::math::hypergeometric_1F1(a, b, z, Policy()); }\ + +#define BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)\ + \ + BOOST_MATH_DETAIL_LL_FUNC(Policy)\ + BOOST_MATH_DETAIL_11_FUNC(Policy)\ + \ + template \ + inline typename boost::math::tools::promote_args::type \ + beta(RT1 a, RT2 b) { return ::boost::math::beta(a, b, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + beta(RT1 a, RT2 b, A x){ return ::boost::math::beta(a, b, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + betac(RT1 a, RT2 b, RT3 x) { return ::boost::math::betac(a, b, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta(a, b, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibetac(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibetac(a, b, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta_inv(T1 a, T2 b, T3 p, T4* py){ return ::boost::math::ibeta_inv(a, b, p, py, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta_inv(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inv(a, b, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibetac_inv(T1 a, T2 b, T3 q, T4* py){ return ::boost::math::ibetac_inv(a, b, q, py, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta_inva(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_inva(a, b, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibetac_inva(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_inva(a, b, q, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta_invb(RT1 a, RT2 b, RT3 p){ return ::boost::math::ibeta_invb(a, b, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibetac_invb(T1 a, T2 b, T3 q){ return ::boost::math::ibetac_invb(a, b, q, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibetac_inv(RT1 a, RT2 b, RT3 q){ return ::boost::math::ibetac_inv(a, b, q, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ibeta_derivative(RT1 a, RT2 b, RT3 x){ return ::boost::math::ibeta_derivative(a, b, x, Policy()); }\ +\ + template T binomial_coefficient(unsigned n, unsigned k){ return ::boost::math::binomial_coefficient(n, k, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type erf(RT z) { return ::boost::math::erf(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type erfc(RT z){ return ::boost::math::erfc(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type erf_inv(RT z) { return ::boost::math::erf_inv(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type erfc_inv(RT z){ return ::boost::math::erfc_inv(z, Policy()); }\ +\ + using boost::math::legendre_next;\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + legendre_p(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + legendre_p_prime(int l, T x){ return ::boost::math::legendre_p(l, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + legendre_q(unsigned l, T x){ return ::boost::math::legendre_q(l, x, Policy()); }\ +\ + using ::boost::math::legendre_next;\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + legendre_p(int l, int m, T x){ return ::boost::math::legendre_p(l, m, x, Policy()); }\ +\ + using ::boost::math::laguerre_next;\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + laguerre(unsigned n, T x){ return ::boost::math::laguerre(n, x, Policy()); }\ +\ + template \ + inline typename boost::math::laguerre_result::type \ + laguerre(unsigned n, T1 m, T2 x) { return ::boost::math::laguerre(n, m, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + hermite(unsigned n, T x){ return ::boost::math::hermite(n, x, Policy()); }\ +\ + using boost::math::hermite_next;\ +\ + using boost::math::chebyshev_next;\ +\ + template\ + Real chebyshev_t(unsigned n, Real const & x){ return ::boost::math::chebyshev_t(n, x, Policy()); }\ +\ + template\ + Real chebyshev_u(unsigned n, Real const & x){ return ::boost::math::chebyshev_u(n, x, Policy()); }\ +\ + template\ + Real chebyshev_t_prime(unsigned n, Real const & x){ return ::boost::math::chebyshev_t_prime(n, x, Policy()); }\ +\ + using ::boost::math::chebyshev_clenshaw_recurrence;\ +\ + template \ + inline std::complex::type> \ + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic(n, m, theta, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi){ return ::boost::math::spherical_harmonic_r(n, m, theta, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi){ return boost::math::spherical_harmonic_i(n, m, theta, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol);\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ellint_rf(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rf(x, y, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ellint_rd(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rd(x, y, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ellint_rc(T1 x, T2 y){ return ::boost::math::ellint_rc(x, y, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ellint_rj(T1 x, T2 y, T3 z, T4 p){ return boost::math::ellint_rj(x, y, z, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + ellint_rg(T1 x, T2 y, T3 z){ return ::boost::math::ellint_rg(x, y, z, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type ellint_2(T k){ return boost::math::ellint_2(k, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_2(T1 k, T2 phi){ return boost::math::ellint_2(k, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_d(T k){ return boost::math::ellint_d(k, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_d(T1 k, T2 phi){ return boost::math::ellint_d(k, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type jacobi_zeta(T1 k, T2 phi){ return boost::math::jacobi_zeta(k, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type heuman_lambda(T1 k, T2 phi){ return boost::math::heuman_lambda(k, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_1(T k){ return boost::math::ellint_1(k, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_1(T1 k, T2 phi){ return boost::math::ellint_1(k, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_3(T1 k, T2 v, T3 phi){ return boost::math::ellint_3(k, v, phi, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type ellint_3(T1 k, T2 v){ return boost::math::ellint_3(k, v, Policy()); }\ +\ + using boost::math::max_factorial;\ + template \ + inline RT factorial(unsigned int i) { return boost::math::factorial(i, Policy()); }\ + using boost::math::unchecked_factorial;\ + template \ + inline RT double_factorial(unsigned i){ return boost::math::double_factorial(i, Policy()); }\ + template \ + inline typename boost::math::tools::promote_args::type falling_factorial(RT x, unsigned n){ return boost::math::falling_factorial(x, n, Policy()); }\ + template \ + inline typename boost::math::tools::promote_args::type rising_factorial(RT x, unsigned n){ return boost::math::rising_factorial(x, n, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma(RT z){ return boost::math::tgamma(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma1pm1(RT z){ return boost::math::tgamma1pm1(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma(RT1 a, RT2 z){ return boost::math::tgamma(a, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type lgamma(RT z, int* sign){ return boost::math::lgamma(z, sign, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type lgamma(RT x){ return boost::math::lgamma(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma_lower(RT1 a, RT2 z){ return boost::math::tgamma_lower(a, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_q(RT1 a, RT2 z){ return boost::math::gamma_q(a, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_p(RT1 a, RT2 z){ return boost::math::gamma_p(a, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma_delta_ratio(T1 z, T2 delta){ return boost::math::tgamma_delta_ratio(z, delta, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type tgamma_ratio(T1 a, T2 b) { return boost::math::tgamma_ratio(a, b, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_p_derivative(T1 a, T2 x){ return boost::math::gamma_p_derivative(a, x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_p_inv(T1 a, T2 p){ return boost::math::gamma_p_inv(a, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_p_inva(T1 a, T2 p){ return boost::math::gamma_p_inva(a, p, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_q_inv(T1 a, T2 q){ return boost::math::gamma_q_inv(a, q, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type gamma_q_inva(T1 a, T2 q){ return boost::math::gamma_q_inva(a, q, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type digamma(T x){ return boost::math::digamma(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type trigamma(T x){ return boost::math::trigamma(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type polygamma(int n, T x){ return boost::math::polygamma(n, x, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type \ + hypot(T1 x, T2 y){ return boost::math::hypot(x, y, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type cbrt(RT z){ return boost::math::cbrt(z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type log1p(T x){ return boost::math::log1p(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type log1pmx(T x){ return boost::math::log1pmx(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type expm1(T x){ return boost::math::expm1(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type \ + powm1(const T1 a, const T2 z){ return boost::math::powm1(a, z, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type sqrt1pm1(const T& val){ return boost::math::sqrt1pm1(val, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type sinc_pi(T x){ return boost::math::sinc_pi(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type sinhc_pi(T x){ return boost::math::sinhc_pi(x, Policy()); }\ +\ + template\ + inline typename boost::math::tools::promote_args::type asinh(const T x){ return boost::math::asinh(x, Policy()); }\ +\ + template\ + inline typename boost::math::tools::promote_args::type acosh(const T x){ return boost::math::acosh(x, Policy()); }\ +\ + template\ + inline typename boost::math::tools::promote_args::type atanh(const T x){ return boost::math::atanh(x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j(T1 v, T2 x)\ + { return boost::math::cyl_bessel_j(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j_prime(T1 v, T2 x)\ + { return boost::math::cyl_bessel_j_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type sph_bessel(unsigned v, T x)\ + { return boost::math::sph_bessel(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type sph_bessel_prime(unsigned v, T x)\ + { return boost::math::sph_bessel_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_i(T1 v, T2 x) { return boost::math::cyl_bessel_i(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_i_prime(T1 v, T2 x) { return boost::math::cyl_bessel_i_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_k(T1 v, T2 x) { return boost::math::cyl_bessel_k(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_bessel_k_prime(T1 v, T2 x) { return boost::math::cyl_bessel_k_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_neumann(T1 v, T2 x){ return boost::math::cyl_neumann(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + cyl_neumann_prime(T1 v, T2 x){ return boost::math::cyl_neumann_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + sph_neumann(unsigned v, T x){ return boost::math::sph_neumann(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type \ + sph_neumann_prime(unsigned v, T x){ return boost::math::sph_neumann_prime(v, x, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_bessel_j_zero(T v, int m)\ + { return boost::math::cyl_bessel_j_zero(v, m, Policy()); }\ +\ +template \ + inline void cyl_bessel_j_zero(T v,\ + int start_index,\ + unsigned number_of_zeros,\ + OutputIterator out_it)\ + { boost::math::cyl_bessel_j_zero(v, start_index, number_of_zeros, out_it, Policy()); }\ +\ + template \ + inline typename boost::math::detail::bessel_traits::result_type cyl_neumann_zero(T v, int m)\ + { return boost::math::cyl_neumann_zero(v, m, Policy()); }\ +\ +template \ + inline void cyl_neumann_zero(T v,\ + int start_index,\ + unsigned number_of_zeros,\ + OutputIterator out_it)\ + { boost::math::cyl_neumann_zero(v, start_index, number_of_zeros, out_it, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type sin_pi(T x){ return boost::math::sin_pi(x, Policy()); }\ +\ + template \ + inline typename boost::math::tools::promote_args::type cos_pi(T x){ return boost::math::cos_pi(x, Policy()); }\ +\ + using boost::math::fpclassify;\ + using boost::math::isfinite;\ + using boost::math::isinf;\ + using boost::math::isnan;\ + using boost::math::isnormal;\ + using boost::math::signbit;\ + using boost::math::sign;\ + using boost::math::copysign;\ + using boost::math::changesign;\ + \ + template \ + inline typename boost::math::tools::promote_args::type expint(T const& z, U const& u)\ + { return boost::math::expint(z, u, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type expint(T z){ return boost::math::expint(z, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type zeta(T s){ return boost::math::zeta(s, Policy()); }\ + \ + template \ + inline T round(const T& v){ using boost::math::round; return round(v, Policy()); }\ + \ + template \ + inline int iround(const T& v){ using boost::math::iround; return iround(v, Policy()); }\ + \ + template \ + inline long lround(const T& v){ using boost::math::lround; return lround(v, Policy()); }\ + \ + template \ + inline T trunc(const T& v){ using boost::math::trunc; return trunc(v, Policy()); }\ + \ + template \ + inline int itrunc(const T& v){ using boost::math::itrunc; return itrunc(v, Policy()); }\ + \ + template \ + inline long ltrunc(const T& v){ using boost::math::ltrunc; return ltrunc(v, Policy()); }\ + \ + template \ + inline T modf(const T& v, T* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + inline T modf(const T& v, int* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + inline T modf(const T& v, long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type pow(T v){ return boost::math::pow(v, Policy()); }\ + \ + template T nextafter(const T& a, const T& b){ return boost::math::nextafter(a, b, Policy()); }\ + template T float_next(const T& a){ return boost::math::float_next(a, Policy()); }\ + template T float_prior(const T& a){ return boost::math::float_prior(a, Policy()); }\ + template T float_distance(const T& a, const T& b){ return boost::math::float_distance(a, b, Policy()); }\ + template T ulp(const T& a){ return boost::math::ulp(a, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type owens_t(RT1 a, RT2 z){ return boost::math::owens_t(a, z, Policy()); }\ + \ + template \ + inline std::complex::result_type> cyl_hankel_1(T1 v, T2 x)\ + { return boost::math::cyl_hankel_1(v, x, Policy()); }\ + \ + template \ + inline std::complex::result_type> cyl_hankel_2(T1 v, T2 x)\ + { return boost::math::cyl_hankel_2(v, x, Policy()); }\ + \ + template \ + inline std::complex::result_type> sph_hankel_1(T1 v, T2 x)\ + { return boost::math::sph_hankel_1(v, x, Policy()); }\ + \ + template \ + inline std::complex::result_type> sph_hankel_2(T1 v, T2 x)\ + { return boost::math::sph_hankel_2(v, x, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_elliptic(T k, T theta, T* pcn, T* pdn)\ + { return boost::math::jacobi_elliptic(k, theta, pcn, pdn, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_sn(U k, T theta)\ + { return boost::math::jacobi_sn(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_cn(T k, U theta)\ + { return boost::math::jacobi_cn(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_dn(T k, U theta)\ + { return boost::math::jacobi_dn(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_cd(T k, U theta)\ + { return boost::math::jacobi_cd(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_dc(T k, U theta)\ + { return boost::math::jacobi_dc(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_ns(T k, U theta)\ + { return boost::math::jacobi_ns(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_sd(T k, U theta)\ + { return boost::math::jacobi_sd(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_ds(T k, U theta)\ + { return boost::math::jacobi_ds(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_nc(T k, U theta)\ + { return boost::math::jacobi_nc(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_nd(T k, U theta)\ + { return boost::math::jacobi_nd(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_sc(T k, U theta)\ + { return boost::math::jacobi_sc(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_cs(T k, U theta)\ + { return boost::math::jacobi_cs(k, theta, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta1(T z, U q)\ + { return boost::math::jacobi_theta1(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta2(T z, U q)\ + { return boost::math::jacobi_theta2(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta3(T z, U q)\ + { return boost::math::jacobi_theta3(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta4(T z, U q)\ + { return boost::math::jacobi_theta4(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta1tau(T z, U q)\ + { return boost::math::jacobi_theta1tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta2tau(T z, U q)\ + { return boost::math::jacobi_theta2tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta3tau(T z, U q)\ + { return boost::math::jacobi_theta3tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta4tau(T z, U q)\ + { return boost::math::jacobi_theta4tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta3m1(T z, U q)\ + { return boost::math::jacobi_theta3m1(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta4m1(T z, U q)\ + { return boost::math::jacobi_theta4m1(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta3m1tau(T z, U q)\ + { return boost::math::jacobi_theta3m1tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type jacobi_theta4m1tau(T z, U q)\ + { return boost::math::jacobi_theta4m1tau(z, q, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type airy_ai(T x)\ + { return boost::math::airy_ai(x, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type airy_bi(T x)\ + { return boost::math::airy_bi(x, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type airy_ai_prime(T x)\ + { return boost::math::airy_ai_prime(x, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type airy_bi_prime(T x)\ + { return boost::math::airy_bi_prime(x, Policy()); }\ + \ + template \ + inline T airy_ai_zero(int m)\ + { return boost::math::airy_ai_zero(m, Policy()); }\ + template \ + OutputIterator airy_ai_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\ + { return boost::math::airy_ai_zero(start_index, number_of_zeros, out_it, Policy()); }\ + \ + template \ + inline T airy_bi_zero(int m)\ + { return boost::math::airy_bi_zero(m, Policy()); }\ + template \ + OutputIterator airy_bi_zero(int start_index, unsigned number_of_zeros, OutputIterator out_it)\ + { return boost::math::airy_bi_zero(start_index, number_of_zeros, out_it, Policy()); }\ + \ + template \ + T bernoulli_b2n(const int i)\ + { return boost::math::bernoulli_b2n(i, Policy()); }\ + template \ + OutputIterator bernoulli_b2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\ + { return boost::math::bernoulli_b2n(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\ + \ + template \ + T tangent_t2n(const int i)\ + { return boost::math::tangent_t2n(i, Policy()); }\ + template \ + OutputIterator tangent_t2n(int start_index, unsigned number_of_bernoullis_b2n, OutputIterator out_it)\ + { return boost::math::tangent_t2n(start_index, number_of_bernoullis_b2n, out_it, Policy()); }\ + \ + template inline typename boost::math::tools::promote_args::type lambert_w0(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline typename boost::math::tools::promote_args::type lambert_wm1(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline typename boost::math::tools::promote_args::type lambert_w0_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + template inline typename boost::math::tools::promote_args::type lambert_wm1_prime(T z) { return boost::math::lambert_w0(z, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type hypergeometric_1F0(const T& a, const U& z)\ + { return boost::math::hypergeometric_1F0(a, z, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type hypergeometric_0F1(const T& a, const U& z)\ + { return boost::math::hypergeometric_0F1(a, z, Policy()); }\ + \ + template \ + inline typename boost::math::tools::promote_args::type hypergeometric_2F0(const T& a1, const U& a2, const V& z)\ + { return boost::math::hypergeometric_2F0(a1, a2, z, Policy()); }\ + \ + + + + + + +#endif // BOOST_MATH_SPECIAL_MATH_FWD_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/modf.hpp b/libcxx/src/third-party/boost/math/special_functions/modf.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/modf.hpp @@ -0,0 +1,69 @@ +// Copyright John Maddock 2007. +// 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_MODF_HPP +#define BOOST_MATH_MODF_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ + +template +inline T modf(const T& v, T* ipart, const Policy& pol) +{ + *ipart = trunc(v, pol); + return v - *ipart; +} +template +inline T modf(const T& v, T* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +inline T modf(const T& v, int* ipart, const Policy& pol) +{ + *ipart = itrunc(v, pol); + return v - *ipart; +} +template +inline T modf(const T& v, int* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +inline T modf(const T& v, long* ipart, const Policy& pol) +{ + *ipart = ltrunc(v, pol); + return v - *ipart; +} +template +inline T modf(const T& v, long* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +template +inline T modf(const T& v, long long* ipart, const Policy& pol) +{ + *ipart = lltrunc(v, pol); + return v - *ipart; +} +template +inline T modf(const T& v, long long* ipart) +{ + return modf(v, ipart, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_MODF_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/next.hpp b/libcxx/src/third-party/boost/math/special_functions/next.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/next.hpp @@ -0,0 +1,906 @@ +// (C) Copyright John Maddock 2008. +// 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_NEXT_HPP +#define BOOST_MATH_SPECIAL_NEXT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + + +#if !defined(_CRAYC) && !defined(__CUDACC__) && (!defined(__GNUC__) || (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ > 3))) +#if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(__SSE2__) +#include "xmmintrin.h" +#define BOOST_MATH_CHECK_SSE2 +#endif +#endif + +namespace boost{ namespace math{ + + namespace concepts { + + class real_concept; + class std_real_concept; + + } + +namespace detail{ + +template +struct has_hidden_guard_digits; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; +#ifdef BOOST_HAS_FLOAT128 +template <> +struct has_hidden_guard_digits<__float128> : public std::false_type {}; +#endif +template <> +struct has_hidden_guard_digits : public std::false_type {}; +template <> +struct has_hidden_guard_digits : public std::false_type {}; + +template +struct has_hidden_guard_digits_10 : public std::false_type {}; +template +struct has_hidden_guard_digits_10 : public std::integral_constant::digits10 != std::numeric_limits::max_digits10)> {}; + +template +struct has_hidden_guard_digits + : public has_hidden_guard_digits_10::is_specialized + && (std::numeric_limits::radix == 10) > +{}; + +template +inline const T& normalize_value(const T& val, const std::false_type&) { return val; } +template +inline T normalize_value(const T& val, const std::true_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + std::intmax_t shift = (std::intmax_t)std::numeric_limits::digits - (std::intmax_t)ilogb(val) - 1; + T result = scalbn(val, shift); + result = round(result); + return scalbn(result, -shift); +} + +template +inline T get_smallest_value(std::true_type const&) +{ + // + // numeric_limits lies about denorms being present - particularly + // when this can be turned on or off at runtime, as is the case + // when using the SSE2 registers in DAZ or FTZ mode. + // + static const T m = std::numeric_limits::denorm_min(); +#ifdef BOOST_MATH_CHECK_SSE2 + return (_mm_getcsr() & (_MM_FLUSH_ZERO_ON | 0x40)) ? tools::min_value() : m; +#else + return ((tools::min_value() / 2) == 0) ? tools::min_value() : m; +#endif +} + +template +inline T get_smallest_value(std::false_type const&) +{ + return tools::min_value(); +} + +template +inline T get_smallest_value() +{ +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1310) + return get_smallest_value(std::integral_constant::is_specialized && (std::numeric_limits::has_denorm == 1)>()); +#else + return get_smallest_value(std::integral_constant::is_specialized && (std::numeric_limits::has_denorm == std::denorm_present)>()); +#endif +} + +// +// Returns the smallest value that won't generate denorms when +// we calculate the value of the least-significant-bit: +// +template +T get_min_shift_value(); + +template +struct min_shift_initializer +{ + struct init + { + init() + { + do_init(); + } + static void do_init() + { + get_min_shift_value(); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename min_shift_initializer::init min_shift_initializer::initializer; + +template +inline T calc_min_shifted(const std::true_type&) +{ + BOOST_MATH_STD_USING + return ldexp(tools::min_value(), tools::digits() + 1); +} +template +inline T calc_min_shifted(const std::false_type&) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + return scalbn(tools::min_value(), std::numeric_limits::digits + 1); +} + + +template +inline T get_min_shift_value() +{ + static const T val = calc_min_shifted(std::integral_constant::is_specialized || std::numeric_limits::radix == 2>()); + min_shift_initializer::force_instantiate(); + + return val; +} + +template ::value> +struct exponent_type +{ + typedef int type; +}; + +template +struct exponent_type +{ + typedef typename T::backend_type::exponent_type type; +}; + +template +T float_next_imp(const T& val, const std::true_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_next<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + { + if(val < 0) + return -tools::max_value(); + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return ldexp(float_next(T(ldexp(val, 2 * tools::digits())), pol), -2 * tools::digits()); + } + + if(-0.5f == frexp(val, &expon)) + --expon; // reduce exponent when val is a power of two, and negative. + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return val + diff; +} // float_next_imp +// +// Special version for some base other than 2: +// +template +T float_next_imp(const T& val, const std::false_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_next<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + { + if(val < 0) + return -tools::max_value(); + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != -tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return scalbn(float_next(T(scalbn(val, 2 * std::numeric_limits::digits)), pol), -2 * std::numeric_limits::digits); + } + + expon = 1 + ilogb(val); + if(-1 == scalbn(val, -expon) * std::numeric_limits::radix) + --expon; // reduce exponent when val is a power of base, and negative. + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return val + diff; +} // float_next_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_next(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_next_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +#if 0 //def BOOST_MSVC +// +// We used to use ::_nextafter here, but doing so fails when using +// the SSE2 registers if the FTZ or DAZ flags are set, so use our own +// - albeit slower - code instead as at least that gives the correct answer. +// +template +inline double float_next(const double& val, const Policy& pol) +{ + static const char* function = "float_next<%1%>(%1%)"; + + if(!(boost::math::isfinite)(val) && (val > 0)) + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + + if(val >= tools::max_value()) + return policies::raise_overflow_error(function, nullptr, pol); + + return ::_nextafter(val, tools::max_value()); +} +#endif + +template +inline typename tools::promote_args::type float_next(const T& val) +{ + return float_next(val, policies::policy<>()); +} + +namespace detail{ + +template +T float_prior_imp(const T& val, const std::true_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_prior<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + { + if(val > 0) + return tools::max_value(); + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return -detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return ldexp(float_prior(T(ldexp(val, 2 * tools::digits())), pol), -2 * tools::digits()); + } + + T remain = frexp(val, &expon); + if(remain == 0.5f) + --expon; // when val is a power of two we must reduce the exponent + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return val - diff; +} // float_prior_imp +// +// Special version for bases other than 2: +// +template +T float_prior_imp(const T& val, const std::false_type&, const Policy& pol) +{ + typedef typename exponent_type::type exponent_type; + + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + exponent_type expon; + static const char* function = "float_prior<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + { + if(val > 0) + return tools::max_value(); + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + if(val == 0) + return -detail::get_smallest_value(); + + if((fpclass != (int)FP_SUBNORMAL) && (fpclass != (int)FP_ZERO) && (fabs(val) < detail::get_min_shift_value()) && (val != tools::min_value())) + { + // + // Special case: if the value of the least significant bit is a denorm, and the result + // would not be a denorm, then shift the input, increment, and shift back. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + return scalbn(float_prior(T(scalbn(val, 2 * std::numeric_limits::digits)), pol), -2 * std::numeric_limits::digits); + } + + expon = 1 + ilogb(val); + T remain = scalbn(val, -expon); + if(remain * std::numeric_limits::radix == 1) + --expon; // when val is a power of two we must reduce the exponent + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return val - diff; +} // float_prior_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_prior(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_prior_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +#if 0 //def BOOST_MSVC +// +// We used to use ::_nextafter here, but doing so fails when using +// the SSE2 registers if the FTZ or DAZ flags are set, so use our own +// - albeit slower - code instead as at least that gives the correct answer. +// +template +inline double float_prior(const double& val, const Policy& pol) +{ + static const char* function = "float_prior<%1%>(%1%)"; + + if(!(boost::math::isfinite)(val) && (val < 0)) + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + + if(val <= -tools::max_value()) + return -policies::raise_overflow_error(function, nullptr, pol); + + return ::_nextafter(val, -tools::max_value()); +} +#endif + +template +inline typename tools::promote_args::type float_prior(const T& val) +{ + return float_prior(val, policies::policy<>()); +} + +template +inline typename tools::promote_args::type nextafter(const T& val, const U& direction, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return val < direction ? boost::math::float_next(val, pol) : val == direction ? val : boost::math::float_prior(val, pol); +} + +template +inline typename tools::promote_args::type nextafter(const T& val, const U& direction) +{ + return nextafter(val, direction, policies::policy<>()); +} + +namespace detail{ + +template +T float_distance_imp(const T& a, const T& b, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_distance<%1%>(%1%, %1%)"; + if(!(boost::math::isfinite)(a)) + return policies::raise_domain_error( + function, + "Argument a must be finite, but got %1%", a, pol); + if(!(boost::math::isfinite)(b)) + return policies::raise_domain_error( + function, + "Argument b must be finite, but got %1%", b, pol); + // + // Special cases: + // + if(a > b) + return -float_distance(b, a, pol); + if(a == b) + return T(0); + if(a == 0) + return 1 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)); + if(b == 0) + return 1 + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + if(boost::math::sign(a) != boost::math::sign(b)) + return 2 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)) + + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + // + // By the time we get here, both a and b must have the same sign, we want + // b > a and both positive for the following logic: + // + if(a < 0) + return float_distance(static_cast(-b), static_cast(-a), pol); + + BOOST_MATH_ASSERT(a >= 0); + BOOST_MATH_ASSERT(b >= a); + + int expon; + // + // Note that if a is a denorm then the usual formula fails + // because we actually have fewer than tools::digits() + // significant bits in the representation: + // + (void)frexp(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value() : a, &expon); + T upper = ldexp(T(1), expon); + T result = T(0); + // + // If b is greater than upper, then we *must* split the calculation + // as the size of the ULP changes with each order of magnitude change: + // + if(b > upper) + { + int expon2; + (void)frexp(b, &expon2); + T upper2 = ldexp(T(0.5), expon2); + result = float_distance(upper2, b); + result += (expon2 - expon - 1) * ldexp(T(1), tools::digits() - 1); + } + // + // Use compensated double-double addition to avoid rounding + // errors in the subtraction: + // + expon = tools::digits() - expon; + T mb, x, y, z; + if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value())) + { + // + // Special case - either one end of the range is a denormal, or else the difference is. + // The regular code will fail if we're using the SSE2 registers on Intel and either + // the FTZ or DAZ flags are set. + // + T a2 = ldexp(a, tools::digits()); + T b2 = ldexp(b, tools::digits()); + mb = -(std::min)(T(ldexp(upper, tools::digits())), b2); + x = a2 + mb; + z = x - a2; + y = (a2 - (x - z)) + (mb - z); + + expon -= tools::digits(); + } + else + { + mb = -(std::min)(upper, b); + x = a + mb; + z = x - a; + y = (a - (x - z)) + (mb - z); + } + if(x < 0) + { + x = -x; + y = -y; + } + result += ldexp(x, expon) + ldexp(y, expon); + // + // Result must be an integer: + // + BOOST_MATH_ASSERT(result == floor(result)); + return result; +} // float_distance_imp +// +// Special versions for bases other than 2: +// +template +T float_distance_imp(const T& a, const T& b, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_distance<%1%>(%1%, %1%)"; + if(!(boost::math::isfinite)(a)) + return policies::raise_domain_error( + function, + "Argument a must be finite, but got %1%", a, pol); + if(!(boost::math::isfinite)(b)) + return policies::raise_domain_error( + function, + "Argument b must be finite, but got %1%", b, pol); + // + // Special cases: + // + if(a > b) + return -float_distance(b, a, pol); + if(a == b) + return T(0); + if(a == 0) + return 1 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)); + if(b == 0) + return 1 + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + if(boost::math::sign(a) != boost::math::sign(b)) + return 2 + fabs(float_distance(static_cast((b < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), b, pol)) + + fabs(float_distance(static_cast((a < 0) ? T(-detail::get_smallest_value()) : detail::get_smallest_value()), a, pol)); + // + // By the time we get here, both a and b must have the same sign, we want + // b > a and both positive for the following logic: + // + if(a < 0) + return float_distance(static_cast(-b), static_cast(-a), pol); + + BOOST_MATH_ASSERT(a >= 0); + BOOST_MATH_ASSERT(b >= a); + + std::intmax_t expon; + // + // Note that if a is a denorm then the usual formula fails + // because we actually have fewer than tools::digits() + // significant bits in the representation: + // + expon = 1 + ilogb(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) ? tools::min_value() : a); + T upper = scalbn(T(1), expon); + T result = T(0); + // + // If b is greater than upper, then we *must* split the calculation + // as the size of the ULP changes with each order of magnitude change: + // + if(b > upper) + { + std::intmax_t expon2 = 1 + ilogb(b); + T upper2 = scalbn(T(1), expon2 - 1); + result = float_distance(upper2, b); + result += (expon2 - expon - 1) * scalbn(T(1), std::numeric_limits::digits - 1); + } + // + // Use compensated double-double addition to avoid rounding + // errors in the subtraction: + // + expon = std::numeric_limits::digits - expon; + T mb, x, y, z; + if(((boost::math::fpclassify)(a) == (int)FP_SUBNORMAL) || (b - a < tools::min_value())) + { + // + // Special case - either one end of the range is a denormal, or else the difference is. + // The regular code will fail if we're using the SSE2 registers on Intel and either + // the FTZ or DAZ flags are set. + // + T a2 = scalbn(a, std::numeric_limits::digits); + T b2 = scalbn(b, std::numeric_limits::digits); + mb = -(std::min)(T(scalbn(upper, std::numeric_limits::digits)), b2); + x = a2 + mb; + z = x - a2; + y = (a2 - (x - z)) + (mb - z); + + expon -= std::numeric_limits::digits; + } + else + { + mb = -(std::min)(upper, b); + x = a + mb; + z = x - a; + y = (a - (x - z)) + (mb - z); + } + if(x < 0) + { + x = -x; + y = -y; + } + result += scalbn(x, expon) + scalbn(y, expon); + // + // Result must be an integer: + // + BOOST_MATH_ASSERT(result == floor(result)); + return result; +} // float_distance_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_distance(const T& a, const U& b, const Policy& pol) +{ + // + // We allow ONE of a and b to be an integer type, otherwise both must be the SAME type. + // + static_assert( + (std::is_same::value + || (std::is_integral::value && !std::is_integral::value) + || (!std::is_integral::value && std::is_integral::value) + || (std::numeric_limits::is_specialized && std::numeric_limits::is_specialized + && (std::numeric_limits::digits == std::numeric_limits::digits) + && (std::numeric_limits::radix == std::numeric_limits::radix) + && !std::numeric_limits::is_integer && !std::numeric_limits::is_integer)), + "Float distance between two different floating point types is undefined."); + + BOOST_IF_CONSTEXPR (!std::is_same::value) + { + BOOST_IF_CONSTEXPR(std::is_integral::value) + { + return float_distance(static_cast(a), b, pol); + } + else + { + return float_distance(a, static_cast(b), pol); + } + } + else + { + typedef typename tools::promote_args::type result_type; + return detail::float_distance_imp(detail::normalize_value(static_cast(a), typename detail::has_hidden_guard_digits::type()), detail::normalize_value(static_cast(b), typename detail::has_hidden_guard_digits::type()), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); + } +} + +template +typename tools::promote_args::type float_distance(const T& a, const U& b) +{ + return boost::math::float_distance(a, b, policies::policy<>()); +} + +namespace detail{ + +template +T float_advance_imp(T val, int distance, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_advance<%1%>(%1%, int)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + return policies::raise_domain_error( + function, + "Argument val must be finite, but got %1%", val, pol); + + if(val < 0) + return -float_advance(-val, -distance, pol); + if(distance == 0) + return val; + if(distance == 1) + return float_next(val, pol); + if(distance == -1) + return float_prior(val, pol); + + if(fabs(val) < detail::get_min_shift_value()) + { + // + // Special case: if the value of the least significant bit is a denorm, + // implement in terms of float_next/float_prior. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + if(distance > 0) + { + do{ val = float_next(val, pol); } while(--distance); + } + else + { + do{ val = float_prior(val, pol); } while(++distance); + } + return val; + } + + int expon; + (void)frexp(val, &expon); + T limit = ldexp((distance < 0 ? T(0.5f) : T(1)), expon); + if(val <= tools::min_value()) + { + limit = sign(T(distance)) * tools::min_value(); + } + T limit_distance = float_distance(val, limit); + while(fabs(limit_distance) < abs(distance)) + { + distance -= itrunc(limit_distance); + val = limit; + if(distance < 0) + { + limit /= 2; + expon--; + } + else + { + limit *= 2; + expon++; + } + limit_distance = float_distance(val, limit); + if(distance && (limit_distance == 0)) + { + return policies::raise_evaluation_error(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); + } + } + if((0.5f == frexp(val, &expon)) && (distance < 0)) + --expon; + T diff = 0; + if(val != 0) + diff = distance * ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = distance * detail::get_smallest_value(); + return val += diff; +} // float_advance_imp +// +// Special version for bases other than 2: +// +template +T float_advance_imp(T val, int distance, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + + BOOST_MATH_STD_USING + // + // Error handling: + // + static const char* function = "float_advance<%1%>(%1%, int)"; + + int fpclass = (boost::math::fpclassify)(val); + + if((fpclass == (int)FP_NAN) || (fpclass == (int)FP_INFINITE)) + return policies::raise_domain_error( + function, + "Argument val must be finite, but got %1%", val, pol); + + if(val < 0) + return -float_advance(-val, -distance, pol); + if(distance == 0) + return val; + if(distance == 1) + return float_next(val, pol); + if(distance == -1) + return float_prior(val, pol); + + if(fabs(val) < detail::get_min_shift_value()) + { + // + // Special case: if the value of the least significant bit is a denorm, + // implement in terms of float_next/float_prior. + // This avoids issues with the Intel SSE2 registers when the FTZ or DAZ flags are set. + // + if(distance > 0) + { + do{ val = float_next(val, pol); } while(--distance); + } + else + { + do{ val = float_prior(val, pol); } while(++distance); + } + return val; + } + + std::intmax_t expon = 1 + ilogb(val); + T limit = scalbn(T(1), distance < 0 ? expon - 1 : expon); + if(val <= tools::min_value()) + { + limit = sign(T(distance)) * tools::min_value(); + } + T limit_distance = float_distance(val, limit); + while(fabs(limit_distance) < abs(distance)) + { + distance -= itrunc(limit_distance); + val = limit; + if(distance < 0) + { + limit /= std::numeric_limits::radix; + expon--; + } + else + { + limit *= std::numeric_limits::radix; + expon++; + } + limit_distance = float_distance(val, limit); + if(distance && (limit_distance == 0)) + { + return policies::raise_evaluation_error(function, "Internal logic failed while trying to increment floating point value %1%: most likely your FPU is in non-IEEE conforming mode.", val, pol); + } + } + /*expon = 1 + ilogb(val); + if((1 == scalbn(val, 1 + expon)) && (distance < 0)) + --expon;*/ + T diff = 0; + if(val != 0) + diff = distance * scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = distance * detail::get_smallest_value(); + return val += diff; +} // float_advance_imp + +} // namespace detail + +template +inline typename tools::promote_args::type float_advance(T val, int distance, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::float_advance_imp(detail::normalize_value(static_cast(val), typename detail::has_hidden_guard_digits::type()), distance, std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +template +inline typename tools::promote_args::type float_advance(const T& val, int distance) +{ + return boost::math::float_advance(val, distance, policies::policy<>()); +} + +}} // boost math namespaces + +#endif // BOOST_MATH_SPECIAL_NEXT_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/nonfinite_num_facets.hpp b/libcxx/src/third-party/boost/math/special_functions/nonfinite_num_facets.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/nonfinite_num_facets.hpp @@ -0,0 +1,590 @@ +#ifndef BOOST_MATH_NONFINITE_NUM_FACETS_HPP +#define BOOST_MATH_NONFINITE_NUM_FACETS_HPP + +// Copyright 2006 Johan Rade +// Copyright 2012 K R Walker +// Copyright 2011, 2012 Paul A. Bristow + +// Distributed under 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) + +/* +\file + +\brief non_finite_num facets for C99 standard output of infinity and NaN. + +\details See fuller documentation at Boost.Math Facets + for Floating-Point Infinities and NaNs. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4127) // conditional expression is constant. +# pragma warning(disable : 4706) // assignment within conditional expression. +#endif + +namespace boost { + namespace math { + + // flags (enums can be ORed together) ----------------------------------- + + const int legacy = 0x1; //!< get facet will recognize most string representations of infinity and NaN. + const int signed_zero = 0x2; //!< put facet will distinguish between positive and negative zero. + const int trap_infinity = 0x4; /*!< put facet will throw an exception of type std::ios_base::failure + when an attempt is made to format positive or negative infinity. + get will set the fail bit of the stream when an attempt is made + to parse a string that represents positive or negative sign infinity. + */ + const int trap_nan = 0x8; /*!< put facet will throw an exception of type std::ios_base::failure + when an attempt is made to format positive or negative NaN. + get will set the fail bit of the stream when an attempt is made + to parse a string that represents positive or negative sign infinity. + */ + + // class nonfinite_num_put ----------------------------------------------------- + + template< + class CharType, + class OutputIterator = std::ostreambuf_iterator + > + class nonfinite_num_put : public std::num_put + { + public: + explicit nonfinite_num_put(int flags = 0) : flags_(flags) {} + + protected: + virtual OutputIterator do_put( + OutputIterator it, std::ios_base& iosb, CharType fill, double val) const + { + put_and_reset_width(it, iosb, fill, val); + return it; + } + + virtual OutputIterator do_put( + OutputIterator it, std::ios_base& iosb, CharType fill, long double val) const + { + put_and_reset_width(it, iosb, fill, val); + return it; + } + + private: + template void put_and_reset_width( + OutputIterator& it, std::ios_base& iosb, + CharType fill, ValType val) const + { + put_impl(it, iosb, fill, val); + iosb.width(0); + } + + template void put_impl( + OutputIterator& it, std::ios_base& iosb, + CharType fill, ValType val) const + { + static const CharType prefix_plus[2] = { '+', '\0' }; + static const CharType prefix_minus[2] = { '-', '\0' }; + static const CharType body_inf[4] = { 'i', 'n', 'f', '\0' }; + static const CharType body_nan[4] = { 'n', 'a', 'n', '\0' }; + static const CharType* null_string = 0; + + switch((boost::math::fpclassify)(val)) + { + + case FP_INFINITE: + if(flags_ & trap_infinity) + { + BOOST_MATH_THROW_EXCEPTION(std::ios_base::failure("Infinity")); + } + else if((boost::math::signbit)(val)) + { // negative infinity. + put_num_and_fill(it, iosb, prefix_minus, body_inf, fill, val); + } + else if(iosb.flags() & std::ios_base::showpos) + { // Explicit "+inf" wanted. + put_num_and_fill(it, iosb, prefix_plus, body_inf, fill, val); + } + else + { // just "inf" wanted. + put_num_and_fill(it, iosb, null_string, body_inf, fill, val); + } + break; + + case FP_NAN: + if(flags_ & trap_nan) + { + BOOST_MATH_THROW_EXCEPTION(std::ios_base::failure("NaN")); + } + else if((boost::math::signbit)(val)) + { // negative so "-nan". + put_num_and_fill(it, iosb, prefix_minus, body_nan, fill, val); + } + else if(iosb.flags() & std::ios_base::showpos) + { // explicit "+nan" wanted. + put_num_and_fill(it, iosb, prefix_plus, body_nan, fill, val); + } + else + { // Just "nan". + put_num_and_fill(it, iosb, null_string, body_nan, fill, val); + } + break; + + case FP_ZERO: + if((flags_ & signed_zero) && ((boost::math::signbit)(val))) + { // Flag set to distinguish between positive and negative zero. + // But string "0" should have stuff after decimal point if setprecision and/or exp format. + + std::basic_ostringstream zeros; // Needs to be CharType version. + + // Copy flags, fill, width and precision. + zeros.flags(iosb.flags()); + zeros.unsetf(std::ios::showpos); // Ignore showpos because must be negative. + zeros.precision(iosb.precision()); + //zeros.width is set by put_num_and_fill + zeros.fill(static_cast(fill)); + zeros << ValType(0); + put_num_and_fill(it, iosb, prefix_minus, zeros.str().c_str(), fill, val); + } + else + { // Output the platform default for positive and negative zero. + put_num_and_fill(it, iosb, null_string, null_string, fill, val); + } + break; + + default: // Normal non-zero finite value. + it = std::num_put::do_put(it, iosb, fill, val); + break; + } + } + + template + void put_num_and_fill( + OutputIterator& it, std::ios_base& iosb, const CharType* prefix, + const CharType* body, CharType fill, ValType val) const + { + int prefix_length = prefix ? (int)std::char_traits::length(prefix) : 0; + int body_length = body ? (int)std::char_traits::length(body) : 0; + int width = prefix_length + body_length; + std::ios_base::fmtflags adjust = iosb.flags() & std::ios_base::adjustfield; + const std::ctype& ct + = std::use_facet >(iosb.getloc()); + + if(body || prefix) + { // adjust == std::ios_base::right, so leading fill needed. + if(adjust != std::ios_base::internal && adjust != std::ios_base::left) + put_fill(it, iosb, fill, width); + } + + if(prefix) + { // Adjust width for prefix. + while(*prefix) + *it = *(prefix++); + iosb.width( iosb.width() - prefix_length ); + width -= prefix_length; + } + + if(body) + { // + if(adjust == std::ios_base::internal) + { // Put fill between sign and digits. + put_fill(it, iosb, fill, width); + } + if(iosb.flags() & std::ios_base::uppercase) + { + while(*body) + *it = ct.toupper(*(body++)); + } + else + { + while(*body) + *it = *(body++); + } + + if(adjust == std::ios_base::left) + put_fill(it, iosb, fill, width); + } + else + { + it = std::num_put::do_put(it, iosb, fill, val); + } + } + + void put_fill( + OutputIterator& it, std::ios_base& iosb, CharType fill, int width) const + { // Insert fill chars. + for(std::streamsize i = iosb.width() - static_cast(width); i > 0; --i) + *it = fill; + } + + private: + const int flags_; + }; + + + // class nonfinite_num_get ------------------------------------------------------ + + template< + class CharType, + class InputIterator = std::istreambuf_iterator + > + class nonfinite_num_get : public std::num_get + { + + public: + explicit nonfinite_num_get(int flags = 0) : flags_(flags) + {} + + protected: // float, double and long double versions of do_get. + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, float& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, double& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + virtual InputIterator do_get( + InputIterator it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, long double& val) const + { + get_and_check_eof(it, end, iosb, state, val); + return it; + } + + //.............................................................................. + + private: + template static ValType positive_nan() + { + // On some platforms quiet_NaN() may be negative. + return (boost::math::copysign)( + std::numeric_limits::quiet_NaN(), static_cast(1) + ); + // static_cast(1) added Paul A. Bristow 5 Apr 11 + } + + template void get_and_check_eof + ( + InputIterator& it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, ValType& val + ) const + { + get_signed(it, end, iosb, state, val); + if(it == end) + state |= std::ios_base::eofbit; + } + + template void get_signed + ( + InputIterator& it, InputIterator end, std::ios_base& iosb, + std::ios_base::iostate& state, ValType& val + ) const + { + const std::ctype& ct + = std::use_facet >(iosb.getloc()); + + char c = peek_char(it, end, ct); + + bool negative = (c == '-'); + + if(negative || c == '+') + { + ++it; + c = peek_char(it, end, ct); + if(c == '-' || c == '+') + { // Without this check, "++5" etc would be accepted. + state |= std::ios_base::failbit; + return; + } + } + + get_unsigned(it, end, iosb, ct, state, val); + + if(negative) + { + val = (boost::math::changesign)(val); + } + } // void get_signed + + template void get_unsigned + ( //! Get an unsigned floating-point value into val, + //! but checking for letters indicating non-finites. + InputIterator& it, InputIterator end, std::ios_base& iosb, + const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + switch(peek_char(it, end, ct)) + { + case 'i': + get_i(it, end, ct, state, val); + break; + + case 'n': + get_n(it, end, ct, state, val); + break; + + case 'q': + case 's': + get_q(it, end, ct, state, val); + break; + + default: // Got a normal floating-point value into val. + it = std::num_get::do_get( + it, end, iosb, state, val); + if((flags_ & legacy) && val == static_cast(1) + && peek_char(it, end, ct) == '#') + get_one_hash(it, end, ct, state, val); + break; + } + } // get_unsigned + + //.......................................................................... + + template void get_i + ( // Get the rest of all strings starting with 'i', expect "inf", "infinity". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_infinity + || (flags_ & trap_infinity)) + { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "nf")) + { + state |= std::ios_base::failbit; + return; + } + + if(peek_char(it, end, ct) != 'i') + { + val = std::numeric_limits::infinity(); // "inf" + return; + } + + ++it; + if(!match_string(it, end, ct, "nity")) + { // Expected "infinity" + state |= std::ios_base::failbit; + return; + } + + val = std::numeric_limits::infinity(); // "infinity" + } // void get_i + + template void get_n + ( // Get expected strings after 'n', "nan", "nanq", "nans", "nan(...)" + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_quiet_NaN + || (flags_ & trap_nan)) { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "an")) + { + state |= std::ios_base::failbit; + return; + } + + switch(peek_char(it, end, ct)) { + case 'q': + case 's': + if(flags_ & legacy) + ++it; + break; // "nanq", "nans" + + case '(': // Optional payload field in (...) follows. + { + ++it; + char c; + while((c = peek_char(it, end, ct)) + && c != ')' && c != ' ' && c != '\n' && c != '\t') + ++it; + if(c != ')') + { // Optional payload field terminator missing! + state |= std::ios_base::failbit; + return; + } + ++it; + break; // "nan(...)" + } + + default: + break; // "nan" + } + + val = positive_nan(); + } // void get_n + + template void get_q + ( // Get expected rest of string starting with 'q': "qnan". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + if(!std::numeric_limits::has_quiet_NaN + || (flags_ & trap_nan) || !(flags_ & legacy)) + { + state |= std::ios_base::failbit; + return; + } + + ++it; + if(!match_string(it, end, ct, "nan")) + { + state |= std::ios_base::failbit; + return; + } + + val = positive_nan(); // "QNAN" + } // void get_q + + template void get_one_hash + ( // Get expected string after having read "1.#": "1.#IND", "1.#QNAN", "1.#SNAN". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + + ++it; + switch(peek_char(it, end, ct)) + { + case 'i': // from IND (indeterminate), considered same a QNAN. + get_one_hash_i(it, end, ct, state, val); // "1.#IND" + return; + + case 'q': // from QNAN + case 's': // from SNAN - treated the same as QNAN. + if(std::numeric_limits::has_quiet_NaN + && !(flags_ & trap_nan)) + { + ++it; + if(match_string(it, end, ct, "nan")) + { // "1.#QNAN", "1.#SNAN" + // ++it; // removed as caused assert() cannot increment iterator). +// (match_string consumes string, so not needed?). +// https://svn.boost.org/trac/boost/ticket/5467 +// Change in nonfinite_num_facet.hpp Paul A. Bristow 11 Apr 11 makes legacy_test.cpp work OK. + val = positive_nan(); // "1.#QNAN" + return; + } + } + break; + + default: + break; + } + + state |= std::ios_base::failbit; + } // void get_one_hash + + template void get_one_hash_i + ( // Get expected strings after 'i', "1.#INF", 1.#IND". + InputIterator& it, InputIterator end, const std::ctype& ct, + std::ios_base::iostate& state, ValType& val + ) const + { + ++it; + + if(peek_char(it, end, ct) == 'n') + { + ++it; + switch(peek_char(it, end, ct)) + { + case 'f': // "1.#INF" + if(std::numeric_limits::has_infinity + && !(flags_ & trap_infinity)) + { + ++it; + val = std::numeric_limits::infinity(); + return; + } + break; + + case 'd': // 1.#IND" + if(std::numeric_limits::has_quiet_NaN + && !(flags_ & trap_nan)) + { + ++it; + val = positive_nan(); + return; + } + break; + + default: + break; + } + } + + state |= std::ios_base::failbit; + } // void get_one_hash_i + + //.......................................................................... + + char peek_char + ( //! \return next char in the input buffer, ensuring lowercase (but do not 'consume' char). + InputIterator& it, InputIterator end, + const std::ctype& ct + ) const + { + if(it == end) return 0; + return ct.narrow(ct.tolower(*it), 0); // Always tolower to ensure case insensitive. + } + + bool match_string + ( //! Match remaining chars to expected string (case insensitive), + //! consuming chars that match OK. + //! \return true if matched expected string, else false. + InputIterator& it, InputIterator end, + const std::ctype& ct, + const char* s + ) const + { + while(it != end && *s && *s == ct.narrow(ct.tolower(*it), 0)) + { + ++s; + ++it; // + } + return !*s; + } // bool match_string + + private: + const int flags_; + }; // + + //------------------------------------------------------------------------------ + + } // namespace math +} // namespace boost + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +#endif // BOOST_MATH_NONFINITE_NUM_FACETS_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/owens_t.hpp b/libcxx/src/third-party/boost/math/special_functions/owens_t.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/owens_t.hpp @@ -0,0 +1,1090 @@ +// Copyright Benjamin Sobotta 2012 + +// 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_OWENS_T_HPP +#define BOOST_OWENS_T_HPP + +// Reference: +// Mike Patefield, David Tandy +// FAST AND ACCURATE CALCULATION OF OWEN'S T-FUNCTION +// Journal of Statistical Software, 5 (5), 1-25 + +#ifdef _MSC_VER +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4127) +#endif + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost +{ + namespace math + { + namespace detail + { + // owens_t_znorm1(x) = P(-oo + inline RealType owens_t_znorm1(const RealType x, const Policy& pol) + { + using namespace boost::math::constants; + return boost::math::erf(x*one_div_root_two(), pol)*half(); + } // RealType owens_t_znorm1(const RealType x) + + // owens_t_znorm2(x) = P(x<=Z + inline RealType owens_t_znorm2(const RealType x, const Policy& pol) + { + using namespace boost::math::constants; + return boost::math::erfc(x*one_div_root_two(), pol)*half(); + } // RealType owens_t_znorm2(const RealType x) + + // Auxiliary function, it computes an array key that is used to determine + // the specific computation method for Owen's T and the order thereof + // used in owens_t_dispatch. + template + inline unsigned short owens_t_compute_code(const RealType h, const RealType a) + { + static const RealType hrange[] = + { 0.02f, 0.06f, 0.09f, 0.125f, 0.26f, 0.4f, 0.6f, 1.6f, 1.7f, 2.33f, 2.4f, 3.36f, 3.4f, 4.8f }; + + static const RealType arange[] = { 0.025f, 0.09f, 0.15f, 0.36f, 0.5f, 0.9f, 0.99999f }; + /* + original select array from paper: + 1, 1, 2,13,13,13,13,13,13,13,13,16,16,16, 9 + 1, 2, 2, 3, 3, 5, 5,14,14,15,15,16,16,16, 9 + 2, 2, 3, 3, 3, 5, 5,15,15,15,15,16,16,16,10 + 2, 2, 3, 5, 5, 5, 5, 7, 7,16,16,16,16,16,10 + 2, 3, 3, 5, 5, 6, 6, 8, 8,17,17,17,12,12,11 + 2, 3, 5, 5, 5, 6, 6, 8, 8,17,17,17,12,12,12 + 2, 3, 4, 4, 6, 6, 8, 8,17,17,17,17,17,12,12 + 2, 3, 4, 4, 6, 6,18,18,18,18,17,17,17,12,12 + */ + // subtract one because the array is written in FORTRAN in mind - in C arrays start @ zero + static const unsigned short select[] = + { + 0, 0 , 1 , 12 ,12 , 12 , 12 , 12 , 12 , 12 , 12 , 15 , 15 , 15 , 8, + 0 , 1 , 1 , 2 , 2 , 4 , 4 , 13 , 13 , 14 , 14 , 15 , 15 , 15 , 8, + 1 , 1 , 2 , 2 , 2 , 4 , 4 , 14 , 14 , 14 , 14 , 15 , 15 , 15 , 9, + 1 , 1 , 2 , 4 , 4 , 4 , 4 , 6 , 6 , 15 , 15 , 15 , 15 , 15 , 9, + 1 , 2 , 2 , 4 , 4 , 5 , 5 , 7 , 7 , 16 ,16 , 16 , 11 , 11 , 10, + 1 , 2 , 4 , 4 , 4 , 5 , 5 , 7 , 7 , 16 , 16 , 16 , 11 , 11 , 11, + 1 , 2 , 3 , 3 , 5 , 5 , 7 , 7 , 16 , 16 , 16 , 16 , 16 , 11 , 11, + 1 , 2 , 3 , 3 , 5 , 5 , 17 , 17 , 17 , 17 , 16 , 16 , 16 , 11 , 11 + }; + + unsigned short ihint = 14, iaint = 7; + for(unsigned short i = 0; i != 14; i++) + { + if( h <= hrange[i] ) + { + ihint = i; + break; + } + } // for(unsigned short i = 0; i != 14; i++) + + for(unsigned short i = 0; i != 7; i++) + { + if( a <= arange[i] ) + { + iaint = i; + break; + } + } // for(unsigned short i = 0; i != 7; i++) + + // interpret select array as 8x15 matrix + return select[iaint*15 + ihint]; + + } // unsigned short owens_t_compute_code(const RealType h, const RealType a) + + template + inline unsigned short owens_t_get_order_imp(const unsigned short icode, RealType, const std::integral_constant&) + { + static const unsigned short ord[] = {2, 3, 4, 5, 7, 10, 12, 18, 10, 20, 30, 0, 4, 7, 8, 20, 0, 0}; // 18 entries + + BOOST_MATH_ASSERT(icode<18); + + return ord[icode]; + } // unsigned short owens_t_get_order(const unsigned short icode, RealType, std::integral_constant const&) + + template + inline unsigned short owens_t_get_order_imp(const unsigned short icode, RealType, const std::integral_constant&) + { + // method ================>>> {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5, 6} + static const unsigned short ord[] = {3, 4, 5, 6, 8, 11, 13, 19, 10, 20, 30, 0, 7, 10, 11, 23, 0, 0}; // 18 entries + + BOOST_MATH_ASSERT(icode<18); + + return ord[icode]; + } // unsigned short owens_t_get_order(const unsigned short icode, RealType, std::integral_constant const&) + + template + inline unsigned short owens_t_get_order(const unsigned short icode, RealType r, const Policy&) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_get_order_imp(icode, r, tag_type()); + } + + // compute the value of Owen's T function with method T1 from the reference paper + template + inline RealType owens_t_T1(const RealType h, const RealType a, const unsigned short m, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType hs = -h*h*half(); + const RealType dhs = exp( hs ); + const RealType as = a*a; + + unsigned short j=1; + RealType jj = 1; + RealType aj = a * one_div_two_pi(); + RealType dj = boost::math::expm1( hs, pol); + RealType gj = hs*dhs; + + RealType val = atan( a ) * one_div_two_pi(); + + while( true ) + { + val += dj*aj/jj; + + if( m <= j ) + break; + + j++; + jj += static_cast(2); + aj *= as; + dj = gj - dj; + gj *= hs / static_cast(j); + } // while( true ) + + return val; + } // RealType owens_t_T1(const RealType h, const RealType a, const unsigned short m) + + // compute the value of Owen's T function with method T2 from the reference paper + template + inline RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah, const Policy& pol, const std::false_type&) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType z = owens_t_znorm1(ah, pol)/h; + + while( true ) + { + val += z; + if( maxii <= ii ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( maxii <= ii ) + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + + return val; + } // RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah) + + // compute the value of Owen's T function with method T3 from the reference paper + template + inline RealType owens_t_T3_imp(const RealType h, const RealType a, const RealType ah, const std::integral_constant&, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short m = 20; + + static const RealType c2[] = + { + static_cast(0.99999999999999987510), + static_cast(-0.99999999999988796462), static_cast(0.99999999998290743652), + static_cast(-0.99999999896282500134), static_cast(0.99999996660459362918), + static_cast(-0.99999933986272476760), static_cast(0.99999125611136965852), + static_cast(-0.99991777624463387686), static_cast(0.99942835555870132569), + static_cast(-0.99697311720723000295), static_cast(0.98751448037275303682), + static_cast(-0.95915857980572882813), static_cast(0.89246305511006708555), + static_cast(-0.76893425990463999675), static_cast(0.58893528468484693250), + static_cast(-0.38380345160440256652), static_cast(0.20317601701045299653), + static_cast(-0.82813631607004984866E-01), static_cast(0.24167984735759576523E-01), + static_cast(-0.44676566663971825242E-02), static_cast(0.39141169402373836468E-03) + }; + + const RealType as = a*a; + const RealType hs = h*h; + const RealType y = static_cast(1)/hs; + + RealType ii = 1; + unsigned short i = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType zi = owens_t_znorm1(ah, pol)/h; + RealType val = 0; + + while( true ) + { + BOOST_MATH_ASSERT(i < 21); + val += zi*c2[i]; + if( m <= i ) // if( m < i+1 ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( m < i ) + zi = y * (ii*zi - vi); + vi *= as; + ii += 2; + i++; + } // while( true ) + + return val; + } // RealType owens_t_T3(const RealType h, const RealType a, const RealType ah) + + // compute the value of Owen's T function with method T3 from the reference paper + template + inline RealType owens_t_T3_imp(const RealType h, const RealType a, const RealType ah, const std::integral_constant&, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short m = 30; + + static const RealType c2[] = + { + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999999999999999729978162447266851932041876728736094298092917625009873), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.99999999999999999999467056379678391810626533251885323416799874878563998732905968), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999999999824849349313270659391127814689133077036298754586814091034842536), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999999999997703859616213643405880166422891953033591551179153879839440241685), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99999999999998394883415238173334565554173013941245103172035286759201504179038147), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999999993063616095509371081203145247992197457263066869044528823599399470977), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999999999797336340409464429599229870590160411238245275855903767652432017766116267), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.999999999574958412069046680119051639753412378037565521359444170241346845522403274), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999999933226234193375324943920160947158239076786103108097456617750134812033362048), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.9999999188923242461073033481053037468263536806742737922476636768006622772762168467), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.9999992195143483674402853783549420883055129680082932629160081128947764415749728967), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.999993935137206712830997921913316971472227199741857386575097250553105958772041501), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.99996135597690552745362392866517133091672395614263398912807169603795088421057688716), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.99979556366513946026406788969630293820987757758641211293079784585126692672425362469), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.999092789629617100153486251423850590051366661947344315423226082520411961968929483), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.996593837411918202119308620432614600338157335862888580671450938858935084316004769854), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.98910017138386127038463510314625339359073956513420458166238478926511821146316469589567), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.970078558040693314521331982203762771512160168582494513347846407314584943870399016019), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.92911438683263187495758525500033707204091967947532160289872782771388170647150321633673), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.8542058695956156057286980736842905011429254735181323743367879525470479126968822863), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.73796526033030091233118357742803709382964420335559408722681794195743240930748630755), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.58523469882837394570128599003785154144164680587615878645171632791404210655891158), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.415997776145676306165661663581868460503874205343014196580122174949645271353372263), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.2588210875241943574388730510317252236407805082485246378222935376279663808416534365), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.1375535825163892648504646951500265585055789019410617565727090346559210218472356689), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.0607952766325955730493900985022020434830339794955745989150270485056436844239206648), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.0216337683299871528059836483840390514275488679530797294557060229266785853764115), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -0.00593405693455186729876995814181203900550014220428843483927218267309209471516256), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 0.0011743414818332946510474576182739210553333860106811865963485870668929503649964142), + BOOST_MATH_BIG_CONSTANT(RealType, 260, -1.489155613350368934073453260689881330166342484405529981510694514036264969925132e-4), + BOOST_MATH_BIG_CONSTANT(RealType, 260, 9.072354320794357587710929507988814669454281514268844884841547607134260303118208e-6) + }; + + const RealType as = a*a; + const RealType hs = h*h; + const RealType y = 1 / hs; + + RealType ii = 1; + unsigned short i = 0; + RealType vi = a * exp( -ah*ah*half() ) * one_div_root_two_pi(); + RealType zi = owens_t_znorm1(ah, pol)/h; + RealType val = 0; + + while( true ) + { + BOOST_MATH_ASSERT(i < 31); + val += zi*c2[i]; + if( m <= i ) // if( m < i+1 ) + { + val *= exp( -hs*half() ) * one_div_root_two_pi(); + break; + } // if( m < i ) + zi = y * (ii*zi - vi); + vi *= as; + ii += 2; + i++; + } // while( true ) + + return val; + } // RealType owens_t_T3(const RealType h, const RealType a, const RealType ah) + + template + inline RealType owens_t_T3(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_T3_imp(h, a, ah, tag_type(), pol); + } + + // compute the value of Owen's T function with method T4 from the reference paper + template + inline RealType owens_t_T4(const RealType h, const RealType a, const unsigned short m) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + + unsigned short ii = 1; + RealType ai = a * exp( -hs*(static_cast(1)-as)*half() ) * one_div_two_pi(); + RealType yi = 1; + RealType val = 0; + + while( true ) + { + val += ai*yi; + if( maxii <= ii ) + break; + ii += 2; + yi = (static_cast(1)-hs*yi) / static_cast(ii); + ai *= as; + } // while( true ) + + return val; + } // RealType owens_t_T4(const RealType h, const RealType a, const unsigned short m) + + // compute the value of Owen's T function with method T5 from the reference paper + template + inline RealType owens_t_T5_imp(const RealType h, const RealType a, const std::integral_constant&) + { + BOOST_MATH_STD_USING + /* + NOTICE: + - The pts[] array contains the squares (!) of the abscissas, i.e. the roots of the Legendre + polynomial P_n(x), instead of the plain roots as required in Gauss-Legendre + quadrature, because T5(h,a,m) contains only x^2 terms. + - The wts[] array contains the weights for Gauss-Legendre quadrature scaled with a factor + of 1/(2*pi) according to T5(h,a,m). + */ + + const unsigned short m = 13; + static const RealType pts[] = { + static_cast(0.35082039676451715489E-02), + static_cast(0.31279042338030753740E-01), static_cast(0.85266826283219451090E-01), + static_cast(0.16245071730812277011), static_cast(0.25851196049125434828), + static_cast(0.36807553840697533536), static_cast(0.48501092905604697475), + static_cast(0.60277514152618576821), static_cast(0.71477884217753226516), + static_cast(0.81475510988760098605), static_cast(0.89711029755948965867), + static_cast(0.95723808085944261843), static_cast(0.99178832974629703586) }; + static const RealType wts[] = { + static_cast(0.18831438115323502887E-01), + static_cast(0.18567086243977649478E-01), static_cast(0.18042093461223385584E-01), + static_cast(0.17263829606398753364E-01), static_cast(0.16243219975989856730E-01), + static_cast(0.14994592034116704829E-01), static_cast(0.13535474469662088392E-01), + static_cast(0.11886351605820165233E-01), static_cast(0.10070377242777431897E-01), + static_cast(0.81130545742299586629E-02), static_cast(0.60419009528470238773E-02), + static_cast(0.38862217010742057883E-02), static_cast(0.16793031084546090448E-02) }; + + const RealType as = a*a; + const RealType hs = -h*h*boost::math::constants::half(); + + RealType val = 0; + for(unsigned short i = 0; i < m; ++i) + { + BOOST_MATH_ASSERT(i < 13); + const RealType r = static_cast(1) + as*pts[i]; + val += wts[i] * exp( hs*r ) / r; + } // for(unsigned short i = 0; i < m; ++i) + + return val*a; + } // RealType owens_t_T5(const RealType h, const RealType a) + + // compute the value of Owen's T function with method T5 from the reference paper + template + inline RealType owens_t_T5_imp(const RealType h, const RealType a, const std::integral_constant&) + { + BOOST_MATH_STD_USING + /* + NOTICE: + - The pts[] array contains the squares (!) of the abscissas, i.e. the roots of the Legendre + polynomial P_n(x), instead of the plain roots as required in Gauss-Legendre + quadrature, because T5(h,a,m) contains only x^2 terms. + - The wts[] array contains the weights for Gauss-Legendre quadrature scaled with a factor + of 1/(2*pi) according to T5(h,a,m). + */ + + const unsigned short m = 19; + static const RealType pts[] = { + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0016634282895983227941), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.014904509242697054183), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.04103478879005817919), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.079359853513391511008), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.1288612130237615133), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.18822336642448518856), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.25586876186122962384), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.32999972011807857222), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.40864620815774761438), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.48971819306044782365), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.57106118513245543894), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.6505134942981533829), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.72596367859928091618), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.79540665919549865924), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.85699701386308739244), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.90909804422384697594), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.95032536436570154409), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.97958418733152273717), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.99610366384229088321) + }; + static const RealType wts[] = { + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012975111395684900835), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012888764187499150078), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012716644398857307844), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012459897461364705691), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.012120231988292330388), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.011699908404856841158), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.011201723906897224448), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.010628993848522759853), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0099855296835573320047), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0092756136096132857933), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0085039700881139589055), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0076757344408814561254), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0067964187616556459109), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.005871875456524750363), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0049082589542498110071), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0039119870792519721409), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0028897090921170700834), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.0018483371329504443947), + BOOST_MATH_BIG_CONSTANT(RealType, 64, 0.00079623320100438873578) + }; + + const RealType as = a*a; + const RealType hs = -h*h*boost::math::constants::half(); + + RealType val = 0; + for(unsigned short i = 0; i < m; ++i) + { + BOOST_MATH_ASSERT(i < 19); + const RealType r = 1 + as*pts[i]; + val += wts[i] * exp( hs*r ) / r; + } // for(unsigned short i = 0; i < m; ++i) + + return val*a; + } // RealType owens_t_T5(const RealType h, const RealType a) + + template + inline RealType owens_t_T5(const RealType h, const RealType a, const Policy&) + { + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_T5_imp(h, a, tag_type()); + } + + + // compute the value of Owen's T function with method T6 from the reference paper + template + inline RealType owens_t_T6(const RealType h, const RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType normh = owens_t_znorm2(h, pol); + const RealType y = static_cast(1) - a; + const RealType r = atan2(y, static_cast(1 + a) ); + + RealType val = normh * ( static_cast(1) - normh ) * half(); + + if( r != 0 ) + val -= r * exp( -y*h*h*half()/r ) * one_div_two_pi(); + + return val; + } // RealType owens_t_T6(const RealType h, const RealType a, const unsigned short m) + + template + std::pair owens_t_T1_accelerated(T h, T a, const Policy& pol) + { + // + // This is the same series as T1, but: + // * The Taylor series for atan has been combined with that for T1, + // reducing but not eliminating cancellation error. + // * The resulting alternating series is then accelerated using method 1 + // from H. Cohen, F. Rodriguez Villegas, D. Zagier, + // "Convergence acceleration of alternating series", Bonn, (1991). + // + BOOST_MATH_STD_USING + static const char* function = "boost::math::owens_t<%1%>(%1%, %1%)"; + T half_h_h = h * h / 2; + T a_pow = a; + T aa = a * a; + T exp_term = exp(-h * h / 2); + T one_minus_dj_sum = exp_term; + T sum = a_pow * exp_term; + T dj_pow = exp_term; + T term = sum; + T abs_err; + int j = 1; + + // + // Normally with this form of series acceleration we can calculate + // up front how many terms will be required - based on the assumption + // that each term decreases in size by a factor of 3. However, + // that assumption does not apply here, as the underlying T1 series can + // go quite strongly divergent in the early terms, before strongly + // converging later. Various "guesstimates" have been tried to take account + // of this, but they don't always work.... so instead set "n" to the + // largest value that won't cause overflow later, and abort iteration + // when the last accelerated term was small enough... + // + int n; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + n = itrunc(T(tools::log_max_value() / 6)); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + n = (std::numeric_limits::max)(); + } +#endif + n = (std::min)(n, 1500); + T d = pow(3 + sqrt(T(8)), n); + d = (d + 1 / d) / 2; + T b = -1; + T c = -d; + c = b - c; + sum *= c; + b = -n * n * b * 2; + abs_err = ldexp(fabs(sum), -tools::digits()); + + while(j < n) + { + a_pow *= aa; + dj_pow *= half_h_h / j; + one_minus_dj_sum += dj_pow; + term = one_minus_dj_sum * a_pow / (2 * j + 1); + c = b - c; + sum += c * term; + abs_err += ldexp((std::max)(T(fabs(sum)), T(fabs(c*term))), -tools::digits()); + b = (j + n) * (j - n) * b / ((j + T(0.5)) * (j + 1)); + ++j; + // + // Include an escape route to prevent calculating too many terms: + // + if((j > 10) && (fabs(sum * tools::epsilon()) > fabs(c * term))) + break; + } + abs_err += fabs(c * term); + if(sum < 0) // sum must always be positive, if it's negative something really bad has happened: + policies::raise_evaluation_error(function, 0, T(0), pol); + return std::pair((sum / d) / boost::math::constants::two_pi(), abs_err / sum); + } + + template + inline RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah, const Policy& pol, const std::true_type&) + { + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const unsigned short maxii = m+m+1; + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) / root_two_pi(); + RealType z = owens_t_znorm1(ah, pol)/h; + RealType last_z = fabs(z); + RealType lim = policies::get_epsilon(); + + while( true ) + { + val += z; + // + // This series stops converging after a while, so put a limit + // on how far we go before returning our best guess: + // + if((fabs(lim * val) > fabs(z)) || ((ii > maxii) && (fabs(z) > last_z)) || (z == 0)) + { + val *= exp( -hs*half() ) / root_two_pi(); + break; + } // if( maxii <= ii ) + last_z = fabs(z); + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + + return val; + } // RealType owens_t_T2(const RealType h, const RealType a, const unsigned short m, const RealType ah) + + template + inline std::pair owens_t_T2_accelerated(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + // + // This is the same series as T2, but with acceleration applied. + // Note that we have to be *very* careful to check that nothing bad + // has happened during evaluation - this series will go divergent + // and/or fail to alternate at a drop of a hat! :-( + // + BOOST_MATH_STD_USING + using namespace boost::math::constants; + + const RealType hs = h*h; + const RealType as = -a*a; + const RealType y = static_cast(1) / hs; + + unsigned short ii = 1; + RealType val = 0; + RealType vi = a * exp( -ah*ah*half() ) / root_two_pi(); + RealType z = boost::math::detail::owens_t_znorm1(ah, pol)/h; + RealType last_z = fabs(z); + + // + // Normally with this form of series acceleration we can calculate + // up front how many terms will be required - based on the assumption + // that each term decreases in size by a factor of 3. However, + // that assumption does not apply here, as the underlying T1 series can + // go quite strongly divergent in the early terms, before strongly + // converging later. Various "guesstimates" have been tried to take account + // of this, but they don't always work.... so instead set "n" to the + // largest value that won't cause overflow later, and abort iteration + // when the last accelerated term was small enough... + // + int n; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + n = itrunc(RealType(tools::log_max_value() / 6)); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + n = (std::numeric_limits::max)(); + } +#endif + n = (std::min)(n, 1500); + RealType d = pow(3 + sqrt(RealType(8)), n); + d = (d + 1 / d) / 2; + RealType b = -1; + RealType c = -d; + int s = 1; + + for(int k = 0; k < n; ++k) + { + // + // Check for both convergence and whether the series has gone bad: + // + if( + (fabs(z) > last_z) // Series has gone divergent, abort + || (fabs(val) * tools::epsilon() > fabs(c * s * z)) // Convergence! + || (z * s < 0) // Series has stopped alternating - all bets are off - abort. + ) + { + break; + } + c = b - c; + val += c * s * z; + b = (k + n) * (k - n) * b / ((k + RealType(0.5)) * (k + 1)); + last_z = fabs(z); + s = -s; + z = y * ( vi - static_cast(ii) * z ); + vi *= as; + ii += 2; + } // while( true ) + RealType err = fabs(c * z) / val; + return std::pair(val * exp( -hs*half() ) / (d * root_two_pi()), err); + } // RealType owens_t_T2_accelerated(const RealType h, const RealType a, const RealType ah, const Policy&) + + template + inline RealType T4_mp(const RealType h, const RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + + const RealType hs = h*h; + const RealType as = -a*a; + + unsigned short ii = 1; + RealType ai = constants::one_div_two_pi() * a * exp( -0.5*hs*(1.0-as) ); + RealType yi = 1.0; + RealType val = 0.0; + + RealType lim = boost::math::policies::get_epsilon(); + + while( true ) + { + RealType term = ai*yi; + val += term; + if((yi != 0) && (fabs(val * lim) > fabs(term))) + break; + ii += 2; + yi = (1.0-hs*yi) / static_cast(ii); + ai *= as; + if(ii > (std::min)(1500, (int)policies::get_max_series_iterations())) + policies::raise_evaluation_error("boost::math::owens_t<%1%>", 0, val, pol); + } // while( true ) + + return val; + } // arg_type owens_t_T4(const arg_type h, const arg_type a, const unsigned short m) + + + // This routine dispatches the call to one of six subroutines, depending on the values + // of h and a. + // preconditions: h >= 0, 0<=a<=1, ah=a*h + // + // Note there are different versions for different precisions.... + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, std::integral_constant const&) + { + // Simple main case for 64-bit precision or less, this is as per the Patefield-Tandy paper: + BOOST_MATH_STD_USING + // + // Handle some special cases first, these are from + // page 1077 of Owen's original paper: + // + if(h == 0) + { + return atan(a) * constants::one_div_two_pi(); + } + if(a == 0) + { + return 0; + } + if(a == 1) + { + return owens_t_znorm2(RealType(-h), pol) * owens_t_znorm2(h, pol) / 2; + } + if(a >= tools::max_value()) + { + return owens_t_znorm2(RealType(fabs(h)), pol); + } + RealType val = 0; // avoid compiler warnings, 0 will be overwritten in any case + const unsigned short icode = owens_t_compute_code(h, a); + const unsigned short m = owens_t_get_order(icode, val /* just a dummy for the type */, pol); + static const unsigned short meth[] = {1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 4, 4, 4, 4, 5, 6}; // 18 entries + + // determine the appropriate method, T1 ... T6 + switch( meth[icode] ) + { + case 1: // T1 + val = owens_t_T1(h,a,m,pol); + break; + case 2: // T2 + typedef typename policies::precision::type precision_type; + typedef std::integral_constant 64)> tag_type; + val = owens_t_T2(h, a, m, ah, pol, tag_type()); + break; + case 3: // T3 + val = owens_t_T3(h,a,ah, pol); + break; + case 4: // T4 + val = owens_t_T4(h,a,m); + break; + case 5: // T5 + val = owens_t_T5(h,a, pol); + break; + case 6: // T6 + val = owens_t_T6(h,a, pol); + break; + default: + val = policies::raise_evaluation_error("boost::math::owens_t", "selection routine in Owen's T function failed with h = %1%", h, pol); + } + return val; + } + + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, const std::integral_constant&) + { + // Arbitrary precision version: + BOOST_MATH_STD_USING + // + // Handle some special cases first, these are from + // page 1077 of Owen's original paper: + // + if(h == 0) + { + return atan(a) * constants::one_div_two_pi(); + } + if(a == 0) + { + return 0; + } + if(a == 1) + { + return owens_t_znorm2(RealType(-h), pol) * owens_t_znorm2(h, pol) / 2; + } + if(a >= tools::max_value()) + { + return owens_t_znorm2(RealType(fabs(h)), pol); + } + // Attempt arbitrary precision code, this will throw if it goes wrong: + typedef typename boost::math::policies::normalise >::type forwarding_policy; + std::pair p1(0, tools::max_value()), p2(0, tools::max_value()); + RealType target_precision = policies::get_epsilon() * 1000; + bool have_t1(false), have_t2(false); + if(ah < 3) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + have_t1 = true; + p1 = owens_t_T1_accelerated(h, a, forwarding_policy()); + if(p1.second < target_precision) + return p1.first; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T1 may fail and throw, that's OK +#endif + } + if(ah > 1) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + have_t2 = true; + p2 = owens_t_T2_accelerated(h, a, ah, forwarding_policy()); + if(p2.second < target_precision) + return p2.first; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T2 may fail and throw, that's OK +#endif + } + // + // If we haven't tried T1 yet, do it now - sometimes it succeeds and the number of iterations + // is fairly low compared to T4. + // + if(!have_t1) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + have_t1 = true; + p1 = owens_t_T1_accelerated(h, a, forwarding_policy()); + if(p1.second < target_precision) + return p1.first; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T1 may fail and throw, that's OK +#endif + } + // + // If we haven't tried T2 yet, do it now - sometimes it succeeds and the number of iterations + // is fairly low compared to T4. + // + if(!have_t2) + { +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + have_t2 = true; + p2 = owens_t_T2_accelerated(h, a, ah, forwarding_policy()); + if(p2.second < target_precision) + return p2.first; +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T2 may fail and throw, that's OK +#endif + } + // + // OK, nothing left to do but try the most expensive option which is T4, + // this is often slow to converge, but when it does converge it tends to + // be accurate: +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + return T4_mp(h, a, pol); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::evaluation_error&){} // T4 may fail and throw, that's OK +#endif + // + // Now look back at the results from T1 and T2 and see if either gave better + // results than we could get from the 64-bit precision versions. + // + if((std::min)(p1.second, p2.second) < 1e-20) + { + return p1.second < p2.second ? p1.first : p2.first; + } + // + // We give up - no arbitrary precision versions succeeded! + // + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + } // RealType owens_t_dispatch(RealType h, RealType a, RealType ah) + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol, const std::integral_constant&) + { + // We don't know what the precision is until runtime: + if(tools::digits() <= 64) + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + return owens_t_dispatch(h, a, ah, pol, std::integral_constant()); + } + template + inline RealType owens_t_dispatch(const RealType h, const RealType a, const RealType ah, const Policy& pol) + { + // Figure out the precision and forward to the correct version: + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + return owens_t_dispatch(h, a, ah, pol, tag_type()); + } + // compute Owen's T function, T(h,a), for arbitrary values of h and a + template + inline RealType owens_t(RealType h, RealType a, const Policy& pol) + { + BOOST_MATH_STD_USING + // exploit that T(-h,a) == T(h,a) + h = fabs(h); + + // Use equation (2) in the paper to remap the arguments + // such that h>=0 and 0<=a<=1 for the call of the actual + // computation routine. + + const RealType fabs_a = fabs(a); + const RealType fabs_ah = fabs_a*h; + + RealType val = 0.0; // avoid compiler warnings, 0.0 will be overwritten in any case + + if(fabs_a <= 1) + { + val = owens_t_dispatch(h, fabs_a, fabs_ah, pol); + } // if(fabs_a <= 1.0) + else + { + if( h <= 0.67 ) + { + const RealType normh = owens_t_znorm1(h, pol); + const RealType normah = owens_t_znorm1(fabs_ah, pol); + val = static_cast(1)/static_cast(4) - normh*normah - + owens_t_dispatch(fabs_ah, static_cast(1 / fabs_a), h, pol); + } // if( h <= 0.67 ) + else + { + const RealType normh = detail::owens_t_znorm2(h, pol); + const RealType normah = detail::owens_t_znorm2(fabs_ah, pol); + val = constants::half()*(normh+normah) - normh*normah - + owens_t_dispatch(fabs_ah, static_cast(1 / fabs_a), h, pol); + } // else [if( h <= 0.67 )] + } // else [if(fabs_a <= 1)] + + // exploit that T(h,-a) == -T(h,a) + if(a < 0) + { + return -val; + } // if(a < 0) + + return val; + } // RealType owens_t(RealType h, RealType a) + + template + struct owens_t_initializer + { + struct init + { + init() + { + do_init(tag()); + } + template + static void do_init(const std::integral_constant&){} + static void do_init(const std::integral_constant&) + { + boost::math::owens_t(static_cast(7), static_cast(0.96875), Policy()); + boost::math::owens_t(static_cast(2), static_cast(0.5), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } + }; + + template + const typename owens_t_initializer::init owens_t_initializer::initializer; + + } // namespace detail + + template + inline typename tools::promote_args::type owens_t(T1 h, T2 a, const Policy& pol) + { + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + + detail::owens_t_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::owens_t(static_cast(h), static_cast(a), pol), "boost::math::owens_t<%1%>(%1%,%1%)"); + } + + template + inline typename tools::promote_args::type owens_t(T1 h, T2 a) + { + return owens_t(h, a, policies::policy<>()); + } + + + } // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif +// EOF diff --git a/libcxx/src/third-party/boost/math/special_functions/polygamma.hpp b/libcxx/src/third-party/boost/math/special_functions/polygamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/polygamma.hpp @@ -0,0 +1,83 @@ + +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2013 Nikhar Agrawal +// Copyright 2013 Christopher Kormanyos +// Copyright 2014 John Maddock +// Copyright 2013 Paul Bristow +// Distributed under 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_POLYGAMMA_2013_07_30_HPP_ + #define _BOOST_POLYGAMMA_2013_07_30_HPP_ + +#include +#include +#include + +namespace boost { namespace math { + + + template + inline typename tools::promote_args::type polygamma(const int n, T x, const Policy& pol) + { + // + // Filter off special cases right at the start: + // + if(n == 0) + return boost::math::digamma(x, pol); + if(n == 1) + return boost::math::trigamma(x, pol); + // + // We've found some standard library functions to misbehave if any FPU exception flags + // are set prior to their call, this code will clear those flags, then reset them + // on exit: + // + BOOST_FPU_EXCEPTION_GUARD + // + // The type of the result - the common type of T and U after + // any integer types have been promoted to double: + // + typedef typename tools::promote_args::type result_type; + // + // The type used for the calculation. This may be a wider type than + // the result in order to ensure full precision: + // + typedef typename policies::evaluation::type value_type; + // + // The type of the policy to forward to the actual implementation. + // We disable promotion of float and double as that's [possibly] + // happened already in the line above. Also reset to the default + // any policies we don't use (reduces code bloat if we're called + // multiple times with differing policies we don't actually use). + // Also normalise the type, again to reduce code bloat in case we're + // called multiple times with functionally identical policies that happen + // to be different types. + // + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + // + // Whew. Now we can make the actual call to the implementation. + // Arguments are explicitly cast to the evaluation type, and the result + // passed through checked_narrowing_cast which handles things like overflow + // according to the policy passed: + // + return policies::checked_narrowing_cast( + detail::polygamma_imp(n, static_cast(x), forwarding_policy()), + "boost::math::polygamma<%1%>(int, %1%)"); + } + + template + inline typename tools::promote_args::type polygamma(const int n, T x) + { + return boost::math::polygamma(n, x, policies::policy<>()); + } + +} } // namespace boost::math + +#endif // _BOOST_BERNOULLI_2013_05_30_HPP_ + diff --git a/libcxx/src/third-party/boost/math/special_functions/pow.hpp b/libcxx/src/third-party/boost/math/special_functions/pow.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/pow.hpp @@ -0,0 +1,141 @@ +// Boost pow.hpp header file +// Computes a power with exponent known at compile-time + +// (C) Copyright Bruno Lalande 2008. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + + +#ifndef BOOST_MATH_POW_HPP +#define BOOST_MATH_POW_HPP + + +#include +#include +#include +#include + + +namespace boost { +namespace math { + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code, only triggered in release mode and /W4 +#endif + +namespace detail { + + +template +struct positive_power +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base) + { + T power = positive_power::result(base); + return power * power; + } +}; + +template +struct positive_power +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base) + { + T power = positive_power::result(base); + return base * power * power; + } +}; + +template <> +struct positive_power<1, 1> +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base){ return base; } +}; + + +template +struct power_if_positive +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base, const Policy&) + { return positive_power::result(base); } +}; + +template +struct power_if_positive +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy) + { + if (base == 0) + { + return policies::raise_overflow_error( + "boost::math::pow(%1%)", + "Attempted to compute a negative power of 0", + policy + ); + } + + return T(1) / positive_power<-N>::result(base); + } +}; + +template <> +struct power_if_positive<0, true> +{ + template + static BOOST_CXX14_CONSTEXPR T result(T base, const Policy& policy) + { + if (base == 0) + { + return policies::raise_indeterminate_result_error( + "boost::math::pow(%1%)", + "The result of pow<0>(%1%) is undetermined", + base, + T(1), + policy + ); + } + + return T(1); + } +}; + + +template +struct select_power_if_positive +{ + using type = power_if_positive= 0)>; +}; + + +} // namespace detail + + +template +BOOST_CXX14_CONSTEXPR inline typename tools::promote_args::type pow(T base, const Policy& policy) +{ + using result_type = typename tools::promote_args::type; + return detail::select_power_if_positive::type::result(static_cast(base), policy); +} + +template +BOOST_CXX14_CONSTEXPR inline typename tools::promote_args::type pow(T base) +{ return pow(base, policies::policy<>()); } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +} // namespace math +} // namespace boost + + +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/powm1.hpp b/libcxx/src/third-party/boost/math/special_functions/powm1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/powm1.hpp @@ -0,0 +1,84 @@ +// (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_POWM1 +#define BOOST_MATH_POWM1 + +#ifdef _MSC_VER +#pragma once +#pragma warning(push) +#pragma warning(disable:4702) // Unreachable code (release mode only warning) +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline T powm1_imp(const T x, const T y, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::powm1<%1%>(%1%, %1%)"; + + if (x > 0) + { + if ((fabs(y * (x - 1)) < 0.5) || (fabs(y) < 0.2)) + { + // We don't have any good/quick approximation for log(x) * y + // so just try it and see: + T l = y * log(x); + if (l < 0.5) + return boost::math::expm1(l, pol); + if (l > boost::math::tools::log_max_value()) + return boost::math::policies::raise_overflow_error(function, nullptr, pol); + // fall through.... + } + } + else if (x < 0) + { + // y had better be an integer: + if (boost::math::trunc(y) != y) + return boost::math::policies::raise_domain_error(function, "For non-integral exponent, expected base > 0 but got %1%", x, pol); + if (boost::math::trunc(y / 2) == y / 2) + return powm1_imp(T(-x), y, pol); + } + return pow(x, y) - 1; +} + +} // detail + +template +inline typename tools::promote_args::type + powm1(const T1 a, const T2 z) +{ + typedef typename tools::promote_args::type result_type; + return detail::powm1_imp(static_cast(a), static_cast(z), policies::policy<>()); +} + +template +inline typename tools::promote_args::type + powm1(const T1 a, const T2 z, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::powm1_imp(static_cast(a), static_cast(z), pol); +} + +} // namespace math +} // namespace boost + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // BOOST_MATH_POWM1 + + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/prime.hpp b/libcxx/src/third-party/boost/math/special_functions/prime.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/prime.hpp @@ -0,0 +1,1235 @@ +// Copyright 2008 John Maddock +// +// 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_SF_PRIME_HPP +#define BOOST_MATH_SF_PRIME_HPP + +#include +#include +#include +#include + +namespace boost{ namespace math{ + + template + BOOST_MATH_CONSTEXPR_TABLE_FUNCTION std::uint32_t prime(unsigned n, const Policy& pol) + { + // + // This is basically three big tables which together + // occupy 19946 bytes, we use the smallest type which + // will handle each value, and store the final set of + // values in a uint16_t with the values offset by 0xffff. + // That gives us the first 10000 primes with the largest + // being 104729: + // +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr unsigned b1 = 53; + constexpr unsigned b2 = 6541; + constexpr unsigned b3 = 10000; + constexpr std::array a1 = {{ +#else + static const unsigned b1 = 53; + static const unsigned b2 = 6541; + static const unsigned b3 = 10000; + static const std::array a1 = {{ +#endif + 2u, 3u, 5u, 7u, 11u, 13u, 17u, 19u, 23u, 29u, 31u, + 37u, 41u, 43u, 47u, 53u, 59u, 61u, 67u, 71u, 73u, + 79u, 83u, 89u, 97u, 101u, 103u, 107u, 109u, 113u, + 127u, 131u, 137u, 139u, 149u, 151u, 157u, 163u, + 167u, 173u, 179u, 181u, 191u, 193u, 197u, 199u, + 211u, 223u, 227u, 229u, 233u, 239u, 241u, 251u + }}; +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array a2 = {{ +#else + static const std::array a2 = {{ +#endif + 257u, 263u, 269u, 271u, 277u, 281u, 283u, 293u, + 307u, 311u, 313u, 317u, 331u, 337u, 347u, 349u, 353u, + 359u, 367u, 373u, 379u, 383u, 389u, 397u, 401u, 409u, + 419u, 421u, 431u, 433u, 439u, 443u, 449u, 457u, 461u, + 463u, 467u, 479u, 487u, 491u, 499u, 503u, 509u, 521u, + 523u, 541u, 547u, 557u, 563u, 569u, 571u, 577u, 587u, + 593u, 599u, 601u, 607u, 613u, 617u, 619u, 631u, 641u, + 643u, 647u, 653u, 659u, 661u, 673u, 677u, 683u, 691u, + 701u, 709u, 719u, 727u, 733u, 739u, 743u, 751u, 757u, + 761u, 769u, 773u, 787u, 797u, 809u, 811u, 821u, 823u, + 827u, 829u, 839u, 853u, 857u, 859u, 863u, 877u, 881u, + 883u, 887u, 907u, 911u, 919u, 929u, 937u, 941u, 947u, + 953u, 967u, 971u, 977u, 983u, 991u, 997u, 1009u, 1013u, + 1019u, 1021u, 1031u, 1033u, 1039u, 1049u, 1051u, 1061u, 1063u, + 1069u, 1087u, 1091u, 1093u, 1097u, 1103u, 1109u, 1117u, 1123u, + 1129u, 1151u, 1153u, 1163u, 1171u, 1181u, 1187u, 1193u, 1201u, + 1213u, 1217u, 1223u, 1229u, 1231u, 1237u, 1249u, 1259u, 1277u, + 1279u, 1283u, 1289u, 1291u, 1297u, 1301u, 1303u, 1307u, 1319u, + 1321u, 1327u, 1361u, 1367u, 1373u, 1381u, 1399u, 1409u, 1423u, + 1427u, 1429u, 1433u, 1439u, 1447u, 1451u, 1453u, 1459u, 1471u, + 1481u, 1483u, 1487u, 1489u, 1493u, 1499u, 1511u, 1523u, 1531u, + 1543u, 1549u, 1553u, 1559u, 1567u, 1571u, 1579u, 1583u, 1597u, + 1601u, 1607u, 1609u, 1613u, 1619u, 1621u, 1627u, 1637u, 1657u, + 1663u, 1667u, 1669u, 1693u, 1697u, 1699u, 1709u, 1721u, 1723u, + 1733u, 1741u, 1747u, 1753u, 1759u, 1777u, 1783u, 1787u, 1789u, + 1801u, 1811u, 1823u, 1831u, 1847u, 1861u, 1867u, 1871u, 1873u, + 1877u, 1879u, 1889u, 1901u, 1907u, 1913u, 1931u, 1933u, 1949u, + 1951u, 1973u, 1979u, 1987u, 1993u, 1997u, 1999u, 2003u, 2011u, + 2017u, 2027u, 2029u, 2039u, 2053u, 2063u, 2069u, 2081u, 2083u, + 2087u, 2089u, 2099u, 2111u, 2113u, 2129u, 2131u, 2137u, 2141u, + 2143u, 2153u, 2161u, 2179u, 2203u, 2207u, 2213u, 2221u, 2237u, + 2239u, 2243u, 2251u, 2267u, 2269u, 2273u, 2281u, 2287u, 2293u, + 2297u, 2309u, 2311u, 2333u, 2339u, 2341u, 2347u, 2351u, 2357u, + 2371u, 2377u, 2381u, 2383u, 2389u, 2393u, 2399u, 2411u, 2417u, + 2423u, 2437u, 2441u, 2447u, 2459u, 2467u, 2473u, 2477u, 2503u, + 2521u, 2531u, 2539u, 2543u, 2549u, 2551u, 2557u, 2579u, 2591u, + 2593u, 2609u, 2617u, 2621u, 2633u, 2647u, 2657u, 2659u, 2663u, + 2671u, 2677u, 2683u, 2687u, 2689u, 2693u, 2699u, 2707u, 2711u, + 2713u, 2719u, 2729u, 2731u, 2741u, 2749u, 2753u, 2767u, 2777u, + 2789u, 2791u, 2797u, 2801u, 2803u, 2819u, 2833u, 2837u, 2843u, + 2851u, 2857u, 2861u, 2879u, 2887u, 2897u, 2903u, 2909u, 2917u, + 2927u, 2939u, 2953u, 2957u, 2963u, 2969u, 2971u, 2999u, 3001u, + 3011u, 3019u, 3023u, 3037u, 3041u, 3049u, 3061u, 3067u, 3079u, + 3083u, 3089u, 3109u, 3119u, 3121u, 3137u, 3163u, 3167u, 3169u, + 3181u, 3187u, 3191u, 3203u, 3209u, 3217u, 3221u, 3229u, 3251u, + 3253u, 3257u, 3259u, 3271u, 3299u, 3301u, 3307u, 3313u, 3319u, + 3323u, 3329u, 3331u, 3343u, 3347u, 3359u, 3361u, 3371u, 3373u, + 3389u, 3391u, 3407u, 3413u, 3433u, 3449u, 3457u, 3461u, 3463u, + 3467u, 3469u, 3491u, 3499u, 3511u, 3517u, 3527u, 3529u, 3533u, + 3539u, 3541u, 3547u, 3557u, 3559u, 3571u, 3581u, 3583u, 3593u, + 3607u, 3613u, 3617u, 3623u, 3631u, 3637u, 3643u, 3659u, 3671u, + 3673u, 3677u, 3691u, 3697u, 3701u, 3709u, 3719u, 3727u, 3733u, + 3739u, 3761u, 3767u, 3769u, 3779u, 3793u, 3797u, 3803u, 3821u, + 3823u, 3833u, 3847u, 3851u, 3853u, 3863u, 3877u, 3881u, 3889u, + 3907u, 3911u, 3917u, 3919u, 3923u, 3929u, 3931u, 3943u, 3947u, + 3967u, 3989u, 4001u, 4003u, 4007u, 4013u, 4019u, 4021u, 4027u, + 4049u, 4051u, 4057u, 4073u, 4079u, 4091u, 4093u, 4099u, 4111u, + 4127u, 4129u, 4133u, 4139u, 4153u, 4157u, 4159u, 4177u, 4201u, + 4211u, 4217u, 4219u, 4229u, 4231u, 4241u, 4243u, 4253u, 4259u, + 4261u, 4271u, 4273u, 4283u, 4289u, 4297u, 4327u, 4337u, 4339u, + 4349u, 4357u, 4363u, 4373u, 4391u, 4397u, 4409u, 4421u, 4423u, + 4441u, 4447u, 4451u, 4457u, 4463u, 4481u, 4483u, 4493u, 4507u, + 4513u, 4517u, 4519u, 4523u, 4547u, 4549u, 4561u, 4567u, 4583u, + 4591u, 4597u, 4603u, 4621u, 4637u, 4639u, 4643u, 4649u, 4651u, + 4657u, 4663u, 4673u, 4679u, 4691u, 4703u, 4721u, 4723u, 4729u, + 4733u, 4751u, 4759u, 4783u, 4787u, 4789u, 4793u, 4799u, 4801u, + 4813u, 4817u, 4831u, 4861u, 4871u, 4877u, 4889u, 4903u, 4909u, + 4919u, 4931u, 4933u, 4937u, 4943u, 4951u, 4957u, 4967u, 4969u, + 4973u, 4987u, 4993u, 4999u, 5003u, 5009u, 5011u, 5021u, 5023u, + 5039u, 5051u, 5059u, 5077u, 5081u, 5087u, 5099u, 5101u, 5107u, + 5113u, 5119u, 5147u, 5153u, 5167u, 5171u, 5179u, 5189u, 5197u, + 5209u, 5227u, 5231u, 5233u, 5237u, 5261u, 5273u, 5279u, 5281u, + 5297u, 5303u, 5309u, 5323u, 5333u, 5347u, 5351u, 5381u, 5387u, + 5393u, 5399u, 5407u, 5413u, 5417u, 5419u, 5431u, 5437u, 5441u, + 5443u, 5449u, 5471u, 5477u, 5479u, 5483u, 5501u, 5503u, 5507u, + 5519u, 5521u, 5527u, 5531u, 5557u, 5563u, 5569u, 5573u, 5581u, + 5591u, 5623u, 5639u, 5641u, 5647u, 5651u, 5653u, 5657u, 5659u, + 5669u, 5683u, 5689u, 5693u, 5701u, 5711u, 5717u, 5737u, 5741u, + 5743u, 5749u, 5779u, 5783u, 5791u, 5801u, 5807u, 5813u, 5821u, + 5827u, 5839u, 5843u, 5849u, 5851u, 5857u, 5861u, 5867u, 5869u, + 5879u, 5881u, 5897u, 5903u, 5923u, 5927u, 5939u, 5953u, 5981u, + 5987u, 6007u, 6011u, 6029u, 6037u, 6043u, 6047u, 6053u, 6067u, + 6073u, 6079u, 6089u, 6091u, 6101u, 6113u, 6121u, 6131u, 6133u, + 6143u, 6151u, 6163u, 6173u, 6197u, 6199u, 6203u, 6211u, 6217u, + 6221u, 6229u, 6247u, 6257u, 6263u, 6269u, 6271u, 6277u, 6287u, + 6299u, 6301u, 6311u, 6317u, 6323u, 6329u, 6337u, 6343u, 6353u, + 6359u, 6361u, 6367u, 6373u, 6379u, 6389u, 6397u, 6421u, 6427u, + 6449u, 6451u, 6469u, 6473u, 6481u, 6491u, 6521u, 6529u, 6547u, + 6551u, 6553u, 6563u, 6569u, 6571u, 6577u, 6581u, 6599u, 6607u, + 6619u, 6637u, 6653u, 6659u, 6661u, 6673u, 6679u, 6689u, 6691u, + 6701u, 6703u, 6709u, 6719u, 6733u, 6737u, 6761u, 6763u, 6779u, + 6781u, 6791u, 6793u, 6803u, 6823u, 6827u, 6829u, 6833u, 6841u, + 6857u, 6863u, 6869u, 6871u, 6883u, 6899u, 6907u, 6911u, 6917u, + 6947u, 6949u, 6959u, 6961u, 6967u, 6971u, 6977u, 6983u, 6991u, + 6997u, 7001u, 7013u, 7019u, 7027u, 7039u, 7043u, 7057u, 7069u, + 7079u, 7103u, 7109u, 7121u, 7127u, 7129u, 7151u, 7159u, 7177u, + 7187u, 7193u, 7207u, 7211u, 7213u, 7219u, 7229u, 7237u, 7243u, + 7247u, 7253u, 7283u, 7297u, 7307u, 7309u, 7321u, 7331u, 7333u, + 7349u, 7351u, 7369u, 7393u, 7411u, 7417u, 7433u, 7451u, 7457u, + 7459u, 7477u, 7481u, 7487u, 7489u, 7499u, 7507u, 7517u, 7523u, + 7529u, 7537u, 7541u, 7547u, 7549u, 7559u, 7561u, 7573u, 7577u, + 7583u, 7589u, 7591u, 7603u, 7607u, 7621u, 7639u, 7643u, 7649u, + 7669u, 7673u, 7681u, 7687u, 7691u, 7699u, 7703u, 7717u, 7723u, + 7727u, 7741u, 7753u, 7757u, 7759u, 7789u, 7793u, 7817u, 7823u, + 7829u, 7841u, 7853u, 7867u, 7873u, 7877u, 7879u, 7883u, 7901u, + 7907u, 7919u, 7927u, 7933u, 7937u, 7949u, 7951u, 7963u, 7993u, + 8009u, 8011u, 8017u, 8039u, 8053u, 8059u, 8069u, 8081u, 8087u, + 8089u, 8093u, 8101u, 8111u, 8117u, 8123u, 8147u, 8161u, 8167u, + 8171u, 8179u, 8191u, 8209u, 8219u, 8221u, 8231u, 8233u, 8237u, + 8243u, 8263u, 8269u, 8273u, 8287u, 8291u, 8293u, 8297u, 8311u, + 8317u, 8329u, 8353u, 8363u, 8369u, 8377u, 8387u, 8389u, 8419u, + 8423u, 8429u, 8431u, 8443u, 8447u, 8461u, 8467u, 8501u, 8513u, + 8521u, 8527u, 8537u, 8539u, 8543u, 8563u, 8573u, 8581u, 8597u, + 8599u, 8609u, 8623u, 8627u, 8629u, 8641u, 8647u, 8663u, 8669u, + 8677u, 8681u, 8689u, 8693u, 8699u, 8707u, 8713u, 8719u, 8731u, + 8737u, 8741u, 8747u, 8753u, 8761u, 8779u, 8783u, 8803u, 8807u, + 8819u, 8821u, 8831u, 8837u, 8839u, 8849u, 8861u, 8863u, 8867u, + 8887u, 8893u, 8923u, 8929u, 8933u, 8941u, 8951u, 8963u, 8969u, + 8971u, 8999u, 9001u, 9007u, 9011u, 9013u, 9029u, 9041u, 9043u, + 9049u, 9059u, 9067u, 9091u, 9103u, 9109u, 9127u, 9133u, 9137u, + 9151u, 9157u, 9161u, 9173u, 9181u, 9187u, 9199u, 9203u, 9209u, + 9221u, 9227u, 9239u, 9241u, 9257u, 9277u, 9281u, 9283u, 9293u, + 9311u, 9319u, 9323u, 9337u, 9341u, 9343u, 9349u, 9371u, 9377u, + 9391u, 9397u, 9403u, 9413u, 9419u, 9421u, 9431u, 9433u, 9437u, + 9439u, 9461u, 9463u, 9467u, 9473u, 9479u, 9491u, 9497u, 9511u, + 9521u, 9533u, 9539u, 9547u, 9551u, 9587u, 9601u, 9613u, 9619u, + 9623u, 9629u, 9631u, 9643u, 9649u, 9661u, 9677u, 9679u, 9689u, + 9697u, 9719u, 9721u, 9733u, 9739u, 9743u, 9749u, 9767u, 9769u, + 9781u, 9787u, 9791u, 9803u, 9811u, 9817u, 9829u, 9833u, 9839u, + 9851u, 9857u, 9859u, 9871u, 9883u, 9887u, 9901u, 9907u, 9923u, + 9929u, 9931u, 9941u, 9949u, 9967u, 9973u, 10007u, 10009u, 10037u, + 10039u, 10061u, 10067u, 10069u, 10079u, 10091u, 10093u, 10099u, 10103u, + 10111u, 10133u, 10139u, 10141u, 10151u, 10159u, 10163u, 10169u, 10177u, + 10181u, 10193u, 10211u, 10223u, 10243u, 10247u, 10253u, 10259u, 10267u, + 10271u, 10273u, 10289u, 10301u, 10303u, 10313u, 10321u, 10331u, 10333u, + 10337u, 10343u, 10357u, 10369u, 10391u, 10399u, 10427u, 10429u, 10433u, + 10453u, 10457u, 10459u, 10463u, 10477u, 10487u, 10499u, 10501u, 10513u, + 10529u, 10531u, 10559u, 10567u, 10589u, 10597u, 10601u, 10607u, 10613u, + 10627u, 10631u, 10639u, 10651u, 10657u, 10663u, 10667u, 10687u, 10691u, + 10709u, 10711u, 10723u, 10729u, 10733u, 10739u, 10753u, 10771u, 10781u, + 10789u, 10799u, 10831u, 10837u, 10847u, 10853u, 10859u, 10861u, 10867u, + 10883u, 10889u, 10891u, 10903u, 10909u, 10937u, 10939u, 10949u, 10957u, + 10973u, 10979u, 10987u, 10993u, 11003u, 11027u, 11047u, 11057u, 11059u, + 11069u, 11071u, 11083u, 11087u, 11093u, 11113u, 11117u, 11119u, 11131u, + 11149u, 11159u, 11161u, 11171u, 11173u, 11177u, 11197u, 11213u, 11239u, + 11243u, 11251u, 11257u, 11261u, 11273u, 11279u, 11287u, 11299u, 11311u, + 11317u, 11321u, 11329u, 11351u, 11353u, 11369u, 11383u, 11393u, 11399u, + 11411u, 11423u, 11437u, 11443u, 11447u, 11467u, 11471u, 11483u, 11489u, + 11491u, 11497u, 11503u, 11519u, 11527u, 11549u, 11551u, 11579u, 11587u, + 11593u, 11597u, 11617u, 11621u, 11633u, 11657u, 11677u, 11681u, 11689u, + 11699u, 11701u, 11717u, 11719u, 11731u, 11743u, 11777u, 11779u, 11783u, + 11789u, 11801u, 11807u, 11813u, 11821u, 11827u, 11831u, 11833u, 11839u, + 11863u, 11867u, 11887u, 11897u, 11903u, 11909u, 11923u, 11927u, 11933u, + 11939u, 11941u, 11953u, 11959u, 11969u, 11971u, 11981u, 11987u, 12007u, + 12011u, 12037u, 12041u, 12043u, 12049u, 12071u, 12073u, 12097u, 12101u, + 12107u, 12109u, 12113u, 12119u, 12143u, 12149u, 12157u, 12161u, 12163u, + 12197u, 12203u, 12211u, 12227u, 12239u, 12241u, 12251u, 12253u, 12263u, + 12269u, 12277u, 12281u, 12289u, 12301u, 12323u, 12329u, 12343u, 12347u, + 12373u, 12377u, 12379u, 12391u, 12401u, 12409u, 12413u, 12421u, 12433u, + 12437u, 12451u, 12457u, 12473u, 12479u, 12487u, 12491u, 12497u, 12503u, + 12511u, 12517u, 12527u, 12539u, 12541u, 12547u, 12553u, 12569u, 12577u, + 12583u, 12589u, 12601u, 12611u, 12613u, 12619u, 12637u, 12641u, 12647u, + 12653u, 12659u, 12671u, 12689u, 12697u, 12703u, 12713u, 12721u, 12739u, + 12743u, 12757u, 12763u, 12781u, 12791u, 12799u, 12809u, 12821u, 12823u, + 12829u, 12841u, 12853u, 12889u, 12893u, 12899u, 12907u, 12911u, 12917u, + 12919u, 12923u, 12941u, 12953u, 12959u, 12967u, 12973u, 12979u, 12983u, + 13001u, 13003u, 13007u, 13009u, 13033u, 13037u, 13043u, 13049u, 13063u, + 13093u, 13099u, 13103u, 13109u, 13121u, 13127u, 13147u, 13151u, 13159u, + 13163u, 13171u, 13177u, 13183u, 13187u, 13217u, 13219u, 13229u, 13241u, + 13249u, 13259u, 13267u, 13291u, 13297u, 13309u, 13313u, 13327u, 13331u, + 13337u, 13339u, 13367u, 13381u, 13397u, 13399u, 13411u, 13417u, 13421u, + 13441u, 13451u, 13457u, 13463u, 13469u, 13477u, 13487u, 13499u, 13513u, + 13523u, 13537u, 13553u, 13567u, 13577u, 13591u, 13597u, 13613u, 13619u, + 13627u, 13633u, 13649u, 13669u, 13679u, 13681u, 13687u, 13691u, 13693u, + 13697u, 13709u, 13711u, 13721u, 13723u, 13729u, 13751u, 13757u, 13759u, + 13763u, 13781u, 13789u, 13799u, 13807u, 13829u, 13831u, 13841u, 13859u, + 13873u, 13877u, 13879u, 13883u, 13901u, 13903u, 13907u, 13913u, 13921u, + 13931u, 13933u, 13963u, 13967u, 13997u, 13999u, 14009u, 14011u, 14029u, + 14033u, 14051u, 14057u, 14071u, 14081u, 14083u, 14087u, 14107u, 14143u, + 14149u, 14153u, 14159u, 14173u, 14177u, 14197u, 14207u, 14221u, 14243u, + 14249u, 14251u, 14281u, 14293u, 14303u, 14321u, 14323u, 14327u, 14341u, + 14347u, 14369u, 14387u, 14389u, 14401u, 14407u, 14411u, 14419u, 14423u, + 14431u, 14437u, 14447u, 14449u, 14461u, 14479u, 14489u, 14503u, 14519u, + 14533u, 14537u, 14543u, 14549u, 14551u, 14557u, 14561u, 14563u, 14591u, + 14593u, 14621u, 14627u, 14629u, 14633u, 14639u, 14653u, 14657u, 14669u, + 14683u, 14699u, 14713u, 14717u, 14723u, 14731u, 14737u, 14741u, 14747u, + 14753u, 14759u, 14767u, 14771u, 14779u, 14783u, 14797u, 14813u, 14821u, + 14827u, 14831u, 14843u, 14851u, 14867u, 14869u, 14879u, 14887u, 14891u, + 14897u, 14923u, 14929u, 14939u, 14947u, 14951u, 14957u, 14969u, 14983u, + 15013u, 15017u, 15031u, 15053u, 15061u, 15073u, 15077u, 15083u, 15091u, + 15101u, 15107u, 15121u, 15131u, 15137u, 15139u, 15149u, 15161u, 15173u, + 15187u, 15193u, 15199u, 15217u, 15227u, 15233u, 15241u, 15259u, 15263u, + 15269u, 15271u, 15277u, 15287u, 15289u, 15299u, 15307u, 15313u, 15319u, + 15329u, 15331u, 15349u, 15359u, 15361u, 15373u, 15377u, 15383u, 15391u, + 15401u, 15413u, 15427u, 15439u, 15443u, 15451u, 15461u, 15467u, 15473u, + 15493u, 15497u, 15511u, 15527u, 15541u, 15551u, 15559u, 15569u, 15581u, + 15583u, 15601u, 15607u, 15619u, 15629u, 15641u, 15643u, 15647u, 15649u, + 15661u, 15667u, 15671u, 15679u, 15683u, 15727u, 15731u, 15733u, 15737u, + 15739u, 15749u, 15761u, 15767u, 15773u, 15787u, 15791u, 15797u, 15803u, + 15809u, 15817u, 15823u, 15859u, 15877u, 15881u, 15887u, 15889u, 15901u, + 15907u, 15913u, 15919u, 15923u, 15937u, 15959u, 15971u, 15973u, 15991u, + 16001u, 16007u, 16033u, 16057u, 16061u, 16063u, 16067u, 16069u, 16073u, + 16087u, 16091u, 16097u, 16103u, 16111u, 16127u, 16139u, 16141u, 16183u, + 16187u, 16189u, 16193u, 16217u, 16223u, 16229u, 16231u, 16249u, 16253u, + 16267u, 16273u, 16301u, 16319u, 16333u, 16339u, 16349u, 16361u, 16363u, + 16369u, 16381u, 16411u, 16417u, 16421u, 16427u, 16433u, 16447u, 16451u, + 16453u, 16477u, 16481u, 16487u, 16493u, 16519u, 16529u, 16547u, 16553u, + 16561u, 16567u, 16573u, 16603u, 16607u, 16619u, 16631u, 16633u, 16649u, + 16651u, 16657u, 16661u, 16673u, 16691u, 16693u, 16699u, 16703u, 16729u, + 16741u, 16747u, 16759u, 16763u, 16787u, 16811u, 16823u, 16829u, 16831u, + 16843u, 16871u, 16879u, 16883u, 16889u, 16901u, 16903u, 16921u, 16927u, + 16931u, 16937u, 16943u, 16963u, 16979u, 16981u, 16987u, 16993u, 17011u, + 17021u, 17027u, 17029u, 17033u, 17041u, 17047u, 17053u, 17077u, 17093u, + 17099u, 17107u, 17117u, 17123u, 17137u, 17159u, 17167u, 17183u, 17189u, + 17191u, 17203u, 17207u, 17209u, 17231u, 17239u, 17257u, 17291u, 17293u, + 17299u, 17317u, 17321u, 17327u, 17333u, 17341u, 17351u, 17359u, 17377u, + 17383u, 17387u, 17389u, 17393u, 17401u, 17417u, 17419u, 17431u, 17443u, + 17449u, 17467u, 17471u, 17477u, 17483u, 17489u, 17491u, 17497u, 17509u, + 17519u, 17539u, 17551u, 17569u, 17573u, 17579u, 17581u, 17597u, 17599u, + 17609u, 17623u, 17627u, 17657u, 17659u, 17669u, 17681u, 17683u, 17707u, + 17713u, 17729u, 17737u, 17747u, 17749u, 17761u, 17783u, 17789u, 17791u, + 17807u, 17827u, 17837u, 17839u, 17851u, 17863u, 17881u, 17891u, 17903u, + 17909u, 17911u, 17921u, 17923u, 17929u, 17939u, 17957u, 17959u, 17971u, + 17977u, 17981u, 17987u, 17989u, 18013u, 18041u, 18043u, 18047u, 18049u, + 18059u, 18061u, 18077u, 18089u, 18097u, 18119u, 18121u, 18127u, 18131u, + 18133u, 18143u, 18149u, 18169u, 18181u, 18191u, 18199u, 18211u, 18217u, + 18223u, 18229u, 18233u, 18251u, 18253u, 18257u, 18269u, 18287u, 18289u, + 18301u, 18307u, 18311u, 18313u, 18329u, 18341u, 18353u, 18367u, 18371u, + 18379u, 18397u, 18401u, 18413u, 18427u, 18433u, 18439u, 18443u, 18451u, + 18457u, 18461u, 18481u, 18493u, 18503u, 18517u, 18521u, 18523u, 18539u, + 18541u, 18553u, 18583u, 18587u, 18593u, 18617u, 18637u, 18661u, 18671u, + 18679u, 18691u, 18701u, 18713u, 18719u, 18731u, 18743u, 18749u, 18757u, + 18773u, 18787u, 18793u, 18797u, 18803u, 18839u, 18859u, 18869u, 18899u, + 18911u, 18913u, 18917u, 18919u, 18947u, 18959u, 18973u, 18979u, 19001u, + 19009u, 19013u, 19031u, 19037u, 19051u, 19069u, 19073u, 19079u, 19081u, + 19087u, 19121u, 19139u, 19141u, 19157u, 19163u, 19181u, 19183u, 19207u, + 19211u, 19213u, 19219u, 19231u, 19237u, 19249u, 19259u, 19267u, 19273u, + 19289u, 19301u, 19309u, 19319u, 19333u, 19373u, 19379u, 19381u, 19387u, + 19391u, 19403u, 19417u, 19421u, 19423u, 19427u, 19429u, 19433u, 19441u, + 19447u, 19457u, 19463u, 19469u, 19471u, 19477u, 19483u, 19489u, 19501u, + 19507u, 19531u, 19541u, 19543u, 19553u, 19559u, 19571u, 19577u, 19583u, + 19597u, 19603u, 19609u, 19661u, 19681u, 19687u, 19697u, 19699u, 19709u, + 19717u, 19727u, 19739u, 19751u, 19753u, 19759u, 19763u, 19777u, 19793u, + 19801u, 19813u, 19819u, 19841u, 19843u, 19853u, 19861u, 19867u, 19889u, + 19891u, 19913u, 19919u, 19927u, 19937u, 19949u, 19961u, 19963u, 19973u, + 19979u, 19991u, 19993u, 19997u, 20011u, 20021u, 20023u, 20029u, 20047u, + 20051u, 20063u, 20071u, 20089u, 20101u, 20107u, 20113u, 20117u, 20123u, + 20129u, 20143u, 20147u, 20149u, 20161u, 20173u, 20177u, 20183u, 20201u, + 20219u, 20231u, 20233u, 20249u, 20261u, 20269u, 20287u, 20297u, 20323u, + 20327u, 20333u, 20341u, 20347u, 20353u, 20357u, 20359u, 20369u, 20389u, + 20393u, 20399u, 20407u, 20411u, 20431u, 20441u, 20443u, 20477u, 20479u, + 20483u, 20507u, 20509u, 20521u, 20533u, 20543u, 20549u, 20551u, 20563u, + 20593u, 20599u, 20611u, 20627u, 20639u, 20641u, 20663u, 20681u, 20693u, + 20707u, 20717u, 20719u, 20731u, 20743u, 20747u, 20749u, 20753u, 20759u, + 20771u, 20773u, 20789u, 20807u, 20809u, 20849u, 20857u, 20873u, 20879u, + 20887u, 20897u, 20899u, 20903u, 20921u, 20929u, 20939u, 20947u, 20959u, + 20963u, 20981u, 20983u, 21001u, 21011u, 21013u, 21017u, 21019u, 21023u, + 21031u, 21059u, 21061u, 21067u, 21089u, 21101u, 21107u, 21121u, 21139u, + 21143u, 21149u, 21157u, 21163u, 21169u, 21179u, 21187u, 21191u, 21193u, + 21211u, 21221u, 21227u, 21247u, 21269u, 21277u, 21283u, 21313u, 21317u, + 21319u, 21323u, 21341u, 21347u, 21377u, 21379u, 21383u, 21391u, 21397u, + 21401u, 21407u, 21419u, 21433u, 21467u, 21481u, 21487u, 21491u, 21493u, + 21499u, 21503u, 21517u, 21521u, 21523u, 21529u, 21557u, 21559u, 21563u, + 21569u, 21577u, 21587u, 21589u, 21599u, 21601u, 21611u, 21613u, 21617u, + 21647u, 21649u, 21661u, 21673u, 21683u, 21701u, 21713u, 21727u, 21737u, + 21739u, 21751u, 21757u, 21767u, 21773u, 21787u, 21799u, 21803u, 21817u, + 21821u, 21839u, 21841u, 21851u, 21859u, 21863u, 21871u, 21881u, 21893u, + 21911u, 21929u, 21937u, 21943u, 21961u, 21977u, 21991u, 21997u, 22003u, + 22013u, 22027u, 22031u, 22037u, 22039u, 22051u, 22063u, 22067u, 22073u, + 22079u, 22091u, 22093u, 22109u, 22111u, 22123u, 22129u, 22133u, 22147u, + 22153u, 22157u, 22159u, 22171u, 22189u, 22193u, 22229u, 22247u, 22259u, + 22271u, 22273u, 22277u, 22279u, 22283u, 22291u, 22303u, 22307u, 22343u, + 22349u, 22367u, 22369u, 22381u, 22391u, 22397u, 22409u, 22433u, 22441u, + 22447u, 22453u, 22469u, 22481u, 22483u, 22501u, 22511u, 22531u, 22541u, + 22543u, 22549u, 22567u, 22571u, 22573u, 22613u, 22619u, 22621u, 22637u, + 22639u, 22643u, 22651u, 22669u, 22679u, 22691u, 22697u, 22699u, 22709u, + 22717u, 22721u, 22727u, 22739u, 22741u, 22751u, 22769u, 22777u, 22783u, + 22787u, 22807u, 22811u, 22817u, 22853u, 22859u, 22861u, 22871u, 22877u, + 22901u, 22907u, 22921u, 22937u, 22943u, 22961u, 22963u, 22973u, 22993u, + 23003u, 23011u, 23017u, 23021u, 23027u, 23029u, 23039u, 23041u, 23053u, + 23057u, 23059u, 23063u, 23071u, 23081u, 23087u, 23099u, 23117u, 23131u, + 23143u, 23159u, 23167u, 23173u, 23189u, 23197u, 23201u, 23203u, 23209u, + 23227u, 23251u, 23269u, 23279u, 23291u, 23293u, 23297u, 23311u, 23321u, + 23327u, 23333u, 23339u, 23357u, 23369u, 23371u, 23399u, 23417u, 23431u, + 23447u, 23459u, 23473u, 23497u, 23509u, 23531u, 23537u, 23539u, 23549u, + 23557u, 23561u, 23563u, 23567u, 23581u, 23593u, 23599u, 23603u, 23609u, + 23623u, 23627u, 23629u, 23633u, 23663u, 23669u, 23671u, 23677u, 23687u, + 23689u, 23719u, 23741u, 23743u, 23747u, 23753u, 23761u, 23767u, 23773u, + 23789u, 23801u, 23813u, 23819u, 23827u, 23831u, 23833u, 23857u, 23869u, + 23873u, 23879u, 23887u, 23893u, 23899u, 23909u, 23911u, 23917u, 23929u, + 23957u, 23971u, 23977u, 23981u, 23993u, 24001u, 24007u, 24019u, 24023u, + 24029u, 24043u, 24049u, 24061u, 24071u, 24077u, 24083u, 24091u, 24097u, + 24103u, 24107u, 24109u, 24113u, 24121u, 24133u, 24137u, 24151u, 24169u, + 24179u, 24181u, 24197u, 24203u, 24223u, 24229u, 24239u, 24247u, 24251u, + 24281u, 24317u, 24329u, 24337u, 24359u, 24371u, 24373u, 24379u, 24391u, + 24407u, 24413u, 24419u, 24421u, 24439u, 24443u, 24469u, 24473u, 24481u, + 24499u, 24509u, 24517u, 24527u, 24533u, 24547u, 24551u, 24571u, 24593u, + 24611u, 24623u, 24631u, 24659u, 24671u, 24677u, 24683u, 24691u, 24697u, + 24709u, 24733u, 24749u, 24763u, 24767u, 24781u, 24793u, 24799u, 24809u, + 24821u, 24841u, 24847u, 24851u, 24859u, 24877u, 24889u, 24907u, 24917u, + 24919u, 24923u, 24943u, 24953u, 24967u, 24971u, 24977u, 24979u, 24989u, + 25013u, 25031u, 25033u, 25037u, 25057u, 25073u, 25087u, 25097u, 25111u, + 25117u, 25121u, 25127u, 25147u, 25153u, 25163u, 25169u, 25171u, 25183u, + 25189u, 25219u, 25229u, 25237u, 25243u, 25247u, 25253u, 25261u, 25301u, + 25303u, 25307u, 25309u, 25321u, 25339u, 25343u, 25349u, 25357u, 25367u, + 25373u, 25391u, 25409u, 25411u, 25423u, 25439u, 25447u, 25453u, 25457u, + 25463u, 25469u, 25471u, 25523u, 25537u, 25541u, 25561u, 25577u, 25579u, + 25583u, 25589u, 25601u, 25603u, 25609u, 25621u, 25633u, 25639u, 25643u, + 25657u, 25667u, 25673u, 25679u, 25693u, 25703u, 25717u, 25733u, 25741u, + 25747u, 25759u, 25763u, 25771u, 25793u, 25799u, 25801u, 25819u, 25841u, + 25847u, 25849u, 25867u, 25873u, 25889u, 25903u, 25913u, 25919u, 25931u, + 25933u, 25939u, 25943u, 25951u, 25969u, 25981u, 25997u, 25999u, 26003u, + 26017u, 26021u, 26029u, 26041u, 26053u, 26083u, 26099u, 26107u, 26111u, + 26113u, 26119u, 26141u, 26153u, 26161u, 26171u, 26177u, 26183u, 26189u, + 26203u, 26209u, 26227u, 26237u, 26249u, 26251u, 26261u, 26263u, 26267u, + 26293u, 26297u, 26309u, 26317u, 26321u, 26339u, 26347u, 26357u, 26371u, + 26387u, 26393u, 26399u, 26407u, 26417u, 26423u, 26431u, 26437u, 26449u, + 26459u, 26479u, 26489u, 26497u, 26501u, 26513u, 26539u, 26557u, 26561u, + 26573u, 26591u, 26597u, 26627u, 26633u, 26641u, 26647u, 26669u, 26681u, + 26683u, 26687u, 26693u, 26699u, 26701u, 26711u, 26713u, 26717u, 26723u, + 26729u, 26731u, 26737u, 26759u, 26777u, 26783u, 26801u, 26813u, 26821u, + 26833u, 26839u, 26849u, 26861u, 26863u, 26879u, 26881u, 26891u, 26893u, + 26903u, 26921u, 26927u, 26947u, 26951u, 26953u, 26959u, 26981u, 26987u, + 26993u, 27011u, 27017u, 27031u, 27043u, 27059u, 27061u, 27067u, 27073u, + 27077u, 27091u, 27103u, 27107u, 27109u, 27127u, 27143u, 27179u, 27191u, + 27197u, 27211u, 27239u, 27241u, 27253u, 27259u, 27271u, 27277u, 27281u, + 27283u, 27299u, 27329u, 27337u, 27361u, 27367u, 27397u, 27407u, 27409u, + 27427u, 27431u, 27437u, 27449u, 27457u, 27479u, 27481u, 27487u, 27509u, + 27527u, 27529u, 27539u, 27541u, 27551u, 27581u, 27583u, 27611u, 27617u, + 27631u, 27647u, 27653u, 27673u, 27689u, 27691u, 27697u, 27701u, 27733u, + 27737u, 27739u, 27743u, 27749u, 27751u, 27763u, 27767u, 27773u, 27779u, + 27791u, 27793u, 27799u, 27803u, 27809u, 27817u, 27823u, 27827u, 27847u, + 27851u, 27883u, 27893u, 27901u, 27917u, 27919u, 27941u, 27943u, 27947u, + 27953u, 27961u, 27967u, 27983u, 27997u, 28001u, 28019u, 28027u, 28031u, + 28051u, 28057u, 28069u, 28081u, 28087u, 28097u, 28099u, 28109u, 28111u, + 28123u, 28151u, 28163u, 28181u, 28183u, 28201u, 28211u, 28219u, 28229u, + 28277u, 28279u, 28283u, 28289u, 28297u, 28307u, 28309u, 28319u, 28349u, + 28351u, 28387u, 28393u, 28403u, 28409u, 28411u, 28429u, 28433u, 28439u, + 28447u, 28463u, 28477u, 28493u, 28499u, 28513u, 28517u, 28537u, 28541u, + 28547u, 28549u, 28559u, 28571u, 28573u, 28579u, 28591u, 28597u, 28603u, + 28607u, 28619u, 28621u, 28627u, 28631u, 28643u, 28649u, 28657u, 28661u, + 28663u, 28669u, 28687u, 28697u, 28703u, 28711u, 28723u, 28729u, 28751u, + 28753u, 28759u, 28771u, 28789u, 28793u, 28807u, 28813u, 28817u, 28837u, + 28843u, 28859u, 28867u, 28871u, 28879u, 28901u, 28909u, 28921u, 28927u, + 28933u, 28949u, 28961u, 28979u, 29009u, 29017u, 29021u, 29023u, 29027u, + 29033u, 29059u, 29063u, 29077u, 29101u, 29123u, 29129u, 29131u, 29137u, + 29147u, 29153u, 29167u, 29173u, 29179u, 29191u, 29201u, 29207u, 29209u, + 29221u, 29231u, 29243u, 29251u, 29269u, 29287u, 29297u, 29303u, 29311u, + 29327u, 29333u, 29339u, 29347u, 29363u, 29383u, 29387u, 29389u, 29399u, + 29401u, 29411u, 29423u, 29429u, 29437u, 29443u, 29453u, 29473u, 29483u, + 29501u, 29527u, 29531u, 29537u, 29567u, 29569u, 29573u, 29581u, 29587u, + 29599u, 29611u, 29629u, 29633u, 29641u, 29663u, 29669u, 29671u, 29683u, + 29717u, 29723u, 29741u, 29753u, 29759u, 29761u, 29789u, 29803u, 29819u, + 29833u, 29837u, 29851u, 29863u, 29867u, 29873u, 29879u, 29881u, 29917u, + 29921u, 29927u, 29947u, 29959u, 29983u, 29989u, 30011u, 30013u, 30029u, + 30047u, 30059u, 30071u, 30089u, 30091u, 30097u, 30103u, 30109u, 30113u, + 30119u, 30133u, 30137u, 30139u, 30161u, 30169u, 30181u, 30187u, 30197u, + 30203u, 30211u, 30223u, 30241u, 30253u, 30259u, 30269u, 30271u, 30293u, + 30307u, 30313u, 30319u, 30323u, 30341u, 30347u, 30367u, 30389u, 30391u, + 30403u, 30427u, 30431u, 30449u, 30467u, 30469u, 30491u, 30493u, 30497u, + 30509u, 30517u, 30529u, 30539u, 30553u, 30557u, 30559u, 30577u, 30593u, + 30631u, 30637u, 30643u, 30649u, 30661u, 30671u, 30677u, 30689u, 30697u, + 30703u, 30707u, 30713u, 30727u, 30757u, 30763u, 30773u, 30781u, 30803u, + 30809u, 30817u, 30829u, 30839u, 30841u, 30851u, 30853u, 30859u, 30869u, + 30871u, 30881u, 30893u, 30911u, 30931u, 30937u, 30941u, 30949u, 30971u, + 30977u, 30983u, 31013u, 31019u, 31033u, 31039u, 31051u, 31063u, 31069u, + 31079u, 31081u, 31091u, 31121u, 31123u, 31139u, 31147u, 31151u, 31153u, + 31159u, 31177u, 31181u, 31183u, 31189u, 31193u, 31219u, 31223u, 31231u, + 31237u, 31247u, 31249u, 31253u, 31259u, 31267u, 31271u, 31277u, 31307u, + 31319u, 31321u, 31327u, 31333u, 31337u, 31357u, 31379u, 31387u, 31391u, + 31393u, 31397u, 31469u, 31477u, 31481u, 31489u, 31511u, 31513u, 31517u, + 31531u, 31541u, 31543u, 31547u, 31567u, 31573u, 31583u, 31601u, 31607u, + 31627u, 31643u, 31649u, 31657u, 31663u, 31667u, 31687u, 31699u, 31721u, + 31723u, 31727u, 31729u, 31741u, 31751u, 31769u, 31771u, 31793u, 31799u, + 31817u, 31847u, 31849u, 31859u, 31873u, 31883u, 31891u, 31907u, 31957u, + 31963u, 31973u, 31981u, 31991u, 32003u, 32009u, 32027u, 32029u, 32051u, + 32057u, 32059u, 32063u, 32069u, 32077u, 32083u, 32089u, 32099u, 32117u, + 32119u, 32141u, 32143u, 32159u, 32173u, 32183u, 32189u, 32191u, 32203u, + 32213u, 32233u, 32237u, 32251u, 32257u, 32261u, 32297u, 32299u, 32303u, + 32309u, 32321u, 32323u, 32327u, 32341u, 32353u, 32359u, 32363u, 32369u, + 32371u, 32377u, 32381u, 32401u, 32411u, 32413u, 32423u, 32429u, 32441u, + 32443u, 32467u, 32479u, 32491u, 32497u, 32503u, 32507u, 32531u, 32533u, + 32537u, 32561u, 32563u, 32569u, 32573u, 32579u, 32587u, 32603u, 32609u, + 32611u, 32621u, 32633u, 32647u, 32653u, 32687u, 32693u, 32707u, 32713u, + 32717u, 32719u, 32749u, 32771u, 32779u, 32783u, 32789u, 32797u, 32801u, + 32803u, 32831u, 32833u, 32839u, 32843u, 32869u, 32887u, 32909u, 32911u, + 32917u, 32933u, 32939u, 32941u, 32957u, 32969u, 32971u, 32983u, 32987u, + 32993u, 32999u, 33013u, 33023u, 33029u, 33037u, 33049u, 33053u, 33071u, + 33073u, 33083u, 33091u, 33107u, 33113u, 33119u, 33149u, 33151u, 33161u, + 33179u, 33181u, 33191u, 33199u, 33203u, 33211u, 33223u, 33247u, 33287u, + 33289u, 33301u, 33311u, 33317u, 33329u, 33331u, 33343u, 33347u, 33349u, + 33353u, 33359u, 33377u, 33391u, 33403u, 33409u, 33413u, 33427u, 33457u, + 33461u, 33469u, 33479u, 33487u, 33493u, 33503u, 33521u, 33529u, 33533u, + 33547u, 33563u, 33569u, 33577u, 33581u, 33587u, 33589u, 33599u, 33601u, + 33613u, 33617u, 33619u, 33623u, 33629u, 33637u, 33641u, 33647u, 33679u, + 33703u, 33713u, 33721u, 33739u, 33749u, 33751u, 33757u, 33767u, 33769u, + 33773u, 33791u, 33797u, 33809u, 33811u, 33827u, 33829u, 33851u, 33857u, + 33863u, 33871u, 33889u, 33893u, 33911u, 33923u, 33931u, 33937u, 33941u, + 33961u, 33967u, 33997u, 34019u, 34031u, 34033u, 34039u, 34057u, 34061u, + 34123u, 34127u, 34129u, 34141u, 34147u, 34157u, 34159u, 34171u, 34183u, + 34211u, 34213u, 34217u, 34231u, 34253u, 34259u, 34261u, 34267u, 34273u, + 34283u, 34297u, 34301u, 34303u, 34313u, 34319u, 34327u, 34337u, 34351u, + 34361u, 34367u, 34369u, 34381u, 34403u, 34421u, 34429u, 34439u, 34457u, + 34469u, 34471u, 34483u, 34487u, 34499u, 34501u, 34511u, 34513u, 34519u, + 34537u, 34543u, 34549u, 34583u, 34589u, 34591u, 34603u, 34607u, 34613u, + 34631u, 34649u, 34651u, 34667u, 34673u, 34679u, 34687u, 34693u, 34703u, + 34721u, 34729u, 34739u, 34747u, 34757u, 34759u, 34763u, 34781u, 34807u, + 34819u, 34841u, 34843u, 34847u, 34849u, 34871u, 34877u, 34883u, 34897u, + 34913u, 34919u, 34939u, 34949u, 34961u, 34963u, 34981u, 35023u, 35027u, + 35051u, 35053u, 35059u, 35069u, 35081u, 35083u, 35089u, 35099u, 35107u, + 35111u, 35117u, 35129u, 35141u, 35149u, 35153u, 35159u, 35171u, 35201u, + 35221u, 35227u, 35251u, 35257u, 35267u, 35279u, 35281u, 35291u, 35311u, + 35317u, 35323u, 35327u, 35339u, 35353u, 35363u, 35381u, 35393u, 35401u, + 35407u, 35419u, 35423u, 35437u, 35447u, 35449u, 35461u, 35491u, 35507u, + 35509u, 35521u, 35527u, 35531u, 35533u, 35537u, 35543u, 35569u, 35573u, + 35591u, 35593u, 35597u, 35603u, 35617u, 35671u, 35677u, 35729u, 35731u, + 35747u, 35753u, 35759u, 35771u, 35797u, 35801u, 35803u, 35809u, 35831u, + 35837u, 35839u, 35851u, 35863u, 35869u, 35879u, 35897u, 35899u, 35911u, + 35923u, 35933u, 35951u, 35963u, 35969u, 35977u, 35983u, 35993u, 35999u, + 36007u, 36011u, 36013u, 36017u, 36037u, 36061u, 36067u, 36073u, 36083u, + 36097u, 36107u, 36109u, 36131u, 36137u, 36151u, 36161u, 36187u, 36191u, + 36209u, 36217u, 36229u, 36241u, 36251u, 36263u, 36269u, 36277u, 36293u, + 36299u, 36307u, 36313u, 36319u, 36341u, 36343u, 36353u, 36373u, 36383u, + 36389u, 36433u, 36451u, 36457u, 36467u, 36469u, 36473u, 36479u, 36493u, + 36497u, 36523u, 36527u, 36529u, 36541u, 36551u, 36559u, 36563u, 36571u, + 36583u, 36587u, 36599u, 36607u, 36629u, 36637u, 36643u, 36653u, 36671u, + 36677u, 36683u, 36691u, 36697u, 36709u, 36713u, 36721u, 36739u, 36749u, + 36761u, 36767u, 36779u, 36781u, 36787u, 36791u, 36793u, 36809u, 36821u, + 36833u, 36847u, 36857u, 36871u, 36877u, 36887u, 36899u, 36901u, 36913u, + 36919u, 36923u, 36929u, 36931u, 36943u, 36947u, 36973u, 36979u, 36997u, + 37003u, 37013u, 37019u, 37021u, 37039u, 37049u, 37057u, 37061u, 37087u, + 37097u, 37117u, 37123u, 37139u, 37159u, 37171u, 37181u, 37189u, 37199u, + 37201u, 37217u, 37223u, 37243u, 37253u, 37273u, 37277u, 37307u, 37309u, + 37313u, 37321u, 37337u, 37339u, 37357u, 37361u, 37363u, 37369u, 37379u, + 37397u, 37409u, 37423u, 37441u, 37447u, 37463u, 37483u, 37489u, 37493u, + 37501u, 37507u, 37511u, 37517u, 37529u, 37537u, 37547u, 37549u, 37561u, + 37567u, 37571u, 37573u, 37579u, 37589u, 37591u, 37607u, 37619u, 37633u, + 37643u, 37649u, 37657u, 37663u, 37691u, 37693u, 37699u, 37717u, 37747u, + 37781u, 37783u, 37799u, 37811u, 37813u, 37831u, 37847u, 37853u, 37861u, + 37871u, 37879u, 37889u, 37897u, 37907u, 37951u, 37957u, 37963u, 37967u, + 37987u, 37991u, 37993u, 37997u, 38011u, 38039u, 38047u, 38053u, 38069u, + 38083u, 38113u, 38119u, 38149u, 38153u, 38167u, 38177u, 38183u, 38189u, + 38197u, 38201u, 38219u, 38231u, 38237u, 38239u, 38261u, 38273u, 38281u, + 38287u, 38299u, 38303u, 38317u, 38321u, 38327u, 38329u, 38333u, 38351u, + 38371u, 38377u, 38393u, 38431u, 38447u, 38449u, 38453u, 38459u, 38461u, + 38501u, 38543u, 38557u, 38561u, 38567u, 38569u, 38593u, 38603u, 38609u, + 38611u, 38629u, 38639u, 38651u, 38653u, 38669u, 38671u, 38677u, 38693u, + 38699u, 38707u, 38711u, 38713u, 38723u, 38729u, 38737u, 38747u, 38749u, + 38767u, 38783u, 38791u, 38803u, 38821u, 38833u, 38839u, 38851u, 38861u, + 38867u, 38873u, 38891u, 38903u, 38917u, 38921u, 38923u, 38933u, 38953u, + 38959u, 38971u, 38977u, 38993u, 39019u, 39023u, 39041u, 39043u, 39047u, + 39079u, 39089u, 39097u, 39103u, 39107u, 39113u, 39119u, 39133u, 39139u, + 39157u, 39161u, 39163u, 39181u, 39191u, 39199u, 39209u, 39217u, 39227u, + 39229u, 39233u, 39239u, 39241u, 39251u, 39293u, 39301u, 39313u, 39317u, + 39323u, 39341u, 39343u, 39359u, 39367u, 39371u, 39373u, 39383u, 39397u, + 39409u, 39419u, 39439u, 39443u, 39451u, 39461u, 39499u, 39503u, 39509u, + 39511u, 39521u, 39541u, 39551u, 39563u, 39569u, 39581u, 39607u, 39619u, + 39623u, 39631u, 39659u, 39667u, 39671u, 39679u, 39703u, 39709u, 39719u, + 39727u, 39733u, 39749u, 39761u, 39769u, 39779u, 39791u, 39799u, 39821u, + 39827u, 39829u, 39839u, 39841u, 39847u, 39857u, 39863u, 39869u, 39877u, + 39883u, 39887u, 39901u, 39929u, 39937u, 39953u, 39971u, 39979u, 39983u, + 39989u, 40009u, 40013u, 40031u, 40037u, 40039u, 40063u, 40087u, 40093u, + 40099u, 40111u, 40123u, 40127u, 40129u, 40151u, 40153u, 40163u, 40169u, + 40177u, 40189u, 40193u, 40213u, 40231u, 40237u, 40241u, 40253u, 40277u, + 40283u, 40289u, 40343u, 40351u, 40357u, 40361u, 40387u, 40423u, 40427u, + 40429u, 40433u, 40459u, 40471u, 40483u, 40487u, 40493u, 40499u, 40507u, + 40519u, 40529u, 40531u, 40543u, 40559u, 40577u, 40583u, 40591u, 40597u, + 40609u, 40627u, 40637u, 40639u, 40693u, 40697u, 40699u, 40709u, 40739u, + 40751u, 40759u, 40763u, 40771u, 40787u, 40801u, 40813u, 40819u, 40823u, + 40829u, 40841u, 40847u, 40849u, 40853u, 40867u, 40879u, 40883u, 40897u, + 40903u, 40927u, 40933u, 40939u, 40949u, 40961u, 40973u, 40993u, 41011u, + 41017u, 41023u, 41039u, 41047u, 41051u, 41057u, 41077u, 41081u, 41113u, + 41117u, 41131u, 41141u, 41143u, 41149u, 41161u, 41177u, 41179u, 41183u, + 41189u, 41201u, 41203u, 41213u, 41221u, 41227u, 41231u, 41233u, 41243u, + 41257u, 41263u, 41269u, 41281u, 41299u, 41333u, 41341u, 41351u, 41357u, + 41381u, 41387u, 41389u, 41399u, 41411u, 41413u, 41443u, 41453u, 41467u, + 41479u, 41491u, 41507u, 41513u, 41519u, 41521u, 41539u, 41543u, 41549u, + 41579u, 41593u, 41597u, 41603u, 41609u, 41611u, 41617u, 41621u, 41627u, + 41641u, 41647u, 41651u, 41659u, 41669u, 41681u, 41687u, 41719u, 41729u, + 41737u, 41759u, 41761u, 41771u, 41777u, 41801u, 41809u, 41813u, 41843u, + 41849u, 41851u, 41863u, 41879u, 41887u, 41893u, 41897u, 41903u, 41911u, + 41927u, 41941u, 41947u, 41953u, 41957u, 41959u, 41969u, 41981u, 41983u, + 41999u, 42013u, 42017u, 42019u, 42023u, 42043u, 42061u, 42071u, 42073u, + 42083u, 42089u, 42101u, 42131u, 42139u, 42157u, 42169u, 42179u, 42181u, + 42187u, 42193u, 42197u, 42209u, 42221u, 42223u, 42227u, 42239u, 42257u, + 42281u, 42283u, 42293u, 42299u, 42307u, 42323u, 42331u, 42337u, 42349u, + 42359u, 42373u, 42379u, 42391u, 42397u, 42403u, 42407u, 42409u, 42433u, + 42437u, 42443u, 42451u, 42457u, 42461u, 42463u, 42467u, 42473u, 42487u, + 42491u, 42499u, 42509u, 42533u, 42557u, 42569u, 42571u, 42577u, 42589u, + 42611u, 42641u, 42643u, 42649u, 42667u, 42677u, 42683u, 42689u, 42697u, + 42701u, 42703u, 42709u, 42719u, 42727u, 42737u, 42743u, 42751u, 42767u, + 42773u, 42787u, 42793u, 42797u, 42821u, 42829u, 42839u, 42841u, 42853u, + 42859u, 42863u, 42899u, 42901u, 42923u, 42929u, 42937u, 42943u, 42953u, + 42961u, 42967u, 42979u, 42989u, 43003u, 43013u, 43019u, 43037u, 43049u, + 43051u, 43063u, 43067u, 43093u, 43103u, 43117u, 43133u, 43151u, 43159u, + 43177u, 43189u, 43201u, 43207u, 43223u, 43237u, 43261u, 43271u, 43283u, + 43291u, 43313u, 43319u, 43321u, 43331u, 43391u, 43397u, 43399u, 43403u, + 43411u, 43427u, 43441u, 43451u, 43457u, 43481u, 43487u, 43499u, 43517u, + 43541u, 43543u, 43573u, 43577u, 43579u, 43591u, 43597u, 43607u, 43609u, + 43613u, 43627u, 43633u, 43649u, 43651u, 43661u, 43669u, 43691u, 43711u, + 43717u, 43721u, 43753u, 43759u, 43777u, 43781u, 43783u, 43787u, 43789u, + 43793u, 43801u, 43853u, 43867u, 43889u, 43891u, 43913u, 43933u, 43943u, + 43951u, 43961u, 43963u, 43969u, 43973u, 43987u, 43991u, 43997u, 44017u, + 44021u, 44027u, 44029u, 44041u, 44053u, 44059u, 44071u, 44087u, 44089u, + 44101u, 44111u, 44119u, 44123u, 44129u, 44131u, 44159u, 44171u, 44179u, + 44189u, 44201u, 44203u, 44207u, 44221u, 44249u, 44257u, 44263u, 44267u, + 44269u, 44273u, 44279u, 44281u, 44293u, 44351u, 44357u, 44371u, 44381u, + 44383u, 44389u, 44417u, 44449u, 44453u, 44483u, 44491u, 44497u, 44501u, + 44507u, 44519u, 44531u, 44533u, 44537u, 44543u, 44549u, 44563u, 44579u, + 44587u, 44617u, 44621u, 44623u, 44633u, 44641u, 44647u, 44651u, 44657u, + 44683u, 44687u, 44699u, 44701u, 44711u, 44729u, 44741u, 44753u, 44771u, + 44773u, 44777u, 44789u, 44797u, 44809u, 44819u, 44839u, 44843u, 44851u, + 44867u, 44879u, 44887u, 44893u, 44909u, 44917u, 44927u, 44939u, 44953u, + 44959u, 44963u, 44971u, 44983u, 44987u, 45007u, 45013u, 45053u, 45061u, + 45077u, 45083u, 45119u, 45121u, 45127u, 45131u, 45137u, 45139u, 45161u, + 45179u, 45181u, 45191u, 45197u, 45233u, 45247u, 45259u, 45263u, 45281u, + 45289u, 45293u, 45307u, 45317u, 45319u, 45329u, 45337u, 45341u, 45343u, + 45361u, 45377u, 45389u, 45403u, 45413u, 45427u, 45433u, 45439u, 45481u, + 45491u, 45497u, 45503u, 45523u, 45533u, 45541u, 45553u, 45557u, 45569u, + 45587u, 45589u, 45599u, 45613u, 45631u, 45641u, 45659u, 45667u, 45673u, + 45677u, 45691u, 45697u, 45707u, 45737u, 45751u, 45757u, 45763u, 45767u, + 45779u, 45817u, 45821u, 45823u, 45827u, 45833u, 45841u, 45853u, 45863u, + 45869u, 45887u, 45893u, 45943u, 45949u, 45953u, 45959u, 45971u, 45979u, + 45989u, 46021u, 46027u, 46049u, 46051u, 46061u, 46073u, 46091u, 46093u, + 46099u, 46103u, 46133u, 46141u, 46147u, 46153u, 46171u, 46181u, 46183u, + 46187u, 46199u, 46219u, 46229u, 46237u, 46261u, 46271u, 46273u, 46279u, + 46301u, 46307u, 46309u, 46327u, 46337u, 46349u, 46351u, 46381u, 46399u, + 46411u, 46439u, 46441u, 46447u, 46451u, 46457u, 46471u, 46477u, 46489u, + 46499u, 46507u, 46511u, 46523u, 46549u, 46559u, 46567u, 46573u, 46589u, + 46591u, 46601u, 46619u, 46633u, 46639u, 46643u, 46649u, 46663u, 46679u, + 46681u, 46687u, 46691u, 46703u, 46723u, 46727u, 46747u, 46751u, 46757u, + 46769u, 46771u, 46807u, 46811u, 46817u, 46819u, 46829u, 46831u, 46853u, + 46861u, 46867u, 46877u, 46889u, 46901u, 46919u, 46933u, 46957u, 46993u, + 46997u, 47017u, 47041u, 47051u, 47057u, 47059u, 47087u, 47093u, 47111u, + 47119u, 47123u, 47129u, 47137u, 47143u, 47147u, 47149u, 47161u, 47189u, + 47207u, 47221u, 47237u, 47251u, 47269u, 47279u, 47287u, 47293u, 47297u, + 47303u, 47309u, 47317u, 47339u, 47351u, 47353u, 47363u, 47381u, 47387u, + 47389u, 47407u, 47417u, 47419u, 47431u, 47441u, 47459u, 47491u, 47497u, + 47501u, 47507u, 47513u, 47521u, 47527u, 47533u, 47543u, 47563u, 47569u, + 47581u, 47591u, 47599u, 47609u, 47623u, 47629u, 47639u, 47653u, 47657u, + 47659u, 47681u, 47699u, 47701u, 47711u, 47713u, 47717u, 47737u, 47741u, + 47743u, 47777u, 47779u, 47791u, 47797u, 47807u, 47809u, 47819u, 47837u, + 47843u, 47857u, 47869u, 47881u, 47903u, 47911u, 47917u, 47933u, 47939u, + 47947u, 47951u, 47963u, 47969u, 47977u, 47981u, 48017u, 48023u, 48029u, + 48049u, 48073u, 48079u, 48091u, 48109u, 48119u, 48121u, 48131u, 48157u, + 48163u, 48179u, 48187u, 48193u, 48197u, 48221u, 48239u, 48247u, 48259u, + 48271u, 48281u, 48299u, 48311u, 48313u, 48337u, 48341u, 48353u, 48371u, + 48383u, 48397u, 48407u, 48409u, 48413u, 48437u, 48449u, 48463u, 48473u, + 48479u, 48481u, 48487u, 48491u, 48497u, 48523u, 48527u, 48533u, 48539u, + 48541u, 48563u, 48571u, 48589u, 48593u, 48611u, 48619u, 48623u, 48647u, + 48649u, 48661u, 48673u, 48677u, 48679u, 48731u, 48733u, 48751u, 48757u, + 48761u, 48767u, 48779u, 48781u, 48787u, 48799u, 48809u, 48817u, 48821u, + 48823u, 48847u, 48857u, 48859u, 48869u, 48871u, 48883u, 48889u, 48907u, + 48947u, 48953u, 48973u, 48989u, 48991u, 49003u, 49009u, 49019u, 49031u, + 49033u, 49037u, 49043u, 49057u, 49069u, 49081u, 49103u, 49109u, 49117u, + 49121u, 49123u, 49139u, 49157u, 49169u, 49171u, 49177u, 49193u, 49199u, + 49201u, 49207u, 49211u, 49223u, 49253u, 49261u, 49277u, 49279u, 49297u, + 49307u, 49331u, 49333u, 49339u, 49363u, 49367u, 49369u, 49391u, 49393u, + 49409u, 49411u, 49417u, 49429u, 49433u, 49451u, 49459u, 49463u, 49477u, + 49481u, 49499u, 49523u, 49529u, 49531u, 49537u, 49547u, 49549u, 49559u, + 49597u, 49603u, 49613u, 49627u, 49633u, 49639u, 49663u, 49667u, 49669u, + 49681u, 49697u, 49711u, 49727u, 49739u, 49741u, 49747u, 49757u, 49783u, + 49787u, 49789u, 49801u, 49807u, 49811u, 49823u, 49831u, 49843u, 49853u, + 49871u, 49877u, 49891u, 49919u, 49921u, 49927u, 49937u, 49939u, 49943u, + 49957u, 49991u, 49993u, 49999u, 50021u, 50023u, 50033u, 50047u, 50051u, + 50053u, 50069u, 50077u, 50087u, 50093u, 50101u, 50111u, 50119u, 50123u, + 50129u, 50131u, 50147u, 50153u, 50159u, 50177u, 50207u, 50221u, 50227u, + 50231u, 50261u, 50263u, 50273u, 50287u, 50291u, 50311u, 50321u, 50329u, + 50333u, 50341u, 50359u, 50363u, 50377u, 50383u, 50387u, 50411u, 50417u, + 50423u, 50441u, 50459u, 50461u, 50497u, 50503u, 50513u, 50527u, 50539u, + 50543u, 50549u, 50551u, 50581u, 50587u, 50591u, 50593u, 50599u, 50627u, + 50647u, 50651u, 50671u, 50683u, 50707u, 50723u, 50741u, 50753u, 50767u, + 50773u, 50777u, 50789u, 50821u, 50833u, 50839u, 50849u, 50857u, 50867u, + 50873u, 50891u, 50893u, 50909u, 50923u, 50929u, 50951u, 50957u, 50969u, + 50971u, 50989u, 50993u, 51001u, 51031u, 51043u, 51047u, 51059u, 51061u, + 51071u, 51109u, 51131u, 51133u, 51137u, 51151u, 51157u, 51169u, 51193u, + 51197u, 51199u, 51203u, 51217u, 51229u, 51239u, 51241u, 51257u, 51263u, + 51283u, 51287u, 51307u, 51329u, 51341u, 51343u, 51347u, 51349u, 51361u, + 51383u, 51407u, 51413u, 51419u, 51421u, 51427u, 51431u, 51437u, 51439u, + 51449u, 51461u, 51473u, 51479u, 51481u, 51487u, 51503u, 51511u, 51517u, + 51521u, 51539u, 51551u, 51563u, 51577u, 51581u, 51593u, 51599u, 51607u, + 51613u, 51631u, 51637u, 51647u, 51659u, 51673u, 51679u, 51683u, 51691u, + 51713u, 51719u, 51721u, 51749u, 51767u, 51769u, 51787u, 51797u, 51803u, + 51817u, 51827u, 51829u, 51839u, 51853u, 51859u, 51869u, 51871u, 51893u, + 51899u, 51907u, 51913u, 51929u, 51941u, 51949u, 51971u, 51973u, 51977u, + 51991u, 52009u, 52021u, 52027u, 52051u, 52057u, 52067u, 52069u, 52081u, + 52103u, 52121u, 52127u, 52147u, 52153u, 52163u, 52177u, 52181u, 52183u, + 52189u, 52201u, 52223u, 52237u, 52249u, 52253u, 52259u, 52267u, 52289u, + 52291u, 52301u, 52313u, 52321u, 52361u, 52363u, 52369u, 52379u, 52387u, + 52391u, 52433u, 52453u, 52457u, 52489u, 52501u, 52511u, 52517u, 52529u, + 52541u, 52543u, 52553u, 52561u, 52567u, 52571u, 52579u, 52583u, 52609u, + 52627u, 52631u, 52639u, 52667u, 52673u, 52691u, 52697u, 52709u, 52711u, + 52721u, 52727u, 52733u, 52747u, 52757u, 52769u, 52783u, 52807u, 52813u, + 52817u, 52837u, 52859u, 52861u, 52879u, 52883u, 52889u, 52901u, 52903u, + 52919u, 52937u, 52951u, 52957u, 52963u, 52967u, 52973u, 52981u, 52999u, + 53003u, 53017u, 53047u, 53051u, 53069u, 53077u, 53087u, 53089u, 53093u, + 53101u, 53113u, 53117u, 53129u, 53147u, 53149u, 53161u, 53171u, 53173u, + 53189u, 53197u, 53201u, 53231u, 53233u, 53239u, 53267u, 53269u, 53279u, + 53281u, 53299u, 53309u, 53323u, 53327u, 53353u, 53359u, 53377u, 53381u, + 53401u, 53407u, 53411u, 53419u, 53437u, 53441u, 53453u, 53479u, 53503u, + 53507u, 53527u, 53549u, 53551u, 53569u, 53591u, 53593u, 53597u, 53609u, + 53611u, 53617u, 53623u, 53629u, 53633u, 53639u, 53653u, 53657u, 53681u, + 53693u, 53699u, 53717u, 53719u, 53731u, 53759u, 53773u, 53777u, 53783u, + 53791u, 53813u, 53819u, 53831u, 53849u, 53857u, 53861u, 53881u, 53887u, + 53891u, 53897u, 53899u, 53917u, 53923u, 53927u, 53939u, 53951u, 53959u, + 53987u, 53993u, 54001u, 54011u, 54013u, 54037u, 54049u, 54059u, 54083u, + 54091u, 54101u, 54121u, 54133u, 54139u, 54151u, 54163u, 54167u, 54181u, + 54193u, 54217u, 54251u, 54269u, 54277u, 54287u, 54293u, 54311u, 54319u, + 54323u, 54331u, 54347u, 54361u, 54367u, 54371u, 54377u, 54401u, 54403u, + 54409u, 54413u, 54419u, 54421u, 54437u, 54443u, 54449u, 54469u, 54493u, + 54497u, 54499u, 54503u, 54517u, 54521u, 54539u, 54541u, 54547u, 54559u, + 54563u, 54577u, 54581u, 54583u, 54601u, 54617u, 54623u, 54629u, 54631u, + 54647u, 54667u, 54673u, 54679u, 54709u, 54713u, 54721u, 54727u, 54751u, + 54767u, 54773u, 54779u, 54787u, 54799u, 54829u, 54833u, 54851u, 54869u, + 54877u, 54881u, 54907u, 54917u, 54919u, 54941u, 54949u, 54959u, 54973u, + 54979u, 54983u, 55001u, 55009u, 55021u, 55049u, 55051u, 55057u, 55061u, + 55073u, 55079u, 55103u, 55109u, 55117u, 55127u, 55147u, 55163u, 55171u, + 55201u, 55207u, 55213u, 55217u, 55219u, 55229u, 55243u, 55249u, 55259u, + 55291u, 55313u, 55331u, 55333u, 55337u, 55339u, 55343u, 55351u, 55373u, + 55381u, 55399u, 55411u, 55439u, 55441u, 55457u, 55469u, 55487u, 55501u, + 55511u, 55529u, 55541u, 55547u, 55579u, 55589u, 55603u, 55609u, 55619u, + 55621u, 55631u, 55633u, 55639u, 55661u, 55663u, 55667u, 55673u, 55681u, + 55691u, 55697u, 55711u, 55717u, 55721u, 55733u, 55763u, 55787u, 55793u, + 55799u, 55807u, 55813u, 55817u, 55819u, 55823u, 55829u, 55837u, 55843u, + 55849u, 55871u, 55889u, 55897u, 55901u, 55903u, 55921u, 55927u, 55931u, + 55933u, 55949u, 55967u, 55987u, 55997u, 56003u, 56009u, 56039u, 56041u, + 56053u, 56081u, 56087u, 56093u, 56099u, 56101u, 56113u, 56123u, 56131u, + 56149u, 56167u, 56171u, 56179u, 56197u, 56207u, 56209u, 56237u, 56239u, + 56249u, 56263u, 56267u, 56269u, 56299u, 56311u, 56333u, 56359u, 56369u, + 56377u, 56383u, 56393u, 56401u, 56417u, 56431u, 56437u, 56443u, 56453u, + 56467u, 56473u, 56477u, 56479u, 56489u, 56501u, 56503u, 56509u, 56519u, + 56527u, 56531u, 56533u, 56543u, 56569u, 56591u, 56597u, 56599u, 56611u, + 56629u, 56633u, 56659u, 56663u, 56671u, 56681u, 56687u, 56701u, 56711u, + 56713u, 56731u, 56737u, 56747u, 56767u, 56773u, 56779u, 56783u, 56807u, + 56809u, 56813u, 56821u, 56827u, 56843u, 56857u, 56873u, 56891u, 56893u, + 56897u, 56909u, 56911u, 56921u, 56923u, 56929u, 56941u, 56951u, 56957u, + 56963u, 56983u, 56989u, 56993u, 56999u, 57037u, 57041u, 57047u, 57059u, + 57073u, 57077u, 57089u, 57097u, 57107u, 57119u, 57131u, 57139u, 57143u, + 57149u, 57163u, 57173u, 57179u, 57191u, 57193u, 57203u, 57221u, 57223u, + 57241u, 57251u, 57259u, 57269u, 57271u, 57283u, 57287u, 57301u, 57329u, + 57331u, 57347u, 57349u, 57367u, 57373u, 57383u, 57389u, 57397u, 57413u, + 57427u, 57457u, 57467u, 57487u, 57493u, 57503u, 57527u, 57529u, 57557u, + 57559u, 57571u, 57587u, 57593u, 57601u, 57637u, 57641u, 57649u, 57653u, + 57667u, 57679u, 57689u, 57697u, 57709u, 57713u, 57719u, 57727u, 57731u, + 57737u, 57751u, 57773u, 57781u, 57787u, 57791u, 57793u, 57803u, 57809u, + 57829u, 57839u, 57847u, 57853u, 57859u, 57881u, 57899u, 57901u, 57917u, + 57923u, 57943u, 57947u, 57973u, 57977u, 57991u, 58013u, 58027u, 58031u, + 58043u, 58049u, 58057u, 58061u, 58067u, 58073u, 58099u, 58109u, 58111u, + 58129u, 58147u, 58151u, 58153u, 58169u, 58171u, 58189u, 58193u, 58199u, + 58207u, 58211u, 58217u, 58229u, 58231u, 58237u, 58243u, 58271u, 58309u, + 58313u, 58321u, 58337u, 58363u, 58367u, 58369u, 58379u, 58391u, 58393u, + 58403u, 58411u, 58417u, 58427u, 58439u, 58441u, 58451u, 58453u, 58477u, + 58481u, 58511u, 58537u, 58543u, 58549u, 58567u, 58573u, 58579u, 58601u, + 58603u, 58613u, 58631u, 58657u, 58661u, 58679u, 58687u, 58693u, 58699u, + 58711u, 58727u, 58733u, 58741u, 58757u, 58763u, 58771u, 58787u, 58789u, + 58831u, 58889u, 58897u, 58901u, 58907u, 58909u, 58913u, 58921u, 58937u, + 58943u, 58963u, 58967u, 58979u, 58991u, 58997u, 59009u, 59011u, 59021u, + 59023u, 59029u, 59051u, 59053u, 59063u, 59069u, 59077u, 59083u, 59093u, + 59107u, 59113u, 59119u, 59123u, 59141u, 59149u, 59159u, 59167u, 59183u, + 59197u, 59207u, 59209u, 59219u, 59221u, 59233u, 59239u, 59243u, 59263u, + 59273u, 59281u, 59333u, 59341u, 59351u, 59357u, 59359u, 59369u, 59377u, + 59387u, 59393u, 59399u, 59407u, 59417u, 59419u, 59441u, 59443u, 59447u, + 59453u, 59467u, 59471u, 59473u, 59497u, 59509u, 59513u, 59539u, 59557u, + 59561u, 59567u, 59581u, 59611u, 59617u, 59621u, 59627u, 59629u, 59651u, + 59659u, 59663u, 59669u, 59671u, 59693u, 59699u, 59707u, 59723u, 59729u, + 59743u, 59747u, 59753u, 59771u, 59779u, 59791u, 59797u, 59809u, 59833u, + 59863u, 59879u, 59887u, 59921u, 59929u, 59951u, 59957u, 59971u, 59981u, + 59999u, 60013u, 60017u, 60029u, 60037u, 60041u, 60077u, 60083u, 60089u, + 60091u, 60101u, 60103u, 60107u, 60127u, 60133u, 60139u, 60149u, 60161u, + 60167u, 60169u, 60209u, 60217u, 60223u, 60251u, 60257u, 60259u, 60271u, + 60289u, 60293u, 60317u, 60331u, 60337u, 60343u, 60353u, 60373u, 60383u, + 60397u, 60413u, 60427u, 60443u, 60449u, 60457u, 60493u, 60497u, 60509u, + 60521u, 60527u, 60539u, 60589u, 60601u, 60607u, 60611u, 60617u, 60623u, + 60631u, 60637u, 60647u, 60649u, 60659u, 60661u, 60679u, 60689u, 60703u, + 60719u, 60727u, 60733u, 60737u, 60757u, 60761u, 60763u, 60773u, 60779u, + 60793u, 60811u, 60821u, 60859u, 60869u, 60887u, 60889u, 60899u, 60901u, + 60913u, 60917u, 60919u, 60923u, 60937u, 60943u, 60953u, 60961u, 61001u, + 61007u, 61027u, 61031u, 61043u, 61051u, 61057u, 61091u, 61099u, 61121u, + 61129u, 61141u, 61151u, 61153u, 61169u, 61211u, 61223u, 61231u, 61253u, + 61261u, 61283u, 61291u, 61297u, 61331u, 61333u, 61339u, 61343u, 61357u, + 61363u, 61379u, 61381u, 61403u, 61409u, 61417u, 61441u, 61463u, 61469u, + 61471u, 61483u, 61487u, 61493u, 61507u, 61511u, 61519u, 61543u, 61547u, + 61553u, 61559u, 61561u, 61583u, 61603u, 61609u, 61613u, 61627u, 61631u, + 61637u, 61643u, 61651u, 61657u, 61667u, 61673u, 61681u, 61687u, 61703u, + 61717u, 61723u, 61729u, 61751u, 61757u, 61781u, 61813u, 61819u, 61837u, + 61843u, 61861u, 61871u, 61879u, 61909u, 61927u, 61933u, 61949u, 61961u, + 61967u, 61979u, 61981u, 61987u, 61991u, 62003u, 62011u, 62017u, 62039u, + 62047u, 62053u, 62057u, 62071u, 62081u, 62099u, 62119u, 62129u, 62131u, + 62137u, 62141u, 62143u, 62171u, 62189u, 62191u, 62201u, 62207u, 62213u, + 62219u, 62233u, 62273u, 62297u, 62299u, 62303u, 62311u, 62323u, 62327u, + 62347u, 62351u, 62383u, 62401u, 62417u, 62423u, 62459u, 62467u, 62473u, + 62477u, 62483u, 62497u, 62501u, 62507u, 62533u, 62539u, 62549u, 62563u, + 62581u, 62591u, 62597u, 62603u, 62617u, 62627u, 62633u, 62639u, 62653u, + 62659u, 62683u, 62687u, 62701u, 62723u, 62731u, 62743u, 62753u, 62761u, + 62773u, 62791u, 62801u, 62819u, 62827u, 62851u, 62861u, 62869u, 62873u, + 62897u, 62903u, 62921u, 62927u, 62929u, 62939u, 62969u, 62971u, 62981u, + 62983u, 62987u, 62989u, 63029u, 63031u, 63059u, 63067u, 63073u, 63079u, + 63097u, 63103u, 63113u, 63127u, 63131u, 63149u, 63179u, 63197u, 63199u, + 63211u, 63241u, 63247u, 63277u, 63281u, 63299u, 63311u, 63313u, 63317u, + 63331u, 63337u, 63347u, 63353u, 63361u, 63367u, 63377u, 63389u, 63391u, + 63397u, 63409u, 63419u, 63421u, 63439u, 63443u, 63463u, 63467u, 63473u, + 63487u, 63493u, 63499u, 63521u, 63527u, 63533u, 63541u, 63559u, 63577u, + 63587u, 63589u, 63599u, 63601u, 63607u, 63611u, 63617u, 63629u, 63647u, + 63649u, 63659u, 63667u, 63671u, 63689u, 63691u, 63697u, 63703u, 63709u, + 63719u, 63727u, 63737u, 63743u, 63761u, 63773u, 63781u, 63793u, 63799u, + 63803u, 63809u, 63823u, 63839u, 63841u, 63853u, 63857u, 63863u, 63901u, + 63907u, 63913u, 63929u, 63949u, 63977u, 63997u, 64007u, 64013u, 64019u, + 64033u, 64037u, 64063u, 64067u, 64081u, 64091u, 64109u, 64123u, 64151u, + 64153u, 64157u, 64171u, 64187u, 64189u, 64217u, 64223u, 64231u, 64237u, + 64271u, 64279u, 64283u, 64301u, 64303u, 64319u, 64327u, 64333u, 64373u, + 64381u, 64399u, 64403u, 64433u, 64439u, 64451u, 64453u, 64483u, 64489u, + 64499u, 64513u, 64553u, 64567u, 64577u, 64579u, 64591u, 64601u, 64609u, + 64613u, 64621u, 64627u, 64633u, 64661u, 64663u, 64667u, 64679u, 64693u, + 64709u, 64717u, 64747u, 64763u, 64781u, 64783u, 64793u, 64811u, 64817u, + 64849u, 64853u, 64871u, 64877u, 64879u, 64891u, 64901u, 64919u, 64921u, + 64927u, 64937u, 64951u, 64969u, 64997u, 65003u, 65011u, 65027u, 65029u, + 65033u, 65053u, 65063u, 65071u, 65089u, 65099u, 65101u, 65111u, 65119u, + 65123u, 65129u, 65141u, 65147u, 65167u, 65171u, 65173u, 65179u, 65183u, + 65203u, 65213u, 65239u, 65257u, 65267u, 65269u, 65287u, 65293u, 65309u, + 65323u, 65327u, 65353u, 65357u, 65371u, 65381u, 65393u, 65407u, 65413u, + 65419u, 65423u, 65437u, 65447u, 65449u, 65479u, 65497u, 65519u, 65521u + }}; +#ifdef BOOST_MATH_HAVE_CONSTEXPR_TABLES + constexpr std::array a3 = {{ +#else + static const std::array a3 = {{ +#endif + 2u, 4u, 8u, 16u, 22u, 28u, 44u, + 46u, 52u, 64u, 74u, 82u, 94u, 98u, 112u, + 116u, 122u, 142u, 152u, 164u, 166u, 172u, 178u, + 182u, 184u, 194u, 196u, 226u, 242u, 254u, 274u, + 292u, 296u, 302u, 304u, 308u, 316u, 332u, 346u, + 364u, 386u, 392u, 394u, 416u, 422u, 428u, 446u, + 448u, 458u, 494u, 502u, 506u, 512u, 532u, 536u, + 548u, 554u, 568u, 572u, 574u, 602u, 626u, 634u, + 638u, 644u, 656u, 686u, 704u, 736u, 758u, 766u, + 802u, 808u, 812u, 824u, 826u, 838u, 842u, 848u, + 868u, 878u, 896u, 914u, 922u, 928u, 932u, 956u, + 964u, 974u, 988u, 994u, 998u, 1006u, 1018u, 1034u, + 1036u, 1052u, 1058u, 1066u, 1082u, 1094u, 1108u, 1118u, + 1148u, 1162u, 1166u, 1178u, 1186u, 1198u, 1204u, 1214u, + 1216u, 1228u, 1256u, 1262u, 1274u, 1286u, 1306u, 1316u, + 1318u, 1328u, 1342u, 1348u, 1354u, 1384u, 1388u, 1396u, + 1408u, 1412u, 1414u, 1424u, 1438u, 1442u, 1468u, 1486u, + 1498u, 1508u, 1514u, 1522u, 1526u, 1538u, 1544u, 1568u, + 1586u, 1594u, 1604u, 1606u, 1618u, 1622u, 1634u, 1646u, + 1652u, 1654u, 1676u, 1678u, 1682u, 1684u, 1696u, 1712u, + 1726u, 1736u, 1738u, 1754u, 1772u, 1804u, 1808u, 1814u, + 1834u, 1856u, 1864u, 1874u, 1876u, 1886u, 1892u, 1894u, + 1898u, 1912u, 1918u, 1942u, 1946u, 1954u, 1958u, 1964u, + 1976u, 1988u, 1996u, 2002u, 2012u, 2024u, 2032u, 2042u, + 2044u, 2054u, 2066u, 2072u, 2084u, 2096u, 2116u, 2144u, + 2164u, 2174u, 2188u, 2198u, 2206u, 2216u, 2222u, 2224u, + 2228u, 2242u, 2248u, 2254u, 2266u, 2272u, 2284u, 2294u, + 2308u, 2318u, 2332u, 2348u, 2356u, 2366u, 2392u, 2396u, + 2398u, 2404u, 2408u, 2422u, 2426u, 2432u, 2444u, 2452u, + 2458u, 2488u, 2506u, 2518u, 2524u, 2536u, 2552u, 2564u, + 2576u, 2578u, 2606u, 2612u, 2626u, 2636u, 2672u, 2674u, + 2678u, 2684u, 2692u, 2704u, 2726u, 2744u, 2746u, 2776u, + 2794u, 2816u, 2836u, 2854u, 2864u, 2902u, 2908u, 2912u, + 2914u, 2938u, 2942u, 2948u, 2954u, 2956u, 2966u, 2972u, + 2986u, 2996u, 3004u, 3008u, 3032u, 3046u, 3062u, 3076u, + 3098u, 3104u, 3124u, 3134u, 3148u, 3152u, 3164u, 3176u, + 3178u, 3194u, 3202u, 3208u, 3214u, 3232u, 3236u, 3242u, + 3256u, 3278u, 3284u, 3286u, 3328u, 3344u, 3346u, 3356u, + 3362u, 3364u, 3368u, 3374u, 3382u, 3392u, 3412u, 3428u, + 3458u, 3466u, 3476u, 3484u, 3494u, 3496u, 3526u, 3532u, + 3538u, 3574u, 3584u, 3592u, 3608u, 3614u, 3616u, 3628u, + 3656u, 3658u, 3662u, 3668u, 3686u, 3698u, 3704u, 3712u, + 3722u, 3724u, 3728u, 3778u, 3782u, 3802u, 3806u, 3836u, + 3844u, 3848u, 3854u, 3866u, 3868u, 3892u, 3896u, 3904u, + 3922u, 3928u, 3932u, 3938u, 3946u, 3956u, 3958u, 3962u, + 3964u, 4004u, 4022u, 4058u, 4088u, 4118u, 4126u, 4142u, + 4156u, 4162u, 4174u, 4202u, 4204u, 4226u, 4228u, 4232u, + 4244u, 4274u, 4286u, 4292u, 4294u, 4298u, 4312u, 4322u, + 4324u, 4342u, 4364u, 4376u, 4394u, 4396u, 4406u, 4424u, + 4456u, 4462u, 4466u, 4468u, 4474u, 4484u, 4504u, 4516u, + 4526u, 4532u, 4544u, 4564u, 4576u, 4582u, 4586u, 4588u, + 4604u, 4606u, 4622u, 4628u, 4642u, 4646u, 4648u, 4664u, + 4666u, 4672u, 4688u, 4694u, 4702u, 4706u, 4714u, 4736u, + 4754u, 4762u, 4774u, 4778u, 4786u, 4792u, 4816u, 4838u, + 4844u, 4846u, 4858u, 4888u, 4894u, 4904u, 4916u, 4922u, + 4924u, 4946u, 4952u, 4954u, 4966u, 4972u, 4994u, 5002u, + 5014u, 5036u, 5038u, 5048u, 5054u, 5072u, 5084u, 5086u, + 5092u, 5104u, 5122u, 5128u, 5132u, 5152u, 5174u, 5182u, + 5194u, 5218u, 5234u, 5248u, 5258u, 5288u, 5306u, 5308u, + 5314u, 5318u, 5332u, 5342u, 5344u, 5356u, 5366u, 5378u, + 5384u, 5386u, 5402u, 5414u, 5416u, 5422u, 5434u, 5444u, + 5446u, 5456u, 5462u, 5464u, 5476u, 5488u, 5504u, 5524u, + 5534u, 5546u, 5554u, 5584u, 5594u, 5608u, 5612u, 5618u, + 5626u, 5632u, 5636u, 5656u, 5674u, 5698u, 5702u, 5714u, + 5722u, 5726u, 5728u, 5752u, 5758u, 5782u, 5792u, 5794u, + 5798u, 5804u, 5806u, 5812u, 5818u, 5824u, 5828u, 5852u, + 5854u, 5864u, 5876u, 5878u, 5884u, 5894u, 5902u, 5908u, + 5918u, 5936u, 5938u, 5944u, 5948u, 5968u, 5992u, 6002u, + 6014u, 6016u, 6028u, 6034u, 6058u, 6062u, 6098u, 6112u, + 6128u, 6136u, 6158u, 6164u, 6172u, 6176u, 6178u, 6184u, + 6206u, 6226u, 6242u, 6254u, 6272u, 6274u, 6286u, 6302u, + 6308u, 6314u, 6326u, 6332u, 6344u, 6346u, 6352u, 6364u, + 6374u, 6382u, 6398u, 6406u, 6412u, 6428u, 6436u, 6448u, + 6452u, 6458u, 6464u, 6484u, 6496u, 6508u, 6512u, 6518u, + 6538u, 6542u, 6554u, 6556u, 6566u, 6568u, 6574u, 6604u, + 6626u, 6632u, 6634u, 6638u, 6676u, 6686u, 6688u, 6692u, + 6694u, 6716u, 6718u, 6734u, 6736u, 6742u, 6752u, 6772u, + 6778u, 6802u, 6806u, 6818u, 6832u, 6844u, 6848u, 6886u, + 6896u, 6926u, 6932u, 6934u, 6946u, 6958u, 6962u, 6968u, + 6998u, 7012u, 7016u, 7024u, 7042u, 7078u, 7082u, 7088u, + 7108u, 7112u, 7114u, 7126u, 7136u, 7138u, 7144u, 7154u, + 7166u, 7172u, 7184u, 7192u, 7198u, 7204u, 7228u, 7232u, + 7262u, 7282u, 7288u, 7324u, 7334u, 7336u, 7348u, 7354u, + 7358u, 7366u, 7372u, 7376u, 7388u, 7396u, 7402u, 7414u, + 7418u, 7424u, 7438u, 7442u, 7462u, 7474u, 7478u, 7484u, + 7502u, 7504u, 7508u, 7526u, 7528u, 7544u, 7556u, 7586u, + 7592u, 7598u, 7606u, 7646u, 7654u, 7702u, 7708u, 7724u, + 7742u, 7756u, 7768u, 7774u, 7792u, 7796u, 7816u, 7826u, + 7828u, 7834u, 7844u, 7852u, 7882u, 7886u, 7898u, 7918u, + 7924u, 7936u, 7942u, 7948u, 7982u, 7988u, 7994u, 8012u, + 8018u, 8026u, 8036u, 8048u, 8054u, 8062u, 8072u, 8074u, + 8078u, 8102u, 8108u, 8116u, 8138u, 8144u, 8146u, 8158u, + 8164u, 8174u, 8186u, 8192u, 8216u, 8222u, 8236u, 8248u, + 8284u, 8288u, 8312u, 8314u, 8324u, 8332u, 8342u, 8348u, + 8362u, 8372u, 8404u, 8408u, 8416u, 8426u, 8438u, 8464u, + 8482u, 8486u, 8492u, 8512u, 8516u, 8536u, 8542u, 8558u, + 8564u, 8566u, 8596u, 8608u, 8614u, 8624u, 8626u, 8632u, + 8642u, 8654u, 8662u, 8666u, 8668u, 8674u, 8684u, 8696u, + 8722u, 8744u, 8752u, 8758u, 8762u, 8776u, 8782u, 8788u, + 8818u, 8822u, 8828u, 8842u, 8846u, 8848u, 8876u, 8878u, + 8884u, 8906u, 8914u, 8918u, 8936u, 8954u, 8972u, 8974u, + 8986u, 8992u, 8996u, 9016u, 9026u, 9032u, 9038u, 9052u, + 9062u, 9074u, 9076u, 9088u, 9118u, 9152u, 9164u, 9172u, + 9178u, 9182u, 9184u, 9194u, 9196u, 9212u, 9224u, 9226u, + 9236u, 9244u, 9262u, 9286u, 9292u, 9296u, 9308u, 9322u, + 9326u, 9334u, 9338u, 9352u, 9356u, 9362u, 9368u, 9388u, + 9394u, 9398u, 9406u, 9424u, 9476u, 9478u, 9482u, 9494u, + 9502u, 9506u, 9544u, 9548u, 9574u, 9598u, 9614u, 9626u, + 9632u, 9634u, 9646u, 9658u, 9674u, 9676u, 9682u, 9688u, + 9692u, 9704u, 9718u, 9734u, 9742u, 9754u, 9772u, 9788u, + 9794u, 9802u, 9812u, 9818u, 9832u, 9842u, 9854u, 9856u, + 9866u, 9868u, 9872u, 9896u, 9902u, 9944u, 9968u, 9976u, + 9986u, 9992u, 9998u, 10004u, 10006u, 10018u, 10022u, 10036u, + 10042u, 10048u, 10076u, 10082u, 10084u, 10094u, 10106u, 10118u, + 10124u, 10144u, 10148u, 10154u, 10168u, 10172u, 10174u, 10186u, + 10196u, 10208u, 10232u, 10238u, 10246u, 10252u, 10258u, 10262u, + 10286u, 10298u, 10318u, 10334u, 10348u, 10378u, 10396u, 10402u, + 10406u, 10432u, 10444u, 10448u, 10454u, 10456u, 10462u, 10466u, + 10468u, 10496u, 10504u, 10544u, 10546u, 10556u, 10564u, 10568u, + 10588u, 10594u, 10612u, 10622u, 10624u, 10628u, 10672u, 10678u, + 10696u, 10708u, 10714u, 10718u, 10724u, 10726u, 10748u, 10754u, + 10768u, 10798u, 10808u, 10832u, 10834u, 10844u, 10852u, 10868u, + 10886u, 10888u, 10906u, 10928u, 10936u, 10946u, 10952u, 10958u, + 10972u, 10976u, 10984u, 11002u, 11006u, 11008u, 11026u, 11044u, + 11062u, 11068u, 11072u, 11096u, 11114u, 11116u, 11132u, 11138u, + 11144u, 11162u, 11182u, 11198u, 11218u, 11222u, 11236u, 11242u, + 11246u, 11266u, 11284u, 11294u, 11296u, 11302u, 11312u, 11336u, + 11338u, 11348u, 11372u, 11378u, 11384u, 11408u, 11414u, 11426u, + 11428u, 11456u, 11468u, 11482u, 11488u, 11494u, 11506u, 11512u, + 11534u, 11546u, 11558u, 11566u, 11602u, 11606u, 11618u, 11632u, + 11636u, 11656u, 11666u, 11678u, 11702u, 11704u, 11708u, 11714u, + 11726u, 11728u, 11732u, 11734u, 11744u, 11756u, 11782u, 11788u, + 11804u, 11812u, 11816u, 11824u, 11834u, 11842u, 11848u, 11882u, + 11884u, 11896u, 11912u, 11936u, 11942u, 11944u, 11954u, 11956u, + 11974u, 11978u, 11986u, 11992u, 12008u, 12014u, 12016u, 12022u, + 12028u, 12034u, 12038u, 12052u, 12056u, 12076u, 12082u, 12086u, + 12106u, 12112u, 12124u, 12146u, 12152u, 12154u, 12164u, 12176u, + 12178u, 12184u, 12188u, 12196u, 12208u, 12212u, 12226u, 12238u, + 12248u, 12262u, 12266u, 12278u, 12304u, 12314u, 12328u, 12332u, + 12358u, 12364u, 12394u, 12398u, 12416u, 12434u, 12442u, 12448u, + 12464u, 12472u, 12482u, 12496u, 12506u, 12514u, 12524u, 12544u, + 12566u, 12586u, 12602u, 12604u, 12622u, 12628u, 12632u, 12638u, + 12644u, 12656u, 12658u, 12668u, 12694u, 12698u, 12706u, 12724u, + 12742u, 12748u, 12766u, 12772u, 12776u, 12782u, 12806u, 12812u, + 12832u, 12866u, 12892u, 12902u, 12904u, 12932u, 12944u, 12952u, + 12962u, 12974u, 12976u, 12982u, 13004u, 13006u, 13018u, 13034u, + 13036u, 13042u, 13048u, 13058u, 13072u, 13088u, 13108u, 13114u, + 13118u, 13156u, 13162u, 13172u, 13178u, 13186u, 13202u, 13244u, + 13246u, 13252u, 13256u, 13262u, 13268u, 13274u, 13288u, 13304u, + 13318u, 13322u, 13342u, 13352u, 13354u, 13358u, 13366u, 13384u, + 13394u, 13406u, 13442u, 13444u, 13454u, 13496u, 13504u, 13508u, + 13528u, 13552u, 13568u, 13576u, 13598u, 13604u, 13612u, 13616u, + 13618u, 13624u, 13646u, 13652u, 13658u, 13666u, 13694u, 13696u, + 13706u, 13724u, 13738u, 13744u, 13748u, 13766u, 13774u, 13784u, + 13798u, 13802u, 13814u, 13822u, 13832u, 13844u, 13858u, 13862u, + 13864u, 13876u, 13888u, 13892u, 13898u, 13916u, 13946u, 13958u, + 13996u, 14002u, 14014u, 14024u, 14026u, 14044u, 14054u, 14066u, + 14074u, 14078u, 14086u, 14092u, 14096u, 14098u, 14122u, 14134u, + 14152u, 14156u, 14158u, 14162u, 14164u, 14222u, 14234u, 14242u, + 14266u, 14276u, 14278u, 14282u, 14288u, 14294u, 14306u, 14308u, + 14312u, 14326u, 14332u, 14338u, 14354u, 14366u, 14368u, 14372u, + 14404u, 14408u, 14432u, 14438u, 14444u, 14452u, 14462u, 14464u, + 14486u, 14504u, 14516u, 14536u, 14542u, 14572u, 14576u, 14606u, + 14612u, 14614u, 14618u, 14632u, 14638u, 14642u, 14656u, 14672u, + 14674u, 14686u, 14696u, 14698u, 14704u, 14716u, 14728u, 14738u, + 14744u, 14752u, 14774u, 14782u, 14794u, 14806u, 14812u, 14828u, + 14834u, 14852u, 14872u, 14894u, 14912u, 14914u, 14936u, 14938u, + 14954u, 14956u, 14978u, 14992u, 15002u, 15022u, 15032u, 15064u, + 15068u, 15076u, 15086u, 15092u, 15094u, 15116u, 15122u, 15134u, + 15136u, 15142u, 15146u, 15148u, 15152u, 15166u, 15178u, 15202u, + 15212u, 15214u, 15226u, 15242u, 15244u, 15248u, 15254u, 15268u, + 15274u, 15284u, 15296u, 15298u, 15314u, 15328u, 15362u, 15374u, + 15376u, 15382u, 15388u, 15394u, 15398u, 15418u, 15428u, 15454u, + 15466u, 15478u, 15482u, 15484u, 15488u, 15496u, 15506u, 15508u, + 15512u, 15514u, 15536u, 15542u, 15548u, 15562u, 15566u, 15584u, + 15596u, 15622u, 15628u, 15638u, 15646u, 15662u, 15664u, 15668u, + 15688u, 15698u, 15704u, 15746u, 15748u, 15758u, 15764u, 15772u, + 15796u, 15808u, 15814u, 15818u, 15824u, 15836u, 15838u, 15866u, + 15874u, 15886u, 15904u, 15922u, 15928u, 15974u, 15982u, 15992u, + 15998u, 16012u, 16016u, 16018u, 16024u, 16028u, 16034u, 16076u, + 16084u, 16094u, 16102u, 16112u, 16114u, 16132u, 16136u, 16142u, + 16154u, 16166u, 16168u, 16172u, 16192u, 16202u, 16214u, 16226u, + 16234u, 16238u, 16264u, 16282u, 16304u, 16312u, 16318u, 16334u, + 16348u, 16364u, 16366u, 16384u, 16394u, 16396u, 16402u, 16408u, + 16418u, 16432u, 16436u, 16438u, 16468u, 16472u, 16474u, 16478u, + 16486u, 16496u, 16502u, 16504u, 16516u, 16532u, 16538u, 16594u, + 16604u, 16606u, 16618u, 16628u, 16636u, 16648u, 16654u, 16658u, + 16672u, 16682u, 16684u, 16688u, 16696u, 16702u, 16706u, 16726u, + 16732u, 16744u, 16766u, 16772u, 16804u, 16814u, 16816u, 16826u, + 16838u, 16852u, 16858u, 16886u, 16922u, 16928u, 16934u, 16936u, + 16948u, 16952u, 16958u, 16964u, 16972u, 16994u, 16996u, 17014u, + 17024u, 17026u, 17032u, 17036u, 17056u, 17066u, 17074u, 17078u, + 17084u, 17098u, 17116u, 17122u, 17164u, 17186u, 17188u, 17192u, + 17194u, 17222u, 17224u, 17228u, 17246u, 17252u, 17258u, 17264u, + 17276u, 17278u, 17302u, 17312u, 17348u, 17354u, 17356u, 17368u, + 17378u, 17404u, 17428u, 17446u, 17462u, 17468u, 17474u, 17488u, + 17512u, 17524u, 17528u, 17536u, 17542u, 17554u, 17558u, 17566u, + 17582u, 17602u, 17642u, 17668u, 17672u, 17684u, 17686u, 17692u, + 17696u, 17698u, 17708u, 17722u, 17732u, 17734u, 17738u, 17764u, + 17776u, 17804u, 17806u, 17822u, 17848u, 17854u, 17864u, 17866u, + 17872u, 17882u, 17888u, 17896u, 17902u, 17908u, 17914u, 17924u, + 17936u, 17942u, 17962u, 18002u, 18022u, 18026u, 18028u, 18044u, + 18056u, 18062u, 18074u, 18082u, 18086u, 18104u, 18106u, 18118u, + 18128u, 18154u, 18166u, 18182u, 18184u, 18202u, 18226u, 18238u, + 18242u, 18256u, 18278u, 18298u, 18308u, 18322u, 18334u, 18338u, + 18356u, 18368u, 18376u, 18386u, 18398u, 18404u, 18434u, 18448u, + 18452u, 18476u, 18482u, 18512u, 18518u, 18524u, 18526u, 18532u, + 18554u, 18586u, 18592u, 18596u, 18602u, 18608u, 18628u, 18644u, + 18646u, 18656u, 18664u, 18676u, 18686u, 18688u, 18694u, 18704u, + 18712u, 18728u, 18764u, 18772u, 18778u, 18782u, 18784u, 18812u, + 18814u, 18842u, 18854u, 18856u, 18866u, 18872u, 18886u, 18896u, + 18902u, 18908u, 18914u, 18922u, 18928u, 18932u, 18946u, 18964u, + 18968u, 18974u, 18986u, 18988u, 18998u, 19016u, 19024u, 19054u, + 19094u, 19096u, 19114u, 19118u, 19124u, 19138u, 19156u, 19162u, + 19166u, 19178u, 19184u, 19196u, 19202u, 19216u, 19226u, 19252u, + 19258u, 19274u, 19276u, 19292u, 19322u, 19324u, 19334u, 19336u, + 19378u, 19384u, 19412u, 19426u, 19432u, 19442u, 19444u, 19456u, + 19474u, 19486u, 19492u, 19502u, 19514u, 19526u, 19546u, 19552u, + 19556u, 19558u, 19568u, 19574u, 19586u, 19598u, 19612u, 19624u, + 19658u, 19664u, 19666u, 19678u, 19688u, 19694u, 19702u, 19708u, + 19712u, 19724u, 19762u, 19768u, 19778u, 19796u, 19798u, 19826u, + 19828u, 19834u, 19846u, 19876u, 19892u, 19894u, 19904u, 19912u, + 19916u, 19918u, 19934u, 19952u, 19978u, 19982u, 19988u, 19996u, + 20014u, 20036u, 20042u, 20062u, 20066u, 20072u, 20084u, 20086u, + 20092u, 20104u, 20108u, 20126u, 20132u, 20134u, 20156u, 20168u, + 20176u, 20182u, 20198u, 20216u, 20246u, 20258u, 20282u, 20284u, + 20294u, 20296u, 20302u, 20308u, 20312u, 20318u, 20354u, 20368u, + 20374u, 20396u, 20398u, 20456u, 20464u, 20476u, 20482u, 20492u, + 20494u, 20534u, 20542u, 20548u, 20576u, 20578u, 20582u, 20596u, + 20602u, 20608u, 20626u, 20636u, 20644u, 20648u, 20662u, 20666u, + 20674u, 20704u, 20708u, 20714u, 20722u, 20728u, 20734u, 20752u, + 20756u, 20758u, 20762u, 20776u, 20788u, 20806u, 20816u, 20818u, + 20822u, 20834u, 20836u, 20846u, 20854u, 20864u, 20878u, 20888u, + 20906u, 20918u, 20926u, 20932u, 20942u, 20956u, 20966u, 20974u, + 20996u, 20998u, 21004u, 21026u, 21038u, 21044u, 21052u, 21064u, + 21092u, 21094u, 21142u, 21154u, 21158u, 21176u, 21184u, 21194u, + 21208u, 21218u, 21232u, 21236u, 21248u, 21278u, 21302u, 21308u, + 21316u, 21322u, 21326u, 21334u, 21388u, 21392u, 21394u, 21404u, + 21416u, 21424u, 21434u, 21446u, 21458u, 21476u, 21478u, 21502u, + 21506u, 21514u, 21536u, 21548u, 21568u, 21572u, 21584u, 21586u, + 21598u, 21614u, 21616u, 21644u, 21646u, 21652u, 21676u, 21686u, + 21688u, 21716u, 21718u, 21722u, 21742u, 21746u, 21758u, 21764u, + 21778u, 21782u, 21788u, 21802u, 21824u, 21848u, 21868u, 21872u, + 21886u, 21892u, 21898u, 21908u, 21938u, 21946u, 21956u, 21974u, + 21976u, 21982u, 21988u, 22004u, 22006u, 22012u, 22018u, 22022u, + 22024u, 22048u, 22052u, 22054u, 22078u, 22088u, 22094u, 22096u, + 22106u, 22108u, 22114u, 22136u, 22144u, 22148u, 22156u, 22162u, + 22166u, 22184u, 22186u, 22204u, 22208u, 22216u, 22232u, 22258u, + 22262u, 22268u, 22276u, 22298u, 22318u, 22334u, 22342u, 22346u, + 22352u, 22376u, 22382u, 22396u, 22408u, 22424u, 22426u, 22438u, + 22442u, 22456u, 22466u, 22468u, 22472u, 22484u, 22502u, 22534u, + 22544u, 22558u, 22582u, 22594u, 22634u, 22642u, 22676u, 22688u, + 22702u, 22706u, 22724u, 22726u, 22754u, 22766u, 22786u, 22792u, + 22802u, 22804u, 22844u, 22862u, 22876u, 22888u, 22892u, 22928u, + 22934u, 22936u, 22958u, 22964u, 22978u, 22988u, 23012u, 23054u, + 23056u, 23072u, 23074u, 23108u, 23116u, 23122u, 23126u, 23128u, + 23132u, 23146u, 23186u, 23194u, 23206u, 23212u, 23236u, 23254u, + 23258u, 23264u, 23266u, 23272u, 23276u, 23278u, 23282u, 23284u, + 23308u, 23318u, 23326u, 23332u, 23338u, 23348u, 23362u, 23368u, + 23384u, 23402u, 23416u, 23434u, 23458u, 23462u, 23468u, 23474u, + 23482u, 23486u, 23506u, 23516u, 23522u, 23534u, 23536u, 23548u, + 23552u, 23566u, 23572u, 23578u, 23584u, 23588u, 23602u, 23618u, + 23654u, 23668u, 23674u, 23678u, 23692u, 23696u, 23702u, 23726u, + 23734u, 23738u, 23758u, 23768u, 23782u, 23794u, 23828u, 23836u, + 23846u, 23852u, 23858u, 23864u, 23878u, 23882u, 23896u, 23908u, + 23914u, 23924u, 23942u, 23956u, 23966u, 23978u, 23984u, 23986u, + 23992u, 23998u, 24026u, 24028u, 24032u, 24056u, 24062u, 24064u, + 24068u, 24076u, 24092u, 24098u, 24118u, 24122u, 24124u, 24134u, + 24136u, 24146u, 24154u, 24218u, 24224u, 24232u, 24244u, 24248u, + 24262u, 24274u, 24284u, 24286u, 24298u, 24304u, 24314u, 24332u, + 24356u, 24362u, 24364u, 24374u, 24382u, 24388u, 24404u, 24424u, + 24428u, 24442u, 24448u, 24454u, 24466u, 24472u, 24476u, 24482u, + 24484u, 24488u, 24496u, 24518u, 24524u, 24532u, 24536u, 24538u, + 24554u, 24572u, 24586u, 24592u, 24614u, 24628u, 24638u, 24652u, + 24656u, 24662u, 24664u, 24668u, 24682u, 24692u, 24704u, 24712u, + 24728u, 24736u, 24746u, 24754u, 24778u, 24818u, 24824u, 24836u, + 24838u, 24844u, 24862u, 24866u, 24868u, 24872u, 24902u, 24904u, + 24934u, 24938u, 24946u, 24964u, 24976u, 24988u, 24992u, 24994u, + 24998u, 25012u, 25048u, 25064u, 25082u, 25084u, 25096u, 25106u, + 25112u, 25124u, 25142u, 25144u, 25162u, 25168u, 25174u, 25196u, + 25214u, 25252u, 25258u, 25268u, 25286u, 25288u, 25298u, 25306u, + 25312u, 25328u, 25352u, 25366u, 25372u, 25376u, 25382u, 25396u, + 25412u, 25436u, 25442u, 25454u, 25462u, 25474u, 25484u, 25498u, + 25544u, 25546u, 25562u, 25564u, 25586u, 25592u, 25594u, 25604u, + 25606u, 25616u, 25618u, 25624u, 25628u, 25648u, 25658u, 25664u, + 25694u, 25702u, 25708u, 25714u, 25718u, 25748u, 25756u, 25762u, + 25768u, 25774u, 25796u, 25832u, 25834u, 25838u, 25846u, 25852u, + 25858u, 25862u, 25876u, 25888u, 25898u, 25918u, 25922u, 25924u, + 25928u, 25958u, 25964u, 25978u, 25994u, 26006u, 26036u, 26038u, + 26042u, 26048u, 26056u, 26086u, 26096u, 26104u, 26138u, 26156u, + 26168u, 26176u, 26198u, 26218u, 26222u, 26236u, 26246u, 26266u, + 26272u, 26276u, 26278u, 26288u, 26302u, 26306u, 26332u, 26338u, + 26374u, 26386u, 26404u, 26408u, 26416u, 26422u, 26426u, 26432u, + 26434u, 26462u, 26468u, 26474u, 26498u, 26506u, 26516u, 26542u, + 26548u, 26572u, 26576u, 26584u, 26608u, 26618u, 26638u, 26642u, + 26644u, 26654u, 26668u, 26684u, 26686u, 26692u, 26698u, 26702u, + 26708u, 26716u, 26734u, 26762u, 26776u, 26782u, 26798u, 26812u, + 26818u, 26822u, 26828u, 26834u, 26842u, 26846u, 26848u, 26852u, + 26864u, 26866u, 26878u, 26884u, 26896u, 26924u, 26926u, 26932u, + 26944u, 26954u, 26968u, 26972u, 27016u, 27022u, 27032u, 27034u, + 27046u, 27058u, 27088u, 27092u, 27104u, 27106u, 27112u, 27122u, + 27134u, 27136u, 27146u, 27148u, 27158u, 27164u, 27172u, 27182u, + 27188u, 27202u, 27218u, 27226u, 27232u, 27244u, 27254u, 27256u, + 27266u, 27274u, 27286u, 27296u, 27314u, 27322u, 27326u, 27328u, + 27332u, 27358u, 27364u, 27386u, 27392u, 27406u, 27416u, 27422u, + 27424u, 27452u, 27458u, 27466u, 27512u, 27518u, 27524u, 27542u, + 27548u, 27554u, 27562u, 27568u, 27578u, 27596u, 27598u, 27604u, + 27616u, 27634u, 27644u, 27652u, 27664u, 27694u, 27704u, 27706u, + 27716u, 27718u, 27722u, 27728u, 27746u, 27748u, 27752u, 27772u, + 27784u, 27788u, 27794u, 27802u, 27836u, 27842u, 27848u, 27872u, + 27884u, 27892u, 27928u, 27944u, 27946u, 27952u, 27956u, 27958u, + 27962u, 27968u, 27988u, 27994u, 28018u, 28022u, 28024u, 28028u, + 28046u, 28066u, 28072u, 28094u, 28102u, 28148u, 28166u, 28168u, + 28184u, 28204u, 28226u, 28228u, 28252u, 28274u, 28276u, 28292u, + 28316u, 28336u, 28352u, 28354u, 28358u, 28366u, 28376u, 28378u, + 28388u, 28402u, 28406u, 28414u, 28432u, 28436u, 28444u, 28448u, + 28462u, 28472u, 28474u, 28498u, 28514u, 28522u, 28528u, 28544u, + 28564u, 28574u, 28576u, 28582u, 28586u, 28616u, 28618u, 28634u, + 28666u, 28672u, 28684u, 28694u, 28718u, 28726u, 28738u, 28756u, + 28772u, 28774u, 28786u, 28792u, 28796u, 28808u, 28814u, 28816u, + 28844u, 28862u, 28864u, 28886u, 28892u, 28898u, 28904u, 28906u, + 28912u, 28928u, 28942u, 28948u, 28978u, 28994u, 28996u, 29006u, + 29008u, 29012u, 29024u, 29026u, 29038u, 29048u, 29062u, 29068u, + 29078u, 29086u, 29114u, 29116u, 29152u, 29158u, 29174u, 29188u, + 29192u, 29212u, 29236u, 29242u, 29246u, 29254u, 29258u, 29276u, + 29284u, 29288u, 29302u, 29306u, 29312u, 29314u, 29338u, 29354u, + 29368u, 29372u, 29398u, 29414u, 29416u, 29426u, 29458u, 29464u, + 29468u, 29474u, 29486u, 29492u, 29528u, 29536u, 29548u, 29552u, + 29554u, 29558u, 29566u, 29572u, 29576u, 29596u, 29608u, 29618u, + 29642u, 29654u, 29656u, 29668u, 29678u, 29684u, 29696u, 29698u, + 29704u, 29722u, 29726u, 29732u, 29738u, 29744u, 29752u, 29776u, + 29782u, 29792u, 29804u, 29834u, 29848u, 29858u, 29866u, 29878u, + 29884u, 29894u, 29906u, 29908u, 29926u, 29932u, 29936u, 29944u, + 29948u, 29972u, 29992u, 29996u, 30004u, 30014u, 30026u, 30034u, + 30046u, 30062u, 30068u, 30082u, 30086u, 30094u, 30098u, 30116u, + 30166u, 30172u, 30178u, 30182u, 30188u, 30196u, 30202u, 30212u, + 30238u, 30248u, 30254u, 30256u, 30266u, 30268u, 30278u, 30284u, + 30322u, 30334u, 30338u, 30346u, 30356u, 30376u, 30382u, 30388u, + 30394u, 30412u, 30422u, 30424u, 30436u, 30452u, 30454u, 30466u, + 30478u, 30482u, 30508u, 30518u, 30524u, 30544u, 30562u, 30602u, + 30614u, 30622u, 30632u, 30644u, 30646u, 30664u, 30676u, 30686u, + 30688u, 30698u, 30724u, 30728u, 30734u, 30746u, 30754u, 30758u, + 30788u, 30794u, 30796u, 30802u, 30818u, 30842u, 30866u, 30884u, + 30896u, 30908u, 30916u, 30922u, 30926u, 30934u, 30944u, 30952u, + 30958u, 30962u, 30982u, 30992u, 31018u, 31022u, 31046u, 31052u, + 31054u, 31066u, 31108u, 31126u, 31132u, 31136u, 31162u, 31168u, + 31196u, 31202u, 31204u, 31214u, 31222u, 31228u, 31234u, 31244u, + 31252u, 31262u, 31264u, 31286u, 31288u, 31292u, 31312u, 31316u, + 31322u, 31358u, 31372u, 31376u, 31396u, 31418u, 31424u, 31438u, + 31444u, 31454u, 31462u, 31466u, 31468u, 31472u, 31486u, 31504u, + 31538u, 31546u, 31568u, 31582u, 31592u, 31616u, 31622u, 31624u, + 31634u, 31636u, 31642u, 31652u, 31678u, 31696u, 31706u, 31724u, + 31748u, 31766u, 31768u, 31792u, 31832u, 31834u, 31838u, 31844u, + 31846u, 31852u, 31862u, 31888u, 31894u, 31906u, 31918u, 31924u, + 31928u, 31964u, 31966u, 31976u, 31988u, 32012u, 32014u, 32018u, + 32026u, 32036u, 32042u, 32044u, 32048u, 32072u, 32074u, 32078u, + 32114u, 32116u, 32138u, 32152u, 32176u, 32194u, 32236u, 32242u, + 32252u, 32254u, 32278u, 32294u, 32306u, 32308u, 32312u, 32314u, + 32324u, 32326u, 32336u, 32344u, 32348u, 32384u, 32392u, 32396u, + 32408u, 32426u, 32432u, 32438u, 32452u, 32474u, 32476u, 32482u, + 32506u, 32512u, 32522u, 32546u, 32566u, 32588u, 32594u, 32608u, + 32644u, 32672u, 32678u, 32686u, 32692u, 32716u, 32722u, 32734u, + 32762u, 32764u, 32782u, 32786u, 32788u, 32792u, 32812u, 32834u, + 32842u, 32852u, 32854u, 32872u, 32876u, 32884u, 32894u, 32908u, + 32918u, 32924u, 32932u, 32938u, 32944u, 32956u, 32972u, 32984u, + 32998u, 33008u, 33026u, 33028u, 33038u, 33062u, 33086u, 33092u, + 33104u, 33106u, 33128u, 33134u, 33154u, 33176u, 33178u, 33182u, + 33194u, 33196u, 33202u, 33238u, 33244u, 33266u, 33272u, 33274u, + 33302u, 33314u, 33332u, 33334u, 33338u, 33352u, 33358u, 33362u, + 33364u, 33374u, 33376u, 33392u, 33394u, 33404u, 33412u, 33418u, + 33428u, 33446u, 33458u, 33464u, 33478u, 33482u, 33488u, 33506u, + 33518u, 33544u, 33548u, 33554u, 33568u, 33574u, 33584u, 33596u, + 33598u, 33602u, 33604u, 33614u, 33638u, 33646u, 33656u, 33688u, + 33698u, 33706u, 33716u, 33722u, 33724u, 33742u, 33754u, 33782u, + 33812u, 33814u, 33832u, 33836u, 33842u, 33856u, 33862u, 33866u, + 33874u, 33896u, 33904u, 33934u, 33952u, 33962u, 33988u, 33992u, + 33994u, 34016u, 34024u, 34028u, 34036u, 34042u, 34046u, 34072u, + 34076u, 34088u, 34108u, 34126u, 34132u, 34144u, 34154u, 34172u, + 34174u, 34178u, 34184u, 34186u, 34198u, 34226u, 34232u, 34252u, + 34258u, 34274u, 34282u, 34288u, 34294u, 34298u, 34304u, 34324u, + 34336u, 34342u, 34346u, 34366u, 34372u, 34388u, 34394u, 34426u, + 34436u, 34454u, 34456u, 34468u, 34484u, 34508u, 34514u, 34522u, + 34534u, 34568u, 34574u, 34594u, 34616u, 34618u, 34634u, 34648u, + 34654u, 34658u, 34672u, 34678u, 34702u, 34732u, 34736u, 34744u, + 34756u, 34762u, 34778u, 34798u, 34808u, 34822u, 34826u, 34828u, + 34844u, 34856u, 34858u, 34868u, 34876u, 34882u, 34912u, 34924u, + 34934u, 34948u, 34958u, 34966u, 34976u, 34982u, 34984u, 34988u, + 35002u, 35012u, 35014u, 35024u, 35056u, 35074u, 35078u, 35086u, + 35114u, 35134u, 35138u, 35158u, 35164u, 35168u, 35198u, 35206u, + 35212u, 35234u, 35252u, 35264u, 35266u, 35276u, 35288u, 35294u, + 35312u, 35318u, 35372u, 35378u, 35392u, 35396u, 35402u, 35408u, + 35422u, 35446u, 35452u, 35464u, 35474u, 35486u, 35492u, 35516u, + 35528u, 35546u, 35554u, 35572u, 35576u, 35578u, 35582u, 35584u, + 35606u, 35614u, 35624u, 35626u, 35638u, 35648u, 35662u, 35668u, + 35672u, 35674u, 35686u, 35732u, 35738u, 35744u, 35746u, 35752u, + 35758u, 35788u, 35798u, 35806u, 35812u, 35824u, 35828u, 35842u, + 35848u, 35864u, 35876u, 35884u, 35894u, 35914u, 35932u, 35942u, + 35948u, 35954u, 35966u, 35968u, 35978u, 35992u, 35996u, 35998u, + 36002u, 36026u, 36038u, 36046u, 36064u, 36068u, 36076u, 36092u, + 36106u, 36118u, 36128u, 36146u, 36158u, 36166u, 36184u, 36188u, + 36202u, 36206u, 36212u, 36214u, 36236u, 36254u, 36262u, 36272u, + 36298u, 36302u, 36304u, 36328u, 36334u, 36338u, 36344u, 36356u, + 36382u, 36386u, 36394u, 36404u, 36422u, 36428u, 36442u, 36452u, + 36464u, 36466u, 36478u, 36484u, 36488u, 36496u, 36508u, 36524u, + 36526u, 36536u, 36542u, 36544u, 36566u, 36568u, 36572u, 36586u, + 36604u, 36614u, 36626u, 36646u, 36656u, 36662u, 36664u, 36668u, + 36682u, 36694u, 36698u, 36706u, 36716u, 36718u, 36724u, 36758u, + 36764u, 36766u, 36782u, 36794u, 36802u, 36824u, 36832u, 36862u, + 36872u, 36874u, 36898u, 36902u, 36916u, 36926u, 36946u, 36962u, + 36964u, 36968u, 36988u, 36998u, 37004u, 37012u, 37016u, 37024u, + 37028u, 37052u, 37058u, 37072u, 37076u, 37108u, 37112u, 37118u, + 37132u, 37138u, 37142u, 37144u, 37166u, 37226u, 37228u, 37234u, + 37258u, 37262u, 37276u, 37294u, 37306u, 37324u, 37336u, 37342u, + 37346u, 37376u, 37378u, 37394u, 37396u, 37418u, 37432u, 37448u, + 37466u, 37472u, 37508u, 37514u, 37532u, 37534u, 37544u, 37552u, + 37556u, 37558u, 37564u, 37588u, 37606u, 37636u, 37642u, 37648u, + 37682u, 37696u, 37702u, 37754u, 37756u, 37772u, 37784u, 37798u, + 37814u, 37822u, 37852u, 37856u, 37858u, 37864u, 37874u, 37886u, + 37888u, 37916u, 37922u, 37936u, 37948u, 37976u, 37994u, 38014u, + 38018u, 38026u, 38032u, 38038u, 38042u, 38048u, 38056u, 38078u, + 38084u, 38108u, 38116u, 38122u, 38134u, 38146u, 38152u, 38164u, + 38168u, 38188u, 38234u, 38252u, 38266u, 38276u, 38278u, 38302u, + 38306u, 38308u, 38332u, 38354u, 38368u, 38378u, 38384u, 38416u, + 38428u, 38432u, 38434u, 38444u, 38446u, 38456u, 38458u, 38462u, + 38468u, 38474u, 38486u, 38498u, 38512u, 38518u, 38524u, 38552u, + 38554u, 38572u, 38578u, 38584u, 38588u, 38612u, 38614u, 38626u, + 38638u, 38644u, 38648u, 38672u, 38696u, 38698u, 38704u, 38708u, + 38746u, 38752u, 38762u, 38774u, 38776u, 38788u, 38792u, 38812u, + 38834u, 38846u, 38848u, 38858u, 38864u, 38882u, 38924u, 38936u, + 38938u, 38944u, 38956u, 38978u, 38992u, 39002u, 39008u, 39014u, + 39016u, 39026u, 39044u, 39058u, 39062u, 39088u, 39104u, 39116u, + 39124u, 39142u, 39146u, 39148u, 39158u, 39166u, 39172u, 39176u, + 39182u, 39188u, 39194u + }}; + + if(n <= b1) + return a1[n]; + if(n <= b2) + return a2[n - b1 - 1]; + if(n >= b3) + { + return boost::math::policies::raise_domain_error( + "boost::math::prime<%1%>", "Argument n out of range: got %1%", n, pol); + } + return static_cast(a3[n - b2 - 1]) + 0xFFFFu; + } + + inline BOOST_MATH_CONSTEXPR_TABLE_FUNCTION std::uint32_t prime(unsigned n) + { + return boost::math::prime(n, boost::math::policies::policy<>()); + } + + static const unsigned max_prime = 9999; + +}} // namespace boost and math + +#endif // BOOST_MATH_SF_PRIME_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/relative_difference.hpp b/libcxx/src/third-party/boost/math/special_functions/relative_difference.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/relative_difference.hpp @@ -0,0 +1,134 @@ +// (C) Copyright John Maddock 2006, 2015 +// 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_RELATIVE_ERROR +#define BOOST_MATH_RELATIVE_ERROR + +#include +#include +#include + +namespace boost{ + namespace math{ + + template + typename boost::math::tools::promote_args::type relative_difference(const T& arg_a, const U& arg_b) + { + typedef typename boost::math::tools::promote_args::type result_type; + result_type a = arg_a; + result_type b = arg_b; + BOOST_MATH_STD_USING +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + // + // If math.h has no long double support we can't rely + // on the math functions generating exponents outside + // the range of a double: + // + result_type min_val = (std::max)( + tools::min_value(), + static_cast((std::numeric_limits::min)())); + result_type max_val = (std::min)( + tools::max_value(), + static_cast((std::numeric_limits::max)())); +#else + result_type min_val = tools::min_value(); + result_type max_val = tools::max_value(); +#endif + // Screen out NaN's first, if either value is a NaN then the distance is "infinite": + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + return max_val; + // Screen out infinities: + if(fabs(b) > max_val) + { + if(fabs(a) > max_val) + return (a < 0) == (b < 0) ? 0 : max_val; // one infinity is as good as another! + else + return max_val; // one infinity and one finite value implies infinite difference + } + else if(fabs(a) > max_val) + return max_val; // one infinity and one finite value implies infinite difference + + // + // If the values have different signs, treat as infinite difference: + // + if(((a < 0) != (b < 0)) && (a != 0) && (b != 0)) + return max_val; + a = fabs(a); + b = fabs(b); + // + // Now deal with zero's, if one value is zero (or denorm) then treat it the same as + // min_val for the purposes of the calculation that follows: + // + if(a < min_val) + a = min_val; + if(b < min_val) + b = min_val; + + return (std::max)(fabs((a - b) / a), fabs((a - b) / b)); + } + +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && (LDBL_MAX_EXP <= DBL_MAX_EXP) + template <> + inline boost::math::tools::promote_args::type relative_difference(const double& arg_a, const double& arg_b) + { + BOOST_MATH_STD_USING + double a = arg_a; + double b = arg_b; + // + // On Mac OS X we evaluate "double" functions at "long double" precision, + // but "long double" actually has a very slightly narrower range than "double"! + // Therefore use the range of "long double" as our limits since results outside + // that range may have been truncated to 0 or INF: + // + double min_val = (std::max)((double)tools::min_value(), tools::min_value()); + double max_val = (std::min)((double)tools::max_value(), tools::max_value()); + + // Screen out NaN's first, if either value is a NaN then the distance is "infinite": + if((boost::math::isnan)(a) || (boost::math::isnan)(b)) + return max_val; + // Screen out infinities: + if(fabs(b) > max_val) + { + if(fabs(a) > max_val) + return 0; // one infinity is as good as another! + else + return max_val; // one infinity and one finite value implies infinite difference + } + else if(fabs(a) > max_val) + return max_val; // one infinity and one finite value implies infinite difference + + // + // If the values have different signs, treat as infinite difference: + // + if(((a < 0) != (b < 0)) && (a != 0) && (b != 0)) + return max_val; + a = fabs(a); + b = fabs(b); + // + // Now deal with zero's, if one value is zero (or denorm) then treat it the same as + // min_val for the purposes of the calculation that follows: + // + if(a < min_val) + a = min_val; + if(b < min_val) + b = min_val; + + return (std::max)(fabs((a - b) / a), fabs((a - b) / b)); + } +#endif + + template + inline typename boost::math::tools::promote_args::type epsilon_difference(const T& arg_a, const U& arg_b) + { + typedef typename boost::math::tools::promote_args::type result_type; + result_type r = relative_difference(arg_a, arg_b); + if(tools::max_value() * boost::math::tools::epsilon() < r) + return tools::max_value(); + return r / boost::math::tools::epsilon(); + } +} // namespace math +} // namespace boost + +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/round.hpp b/libcxx/src/third-party/boost/math/special_functions/round.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/round.hpp @@ -0,0 +1,147 @@ +// Copyright John Maddock 2007. +// 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_ROUND_HPP +#define BOOST_MATH_ROUND_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail{ + +template +inline tools::promote_args_t round(const T& v, const Policy& pol, const std::false_type&) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + if(!(boost::math::isfinite)(v)) + { + return policies::raise_rounding_error("boost::math::round<%1%>(%1%)", nullptr, static_cast(v), static_cast(v), pol); + } + // + // The logic here is rather convoluted, but avoids a number of traps, + // see discussion here https://github.com/boostorg/math/pull/8 + // + if (-0.5 < v && v < 0.5) + { + // special case to avoid rounding error on the direct + // predecessor of +0.5 resp. the direct successor of -0.5 in + // IEEE floating point types + return static_cast(0); + } + else if (v > 0) + { + // subtract v from ceil(v) first in order to avoid rounding + // errors on largest representable integer numbers + result_type c(ceil(v)); + return 0.5 < c - v ? c - 1 : c; + } + else + { + // see former branch + result_type f(floor(v)); + return 0.5 < v - f ? f + 1 : f; + } +} +template +inline tools::promote_args_t round(const T& v, const Policy&, const std::true_type&) +{ + return v; +} + +} // namespace detail + +template +inline tools::promote_args_t round(const T& v, const Policy& pol) +{ + return detail::round(v, pol, std::integral_constant::value>()); +} +template +inline tools::promote_args_t round(const T& v) +{ + return round(v, policies::policy<>()); +} +// +// The following functions will not compile unless T has an +// implicit conversion to the integer types. For user-defined +// number types this will likely not be the case. In that case +// these functions should either be specialized for the UDT in +// question, or else overloads should be placed in the same +// namespace as the UDT: these will then be found via argument +// dependent lookup. See our concept archetypes for examples. +// +// Non-standard numeric limits syntax "(std::numeric_limits::max)()" +// is to avoid macro substiution from MSVC +// https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax +// +template +inline int iround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + T r = boost::math::round(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", nullptr, v, 0, pol)); + } + return static_cast(r); +} +template +inline int iround(const T& v) +{ + return iround(v, policies::policy<>()); +} + +template +inline long lround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + T r = boost::math::round(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", nullptr, v, 0L, pol)); + } + return static_cast(r); +} +template +inline long lround(const T& v) +{ + return lround(v, policies::policy<>()); +} + +template +inline long long llround(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + + T r = boost::math::round(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || + r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + return static_cast(r); +} +template +inline long long llround(const T& v) +{ + return llround(v, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ROUND_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/rsqrt.hpp b/libcxx/src/third-party/boost/math/special_functions/rsqrt.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/rsqrt.hpp @@ -0,0 +1,44 @@ +// (C) Copyright Nick Thompson 2020. +// 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_RSQRT_HPP +#define BOOST_MATH_SPECIAL_FUNCTIONS_RSQRT_HPP +#include +#include +#include + +namespace boost::math { + +template +inline Real rsqrt(Real const & x) +{ + using std::sqrt; + if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) + { + return 1/sqrt(x); + } + else + { + // if it's so tiny it rounds to 0 as long double, + // no performance gains are possible: + if (x < std::numeric_limits::denorm_min() || x > (std::numeric_limits::max)()) { + return 1/sqrt(x); + } + Real x0 = 1/sqrt(static_cast(x)); + // Divide by 512 for leeway: + Real s = sqrt(std::numeric_limits::epsilon())*x0/512; + Real x1 = x0 + x0*(1-x*x0*x0)/2; + while(abs(x1 - x0) > s) { + x0 = x1; + x1 = x0 + x0*(1-x*x0*x0)/2; + } + // Final iteration get ~2ULPs: + return x1 + x1*(1-x*x1*x1)/2;; + } +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/special_functions/sign.hpp b/libcxx/src/third-party/boost/math/special_functions/sign.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/sign.hpp @@ -0,0 +1,194 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Johan Rade 2006. +// (C) Copyright Paul A. Bristow 2011 (added changesign). + +// 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_TOOLS_SIGN_HPP +#define BOOST_MATH_TOOLS_SIGN_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ + +namespace detail { + + // signbit + +#ifdef BOOST_MATH_USE_STD_FPCLASSIFY + template + inline int signbit_impl(T x, native_tag const&) + { + return (std::signbit)(x) ? 1 : 0; + } +#endif + + // Generic versions first, note that these do not handle + // signed zero or NaN. + + template + inline int signbit_impl(T x, generic_tag const&) + { + return x < 0; + } + + template + inline int signbit_impl(T x, generic_tag const&) + { + return x < 0; + } + +#if defined(__GNUC__) && (LDBL_MANT_DIG == 106) + // + // Special handling for GCC's "double double" type, + // in this case the sign is the same as the sign we + // get by casting to double, no overflow/underflow + // can occur since the exponents are the same magnitude + // for the two types: + // + inline int signbit_impl(long double x, generic_tag const&) + { + return (boost::math::signbit)(static_cast(x)); + } + inline int signbit_impl(long double x, generic_tag const&) + { + return (boost::math::signbit)(static_cast(x)); + } +#endif + + template + inline int signbit_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + return a & traits::sign ? 1 : 0; + } + + template + inline int signbit_impl(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::type traits; + + typename traits::bits a; + traits::get_bits(x,a); + + return a & traits::sign ? 1 : 0; + } + + // Changesign + + // Generic versions first, note that these do not handle + // signed zero or NaN. + + template + inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } + + template + inline T (changesign_impl)(T x, generic_tag const&) + { + return -x; + } +#if defined(__GNUC__) && (LDBL_MANT_DIG == 106) + // + // Special handling for GCC's "double double" type, + // in this case we need to change the sign of both + // components of the "double double": + // + inline long double (changesign_impl)(long double x, generic_tag const&) + { + double* pd = reinterpret_cast(&x); + pd[0] = boost::math::changesign(pd[0]); + pd[1] = boost::math::changesign(pd[1]); + return x; + } + inline long double (changesign_impl)(long double x, generic_tag const&) + { + double* pd = reinterpret_cast(&x); + pd[0] = boost::math::changesign(pd[0]); + pd[1] = boost::math::changesign(pd[1]); + return x; + } +#endif + + template + inline T changesign_impl(T x, ieee_copy_all_bits_tag const&) + { + typedef typename fp_traits::sign_change_type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + template + inline T (changesign_impl)(T x, ieee_copy_leading_bits_tag const&) + { + typedef typename fp_traits::sign_change_type traits; + + typename traits::bits a; + traits::get_bits(x,a); + a ^= traits::sign; + traits::set_bits(x,a); + return x; + } + + +} // namespace detail + +template int (signbit)(T x) +{ + typedef typename detail::fp_traits::type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + return detail::signbit_impl(static_cast(x), method()); +} + +template +inline int sign BOOST_NO_MACRO_EXPAND(const T& z) +{ + return (z == 0) ? 0 : (boost::math::signbit)(z) ? -1 : 1; +} + +template typename tools::promote_args_permissive::type (changesign)(const T& x) +{ //!< \brief return unchanged binary pattern of x, except for change of sign bit. + typedef typename detail::fp_traits::sign_change_type traits; + typedef typename traits::method method; + // typedef typename boost::is_floating_point::type fp_tag; + typedef typename tools::promote_args_permissive::type result_type; + + return detail::changesign_impl(static_cast(x), method()); +} + +template +inline typename tools::promote_args_permissive::type + copysign BOOST_NO_MACRO_EXPAND(const T& x, const U& y) +{ + BOOST_MATH_STD_USING + typedef typename tools::promote_args_permissive::type result_type; + return (boost::math::signbit)(static_cast(x)) != (boost::math::signbit)(static_cast(y)) + ? (boost::math::changesign)(static_cast(x)) : static_cast(x); +} + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_TOOLS_SIGN_HPP + + diff --git a/libcxx/src/third-party/boost/math/special_functions/sin_pi.hpp b/libcxx/src/third-party/boost/math/special_functions/sin_pi.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/sin_pi.hpp @@ -0,0 +1,84 @@ +// Copyright (c) 2007 John Maddock +// 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_SIN_PI_HPP +#define BOOST_MATH_SIN_PI_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline T sin_pi_imp(T x, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std names + if(x < 0) + return -sin_pi_imp(T(-x), pol); + // sin of pi*x: + if(x < 0.5) + return sin(constants::pi() * x); + bool invert; + if(x < 1) + { + invert = true; + x = -x; + } + else + invert = false; + + T rem = floor(x); + if(abs(floor(rem/2)*2 - rem) > std::numeric_limits::epsilon()) + { + invert = !invert; + } + rem = x - rem; + if(rem > 0.5f) + rem = 1 - rem; + if(rem == 0.5f) + return static_cast(invert ? -1 : 1); + + rem = sin(constants::pi() * rem); + return invert ? T(-rem) : rem; +} + +} // namespace detail + +template +inline typename tools::promote_args::type sin_pi(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<>, + // We want to ignore overflows since the result is in [-1,1] and the + // check slows the code down considerably. + policies::overflow_error >::type forwarding_policy; + return policies::checked_narrowing_cast(boost::math::detail::sin_pi_imp(x, forwarding_policy()), "sin_pi"); +} + +template +inline typename tools::promote_args::type sin_pi(T x) +{ + return boost::math::sin_pi(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost +#endif + diff --git a/libcxx/src/third-party/boost/math/special_functions/sinc.hpp b/libcxx/src/third-party/boost/math/special_functions/sinc.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/sinc.hpp @@ -0,0 +1,119 @@ +// boost sinc.hpp header file + +// (C) Copyright Hubert Holin 2001. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_SINC_HPP +#define BOOST_SINC_HPP + + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +// These are the the "Sinus Cardinal" functions. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the "Sinus Cardinal" of index Pi. + + template + inline T sinc_pi_imp(const T x) + { + BOOST_MATH_STD_USING + + if (abs(x) >= 3.3 * tools::forth_root_epsilon()) + { + return(sin(x)/x); + } + else + { + // |x| < (eps*120)^(1/4) + return 1 - x * x / 6; + } + } + + } // namespace detail + + template + inline typename tools::promote_args::type sinc_pi(T x) + { + typedef typename tools::promote_args::type result_type; + return detail::sinc_pi_imp(static_cast(x)); + } + + template + inline typename tools::promote_args::type sinc_pi(T x, const Policy&) + { + typedef typename tools::promote_args::type result_type; + return detail::sinc_pi_imp(static_cast(x)); + } + + template class U> + inline U sinc_pi(const U x) + { + BOOST_MATH_STD_USING + using ::std::numeric_limits; + + T const taylor_0_bound = tools::epsilon(); + T const taylor_2_bound = tools::root_epsilon(); + T const taylor_n_bound = tools::forth_root_epsilon(); + + if (abs(x) >= taylor_n_bound) + { + return(sin(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 +#ifdef __MWERKS__ + U result = static_cast >(1); +#else + U result = U(1); +#endif + + if (abs(x) >= taylor_0_bound) + { + U x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result -= x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + + template class U, class Policy> + inline U sinc_pi(const U x, const Policy&) + { + return sinc_pi(x); + } + } +} + +#endif /* BOOST_SINC_HPP */ + diff --git a/libcxx/src/third-party/boost/math/special_functions/sinhc.hpp b/libcxx/src/third-party/boost/math/special_functions/sinhc.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/sinhc.hpp @@ -0,0 +1,135 @@ +// boost sinhc.hpp header file + +// (C) Copyright Hubert Holin 2001. +// Distributed under 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) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_SINHC_HPP +#define BOOST_SINHC_HPP + + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include + +// These are the the "Hyperbolic Sinus Cardinal" functions. + +namespace boost +{ + namespace math + { + namespace detail + { + // This is the "Hyperbolic Sinus Cardinal" of index Pi. + + template + inline T sinhc_pi_imp(const T x) + { + using ::std::abs; + using ::std::sinh; + using ::std::sqrt; + + static T const taylor_0_bound = tools::epsilon(); + static T const taylor_2_bound = sqrt(taylor_0_bound); + static T const taylor_n_bound = sqrt(taylor_2_bound); + + if (abs(x) >= taylor_n_bound) + { + return(sinh(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 + T result = static_cast(1); + + if (abs(x) >= taylor_0_bound) + { + T x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result += x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + + } // namespace detail + + template + inline typename tools::promote_args::type sinhc_pi(T x) + { + typedef typename tools::promote_args::type result_type; + return detail::sinhc_pi_imp(static_cast(x)); + } + + template + inline typename tools::promote_args::type sinhc_pi(T x, const Policy&) + { + return boost::math::sinhc_pi(x); + } + + template class U> + inline U sinhc_pi(const U x) + { + using std::abs; + using std::sinh; + using std::sqrt; + + using ::std::numeric_limits; + + static T const taylor_0_bound = tools::epsilon(); + static T const taylor_2_bound = sqrt(taylor_0_bound); + static T const taylor_n_bound = sqrt(taylor_2_bound); + + if (abs(x) >= taylor_n_bound) + { + return(sinh(x)/x); + } + else + { + // approximation by taylor series in x at 0 up to order 0 +#ifdef __MWERKS__ + U result = static_cast >(1); +#else + U result = U(1); +#endif + + if (abs(x) >= taylor_0_bound) + { + U x2 = x*x; + + // approximation by taylor series in x at 0 up to order 2 + result += x2/static_cast(6); + + if (abs(x) >= taylor_2_bound) + { + // approximation by taylor series in x at 0 up to order 4 + result += (x2*x2)/static_cast(120); + } + } + + return(result); + } + } + } +} + +#endif /* BOOST_SINHC_HPP */ + diff --git a/libcxx/src/third-party/boost/math/special_functions/spherical_harmonic.hpp b/libcxx/src/third-party/boost/math/special_functions/spherical_harmonic.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/spherical_harmonic.hpp @@ -0,0 +1,205 @@ + +// (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_SPHERICAL_HARMONIC_HPP +#define BOOST_MATH_SPECIAL_SPHERICAL_HARMONIC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ +namespace math{ + +namespace detail{ + +// +// Calculates the prefix term that's common to the real +// and imaginary parts. Does *not* fix up the sign of the result +// though. +// +template +inline T spherical_harmonic_prefix(unsigned n, unsigned m, T theta, const Policy& pol) +{ + BOOST_MATH_STD_USING + + if(m > n) + return 0; + + T sin_theta = sin(theta); + T x = cos(theta); + + T leg = detail::legendre_p_imp(n, m, x, static_cast(pow(fabs(sin_theta), T(m))), pol); + + T prefix = boost::math::tgamma_delta_ratio(static_cast(n - m + 1), static_cast(2 * m), pol); + prefix *= (2 * n + 1) / (4 * constants::pi()); + prefix = sqrt(prefix); + return prefix * leg; +} +// +// Real Part: +// +template +T spherical_harmonic_r(unsigned n, int m, T theta, T phi, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions + + bool sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + sign = m&1; + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + T mod = boost::math::tools::fmod_workaround(theta, T(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + sign = !sign; + } + // Get the value and adjust sign as required: + T prefix = spherical_harmonic_prefix(n, m, theta, pol); + prefix *= cos(m * phi); + return sign ? T(-prefix) : prefix; +} + +template +T spherical_harmonic_i(unsigned n, int m, T theta, T phi, const Policy& pol) +{ + BOOST_MATH_STD_USING // ADL of std functions + + bool sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + sign = !(m&1); + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + T mod = boost::math::tools::fmod_workaround(theta, T(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + sign = !sign; + } + // Get the value and adjust sign as required: + T prefix = spherical_harmonic_prefix(n, m, theta, pol); + prefix *= sin(m * phi); + return sign ? T(-prefix) : prefix; +} + +template +std::complex spherical_harmonic(unsigned n, int m, U theta, U phi, const Policy& pol) +{ + BOOST_MATH_STD_USING + // + // Sort out the signs: + // + bool r_sign = false; + bool i_sign = false; + if(m < 0) + { + // Reflect and adjust sign if m < 0: + r_sign = m&1; + i_sign = !(m&1); + m = abs(m); + } + if(m&1) + { + // Check phase if theta is outside [0, PI]: + U mod = boost::math::tools::fmod_workaround(theta, U(2 * constants::pi())); + if(mod < 0) + mod += 2 * constants::pi(); + if(mod > constants::pi()) + { + r_sign = !r_sign; + i_sign = !i_sign; + } + } + // + // Calculate the value: + // + U prefix = spherical_harmonic_prefix(n, m, theta, pol); + U r = prefix * cos(m * phi); + U i = prefix * sin(m * phi); + // + // Add in the signs: + // + if(r_sign) + r = -r; + if(i_sign) + i = -i; + static const char* function = "boost::math::spherical_harmonic<%1%>(int, int, %1%, %1%)"; + return std::complex(policies::checked_narrowing_cast(r, function), policies::checked_narrowing_cast(i, function)); +} + +} // namespace detail + +template +inline std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return detail::spherical_harmonic(n, m, static_cast(theta), static_cast(phi), pol); +} + +template +inline std::complex::type> + spherical_harmonic(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic(n, m, theta, phi, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::spherical_harmonic_r(n, m, static_cast(theta), static_cast(phi), pol), "bost::math::spherical_harmonic_r<%1%>(unsigned, int, %1%, %1%)"); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_r(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic_r(n, m, theta, phi, policies::policy<>()); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + return policies::checked_narrowing_cast(detail::spherical_harmonic_i(n, m, static_cast(theta), static_cast(phi), pol), "boost::math::spherical_harmonic_i<%1%>(unsigned, int, %1%, %1%)"); +} + +template +inline typename tools::promote_args::type + spherical_harmonic_i(unsigned n, int m, T1 theta, T2 phi) +{ + return boost::math::spherical_harmonic_i(n, m, theta, phi, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SPECIAL_SPHERICAL_HARMONIC_HPP + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/sqrt1pm1.hpp b/libcxx/src/third-party/boost/math/special_functions/sqrt1pm1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/sqrt1pm1.hpp @@ -0,0 +1,48 @@ +// (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_SQRT1PM1 +#define BOOST_MATH_SQRT1PM1 + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +// +// This algorithm computes sqrt(1+x)-1 for small x: +// + +namespace boost{ namespace math{ + +template +inline typename tools::promote_args::type sqrt1pm1(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + BOOST_MATH_STD_USING + + if(fabs(result_type(val)) > 0.75) + return sqrt(1 + result_type(val)) - 1; + return boost::math::expm1(boost::math::log1p(val, pol) / 2, pol); +} + +template +inline typename tools::promote_args::type sqrt1pm1(const T& val) +{ + return sqrt1pm1(val, policies::policy<>()); +} + +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_SQRT1PM1 + + + + + diff --git a/libcxx/src/third-party/boost/math/special_functions/trigamma.hpp b/libcxx/src/third-party/boost/math/special_functions/trigamma.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/trigamma.hpp @@ -0,0 +1,467 @@ +// (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_SF_TRIGAMMA_HPP +#define BOOST_MATH_SF_TRIGAMMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ +namespace math{ +namespace detail{ + +template +T polygamma_imp(const int n, T x, const Policy &pol); + +template +T trigamma_prec(T x, const std::integral_constant*, const Policy&) +{ + // Max error in interpolated form: 3.736e-017 + static const T offset = BOOST_MATH_BIG_CONSTANT(T, 53, 2.1093254089355469); + static const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -1.1093280605946045), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.8310674472619321), + BOOST_MATH_BIG_CONSTANT(T, 53, -3.3703848401898283), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.28080574467981213), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.6638069578676164), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468386819102836), + }; + static const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 3.4535389668541151), + BOOST_MATH_BIG_CONSTANT(T, 53, 4.5208926987851437), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.7012734178351534), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.64468798399785611), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.20314516859987728e-6), + }; + // Max error in interpolated form: 1.159e-017 + static const T P_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, -0.13803835004508849e-7), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.50000049158540261), + BOOST_MATH_BIG_CONSTANT(T, 53, 1.6077979838469348), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.5645435828098254), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.0534873203680393), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.74566981111565923), + }; + static const T Q_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 53, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.8822787662376169), + BOOST_MATH_BIG_CONSTANT(T, 53, 4.1681660554090917), + BOOST_MATH_BIG_CONSTANT(T, 53, 2.7853527819234466), + BOOST_MATH_BIG_CONSTANT(T, 53, 0.74967671848044792), + BOOST_MATH_BIG_CONSTANT(T, 53, -0.00057069112416246805), + }; + // Maximum Deviation Found: 6.896e-018 + // Expected Error Term : -6.895e-018 + // Maximum Relative Change in Control Points : 8.497e-004 + static const T P_4_inf[] = { + static_cast(0.68947581948701249e-17L), + static_cast(0.49999999999998975L), + static_cast(1.0177274392923795L), + static_cast(2.498208511343429L), + static_cast(2.1921221359427595L), + static_cast(1.5897035272532764L), + static_cast(0.40154388356961734L), + }; + static const T Q_4_inf[] = { + static_cast(1.0L), + static_cast(1.7021215452463932L), + static_cast(4.4290431747556469L), + static_cast(2.9745631894384922L), + static_cast(2.3013614809773616L), + static_cast(0.28360399799075752L), + static_cast(0.022892987908906897L), + }; + + if(x <= 2) + { + return (offset + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 4) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_2_4, y) / tools::evaluate_polynomial(Q_2_4, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_4_inf, y) / tools::evaluate_polynomial(Q_4_inf, y)) / x; +} + +template +T trigamma_prec(T x, const std::integral_constant*, const Policy&) +{ + // Max error in interpolated form: 1.178e-020 + static const T offset_1_2 = BOOST_MATH_BIG_CONSTANT(T, 64, 2.109325408935546875); + static const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -1.10932535608960258341), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.18793841543017129052), + BOOST_MATH_BIG_CONSTANT(T, 64, -4.63865531898487734531), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.919832884430500908047), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.68074038333180423012), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.21172611429185622377), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635673503366427284), + }; + static const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.77521119359546982995), + BOOST_MATH_BIG_CONSTANT(T, 64, 5.664338024578956321), + BOOST_MATH_BIG_CONSTANT(T, 64, 4.25995134879278028361), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.62956638448940402182), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259635512844691089868), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.629642219810618032207e-8), + }; + // Max error in interpolated form: 3.912e-020 + static const T P_2_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.387540035162952880976e-11), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000276430504), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.21926880986360957306), + BOOST_MATH_BIG_CONSTANT(T, 64, 10.2550347708483445775), + BOOST_MATH_BIG_CONSTANT(T, 64, 18.9002075150709144043), + BOOST_MATH_BIG_CONSTANT(T, 64, 21.0357215832399705625), + BOOST_MATH_BIG_CONSTANT(T, 64, 13.4346512182925923978), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98656291026448279118), + }; + static const T Q_2_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 6.10520430478613667724), + BOOST_MATH_BIG_CONSTANT(T, 64, 18.475001060603645512), + BOOST_MATH_BIG_CONSTANT(T, 64, 31.7087534567758405638), + BOOST_MATH_BIG_CONSTANT(T, 64, 31.908814523890465398), + BOOST_MATH_BIG_CONSTANT(T, 64, 17.4175479039227084798), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.98749106958394941276), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000115917322224411128566), + }; + // Maximum Deviation Found: 2.635e-020 + // Expected Error Term : 2.635e-020 + // Maximum Relative Change in Control Points : 1.791e-003 + static const T P_8_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.263527875092466899848e-19), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.500000000000000058145), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0730121433777364138677), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.94505878379957149534), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0517092358874932620529), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.07995383547483921121), + }; + static const T Q_8_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.187309046577818095504), + BOOST_MATH_BIG_CONSTANT(T, 64, 3.95255391645238842975), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.14743283327078949087), + BOOST_MATH_BIG_CONSTANT(T, 64, 2.52989799376344914499), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.627414303172402506396), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.141554248216425512536), + }; + + if(x <= 2) + { + return (offset_1_2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 8) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_2_8, y) / tools::evaluate_polynomial(Q_2_8, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_8_inf, y) / tools::evaluate_polynomial(Q_8_inf, y)) / x; +} + +template +T trigamma_prec(T x, const std::integral_constant*, const Policy&) +{ + // Max error in interpolated form: 1.916e-035 + + static const T P_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.999999999999999082554457936871832533), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.71237311120865266379041700054847734), + BOOST_MATH_BIG_CONSTANT(T, 113, -7.94125711970499027763789342500817316), + BOOST_MATH_BIG_CONSTANT(T, 113, -5.74657746697664735258222071695644535), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.404213349456398905981223965160595687), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.47877781178642876561595890095758896), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.07714151702455125992166949812126433), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.858877899162360138844032265418028567), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.20499222604410032375789018837922397), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0272103140348194747360175268778415049), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0015764849020876949848954081173520686), + }; + static const T Q_1_2[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.71237311120863419878375031457715223), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.58619118655339853449127952145877467), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.0940067269829372437561421279054968), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.09075424749327792073276309969037885), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.87705890159891405185343806884451286), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.22758678701914477836330837816976782), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.249092040606385004109672077814668716), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0295750413900655597027079600025569048), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00157648490200498142247694709728858139), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.161264050344059471721062360645432809e-14), + }; + + // Max error in interpolated form: 8.958e-035 + static const T P_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -2.55843734739907925764326773972215085), + BOOST_MATH_BIG_CONSTANT(T, 113, -12.2830208240542011967952466273455887), + BOOST_MATH_BIG_CONSTANT(T, 113, -23.9195022162767993526575786066414403), + BOOST_MATH_BIG_CONSTANT(T, 113, -24.9256431504823483094158828285470862), + BOOST_MATH_BIG_CONSTANT(T, 113, -14.7979122765478779075108064826412285), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.46654453928610666393276765059122272), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0191439033405649675717082465687845002), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.515412052554351265708917209749037352), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.195378348786064304378247325360320038), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0334761282624174313035014426794245393), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.002373665205942206348500250056602687), + }; + static const T Q_2_4[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.80098558454419907830670928248659245), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.99220727843170133895059300223445265), + BOOST_MATH_BIG_CONSTANT(T, 113, 11.8896146167631330735386697123464976), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.96613256683809091593793565879092581), + BOOST_MATH_BIG_CONSTANT(T, 113, 4.47254136149624110878909334574485751), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.48600982028196527372434773913633152), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.319570735766764237068541501137990078), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0407358345787680953107374215319322066), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00237366520593271641375755486420859837), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.239554887903526152679337256236302116e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.294749244740618656265237072002026314e-17), + }; + + static const T y_offset_2_4 = BOOST_MATH_BIG_CONSTANT(T, 113, 3.558437347412109375); + + // Max error in interpolated form: 4.319e-035 + static const T P_4_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.166626112697021464248967707021688845e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.499999999999997739552090249208808197), + BOOST_MATH_BIG_CONSTANT(T, 113, 6.40270945019053817915772473771553187), + BOOST_MATH_BIG_CONSTANT(T, 113, 41.3833374155000608013677627389343329), + BOOST_MATH_BIG_CONSTANT(T, 113, 166.803341854562809335667241074035245), + BOOST_MATH_BIG_CONSTANT(T, 113, 453.39964786925369319960722793414521), + BOOST_MATH_BIG_CONSTANT(T, 113, 851.153712317697055375935433362983944), + BOOST_MATH_BIG_CONSTANT(T, 113, 1097.70657567285059133109286478004458), + BOOST_MATH_BIG_CONSTANT(T, 113, 938.431232478455316020076349367632922), + BOOST_MATH_BIG_CONSTANT(T, 113, 487.268001604651932322080970189930074), + BOOST_MATH_BIG_CONSTANT(T, 113, 119.953445242335730062471193124820659), + }; + static const T Q_4_8[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 12.4720855670474488978638945855932398), + BOOST_MATH_BIG_CONSTANT(T, 113, 78.6093129753298570701376952709727391), + BOOST_MATH_BIG_CONSTANT(T, 113, 307.470246050318322489781182863190127), + BOOST_MATH_BIG_CONSTANT(T, 113, 805.140686101151538537565264188630079), + BOOST_MATH_BIG_CONSTANT(T, 113, 1439.12019760292146454787601409644413), + BOOST_MATH_BIG_CONSTANT(T, 113, 1735.6105285756048831268586001383127), + BOOST_MATH_BIG_CONSTANT(T, 113, 1348.32500712856328019355198611280536), + BOOST_MATH_BIG_CONSTANT(T, 113, 607.225985860570846699704222144650563), + BOOST_MATH_BIG_CONSTANT(T, 113, 119.952317857277045332558673164517227), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000140165918355036060868680809129436084), + }; + + // Maximum Deviation Found: 2.867e-035 + // Expected Error Term : 2.866e-035 + // Maximum Relative Change in Control Points : 2.662e-004 + static const T P_8_16[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.184828315274146610610872315609837439e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000004122475157735807738), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.02533865247313349284875558880415875), + BOOST_MATH_BIG_CONSTANT(T, 113, 13.5995927517457371243039532492642734), + BOOST_MATH_BIG_CONSTANT(T, 113, 35.3132224283087906757037999452941588), + BOOST_MATH_BIG_CONSTANT(T, 113, 67.1639424550714159157603179911505619), + BOOST_MATH_BIG_CONSTANT(T, 113, 83.5767733658513967581959839367419891), + BOOST_MATH_BIG_CONSTANT(T, 113, 71.073491212235705900866411319363501), + BOOST_MATH_BIG_CONSTANT(T, 113, 35.8621515614725564575893663483998663), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.72152231639983491987779743154333318), + }; + static const T Q_8_16[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 5.71734397161293452310624822415866372), + BOOST_MATH_BIG_CONSTANT(T, 113, 25.293404179620438179337103263274815), + BOOST_MATH_BIG_CONSTANT(T, 113, 62.2619767967468199111077640625328469), + BOOST_MATH_BIG_CONSTANT(T, 113, 113.955048909238993473389714972250235), + BOOST_MATH_BIG_CONSTANT(T, 113, 130.807138328938966981862203944329408), + BOOST_MATH_BIG_CONSTANT(T, 113, 102.423146902337654110717764213057753), + BOOST_MATH_BIG_CONSTANT(T, 113, 44.0424772805245202514468199602123565), + BOOST_MATH_BIG_CONSTANT(T, 113, 8.89898032477904072082994913461386099), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0296627336872039988632793863671456398), + }; + // Maximum Deviation Found: 1.079e-035 + // Expected Error Term : -1.079e-035 + // Maximum Relative Change in Control Points : 7.884e-003 + static const T P_16_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.500000000000000000000000000000087317), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.345625669885456215194494735902663968), + BOOST_MATH_BIG_CONSTANT(T, 113, 9.62895499360842232127552650044647769), + BOOST_MATH_BIG_CONSTANT(T, 113, 3.5936085382439026269301003761320812), + BOOST_MATH_BIG_CONSTANT(T, 113, 49.459599118438883265036646019410669), + BOOST_MATH_BIG_CONSTANT(T, 113, 7.77519237321893917784735690560496607), + BOOST_MATH_BIG_CONSTANT(T, 113, 74.4536074488178075948642351179304121), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.75209340397069050436806159297952699), + BOOST_MATH_BIG_CONSTANT(T, 113, 23.9292359711471667884504840186561598), + }; + static const T Q_16_inf[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.357918006437579097055656138920742037), + BOOST_MATH_BIG_CONSTANT(T, 113, 19.1386039850709849435325005484512944), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.874349081464143606016221431763364517), + BOOST_MATH_BIG_CONSTANT(T, 113, 98.6516097434855572678195488061432509), + BOOST_MATH_BIG_CONSTANT(T, 113, -16.1051972833382893468655223662534306), + BOOST_MATH_BIG_CONSTANT(T, 113, 154.316860216253720989145047141653727), + BOOST_MATH_BIG_CONSTANT(T, 113, -40.2026880424378986053105969312264534), + BOOST_MATH_BIG_CONSTANT(T, 113, 60.1679136674264778074736441126810223), + BOOST_MATH_BIG_CONSTANT(T, 113, -13.3414844622256422644504472438320114), + BOOST_MATH_BIG_CONSTANT(T, 113, 2.53795636200649908779512969030363442), + }; + + if(x <= 2) + { + return (2 + boost::math::tools::evaluate_polynomial(P_1_2, x) / tools::evaluate_polynomial(Q_1_2, x)) / (x * x); + } + else if(x <= 4) + { + return (y_offset_2_4 + boost::math::tools::evaluate_polynomial(P_2_4, x) / tools::evaluate_polynomial(Q_2_4, x)) / (x * x); + } + else if(x <= 8) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_4_8, y) / tools::evaluate_polynomial(Q_4_8, y)) / x; + } + else if(x <= 16) + { + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_8_16, y) / tools::evaluate_polynomial(Q_8_16, y)) / x; + } + T y = 1 / x; + return (1 + tools::evaluate_polynomial(P_16_inf, y) / tools::evaluate_polynomial(Q_16_inf, y)) / x; +} + +template +T trigamma_imp(T x, const Tag* t, const Policy& pol) +{ + // + // This handles reflection of negative arguments, and all our + // error handling, then forwards to the T-specific approximation. + // + BOOST_MATH_STD_USING // ADL of std functions. + + T result = 0; + // + // Check for negative arguments and use reflection: + // + if(x <= 0) + { + // Reflect: + T z = 1 - x; + // Argument reduction for tan: + if(floor(x) == x) + { + return policies::raise_pole_error("boost::math::trigamma<%1%>(%1%)", nullptr, (1-x), pol); + } + T s = fabs(x) < fabs(z) ? boost::math::sin_pi(x, pol) : boost::math::sin_pi(z, pol); + return -trigamma_imp(z, t, pol) + boost::math::pow<2>(constants::pi()) / (s * s); + } + if(x < 1) + { + result = 1 / (x * x); + x += 1; + } + return result + trigamma_prec(x, t, pol); +} + +template +T trigamma_imp(T x, const std::integral_constant*, const Policy& pol) +{ + return polygamma_imp(1, x, pol); +} +// +// Initializer: ensure all our constants are initialized prior to the first call of main: +// +template +struct trigamma_initializer +{ + struct init + { + init() + { + typedef typename policies::precision::type precision_type; + do_init(std::integral_constant()); + } + void do_init(const std::true_type&) + { + boost::math::trigamma(T(2.5), Policy()); + } + void do_init(const std::false_type&){} + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename trigamma_initializer::init trigamma_initializer::initializer; + +} // namespace detail + +template +inline typename tools::promote_args::type + trigamma(T x, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef std::integral_constant tag_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + + // Force initialization of constants: + detail::trigamma_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::trigamma_imp( + static_cast(x), + static_cast(nullptr), forwarding_policy()), "boost::math::trigamma<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type + trigamma(T x) +{ + return trigamma(x, policies::policy<>()); +} + +} // namespace math +} // namespace boost +#endif + diff --git a/libcxx/src/third-party/boost/math/special_functions/trunc.hpp b/libcxx/src/third-party/boost/math/special_functions/trunc.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/trunc.hpp @@ -0,0 +1,166 @@ +// Copyright John Maddock 2007. +// 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_TRUNC_HPP +#define BOOST_MATH_TRUNC_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +inline tools::promote_args_t trunc(const T& v, const Policy& pol, const std::false_type&) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + if(!(boost::math::isfinite)(v)) + { + return policies::raise_rounding_error("boost::math::trunc<%1%>(%1%)", nullptr, static_cast(v), static_cast(v), pol); + } + return (v >= 0) ? static_cast(floor(v)) : static_cast(ceil(v)); +} + +template +inline tools::promote_args_t trunc(const T& v, const Policy&, const std::true_type&) +{ + return v; +} + +} + +template +inline tools::promote_args_t trunc(const T& v, const Policy& pol) +{ + return detail::trunc(v, pol, std::integral_constant::value>()); +} +template +inline tools::promote_args_t trunc(const T& v) +{ + return trunc(v, policies::policy<>()); +} +// +// The following functions will not compile unless T has an +// implicit conversion to the integer types. For user-defined +// number types this will likely not be the case. In that case +// these functions should either be specialized for the UDT in +// question, or else overloads should be placed in the same +// namespace as the UDT: these will then be found via argument +// dependent lookup. See our concept archetypes for examples. +// +// Non-standard numeric limits syntax "(std::numeric_limits::max)()" +// is to avoid macro substiution from MSVC +// https://stackoverflow.com/questions/27442885/syntax-error-with-stdnumeric-limitsmax +// +template +inline int itrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", nullptr, static_cast(v), 0, pol)); + } + return static_cast(r); +} +template +inline int itrunc(const T& v) +{ + return itrunc(v, policies::policy<>()); +} + +template +inline long ltrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", nullptr, static_cast(v), 0L, pol)); + } + return static_cast(r); +} +template +inline long ltrunc(const T& v) +{ + return ltrunc(v, policies::policy<>()); +} + +template +inline long long lltrunc(const T& v, const Policy& pol) +{ + BOOST_MATH_STD_USING + using result_type = tools::promote_args_t; + result_type r = boost::math::trunc(v, pol); + if(r > static_cast((std::numeric_limits::max)()) || + r < static_cast((std::numeric_limits::min)())) + { + return static_cast(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", nullptr, v, static_cast(0), pol)); + } + return static_cast(r); +} +template +inline long long lltrunc(const T& v) +{ + return lltrunc(v, policies::policy<>()); +} + +template +inline typename std::enable_if::value, int>::type + iconvert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +inline typename std::enable_if::value, int>::type + iconvert(const T& v, const Policy& pol) +{ + using boost::math::itrunc; + return itrunc(v, pol); +} + +template +inline typename std::enable_if::value, long>::type + lconvert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +inline typename std::enable_if::value, long>::type + lconvert(const T& v, const Policy& pol) +{ + using boost::math::ltrunc; + return ltrunc(v, pol); +} + +template +inline typename std::enable_if::value, long long>::type + llconvertert(const T& v, const Policy&) +{ + return static_cast(v); +} + +template +inline typename std::enable_if::value, long long>::type + llconvertert(const T& v, const Policy& pol) +{ + using boost::math::lltrunc; + return lltrunc(v, pol); +} + +}} // namespaces + +#endif // BOOST_MATH_TRUNC_HPP diff --git a/libcxx/src/third-party/boost/math/special_functions/ulp.hpp b/libcxx/src/third-party/boost/math/special_functions/ulp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/ulp.hpp @@ -0,0 +1,105 @@ +// (C) Copyright John Maddock 2015. +// 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_ULP_HPP +#define BOOST_MATH_SPECIAL_ULP_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace detail{ + +template +T ulp_imp(const T& val, const std::true_type&, const Policy& pol) +{ + BOOST_MATH_STD_USING + int expon; + static const char* function = "ulp<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if(fpclass == FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + else if((fpclass == (int)FP_INFINITE) || (fabs(val) >= tools::max_value())) + { + return (val < 0 ? -1 : 1) * policies::raise_overflow_error(function, nullptr, pol); + } + else if(fpclass == FP_ZERO) + return detail::get_smallest_value(); + // + // This code is almost the same as that for float_next, except for negative integers, + // where we preserve the relation ulp(x) == ulp(-x) as does Java: + // + frexp(fabs(val), &expon); + T diff = ldexp(T(1), expon - tools::digits()); + if(diff == 0) + diff = detail::get_smallest_value(); + return diff; +} +// non-binary version: +template +T ulp_imp(const T& val, const std::false_type&, const Policy& pol) +{ + static_assert(std::numeric_limits::is_specialized, "Type T must be specialized."); + static_assert(std::numeric_limits::radix != 2, "Type T must be specialized."); + BOOST_MATH_STD_USING + int expon; + static const char* function = "ulp<%1%>(%1%)"; + + int fpclass = (boost::math::fpclassify)(val); + + if(fpclass == FP_NAN) + { + return policies::raise_domain_error( + function, + "Argument must be finite, but got %1%", val, pol); + } + else if((fpclass == FP_INFINITE) || (fabs(val) >= tools::max_value())) + { + return (val < 0 ? -1 : 1) * policies::raise_overflow_error(function, nullptr, pol); + } + else if(fpclass == FP_ZERO) + return detail::get_smallest_value(); + // + // This code is almost the same as that for float_next, except for negative integers, + // where we preserve the relation ulp(x) == ulp(-x) as does Java: + // + expon = 1 + ilogb(fabs(val)); + T diff = scalbn(T(1), expon - std::numeric_limits::digits); + if(diff == 0) + diff = detail::get_smallest_value(); + return diff; +} + +} + +template +inline typename tools::promote_args::type ulp(const T& val, const Policy& pol) +{ + typedef typename tools::promote_args::type result_type; + return detail::ulp_imp(static_cast(val), std::integral_constant::is_specialized || (std::numeric_limits::radix == 2)>(), pol); +} + +template +inline typename tools::promote_args::type ulp(const T& val) +{ + return ulp(val, policies::policy<>()); +} + + +}} // namespaces + +#endif // BOOST_MATH_SPECIAL_ULP_HPP + diff --git a/libcxx/src/third-party/boost/math/special_functions/zeta.hpp b/libcxx/src/third-party/boost/math/special_functions/zeta.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/special_functions/zeta.hpp @@ -0,0 +1,1101 @@ +// Copyright John Maddock 2007, 2014. +// 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_ZETA_HPP +#define BOOST_MATH_ZETA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128) +// +// This is the only way we can avoid +// warning: non-standard suffix on floating constant [-Wpedantic] +// when building with -Wall -pedantic. Neither __extension__ +// nor #pragma diagnostic ignored work :( +// +#pragma GCC system_header +#endif + +namespace boost{ namespace math{ namespace detail{ + +#if 0 +// +// This code is commented out because we have a better more rapidly converging series +// now. Retained for future reference and in case the new code causes any issues down the line.... +// + +template +struct zeta_series_cache_size +{ + // + // Work how large to make our cache size when evaluating the series + // evaluation: normally this is just large enough for the series + // to have converged, but for arbitrary precision types we need a + // really large cache to achieve reasonable precision in a reasonable + // time. This is important when constructing rational approximations + // to zeta for example. + // + typedef typename boost::math::policies::precision::type precision_type; + typedef typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + typename mpl::if_< + mpl::less_equal >, + std::integral_constant, + std::integral_constant + >::type + >::type + >::type type; +}; + +template +T zeta_series_imp(T s, T sc, const Policy&) +{ + // + // Series evaluation from: + // Havil, J. Gamma: Exploring Euler's Constant. + // Princeton, NJ: Princeton University Press, 2003. + // + // See also http://mathworld.wolfram.com/RiemannZetaFunction.html + // + BOOST_MATH_STD_USING + T sum = 0; + T mult = 0.5; + T change; + typedef typename zeta_series_cache_size::type cache_size; + T powers[cache_size::value] = { 0, }; + unsigned n = 0; + do{ + T binom = -static_cast(n); + T nested_sum = 1; + if(n < sizeof(powers) / sizeof(powers[0])) + powers[n] = pow(static_cast(n + 1), -s); + for(unsigned k = 1; k <= n; ++k) + { + T p; + if(k < sizeof(powers) / sizeof(powers[0])) + { + p = powers[k]; + //p = pow(k + 1, -s); + } + else + p = pow(static_cast(k + 1), -s); + nested_sum += binom * p; + binom *= (k - static_cast(n)) / (k + 1); + } + change = mult * nested_sum; + sum += change; + mult /= 2; + ++n; + }while(fabs(change / sum) > tools::epsilon()); + + return sum * 1 / -boost::math::powm1(T(2), sc); +} + +// +// Classical p-series: +// +template +struct zeta_series2 +{ + typedef T result_type; + zeta_series2(T _s) : s(-_s), k(1){} + T operator()() + { + BOOST_MATH_STD_USING + return pow(static_cast(k++), s); + } +private: + T s; + unsigned k; +}; + +template +inline T zeta_series2_imp(T s, const Policy& pol) +{ + std::uintmax_t max_iter = policies::get_max_series_iterations();; + zeta_series2 f(s); + T result = tools::sum_series( + f, + policies::get_epsilon(), + max_iter); + policies::check_series_iterations("boost::math::zeta_series2<%1%>(%1%)", max_iter, pol); + return result; +} +#endif + +template +T zeta_polynomial_series(T s, T sc, Policy const &) +{ + // + // This is algorithm 3 from: + // + // "An Efficient Algorithm for the Riemann Zeta Function", P. Borwein, + // Canadian Mathematical Society, Conference Proceedings. + // See: http://www.cecm.sfu.ca/personal/pborwein/PAPERS/P155.pdf + // + BOOST_MATH_STD_USING + int n = itrunc(T(log(boost::math::tools::epsilon()) / -2)); + T sum = 0; + T two_n = ldexp(T(1), n); + int ej_sign = 1; + for(int j = 0; j < n; ++j) + { + sum += ej_sign * -two_n / pow(T(j + 1), s); + ej_sign = -ej_sign; + } + T ej_sum = 1; + T ej_term = 1; + for(int j = n; j <= 2 * n - 1; ++j) + { + sum += ej_sign * (ej_sum - two_n) / pow(T(j + 1), s); + ej_sign = -ej_sign; + ej_term *= 2 * n - j; + ej_term /= j - n + 1; + ej_sum += ej_term; + } + return -sum / (two_n * (-powm1(T(2), sc))); +} + +template +T zeta_imp_prec(T s, T sc, const Policy& pol, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s >= policies::digits()) + return 1; + result = zeta_polynomial_series(s, sc, pol); +#if 0 + // Old code archived for future reference: + + // + // Only use power series if it will converge in 100 + // iterations or less: the more iterations it consumes + // the slower convergence becomes so we have to be very + // careful in it's usage. + // + if (s > -log(tools::epsilon()) / 4.5) + result = detail::zeta_series2_imp(s, pol); + else + result = detail::zeta_series_imp(s, sc, pol); +#endif + return result; +} + +template +inline T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 2.020e-18 + // Expected Error Term: -2.020e-18 + // Max error found at double precision: 3.994987e-17 + static const T P[6] = { + static_cast(0.24339294433593750202L), + static_cast(-0.49092470516353571651L), + static_cast(0.0557616214776046784287L), + static_cast(-0.00320912498879085894856L), + static_cast(0.000451534528645796438704L), + static_cast(-0.933241270357061460782e-5L), + }; + static const T Q[6] = { + static_cast(1L), + static_cast(-0.279960334310344432495L), + static_cast(0.0419676223309986037706L), + static_cast(-0.00413421406552171059003L), + static_cast(0.00024978985622317935355L), + static_cast(-0.101855788418564031874e-4L), + }; + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result -= 1.2433929443359375F; + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 9.007e-20 + // Expected Error Term: 9.007e-20 + static const T P[6] = { + static_cast(0.577215664901532860516L), + static_cast(0.243210646940107164097L), + static_cast(0.0417364673988216497593L), + static_cast(0.00390252087072843288378L), + static_cast(0.000249606367151877175456L), + static_cast(0.110108440976732897969e-4L), + }; + static const T Q[6] = { + static_cast(1.0), + static_cast(0.295201277126631761737L), + static_cast(0.043460910607305495864L), + static_cast(0.00434930582085826330659L), + static_cast(0.000255784226140488490982L), + static_cast(0.10991819782396112081e-4L), + }; + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 5.946e-22 + // Expected Error Term: -5.946e-22 + static const float Y = 0.6986598968505859375; + static const T P[6] = { + static_cast(-0.0537258300023595030676L), + static_cast(0.0445163473292365591906L), + static_cast(0.0128677673534519952905L), + static_cast(0.00097541770457391752726L), + static_cast(0.769875101573654070925e-4L), + static_cast(0.328032510000383084155e-5L), + }; + static const T Q[7] = { + 1.0f, + static_cast(0.33383194553034051422L), + static_cast(0.0487798431291407621462L), + static_cast(0.00479039708573558490716L), + static_cast(0.000270776703956336357707L), + static_cast(0.106951867532057341359e-4L), + static_cast(0.236276623974978646399e-7L), + }; + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 7) + { + // Maximum Deviation Found: 2.955e-17 + // Expected Error Term: 2.955e-17 + // Max error found at double precision: 2.009135e-16 + + static const T P[6] = { + static_cast(-2.49710190602259410021L), + static_cast(-2.60013301809475665334L), + static_cast(-0.939260435377109939261L), + static_cast(-0.138448617995741530935L), + static_cast(-0.00701721240549802377623L), + static_cast(-0.229257310594893932383e-4L), + }; + static const T Q[9] = { + 1.0f, + static_cast(0.706039025937745133628L), + static_cast(0.15739599649558626358L), + static_cast(0.0106117950976845084417L), + static_cast(-0.36910273311764618902e-4L), + static_cast(0.493409563927590008943e-5L), + static_cast(-0.234055487025287216506e-6L), + static_cast(0.718833729365459760664e-8L), + static_cast(-0.1129200113474947419e-9L), + }; + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result = 1 + exp(result); + } + else if(s < 15) + { + // Maximum Deviation Found: 7.117e-16 + // Expected Error Term: 7.117e-16 + // Max error found at double precision: 9.387771e-16 + static const T P[7] = { + static_cast(-4.78558028495135619286L), + static_cast(-1.89197364881972536382L), + static_cast(-0.211407134874412820099L), + static_cast(-0.000189204758260076688518L), + static_cast(0.00115140923889178742086L), + static_cast(0.639949204213164496988e-4L), + static_cast(0.139348932445324888343e-5L), + }; + static const T Q[9] = { + 1.0f, + static_cast(0.244345337378188557777L), + static_cast(0.00873370754492288653669L), + static_cast(-0.00117592765334434471562L), + static_cast(-0.743743682899933180415e-4L), + static_cast(-0.21750464515767984778e-5L), + static_cast(0.471001264003076486547e-8L), + static_cast(-0.833378440625385520576e-10L), + static_cast(0.699841545204845636531e-12L), + }; + result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7)); + result = 1 + exp(result); + } + else if(s < 36) + { + // Max error in interpolated form: 1.668e-17 + // Max error found at long double precision: 1.669714e-17 + static const T P[8] = { + static_cast(-10.3948950573308896825L), + static_cast(-2.85827219671106697179L), + static_cast(-0.347728266539245787271L), + static_cast(-0.0251156064655346341766L), + static_cast(-0.00119459173416968685689L), + static_cast(-0.382529323507967522614e-4L), + static_cast(-0.785523633796723466968e-6L), + static_cast(-0.821465709095465524192e-8L), + }; + static const T Q[10] = { + 1.0f, + static_cast(0.208196333572671890965L), + static_cast(0.0195687657317205033485L), + static_cast(0.00111079638102485921877L), + static_cast(0.408507746266039256231e-4L), + static_cast(0.955561123065693483991e-6L), + static_cast(0.118507153474022900583e-7L), + static_cast(0.222609483627352615142e-14L), + }; + result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15)); + result = 1 + exp(result); + } + else if(s < 56) + { + result = 1 + pow(T(2), -s); + } + else + { + result = 1; + } + return result; +} + +template +T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 3.099e-20 + // Expected Error Term: 3.099e-20 + // Max error found at long double precision: 5.890498e-20 + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.243392944335937499969), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.496837806864865688082), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0680008039723709987107), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00511620413006619942112), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000455369899250053003335), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.279496685273033761927e-4), + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.30425480068225790522), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.050052748580371598736), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00519355671064700627862), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000360623385771198350257), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.159600883054550987633e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.339770279812410586032e-6), + }; + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result -= 1.2433929443359375F; + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 1.059e-21 + // Expected Error Term: 1.059e-21 + // Max error found at long double precision: 1.626303e-19 + + static const T P[6] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 0.577215664901532860605), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.222537368917162139445), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0356286324033215682729), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00304465292366350081446), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000178102511649069421904), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.700867470265983665042e-5), + }; + static const T Q[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.259385759149531030085), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0373974962106091316854), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00332735159183332820617), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000188690420706998606469), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.635994377921861930071e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.226583954978371199405e-7), + }; + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 5.946e-22 + // Expected Error Term: -5.946e-22 + static const float Y = 0.6986598968505859375; + static const T P[7] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -0.053725830002359501027), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0470551187571475844778), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0101339410415759517471), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00100240326666092854528), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.685027119098122814867e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.390972820219765942117e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.540319769113543934483e-7), + }; + static const T Q[8] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.286577739726542730421), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0447355811517733225843), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00430125107610252363302), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000284956969089786662045), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.116188101609848411329e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.278090318191657278204e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.19683620233222028478e-8), + }; + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 7) + { + // Max error found at long double precision: 8.132216e-19 + static const T P[8] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -2.49710190602259407065), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.36664913245960625334), + BOOST_MATH_BIG_CONSTANT(T, 64, -1.77180020623777595452), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.464717885249654313933), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0643694921293579472583), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00464265386202805715487), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000165556579779704340166), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252884970740994069582e-5), + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 1.01300131390690459085), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.387898115758643503827), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0695071490045701135188), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00586908595251442839291), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000217752974064612188616), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.397626583349419011731e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.927884739284359700764e-8), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.119810501805618894381e-9), + }; + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result = 1 + exp(result); + } + else if(s < 15) + { + // Max error in interpolated form: 1.133e-18 + // Max error found at long double precision: 2.183198e-18 + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -4.78558028495135548083), + BOOST_MATH_BIG_CONSTANT(T, 64, -3.23873322238609358947), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.892338582881021799922), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.131326296217965913809), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0115651591773783712996), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.000657728968362695775205), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.252051328129449973047e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.626503445372641798925e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.815696314790853893484e-8), + }; + static const T Q[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.525765665400123515036), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.10852641753657122787), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0115669945375362045249), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.000732896513858274091966), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.30683952282420248448e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.819649214609633126119e-6), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.117957556472335968146e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.193432300973017671137e-12), + }; + result = tools::evaluate_polynomial(P, T(s - 7)) / tools::evaluate_polynomial(Q, T(s - 7)); + result = 1 + exp(result); + } + else if(s < 42) + { + // Max error in interpolated form: 1.668e-17 + // Max error found at long double precision: 1.669714e-17 + static const T P[9] = { + BOOST_MATH_BIG_CONSTANT(T, 64, -10.3948950573308861781), + BOOST_MATH_BIG_CONSTANT(T, 64, -2.82646012777913950108), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.342144362739570333665), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.0249285145498722647472), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.00122493108848097114118), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.423055371192592850196e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.1025215577185967488e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.165096762663509467061e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.145392555873022044329e-9), + }; + static const T Q[10] = { + BOOST_MATH_BIG_CONSTANT(T, 64, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.205135978585281988052), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.0192359357875879453602), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.00111496452029715514119), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.434928449016693986857e-4), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.116911068726610725891e-5), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.206704342290235237475e-7), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.209772836100827647474e-9), + BOOST_MATH_BIG_CONSTANT(T, 64, -0.939798249922234703384e-16), + BOOST_MATH_BIG_CONSTANT(T, 64, 0.264584017421245080294e-18), + }; + result = tools::evaluate_polynomial(P, T(s - 15)) / tools::evaluate_polynomial(Q, T(s - 15)); + result = 1 + exp(result); + } + else if(s < 63) + { + result = 1 + pow(T(2), -s); + } + else + { + result = 1; + } + return result; +} + +template +T zeta_imp_prec(T s, T sc, const Policy&, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + T result; + if(s < 1) + { + // Rational Approximation + // Maximum Deviation Found: 9.493e-37 + // Expected Error Term: 9.492e-37 + // Max error found at long double precision: 7.281332e-31 + + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0353008629988648122808504280990313668), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0107795651204927743049369868548706909), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000523961870530500751114866884685172975), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.661805838304910731947595897966487515e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.658932670403818558510656304189164638e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.103437265642266106533814021041010453e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.116818787212666457105375746642927737e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.660690993901506912123512551294239036e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113103113698388531428914333768142527e-10), + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.387483472099602327112637481818565459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0802265315091063135271497708694776875), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0110727276164171919280036408995078164), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00112552716946286252000434849173787243), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.874554160748626916455655180296834352e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.530097847491828379568636739662278322e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.248461553590496154705565904497247452e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.881834921354014787309644951507523899e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.217062446168217797598596496310953025e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.315823200002384492377987848307151168e-11), + }; + result = tools::evaluate_polynomial(P, sc) / tools::evaluate_polynomial(Q, sc); + result += (sc); + result /= (sc); + } + else if(s <= 2) + { + // Maximum Deviation Found: 1.616e-37 + // Expected Error Term: -1.615e-37 + + static const T P[10] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.577215664901532860606512090082402431), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.255597968739771510415479842335906308), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0494056503552807274142218876983542205), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00551372778611700965268920983472292325), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00043667616723970574871427830895192731), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.268562259154821957743669387915239528e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.109249633923016310141743084480436612e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.273895554345300227466534378753023924e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.583103205551702720149237384027795038e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.835774625259919268768735944711219256e-11), + }; + static const T Q[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.316661751179735502065583176348292881), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0540401806533507064453851182728635272), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00598621274107420237785899476374043797), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000474907812321704156213038740142079615), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.272125421722314389581695715835862418e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.112649552156479800925522445229212933e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.301838975502992622733000078063330461e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.422960728687211282539769943184270106e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.377105263588822468076813329270698909e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.581926559304525152432462127383600681e-13), + }; + result = tools::evaluate_polynomial(P, T(-sc)) / tools::evaluate_polynomial(Q, T(-sc)); + result += 1 / (-sc); + } + else if(s <= 4) + { + // Maximum Deviation Found: 1.891e-36 + // Expected Error Term: -1.891e-36 + // Max error found: 2.171527e-35 + + static const float Y = 0.6986598968505859375; + static const T P[11] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0537258300023595010275848333539748089), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0429086930802630159457448174466342553), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0136148228754303412510213395034056857), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00190231601036042925183751238033763915), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000186880390916311438818302549192456581), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.145347370745893262394287982691323657e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.805843276446813106414036600485884885e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.340818159286739137503297172091882574e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.115762357488748996526167305116837246e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.231904754577648077579913403645767214e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.340169592866058506675897646629036044e-12), + }; + static const T Q[12] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.363755247765087100018556983050520554), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0696581979014242539385695131258321598), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00882208914484611029571547753782014817), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000815405623261946661762236085660996718), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.571366167062457197282642344940445452e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.309278269271853502353954062051797838e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.12822982083479010834070516053794262e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.397876357325018976733953479182110033e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.8484432107648683277598472295289279e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.105677416606909614301995218444080615e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.547223964564003701979951154093005354e-15), + }; + result = tools::evaluate_polynomial(P, T(s - 2)) / tools::evaluate_polynomial(Q, T(s - 2)); + result += Y + 1 / (-sc); + } + else if(s <= 6) + { + // Max error in interpolated form: 1.510e-37 + // Max error found at long double precision: 2.769266e-34 + + static const T Y = 3.28348541259765625F; + + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 0.786383506575062179339611614117697622), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.495766593395271370974685959652073976), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.409116737851754766422360889037532228), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.57340744006238263817895456842655987), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.280479899797421910694892949057963111), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0753148409447590257157585696212649869), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0122934003684672788499099362823748632), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00126148398446193639247961370266962927), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.828465038179772939844657040917364896e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.361008916706050977143208468690645684e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.109879825497910544424797771195928112e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.214539416789686920918063075528797059e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.15090220092460596872172844424267351e-10), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.69490865837142338462982225731926485), + BOOST_MATH_BIG_CONSTANT(T, 113, 1.22697696630994080733321401255942464), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.495409420862526540074366618006341533), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.122368084916843823462872905024259633), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0191412993625268971656513890888208623), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00191401538628980617753082598351559642), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000123318142456272424148930280876444459), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.531945488232526067889835342277595709e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.161843184071894368337068779669116236e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.305796079600152506743828859577462778e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.233582592298450202680170811044408894e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.275363878344548055574209713637734269e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.221564186807357535475441900517843892e-15), + }; + result = tools::evaluate_polynomial(P, T(s - 4)) / tools::evaluate_polynomial(Q, T(s - 4)); + result -= Y; + result = 1 + exp(result); + } + else if(s < 10) + { + // Max error in interpolated form: 1.999e-34 + // Max error found at long double precision: 2.156186e-33 + + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -4.0545627381873738086704293881227365), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.70088348734699134347906176097717782), + BOOST_MATH_BIG_CONSTANT(T, 113, -2.36921550900925512951976617607678789), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.684322583796369508367726293719322866), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.126026534540165129870721937592996324), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.015636903921778316147260572008619549), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00135442294754728549644376325814460807), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.842793965853572134365031384646117061e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.385602133791111663372015460784978351e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.130458500394692067189883214401478539e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.315861074947230418778143153383660035e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.500334720512030826996373077844707164e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.420204769185233365849253969097184005e-12), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.97663511666410096104783358493318814), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.40878780231201806504987368939673249), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0963890666609396058945084107597727252), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0142207619090854604824116070866614505), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00139010220902667918476773423995750877), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.940669540194694997889636696089994734e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.458220848507517004399292480807026602e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.16345521617741789012782420625435495e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.414007452533083304371566316901024114e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.68701473543366328016953742622661377e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.603461891080716585087883971886075863e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.294670713571839023181857795866134957e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.147003914536437243143096875069813451e-18), + }; + result = tools::evaluate_polynomial(P, T(s - 6)) / tools::evaluate_polynomial(Q, T(s - 6)); + result = 1 + exp(result); + } + else if(s < 17) + { + // Max error in interpolated form: 1.641e-32 + // Max error found at long double precision: 1.696121e-32 + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -6.91319491921722925920883787894829678), + BOOST_MATH_BIG_CONSTANT(T, 113, -3.65491257639481960248690596951049048), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.813557553449954526442644544105257881), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0994317301685870959473658713841138083), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00726896610245676520248617014211734906), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000317253318715075854811266230916762929), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.66851422826636750855184211580127133e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.879464154730985406003332577806849971e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.113838903158254250631678791998294628e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.379184410304927316385211327537817583e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.612992858643904887150527613446403867e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.347873737198164757035457841688594788e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.289187187441625868404494665572279364e-15), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.427310044448071818775721584949868806), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.074602514873055756201435421385243062), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00688651562174480772901425121653945942), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000360174847635115036351323894321880445), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.973556847713307543918865405758248777e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.853455848314516117964634714780874197e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.118203513654855112421673192194622826e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.462521662511754117095006543363328159e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.834212591919475633107355719369463143e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.5354594751002702935740220218582929e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.406451690742991192964889603000756203e-15), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.887948682401000153828241615760146728e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.34980761098820347103967203948619072e-21), + }; + result = tools::evaluate_polynomial(P, T(s - 10)) / tools::evaluate_polynomial(Q, T(s - 10)); + result = 1 + exp(result); + } + else if(s < 30) + { + // Max error in interpolated form: 1.563e-31 + // Max error found at long double precision: 1.562725e-31 + + static const T P[13] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -11.7824798233959252791987402769438322), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.36131215284987731928174218354118102), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.732260980060982349410898496846972204), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0744985185694913074484248803015717388), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.00517228281320594683022294996292250527), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.000260897206152101522569969046299309939), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.989553462123121764865178453128769948e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.286916799741891410827712096608826167e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.637262477796046963617949532211619729e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.106796831465628373325491288787760494e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.129343095511091870860498356205376823e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.102397936697965977221267881716672084e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.402663128248642002351627980255756363e-16), + }; + static const T Q[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.311288325355705609096155335186466508), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0438318468940415543546769437752132748), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.00374396349183199548610264222242269536), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.000218707451200585197339671707189281302), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.927578767487930747532953583797351219e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.294145760625753561951137473484889639e-6), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.704618586690874460082739479535985395e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.126333332872897336219649130062221257e-9), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.16317315713773503718315435769352765e-11), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.137846712823719515148344938160275695e-13), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.580975420554224366450994232723910583e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.291354445847552426900293580511392459e-22), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.73614324724785855925025452085443636e-25), + }; + result = tools::evaluate_polynomial(P, T(s - 17)) / tools::evaluate_polynomial(Q, T(s - 17)); + result = 1 + exp(result); + } + else if(s < 74) + { + // Max error in interpolated form: 2.311e-27 + // Max error found at long double precision: 2.297544e-27 + static const T P[14] = { + BOOST_MATH_BIG_CONSTANT(T, 113, -20.7944102007844314586649688802236072), + BOOST_MATH_BIG_CONSTANT(T, 113, -4.95759941987499442499908748130192187), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.563290752832461751889194629200298688), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0406197001137935911912457120706122877), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.0020846534789473022216888863613422293), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.808095978462109173749395599401375667e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.244706022206249301640890603610060959e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.589477682919645930544382616501666572e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.113699573675553496343617442433027672e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.174767860183598149649901223128011828e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.210051620306761367764549971980026474e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.189187969537370950337212675466400599e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.116313253429564048145641663778121898e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.376708747782400769427057630528578187e-19), + }; + static const T Q[16] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.0), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.205076752981410805177554569784219717), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.0202526722696670378999575738524540269), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.001278305290005994980069466658219057), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.576404779858501791742255670403304787e-4), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.196477049872253010859712483984252067e-5), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.521863830500876189501054079974475762e-7), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.109524209196868135198775445228552059e-8), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.181698713448644481083966260949267825e-10), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.234793316975091282090312036524695562e-12), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.227490441461460571047545264251399048e-14), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.151500292036937400913870642638520668e-16), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.543475775154780935815530649335936121e-19), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.241647013434111434636554455083309352e-28), + BOOST_MATH_BIG_CONSTANT(T, 113, -0.557103423021951053707162364713587374e-31), + BOOST_MATH_BIG_CONSTANT(T, 113, 0.618708773442584843384712258199645166e-34), + }; + result = tools::evaluate_polynomial(P, T(s - 30)) / tools::evaluate_polynomial(Q, T(s - 30)); + result = 1 + exp(result); + } + else if(s < 117) + { + result = 1 + pow(T(2), -s); + } + else + { + result = 1; + } + return result; +} + +template +T zeta_imp_odd_integer(int s, const T&, const Policy&, const std::true_type&) +{ + static const T results[] = { + BOOST_MATH_BIG_CONSTANT(T, 113, 1.2020569031595942853997381615114500), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0369277551433699263313654864570342), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0083492773819228268397975498497968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0020083928260822144178527692324121), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0004941886041194645587022825264699), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0001227133475784891467518365263574), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000305882363070204935517285106451), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000076371976378997622736002935630), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000019082127165539389256569577951), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000004769329867878064631167196044), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000001192199259653110730677887189), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000298035035146522801860637051), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000074507117898354294919810042), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000018626597235130490064039099), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000004656629065033784072989233), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000001164155017270051977592974), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000291038504449709968692943), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000072759598350574810145209), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000018189896503070659475848), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000004547473783042154026799), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000001136868407680227849349), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000284217097688930185546), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000071054273952108527129), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000017763568435791203275), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000004440892103143813364), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000001110223025141066134), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000277555756213612417), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000069388939045441537), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000017347234760475766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000004336808690020650), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000001084202172494241), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000271050543122347), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000067762635780452), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000016940658945098), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000004235164736273), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000001058791184068), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000264697796017), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000066174449004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000016543612251), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000004135903063), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000001033975766), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000258493941), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000064623485), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000016155871), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000004038968), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000001009742), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000252435), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000063109), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000015777), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000003944), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000986), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000247), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000062), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000015), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000004), BOOST_MATH_BIG_CONSTANT(T, 113, 1.0000000000000000000000000000000001), + }; + return s > 113 ? 1 : results[(s - 3) / 2]; +} + +template +T zeta_imp_odd_integer(int s, const T& sc, const Policy& pol, const std::false_type&) +{ +#ifdef BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES + static_assert(std::is_trivially_destructible::value, "Your platform does not support thread_local with non-trivial types, last checked with Mingw-x64-8.1, Jan 2021. Please try a Mingw build with the POSIX threading model, see https://sourceforge.net/p/mingw-w64/bugs/527/"); +#endif + static BOOST_MATH_THREAD_LOCAL bool is_init = false; + static BOOST_MATH_THREAD_LOCAL T results[50] = {}; + static BOOST_MATH_THREAD_LOCAL int digits = tools::digits(); + int current_digits = tools::digits(); + if(digits != current_digits) + { + // Oh my precision has changed... + is_init = false; + } + if(!is_init) + { + is_init = true; + digits = current_digits; + for(unsigned k = 0; k < sizeof(results) / sizeof(results[0]); ++k) + { + T arg = k * 2 + 3; + T c_arg = 1 - arg; + results[k] = zeta_polynomial_series(arg, c_arg, pol); + } + } + unsigned index = (s - 3) / 2; + return index >= sizeof(results) / sizeof(results[0]) ? zeta_polynomial_series(T(s), sc, pol): results[index]; +} + +template +T zeta_imp(T s, T sc, const Policy& pol, const Tag& tag) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::zeta<%1%>"; + if(sc == 0) + return policies::raise_pole_error( + function, + "Evaluation of zeta function at pole %1%", + s, pol); + T result; + // + // Trivial case: + // + if(s > policies::digits()) + return 1; + // + // Start by seeing if we have a simple closed form: + // + if(floor(s) == s) + { +#ifndef BOOST_NO_EXCEPTIONS + // Without exceptions we expect itrunc to return INT_MAX on overflow + // and we fall through anyway. + try + { +#endif + int v = itrunc(s); + if(v == s) + { + if(v < 0) + { + if(((-v) & 1) == 0) + return 0; + int n = (-v + 1) / 2; + if(n <= (int)boost::math::max_bernoulli_b2n::value) + return T((-v & 1) ? -1 : 1) * boost::math::unchecked_bernoulli_b2n(n) / (1 - v); + } + else if((v & 1) == 0) + { + if(((v / 2) <= (int)boost::math::max_bernoulli_b2n::value) && (v <= (int)boost::math::max_factorial::value)) + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi(), v) * + boost::math::unchecked_bernoulli_b2n(v / 2) / boost::math::unchecked_factorial(v); + return T(((v / 2 - 1) & 1) ? -1 : 1) * ldexp(T(1), v - 1) * pow(constants::pi(), v) * + boost::math::bernoulli_b2n(v / 2) / boost::math::factorial(v, pol); + } + else + return zeta_imp_odd_integer(v, sc, pol, std::integral_constant()); + } +#ifndef BOOST_NO_EXCEPTIONS + } + catch(const boost::math::rounding_error&){} // Just fall through, s is too large to round + catch(const std::overflow_error&){} +#endif + } + + if(fabs(s) < tools::root_epsilon()) + { + result = -0.5f - constants::log_root_two_pi() * s; + } + else if(s < 0) + { + std::swap(s, sc); + if(floor(sc/2) == sc/2) + result = 0; + else + { + if(s > max_factorial::value) + { + T mult = boost::math::sin_pi(0.5f * sc, pol) * 2 * zeta_imp(s, sc, pol, tag); + result = boost::math::lgamma(s, pol); + result -= s * log(2 * constants::pi()); + if(result > tools::log_max_value()) + return sign(mult) * policies::raise_overflow_error(function, nullptr, pol); + result = exp(result); + if(tools::max_value() / fabs(mult) < result) + return boost::math::sign(mult) * policies::raise_overflow_error(function, nullptr, pol); + result *= mult; + } + else + { + result = boost::math::sin_pi(0.5f * sc, pol) + * 2 * pow(2 * constants::pi(), -s) + * boost::math::tgamma(s, pol) + * zeta_imp(s, sc, pol, tag); + } + } + } + else + { + result = zeta_imp_prec(s, sc, pol, tag); + } + return result; +} + +template +struct zeta_initializer +{ + struct init + { + init() + { + do_init(tag()); + } + static void do_init(const std::integral_constant&){ boost::math::zeta(static_cast(5), Policy()); } + static void do_init(const std::integral_constant&){ boost::math::zeta(static_cast(5), Policy()); } + static void do_init(const std::integral_constant&) + { + boost::math::zeta(static_cast(0.5), Policy()); + boost::math::zeta(static_cast(1.5), Policy()); + boost::math::zeta(static_cast(3.5), Policy()); + boost::math::zeta(static_cast(6.5), Policy()); + boost::math::zeta(static_cast(14.5), Policy()); + boost::math::zeta(static_cast(40.5), Policy()); + + boost::math::zeta(static_cast(5), Policy()); + } + static void do_init(const std::integral_constant&) + { + boost::math::zeta(static_cast(0.5), Policy()); + boost::math::zeta(static_cast(1.5), Policy()); + boost::math::zeta(static_cast(3.5), Policy()); + boost::math::zeta(static_cast(5.5), Policy()); + boost::math::zeta(static_cast(9.5), Policy()); + boost::math::zeta(static_cast(16.5), Policy()); + boost::math::zeta(static_cast(25.5), Policy()); + boost::math::zeta(static_cast(70.5), Policy()); + + boost::math::zeta(static_cast(5), Policy()); + } + void force_instantiate()const{} + }; + static const init initializer; + static void force_instantiate() + { + initializer.force_instantiate(); + } +}; + +template +const typename zeta_initializer::init zeta_initializer::initializer; + +} // detail + +template +inline typename tools::promote_args::type zeta(T s, const Policy&) +{ + typedef typename tools::promote_args::type result_type; + typedef typename policies::evaluation::type value_type; + typedef typename policies::precision::type precision_type; + typedef typename policies::normalise< + Policy, + policies::promote_float, + policies::promote_double, + policies::discrete_quantile<>, + policies::assert_undefined<> >::type forwarding_policy; + typedef std::integral_constant tag_type; + + detail::zeta_initializer::force_instantiate(); + + return policies::checked_narrowing_cast(detail::zeta_imp( + static_cast(s), + static_cast(1 - static_cast(s)), + forwarding_policy(), + tag_type()), "boost::math::zeta<%1%>(%1%)"); +} + +template +inline typename tools::promote_args::type zeta(T s) +{ + return zeta(s, policies::policy<>()); +} + +}} // namespaces + +#endif // BOOST_MATH_ZETA_HPP + + + diff --git a/libcxx/src/third-party/boost/math/statistics/anderson_darling.hpp b/libcxx/src/third-party/boost/math/statistics/anderson_darling.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/anderson_darling.hpp @@ -0,0 +1,112 @@ +/* + * Copyright Nick Thompson, 2019 + * 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_STATISTICS_ANDERSON_DARLING_HPP +#define BOOST_MATH_STATISTICS_ANDERSON_DARLING_HPP + +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { + +template +auto anderson_darling_normality_statistic(RandomAccessContainer const & v, + typename RandomAccessContainer::value_type mu = std::numeric_limits::quiet_NaN(), + typename RandomAccessContainer::value_type sd = std::numeric_limits::quiet_NaN()) +{ + using Real = typename RandomAccessContainer::value_type; + using std::log; + using std::sqrt; + using boost::math::erfc; + + if (std::isnan(mu)) { + mu = boost::math::statistics::mean(v); + } + if (std::isnan(sd)) { + sd = sqrt(boost::math::statistics::sample_variance(v)); + } + + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + // This is where Knuth's literate programming could really come in handy! + // I need some LaTeX. The idea is that before any observation, the ecdf is identically zero. + // So we need to compute: + // \int_{-\infty}^{v_0} \frac{F(x)F'(x)}{1- F(x)} \, \mathrm{d}x, where F(x) := \frac{1}{2}[1+\erf(\frac{x-\mu}{\sigma \sqrt{2}})] + // Astonishingly, there is an analytic evaluation to this integral, as you can validate with the following Mathematica command: + // Integrate[(1/2 (1 + Erf[(x - mu)/Sqrt[2*sigma^2]])*Exp[-(x - mu)^2/(2*sigma^2)]*1/Sqrt[2*\[Pi]*sigma^2])/(1 - 1/2 (1 + Erf[(x - mu)/Sqrt[2*sigma^2]])), + // {x, -Infinity, x0}, Assumptions -> {x0 \[Element] Reals && mu \[Element] Reals && sigma > 0}] + // This gives (for s = x-mu/sqrt(2sigma^2)) + // -1/2 + erf(s) + log(2/(1+erf(s))) + + + Real inv_var_scale = 1/(sd*sqrt(Real(2))); + Real s0 = (v[0] - mu)*inv_var_scale; + Real erfcs0 = erfc(s0, no_promote_policy()); + // Note that if erfcs0 == 0, then left_tail = inf (numerically), and hence the entire integral is numerically infinite: + if (erfcs0 <= 0) { + return std::numeric_limits::infinity(); + } + + // Note that we're going to add erfcs0/2 when we compute the integral over [x_0, x_1], so drop it here: + Real left_tail = -1 + log(Real(2)); + + + // For the right tail, the ecdf is identically 1. + // Hence we need the integral: + // \int_{v_{n-1}}^{\infty} \frac{(1-F(x))F'(x)}{F(x)} \, \mathrm{d}x + // This also has an analytic evaluation! It can be found via the following Mathematica command: + // Integrate[(E^(-(z^2/2)) *(1 - 1/2 (1 + Erf[z/Sqrt[2]])))/(Sqrt[2 \[Pi]] (1/2 (1 + Erf[z/Sqrt[2]]))), + // {z, zn, \[Infinity]}, Assumptions -> {zn \[Element] Reals && mu \[Element] Reals}] + // This gives (for sf = xf-mu/sqrt(2sigma^2)) + // -1/2 + erf(sf)/2 + 2log(2/(1+erf(sf))) + + Real sf = (v[v.size()-1] - mu)*inv_var_scale; + //Real erfcsf = erfc(sf, no_promote_policy()); + // This is the actual value of the tail integral. However, the -erfcsf/2 cancels from the integral over [v_{n-2}, v_{n-1}]: + //Real right_tail = -erfcsf/2 + log(Real(2)) - log(2-erfcsf); + + // Use erfc(-x) = 2 - erfc(x) + Real erfcmsf = erfc(-sf, no_promote_policy()); + // Again if this is precisely zero then the integral is numerically infinite: + if (erfcmsf == 0) { + return std::numeric_limits::infinity(); + } + Real right_tail = log(2/erfcmsf); + + // Now we need each integral: + // \int_{v_i}^{v_{i+1}} \frac{(i+1/n - F(x))^2F'(x)}{F(x)(1-F(x))} \, \mathrm{d}x + // Again we get an analytical evaluation via the following Mathematica command: + // Integrate[((E^(-(z^2/2))/Sqrt[2 \[Pi]])*(k1 - F[z])^2)/(F[z]*(1 - F[z])), + // {z, z1, z2}, Assumptions -> {z1 \[Element] Reals && z2 \[Element] Reals &&k1 \[Element] Reals}] // FullSimplify + + Real integrals = 0; + int64_t N = v.size(); + for (int64_t i = 0; i < N - 1; ++i) { + if (v[i] > v[i+1]) { + throw std::domain_error("Input data must be sorted in increasing order v[0] <= v[1] <= . . . <= v[n-1]"); + } + + Real k = (i+1)/Real(N); + Real s1 = (v[i+1]-mu)*inv_var_scale; + Real erfcs1 = erfc(s1, no_promote_policy()); + Real term = k*(k*log(erfcs0*(-2 + erfcs1)/(erfcs1*(-2 + erfcs0))) + 2*log(erfcs1/erfcs0)); + + integrals += term; + s0 = s1; + erfcs0 = erfcs1; + } + integrals -= log(erfcs0); + return v.size()*(left_tail + right_tail + integrals); +} + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/bivariate_statistics.hpp b/libcxx/src/third-party/boost/math/statistics/bivariate_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/bivariate_statistics.hpp @@ -0,0 +1,470 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2021. +// 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_STATISTICS_BIVARIATE_STATISTICS_HPP +#define BOOST_MATH_STATISTICS_BIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#include +#include +#endif + +namespace boost{ namespace math{ namespace statistics { namespace detail { + +// See Equation III.9 of "Numerically Stable, Single-Pass, Parallel Statistics Algorithms", Bennet et al. +template +ReturnType means_and_covariance_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + Real cov = 0; + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + Real mu_u = *u_it++; + Real mu_v = *v_it++; + std::size_t i = 1; + + while(u_it != u_end && v_it != v_end) + { + Real u_temp = (*u_it++ - mu_u)/(i+1); + Real v_temp = *v_it++ - mu_v; + cov += i*u_temp*v_temp; + mu_u = mu_u + u_temp; + mu_v = mu_v + v_temp/(i+1); + i = i + 1; + } + + if(u_it != u_end || v_it != v_end) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + return std::make_tuple(mu_u, mu_v, cov/i, Real(i)); +} + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +// Numerically stable parallel computation of (co-)variance +// https://dl.acm.org/doi/10.1145/3221269.3223036 +template +ReturnType means_and_covariance_parallel_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto u_elements = std::distance(u_begin, u_end); + const auto v_elements = std::distance(v_begin, v_end); + + if(u_elements != v_elements) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // 5.16 comes from benchmarking. See boost/math/reporting/performance/bivariate_statistics_performance.cpp + // Threading is faster for: 10 + 5.16e-3 N/j <= 5.16e-3N => N >= 10^4j/5.16(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(5.16*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/5.16; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(u_elements < parallel_lower_bound) + { + return means_and_covariance_seq_impl(u_begin, u_end, v_begin, v_end); + } + else if(u_elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(5.16*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(u_elements)/num_threads); + + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + + for(std::size_t i = 0; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, v_it, elements_per_thread]() -> ReturnType + { + return means_and_covariance_seq_impl(u_it, std::next(u_it, elements_per_thread), v_it, std::next(v_it, elements_per_thread)); + })); + u_it = std::next(u_it, elements_per_thread); + v_it = std::next(v_it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, u_end, v_it, v_end]() -> ReturnType + { + return means_and_covariance_seq_impl(u_it, u_end, v_it, v_end); + })); + + ReturnType temp = future_manager[0].get(); + Real mu_u_a = std::get<0>(temp); + Real mu_v_a = std::get<1>(temp); + Real cov_a = std::get<2>(temp); + Real n_a = std::get<3>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real mu_u_b = std::get<0>(temp); + Real mu_v_b = std::get<1>(temp); + Real cov_b = std::get<2>(temp); + Real n_b = std::get<3>(temp); + + const Real n_ab = n_a + n_b; + const Real delta_u = mu_u_b - mu_u_a; + const Real delta_v = mu_v_b - mu_v_a; + + cov_a = cov_a + cov_b + (-delta_u)*(-delta_v)*((n_a*n_b)/n_ab); + mu_u_a = mu_u_a + delta_u*(n_b/n_ab); + mu_v_a = mu_v_a + delta_v*(n_b/n_ab); + n_a = n_ab; + } + + return std::make_tuple(mu_u_a, mu_v_a, cov_a, n_a); +} + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +template +ReturnType correlation_coefficient_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + + Real cov = 0; + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + Real mu_u = *u_it++; + Real mu_v = *v_it++; + Real Qu = 0; + Real Qv = 0; + std::size_t i = 1; + + while(u_it != u_end && v_it != v_end) + { + Real u_tmp = *u_it++ - mu_u; + Real v_tmp = *v_it++ - mu_v; + Qu = Qu + (i*u_tmp*u_tmp)/(i+1); + Qv = Qv + (i*v_tmp*v_tmp)/(i+1); + cov += i*u_tmp*v_tmp/(i+1); + mu_u = mu_u + u_tmp/(i+1); + mu_v = mu_v + v_tmp/(i+1); + ++i; + } + + + // If one dataset is constant, then the correlation coefficient is undefined. + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu == 0 || Qv == 0) + { + return std::make_tuple(mu_u, Qu, mu_v, Qv, cov, std::numeric_limits::quiet_NaN(), Real(i)); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov/sqrt(Qu*Qv); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + + return std::make_tuple(mu_u, Qu, mu_v, Qv, cov, rho, Real(i)); +} + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +// Numerically stable parallel computation of (co-)variance: +// https://dl.acm.org/doi/10.1145/3221269.3223036 +// +// Parallel computation of variance: +// http://i.stanford.edu/pub/cstr/reports/cs/tr/79/773/CS-TR-79-773.pdf +template +ReturnType correlation_coefficient_parallel_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto u_elements = std::distance(u_begin, u_end); + const auto v_elements = std::distance(v_begin, v_end); + + if(u_elements != v_elements) + { + throw std::domain_error("The size of each sample set must be the same to compute covariance"); + } + + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // 3.25 comes from benchmarking. See boost/math/reporting/performance/bivariate_statistics_performance.cpp + // Threading is faster for: 10 + 3.25e-3 N/j <= 3.25e-3N => N >= 10^4j/3.25(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(3.25*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/3.25; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(u_elements < parallel_lower_bound) + { + return correlation_coefficient_seq_impl(u_begin, u_end, v_begin, v_end); + } + else if(u_elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(3.25*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(u_elements)/num_threads); + + ForwardIterator u_it = u_begin; + ForwardIterator v_it = v_begin; + + for(std::size_t i = 0; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, v_it, elements_per_thread]() -> ReturnType + { + return correlation_coefficient_seq_impl(u_it, std::next(u_it, elements_per_thread), v_it, std::next(v_it, elements_per_thread)); + })); + u_it = std::next(u_it, elements_per_thread); + v_it = std::next(v_it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [u_it, u_end, v_it, v_end]() -> ReturnType + { + return correlation_coefficient_seq_impl(u_it, u_end, v_it, v_end); + })); + + ReturnType temp = future_manager[0].get(); + Real mu_u_a = std::get<0>(temp); + Real Qu_a = std::get<1>(temp); + Real mu_v_a = std::get<2>(temp); + Real Qv_a = std::get<3>(temp); + Real cov_a = std::get<4>(temp); + Real n_a = std::get<6>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real mu_u_b = std::get<0>(temp); + Real Qu_b = std::get<1>(temp); + Real mu_v_b = std::get<2>(temp); + Real Qv_b = std::get<3>(temp); + Real cov_b = std::get<4>(temp); + Real n_b = std::get<6>(temp); + + const Real n_ab = n_a + n_b; + const Real delta_u = mu_u_b - mu_u_a; + const Real delta_v = mu_v_b - mu_v_a; + + cov_a = cov_a + cov_b + (-delta_u)*(-delta_v)*((n_a*n_b)/n_ab); + mu_u_a = mu_u_a + delta_u*(n_b/n_ab); + mu_v_a = mu_v_a + delta_v*(n_b/n_ab); + Qu_a = Qu_a + Qu_b + delta_u*delta_u*((n_a*n_b)/n_ab); + Qv_b = Qv_a + Qv_b + delta_v*delta_v*((n_a*n_b)/n_ab); + n_a = n_ab; + } + + // If one dataset is constant, then the correlation coefficient is undefined. + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu_a == 0 || Qv_a == 0) + { + return std::make_tuple(mu_u_a, Qu_a, mu_v_a, Qv_a, cov_a, std::numeric_limits::quiet_NaN(), n_a); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov_a/sqrt(Qu_a*Qv_a); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + + return std::make_tuple(mu_u_a, Qu_a, mu_v_a, Qv_a, cov_a, rho, n_a); +} + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +} // namespace detail + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +template +inline auto means_and_covariance(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + else + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + } + else + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + else + { + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); + } + } +} + +template +inline auto means_and_covariance(Container const & u, Container const & v) +{ + return means_and_covariance(std::execution::seq, u, v); +} + +template +inline auto covariance(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + return std::get<2>(means_and_covariance(exec, u, v)); +} + +template +inline auto covariance(Container const & u, Container const & v) +{ + return covariance(std::execution::seq, u, v); +} + +template +inline auto correlation_coefficient(ExecutionPolicy&& exec, Container const & u, Container const & v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + else + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + } + else + { + if constexpr (std::is_integral_v) + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + else + { + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_parallel_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); + } + } +} + +template +inline auto correlation_coefficient(Container const & u, Container const & v) +{ + return correlation_coefficient(std::execution::seq, u, v); +} + +#else // C++11 and single threaded bindings + +template::value, bool>::type = true> +inline auto means_and_covariance(Container const & u, Container const & v) -> std::tuple +{ + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); +} + +template::value, bool>::type = true> +inline auto means_and_covariance(Container const & u, Container const & v) -> std::tuple +{ + using ReturnType = std::tuple; + ReturnType temp = detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); + return std::make_tuple(std::get<0>(temp), std::get<1>(temp), std::get<2>(temp)); +} + +template::value, bool>::type = true> +inline double covariance(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<2>(detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline Real covariance(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<2>(detail::means_and_covariance_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline double correlation_coefficient(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +template::value, bool>::type = true> +inline Real correlation_coefficient(Container const & u, Container const & v) +{ + using ReturnType = std::tuple; + return std::get<5>(detail::correlation_coefficient_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v))); +} + +#endif + +}}} // namespace boost::math::statistics + +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/chatterjee_correlation.hpp b/libcxx/src/third-party/boost/math/statistics/chatterjee_correlation.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/chatterjee_correlation.hpp @@ -0,0 +1,159 @@ +// (C) Copyright Matt Borland 2022. +// 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_STATISTICS_CHATTERJEE_CORRELATION_HPP +#define BOOST_MATH_STATISTICS_CHATTERJEE_CORRELATION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#include +#include +#endif + +namespace boost { namespace math { namespace statistics { + +namespace detail { + +template +std::size_t chatterjee_transform(BDIter begin, BDIter end) +{ + std::size_t sum = 0; + + while(++begin != end) + { + if(*begin > *std::prev(begin)) + { + sum += *begin - *std::prev(begin); + } + else + { + sum += *std::prev(begin) - *begin; + } + } + + return sum; +} + +template +ReturnType chatterjee_correlation_seq_impl(ForwardIterator u_begin, ForwardIterator u_end, ForwardIterator v_begin, ForwardIterator v_end) +{ + using std::abs; + + BOOST_MATH_ASSERT_MSG(std::is_sorted(u_begin, u_end), "The x values must be sorted in order to use this functionality"); + + const std::vector rank_vector = rank(v_begin, v_end); + + std::size_t sum = chatterjee_transform(rank_vector.begin(), rank_vector.end()); + + ReturnType result = static_cast(1) - (static_cast(3 * sum) / static_cast(rank_vector.size() * rank_vector.size() - 1)); + + // If the result is 1 then Y is constant and all the elements must be ties + if (abs(result - static_cast(1)) < std::numeric_limits::epsilon()) + { + return std::numeric_limits::quiet_NaN(); + } + + return result; +} + +} // Namespace detail + +template ::value, double, Real>::type> +inline ReturnType chatterjee_correlation(const Container& u, const Container& v) +{ + return detail::chatterjee_correlation_seq_impl(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // Namespace boost::math::statistics + +#ifdef BOOST_MATH_EXEC_COMPATIBLE + +namespace boost::math::statistics { + +namespace detail { + +template +ReturnType chatterjee_correlation_par_impl(ExecutionPolicy&& exec, ForwardIterator u_begin, ForwardIterator u_end, + ForwardIterator v_begin, ForwardIterator v_end) +{ + using std::abs; + BOOST_MATH_ASSERT_MSG(std::is_sorted(std::forward(exec), u_begin, u_end), "The x values must be sorted in order to use this functionality"); + + auto rank_vector = rank(std::forward(exec), v_begin, v_end); + + const auto num_threads = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + std::vector> future_manager {}; + const auto elements_per_thread = std::ceil(static_cast(rank_vector.size()) / num_threads); + + auto it = rank_vector.begin(); + auto end = rank_vector.end(); + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread]() -> std::size_t + { + return chatterjee_transform(it, std::next(it, elements_per_thread)); + })); + it = std::next(it, elements_per_thread - 1); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, end]() -> std::size_t + { + return chatterjee_transform(it, end); + })); + + std::size_t sum {}; + for(std::size_t i {}; i < future_manager.size(); ++i) + { + sum += future_manager[i].get(); + } + + ReturnType result = static_cast(1) - (static_cast(3 * sum) / static_cast(rank_vector.size() * rank_vector.size() - 1)); + + // If the result is 1 then Y is constant and all the elements must be ties + if (abs(result - static_cast(1)) < std::numeric_limits::epsilon()) + { + return std::numeric_limits::quiet_NaN(); + } + + return result; +} + +} // Namespace detail + +template , double, Real>> +inline ReturnType chatterjee_correlation(ExecutionPolicy&& exec, const Container& u, const Container& v) +{ + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::chatterjee_correlation_seq_impl(std::cbegin(u), std::cend(u), + std::cbegin(v), std::cend(v)); + } + else + { + return detail::chatterjee_correlation_par_impl(std::forward(exec), + std::cbegin(u), std::cend(u), + std::cbegin(v), std::cend(v)); + } +} + +} // Namespace boost::math::statistics + +#endif + +#endif // BOOST_MATH_STATISTICS_CHATTERJEE_CORRELATION_HPP diff --git a/libcxx/src/third-party/boost/math/statistics/detail/rank.hpp b/libcxx/src/third-party/boost/math/statistics/detail/rank.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/detail/rank.hpp @@ -0,0 +1,140 @@ +// (C) Copyright Matt Borland 2022 +// 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_STATISTICS_DETAIL_RANK_HPP +#define BOOST_MATH_STATISTICS_DETAIL_RANK_HPP + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include +#endif + +namespace boost { namespace math { namespace statistics { namespace detail { + +struct pair_equal +{ + template + bool operator()(const std::pair& a, const std::pair& b) const + { + return a.first == b.first; + } +}; + +}}}} // Namespaces + +#ifndef BOOST_MATH_EXEC_COMPATIBLE + +namespace boost { namespace math { namespace statistics { namespace detail { + +template ::value_type> +auto rank(ForwardIterator first, ForwardIterator last) -> std::vector +{ + std::size_t elements = std::distance(first, last); + + std::vector> rank_vector(elements); + std::size_t i = 0; + while (first != last) + { + rank_vector[i] = std::make_pair(*first, i); + ++i; + ++first; + } + + std::sort(rank_vector.begin(), rank_vector.end()); + + // Remove duplicates + rank_vector.erase(std::unique(rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end()); + elements = rank_vector.size(); + + std::pair rank; + std::vector result(elements); + for (i = 0; i < elements; ++i) + { + if (rank_vector[i].first != rank.first) + { + rank = std::make_pair(rank_vector[i].first, i); + } + result[rank_vector[i].second] = rank.second; + } + + return result; +} + +template +inline auto rank(const Container& c) -> std::vector +{ + return rank(std::begin(c), std::end(c)); +} + +}}}} // Namespaces + +#else + +namespace boost::math::statistics::detail { + +template ::value_type> +auto rank(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + std::size_t elements = std::distance(first, last); + + std::vector> rank_vector(elements); + std::size_t i = 0; + while (first != last) + { + rank_vector[i] = std::make_pair(*first, i); + ++i; + ++first; + } + + std::sort(exec, rank_vector.begin(), rank_vector.end()); + + // Remove duplicates + rank_vector.erase(std::unique(exec, rank_vector.begin(), rank_vector.end(), pair_equal()), rank_vector.end()); + elements = rank_vector.size(); + + std::pair rank; + std::vector result(elements); + for (i = 0; i < elements; ++i) + { + if (rank_vector[i].first != rank.first) + { + rank = std::make_pair(rank_vector[i].first, i); + } + result[rank_vector[i].second] = rank.second; + } + + return result; +} + +template +inline auto rank(ExecutionPolicy&& exec, const Container& c) +{ + return rank(exec, std::cbegin(c), std::cend(c)); +} + +template ::value_type> +inline auto rank(ForwardIterator first, ForwardIterator last) +{ + return rank(std::execution::seq, first, last); +} + +template +inline auto rank(const Container& c) +{ + return rank(std::execution::seq, std::cbegin(c), std::cend(c)); +} + +} // Namespaces + +#endif // BOOST_MATH_EXEC_COMPATIBLE + +#endif // BOOST_MATH_STATISTICS_DETAIL_RANK_HPP diff --git a/libcxx/src/third-party/boost/math/statistics/detail/single_pass.hpp b/libcxx/src/third-party/boost/math/statistics/detail/single_pass.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/detail/single_pass.hpp @@ -0,0 +1,401 @@ +// (C) Copyright Nick Thompson 2018 +// (C) Copyright Matt Borland 2020 +// 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_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP +#define BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_THREADS +#include +#include +#endif + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType mean_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + const std::size_t elements {static_cast(std::distance(first, last))}; + std::valarray mu {0, 0, 0, 0}; + std::valarray temp {0, 0, 0, 0}; + ReturnType i {1}; + const ForwardIterator end {std::next(first, elements - (elements % 4))}; + ForwardIterator it {first}; + + while(it != end) + { + const ReturnType inv {ReturnType(1) / i}; + temp = {static_cast(*it++), static_cast(*it++), static_cast(*it++), static_cast(*it++)}; + temp -= mu; + mu += (temp *= inv); + i += 1; + } + + const ReturnType num1 {ReturnType(elements - (elements % 4))/ReturnType(4)}; + const ReturnType num2 {num1 + ReturnType(elements % 4)}; + + while(it != last) + { + mu[3] += (*it-mu[3])/i; + i += 1; + ++it; + } + + return (num1 * std::valarray(mu[std::slice(0,3,1)]).sum() + num2 * mu[3]) / ReturnType(elements); +} + +// Higham, Accuracy and Stability, equation 1.6a and 1.6b: +// Calculates Mean, M2, and variance +template +ReturnType variance_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + Real M = *first; + Real Q = 0; + Real k = 2; + Real M2 = 0; + std::size_t n = 1; + + for(auto it = std::next(first); it != last; ++it) + { + Real tmp = (*it - M) / k; + Real delta_1 = *it - M; + Q += k*(k-1)*tmp*tmp; + M += tmp; + k += 1; + Real delta_2 = *it - M; + M2 += delta_1 * delta_2; + ++n; + } + + return std::make_tuple(M, M2, Q/(k-1), Real(n)); +} + +// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics +template +ReturnType first_four_moments_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using Size = typename std::tuple_element<4, ReturnType>::type; + + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real M4 = 0; + Size n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2, M3, M4, n-1); +} + +#ifdef BOOST_HAS_THREADS + +// https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Higher-order_statistics +// EQN 3.1: https://www.osti.gov/servlets/purl/1426900 +template +ReturnType first_four_moments_parallel_impl(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + const auto elements = std::distance(first, last); + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // Threading is faster for: 10 + 5.13e-3 N/j <= 5.13e-3N => N >= 10^4j/5.13(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(5.13*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/5.13; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(elements < parallel_lower_bound) + { + return detail::first_four_moments_sequential_impl(first, last); + } + else if(elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(5.13*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(elements) / num_threads); + + auto it = first; + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread]() -> ReturnType + { + return first_four_moments_sequential_impl(it, std::next(it, elements_per_thread)); + })); + it = std::next(it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, last]() -> ReturnType + { + return first_four_moments_sequential_impl(it, last); + })); + + auto temp = future_manager[0].get(); + Real M1_a = std::get<0>(temp); + Real M2_a = std::get<1>(temp); + Real M3_a = std::get<2>(temp); + Real M4_a = std::get<3>(temp); + Real range_a = std::get<4>(temp); + + for(std::size_t i = 1; i < future_manager.size(); ++i) + { + temp = future_manager[i].get(); + Real M1_b = std::get<0>(temp); + Real M2_b = std::get<1>(temp); + Real M3_b = std::get<2>(temp); + Real M4_b = std::get<3>(temp); + Real range_b = std::get<4>(temp); + + const Real n_ab = range_a + range_b; + const Real delta = M1_b - M1_a; + + M1_a = (range_a * M1_a + range_b * M1_b) / n_ab; + M2_a = M2_a + M2_b + delta * delta * (range_a * range_b / n_ab); + M3_a = M3_a + M3_b + (delta * delta * delta) * range_a * range_b * (range_a - range_b) / (n_ab * n_ab) + + Real(3) * delta * (range_a * M2_b - range_b * M2_a) / n_ab; + M4_a = M4_a + M4_b + (delta * delta * delta * delta) * range_a * range_b * (range_a * range_a - range_a * range_b + range_b * range_b) / (n_ab * n_ab * n_ab) + + Real(6) * delta * delta * (range_a * range_a * M2_b + range_b * range_b * M2_a) / (n_ab * n_ab) + + Real(4) * delta * (range_a * M3_b - range_b * M3_a) / n_ab; + range_a = n_ab; + } + + return std::make_tuple(M1_a, M2_a, M3_a, M4_a, elements); +} + +#endif // BOOST_HAS_THREADS + +// Follows equation 1.5 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +ReturnType skewness_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute skewness."); + + ReturnType M1 = *first; + ReturnType M2 = 0; + ReturnType M3 = 0; + ReturnType n = 2; + + for (auto it = std::next(first); it != last; ++it) + { + ReturnType delta21 = *it - M1; + ReturnType tmp = delta21/n; + M3 += tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 += tmp*(n-1)*delta21; + M1 += tmp; + n += 1; + } + + ReturnType var = M2/(n-1); + + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return ReturnType(0); + } + + ReturnType skew = M3/(M2*sqrt(var)); + return skew; +} + +template +ReturnType gini_coefficient_sequential_impl(ForwardIterator first, ForwardIterator last) +{ + ReturnType i = 1; + ReturnType num = 0; + ReturnType denom = 0; + + for(auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if(denom == 0) + { + return ReturnType(0); + } + else + { + return ((2*num)/denom - i)/(i-1); + } +} + +template +ReturnType gini_range_fraction(ForwardIterator first, ForwardIterator last, std::size_t starting_index) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + + std::size_t i = starting_index + 1; + Real num = 0; + Real denom = 0; + + for(auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + return std::make_tuple(num, denom, i); +} + +#ifdef BOOST_HAS_THREADS + +template +ReturnType gini_coefficient_parallel_impl(ExecutionPolicy&&, ForwardIterator first, ForwardIterator last) +{ + using range_tuple = std::tuple; + + const auto elements = std::distance(first, last); + const unsigned max_concurrency = std::thread::hardware_concurrency() == 0 ? 2u : std::thread::hardware_concurrency(); + unsigned num_threads = 2u; + + // Threading is faster for: 10 + 10.12e-3 N/j <= 10.12e-3N => N >= 10^4j/10.12(j-1). + const auto parallel_lower_bound = 10e4*max_concurrency/(10.12*(max_concurrency-1)); + const auto parallel_upper_bound = 10e4*2/10.12; // j = 2 + + // https://lemire.me/blog/2020/01/30/cost-of-a-thread-in-c-under-linux/ + if(elements < parallel_lower_bound) + { + return gini_coefficient_sequential_impl(first, last); + } + else if(elements >= parallel_upper_bound) + { + num_threads = max_concurrency; + } + else + { + for(unsigned i = 3; i < max_concurrency; ++i) + { + if(parallel_lower_bound < 10e4*i/(10.12*(i-1))) + { + num_threads = i; + break; + } + } + } + + std::vector> future_manager; + const auto elements_per_thread = std::ceil(static_cast(elements) / num_threads); + + auto it = first; + for(std::size_t i {}; i < num_threads - 1; ++i) + { + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, elements_per_thread, i]() -> range_tuple + { + return gini_range_fraction(it, std::next(it, elements_per_thread), i*elements_per_thread); + })); + it = std::next(it, elements_per_thread); + } + + future_manager.emplace_back(std::async(std::launch::async | std::launch::deferred, [it, last, num_threads, elements_per_thread]() -> range_tuple + { + return gini_range_fraction(it, last, (num_threads - 1)*elements_per_thread); + })); + + ReturnType num = 0; + ReturnType denom = 0; + + for(std::size_t i = 0; i < future_manager.size(); ++i) + { + auto temp = future_manager[i].get(); + num += std::get<0>(temp); + denom += std::get<1>(temp); + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if(denom == 0) + { + return ReturnType(0); + } + else + { + return ((2*num)/denom - elements)/(elements-1); + } +} + +#endif // BOOST_HAS_THREADS + +template +OutputIterator mode_impl(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + using Z = typename std::iterator_traits::value_type; + using Size = typename std::iterator_traits::difference_type; + + std::vector modes {}; + modes.reserve(16); + Size max_counter {0}; + + while(first != last) + { + Size current_count {0}; + ForwardIterator end_it {first}; + while(end_it != last && *end_it == *first) + { + ++current_count; + ++end_it; + } + + if(current_count > max_counter) + { + modes.resize(1); + modes[0] = *first; + max_counter = current_count; + } + + else if(current_count == max_counter) + { + modes.emplace_back(*first); + } + + first = end_it; + } + + return std::move(modes.begin(), modes.end(), output); +} +}}}} + +#endif // BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_DETAIL_SINGLE_PASS_HPP diff --git a/libcxx/src/third-party/boost/math/statistics/linear_regression.hpp b/libcxx/src/third-party/boost/math/statistics/linear_regression.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/linear_regression.hpp @@ -0,0 +1,133 @@ +/* + * Copyright Nick Thompson, 2019 + * Copyright Matt Borland, 2021 + * 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_STATISTICS_LINEAR_REGRESSION_HPP +#define BOOST_MATH_STATISTICS_LINEAR_REGRESSION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + + +template +ReturnType simple_ordinary_least_squares_impl(RandomAccessContainer const & x, + RandomAccessContainer const & y) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + if (x.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to perform a linear regression."); + } + + if (x.size() != y.size()) + { + throw std::domain_error("The same number of samples must be in the independent and dependent variable."); + } + std::tuple temp = boost::math::statistics::means_and_covariance(x, y); + Real mu_x = std::get<0>(temp); + Real mu_y = std::get<1>(temp); + Real cov_xy = std::get<2>(temp); + + Real var_x = boost::math::statistics::variance(x); + + if (var_x <= 0) { + throw std::domain_error("Independent variable has no variance; this breaks linear regression."); + } + + + Real c1 = cov_xy/var_x; + Real c0 = mu_y - c1*mu_x; + + return std::make_pair(c0, c1); +} + +template +ReturnType simple_ordinary_least_squares_with_R_squared_impl(RandomAccessContainer const & x, + RandomAccessContainer const & y) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + if (x.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to perform a linear regression."); + } + + if (x.size() != y.size()) + { + throw std::domain_error("The same number of samples must be in the independent and dependent variable."); + } + std::tuple temp = boost::math::statistics::means_and_covariance(x, y); + Real mu_x = std::get<0>(temp); + Real mu_y = std::get<1>(temp); + Real cov_xy = std::get<2>(temp); + + Real var_x = boost::math::statistics::variance(x); + + if (var_x <= 0) { + throw std::domain_error("Independent variable has no variance; this breaks linear regression."); + } + + + Real c1 = cov_xy/var_x; + Real c0 = mu_y - c1*mu_x; + + Real squared_residuals = 0; + Real squared_mean_deviation = 0; + for(decltype(y.size()) i = 0; i < y.size(); ++i) { + squared_mean_deviation += (y[i] - mu_y)*(y[i]-mu_y); + Real ei = (c0 + c1*x[i]) - y[i]; + squared_residuals += ei*ei; + } + + Real Rsquared; + if (squared_mean_deviation == 0) { + // Then y = constant, so the linear regression is perfect. + Rsquared = 1; + } else { + Rsquared = 1 - squared_residuals/squared_mean_deviation; + } + + return std::make_tuple(c0, c1, Rsquared); +} +} // namespace detail + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::pair +{ + return detail::simple_ordinary_least_squares_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::pair +{ + return detail::simple_ordinary_least_squares_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares_with_R_squared(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::tuple +{ + return detail::simple_ordinary_least_squares_with_R_squared_impl>(x, y); +} + +template::value, bool>::type = true> +inline auto simple_ordinary_least_squares_with_R_squared(RandomAccessContainer const & x, RandomAccessContainer const & y) -> std::tuple +{ + return detail::simple_ordinary_least_squares_with_R_squared_impl>(x, y); +} +}}} // namespace boost::math::statistics +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/ljung_box.hpp b/libcxx/src/third-party/boost/math/statistics/ljung_box.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/ljung_box.hpp @@ -0,0 +1,70 @@ +// (C) Copyright Nick Thompson 2019. +// 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_STATISTICS_LJUNG_BOX_HPP +#define BOOST_MATH_STATISTICS_LJUNG_BOX_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::statistics { + +template +auto ljung_box(RandomAccessIterator begin, RandomAccessIterator end, int64_t lags = -1, int64_t fit_dof = 0) { + using Real = typename std::iterator_traits::value_type; + int64_t n = std::distance(begin, end); + if (lags >= n) { + throw std::domain_error("Number of lags must be < number of elements in array."); + } + + if (lags == -1) { + // This is the same default as Mathematica; it seems sensible enough . . . + lags = static_cast(std::ceil(std::log(Real(n)))); + } + + if (lags <= 0) { + throw std::domain_error("Must have at least one lag."); + } + + auto mu = boost::math::statistics::mean(begin, end); + + std::vector r(lags + 1, Real(0)); + for (size_t i = 0; i < r.size(); ++i) { + for (auto it = begin + i; it != end; ++it) { + Real ak = *(it) - mu; + Real akml = *(it-i) - mu; + r[i] += ak*akml; + } + } + + Real Q = 0; + + for (size_t k = 1; k < r.size(); ++k) { + Q += r[k]*r[k]/(r[0]*r[0]*(n-k)); + } + Q *= n*(n+2); + + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + auto chi = boost::math::chi_squared_distribution(Real(lags - fit_dof)); + + Real pvalue = 1 - boost::math::cdf(chi, Q); + return std::make_pair(Q, pvalue); +} + + +template +auto ljung_box(RandomAccessContainer const & v, int64_t lags = -1, int64_t fit_dof = 0) { + return ljung_box(v.begin(), v.end(), lags, fit_dof); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/runs_test.hpp b/libcxx/src/third-party/boost/math/statistics/runs_test.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/runs_test.hpp @@ -0,0 +1,121 @@ +/* + * Copyright Nick Thompson, 2019 + * 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_STATISTICS_RUNS_TEST_HPP +#define BOOST_MATH_STATISTICS_RUNS_TEST_HPP + +#include +#include +#include +#include +#include + +namespace boost::math::statistics { + +template +auto runs_above_and_below_threshold(RandomAccessContainer const & v, + typename RandomAccessContainer::value_type threshold) +{ + using Real = typename RandomAccessContainer::value_type; + using std::sqrt; + using std::abs; + if (v.size() <= 1) + { + throw std::domain_error("At least 2 samples are required to get number of runs."); + } + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + decltype(v.size()) nabove = 0; + decltype(v.size()) nbelow = 0; + + decltype(v.size()) imin = 0; + + // Take care of the case that v[0] == threshold: + while (imin < v.size() && v[imin] == threshold) { + ++imin; + } + + // Take care of the constant vector case: + if (imin == v.size()) { + return std::make_pair(std::numeric_limits::quiet_NaN(), Real(0)); + } + + bool run_up = (v[imin] > threshold); + if (run_up) { + ++nabove; + } else { + ++nbelow; + } + decltype(v.size()) runs = 1; + for (decltype(v.size()) i = imin + 1; i < v.size(); ++i) { + if (v[i] == threshold) { + // skip values precisely equal to threshold (following R's randtests package) + continue; + } + bool above = (v[i] > threshold); + if (above) { + ++nabove; + } else { + ++nbelow; + } + if (run_up == above) { + continue; + } + else { + run_up = above; + runs++; + } + } + + // If you make n an int, the subtraction is gonna be bad in the variance: + Real n = nabove + nbelow; + + Real expected_runs = Real(1) + Real(2*nabove*nbelow)/Real(n); + Real variance = 2*nabove*nbelow*(2*nabove*nbelow-n)/Real(n*n*(n-1)); + + // Bizarre, pathological limits: + if (variance == 0) + { + if (runs == expected_runs) + { + Real statistic = 0; + Real pvalue = 1; + return std::make_pair(statistic, pvalue); + } + else + { + return std::make_pair(std::numeric_limits::quiet_NaN(), Real(0)); + } + } + + Real sd = sqrt(variance); + Real statistic = (runs - expected_runs)/sd; + + auto normal = boost::math::normal_distribution(0,1); + Real pvalue = 2*boost::math::cdf(normal, -abs(statistic)); + return std::make_pair(statistic, pvalue); +} + +template +auto runs_above_and_below_median(RandomAccessContainer const & v) +{ + using Real = typename RandomAccessContainer::value_type; + using std::log; + using std::sqrt; + + // We have to memcpy v because the median does a partial sort, + // and that would be catastrophic for the runs test. + auto w = v; + Real median = boost::math::statistics::median(w); + return runs_above_and_below_threshold(v, median); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/signal_statistics.hpp b/libcxx/src/third-party/boost/math/statistics/signal_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/signal_statistics.hpp @@ -0,0 +1,343 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_SIGNAL_STATISTICS_HPP +#define BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include + + +namespace boost::math::statistics { + +template +auto absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + using std::abs; + using RealOrComplex = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last, [](RealOrComplex a, RealOrComplex b) { return abs(b) > abs(a); }); + + + decltype(abs(*first)) i = 1; + decltype(abs(*first)) num = 0; + decltype(abs(*first)) denom = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + num += tmp*i; + denom += tmp; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + decltype(abs(*first)) zero = 0; + return zero; + } + return ((2*num)/denom - i)/(i-1); +} + +template +inline auto absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::statistics::absolute_gini_coefficient(v.begin(), v.end()); +} + +template +auto sample_absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + return n*boost::math::statistics::absolute_gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::statistics::sample_absolute_gini_coefficient(v.begin(), v.end()); +} + + +// The Hoyer sparsity measure is defined in: +// https://arxiv.org/pdf/0811.4706.pdf +template +auto hoyer_sparsity(const ForwardIterator first, const ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Hoyer sparsity requires at least two samples."); + + if constexpr (std::is_unsigned::value) + { + T l1 = 0; + T l2 = 0; + size_t n = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + l2 += (*it)*(*it); + n += 1; + } + + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else { + decltype(abs(*first)) l1 = 0; + decltype(abs(*first)) l2 = 0; + // We wouldn't need to count the elements if it was a random access iterator, + // but our only constraint is that it's a forward iterator. + size_t n = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + l1 += tmp; + l2 += tmp*tmp; + n += 1; + } + if constexpr (std::is_integral::value) + { + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else + { + decltype(abs(*first)) rootn = sqrt(static_cast(n)); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + } +} + +template +inline auto hoyer_sparsity(Container const & v) +{ + return boost::math::statistics::hoyer_sparsity(v.cbegin(), v.cend()); +} + + +template +auto oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), + "Signal and noisy_signal must be have the same number of elements."); + if constexpr (std::is_integral::value) + { + double numerator = 0; + double denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (noisy_signal[i] - signal[i])*(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + return numerator/denominator; + } + else if constexpr (boost::math::tools::is_complex_type::value) + + { + using std::norm; + typename Real::value_type numerator = 0; + typename Real::value_type denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += norm(signal[i]); + denominator += norm(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } + else + { + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } +} + +template +auto mean_invariant_oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), "Signal and noisy signal must be have the same number of elements."); + + Real mu = boost::math::statistics::mean(signal); + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + Real tmp = signal[i] - mu; + numerator += tmp*tmp; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + +} + +template +auto mean_invariant_oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::statistics::mean_invariant_oracle_snr(signal, noisy_signal)); +} + + +// Follows the definition of SNR given in Mallat, A Wavelet Tour of Signal Processing, equation 11.16. +template +auto oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::statistics::oracle_snr(signal, noisy_signal)); +} + +// A good reference on the M2M4 estimator: +// D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR estimation techniques for the AWGN channel," IEEE Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. +// A nice python implementation: +// https://github.com/gnuradio/gnuradio/blob/master/gr-digital/examples/snr_estimators.py +template +auto m2m4_snr_estimator(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + BOOST_MATH_ASSERT_MSG(estimated_signal_kurtosis > 0, "The estimated signal kurtosis must be positive"); + BOOST_MATH_ASSERT_MSG(estimated_noise_kurtosis > 0, "The estimated noise kurtosis must be positive."); + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + if constexpr (std::is_floating_point::value || std::numeric_limits::max_exponent) + { + // If we first eliminate N, we obtain the quadratic equation: + // (ka+kw-6)S^2 + 2M2(3-kw)S + kw*M2^2 - M4 = 0 =: a*S^2 + bs*N + cs = 0 + // If we first eliminate S, we obtain the quadratic equation: + // (ka+kw-6)N^2 + 2M2(3-ka)N + ka*M2^2 - M4 = 0 =: a*N^2 + bn*N + cn = 0 + // I believe these equations are totally independent quadratics; + // if one has a complex solution it is not necessarily the case that the other must also. + // However, I can't prove that, so there is a chance that this does unnecessary work. + // Future improvements: There are algorithms which can solve quadratics much more effectively than the naive implementation found here. + // See: https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711#50065711 + auto [M1, M2, M3, M4] = boost::math::statistics::first_four_moments(first, last); + if (M4 == 0) + { + // The signal is constant. There is no noise: + return std::numeric_limits::infinity(); + } + // Change to notation in Pauluzzi, equation 41: + auto kw = estimated_noise_kurtosis; + auto ka = estimated_signal_kurtosis; + // A common case, since it's the default: + Real a = (ka+kw-6); + Real bs = 2*M2*(3-kw); + Real cs = kw*M2*M2 - M4; + Real bn = 2*M2*(3-ka); + Real cn = ka*M2*M2 - M4; + auto [S0, S1] = boost::math::tools::quadratic_roots(a, bs, cs); + if (S1 > 0) + { + auto N = M2 - S1; + if (N > 0) + { + return S1/N; + } + if (S0 > 0) + { + N = M2 - S0; + if (N > 0) + { + return S0/N; + } + } + } + auto [N0, N1] = boost::math::tools::quadratic_roots(a, bn, cn); + if (N1 > 0) + { + auto S = M2 - N1; + if (S > 0) + { + return S/N1; + } + if (N0 > 0) + { + S = M2 - N0; + if (S > 0) + { + return S/N0; + } + } + } + // This happens distressingly often. It's a limitation of the method. + return std::numeric_limits::quiet_NaN(); + } + else + { + BOOST_MATH_ASSERT_MSG(false, "The M2M4 estimator has not been implemented for this type."); + return std::numeric_limits::quiet_NaN(); + } +} + +template +inline auto m2m4_snr_estimator(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + return m2m4_snr_estimator(noisy_signal.cbegin(), noisy_signal.cend(), estimated_signal_kurtosis, estimated_noise_kurtosis); +} + +template +inline auto m2m4_snr_estimator_db(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(first, last, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + + +template +inline auto m2m4_snr_estimator_db(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(noisy_signal, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/t_test.hpp b/libcxx/src/third-party/boost/math/statistics/t_test.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/t_test.hpp @@ -0,0 +1,275 @@ +// (C) Copyright Nick Thompson 2019. +// (C) Copyright Matt Borland 2021. +// 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_STATISTICS_T_TEST_HPP +#define BOOST_MATH_STATISTICS_T_TEST_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType one_sample_t_test_impl(T sample_mean, T sample_variance, T num_samples, T assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + typedef boost::math::policies::policy< + boost::math::policies::promote_float, + boost::math::policies::promote_double > + no_promote_policy; + + Real test_statistic = (sample_mean - assumed_mean)/sqrt(sample_variance/num_samples); + auto student = boost::math::students_t_distribution(num_samples - 1); + Real pvalue; + if (test_statistic > 0) { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType one_sample_t_test_impl(ForwardIterator begin, ForwardIterator end, typename std::iterator_traits::value_type assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + std::pair temp = mean_and_sample_variance(begin, end); + Real mu = std::get<0>(temp); + Real s_sq = std::get<1>(temp); + return one_sample_t_test_impl(mu, s_sq, Real(std::distance(begin, end)), Real(assumed_mean)); +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes,_unequal_variances_(sX1_%3E_2sX2_or_sX2_%3E_2sX1) +template +ReturnType welchs_t_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + Real dof_num = (variance_1/size_1 + variance_2/size_2) * (variance_1/size_1 + variance_2/size_2); + Real dof_denom = ((variance_1/size_1) * (variance_1/size_1))/(size_1 - 1) + + ((variance_2/size_2) * (variance_2/size_2))/(size_2 - 1); + Real dof = dof_num / dof_denom; + + Real s_estimator = sqrt((variance_1/size_1) + (variance_2/size_2)); + + Real test_statistic = (static_cast(mean_1) - static_cast(mean_2))/s_estimator; + auto student = boost::math::students_t_distribution(dof); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Equal_or_unequal_sample_sizes,_similar_variances_(1/2_%3C_sX1/sX2_%3C_2) +template +ReturnType two_sample_t_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + Real dof = size_1 + size_2 - 2; + Real pooled_std_dev = sqrt(((size_1-1)*variance_1 + (size_2-1)*variance_2) / dof); + Real test_statistic = (mean_1-mean_2) / (pooled_std_dev*sqrt(1.0/static_cast(size_1) + 1.0/static_cast(size_2))); + + auto student = boost::math::students_t_distribution(dof); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType two_sample_t_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + auto n1 = std::distance(begin_1, end_1); + auto n2 = std::distance(begin_2, end_2); + + ReturnType temp_1 = mean_and_sample_variance(begin_1, end_1); + Real mean_1 = std::get<0>(temp_1); + Real variance_1 = std::get<1>(temp_1); + Real std_dev_1 = sqrt(variance_1); + + ReturnType temp_2 = mean_and_sample_variance(begin_2, end_2); + Real mean_2 = std::get<0>(temp_2); + Real variance_2 = std::get<1>(temp_2); + Real std_dev_2 = sqrt(variance_2); + + if(std_dev_1 > 2 * std_dev_2 || std_dev_2 > 2 * std_dev_1) + { + return welchs_t_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); + } + else + { + return two_sample_t_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); + } +} + +// https://en.wikipedia.org/wiki/Student%27s_t-test#Dependent_t-test_for_paired_samples +template +ReturnType paired_samples_t_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + using std::sqrt; + + std::vector delta; + ForwardIterator it_1 = begin_1; + ForwardIterator it_2 = begin_2; + std::size_t n = 0; + while(it_1 != end_1 && it_2 != end_2) + { + delta.emplace_back(static_cast(*it_1++) - static_cast(*it_2++)); + ++n; + } + + if(it_1 != end_1 || it_2 != end_2) + { + throw std::domain_error("Both sets must have the same number of values."); + } + + std::pair temp = mean_and_sample_variance(delta.begin(), delta.end()); + Real delta_mean = std::get<0>(temp); + Real delta_std_dev = sqrt(std::get<1>(temp)); + + Real test_statistic = delta_mean/(delta_std_dev/sqrt(n)); + + auto student = boost::math::students_t_distribution(n - 1); + Real pvalue; + if (test_statistic > 0) + { + pvalue = 2*boost::math::cdf(student, -test_statistic);; + } + else + { + pvalue = 2*boost::math::cdf(student, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} +} // namespace detail + +template::value, bool>::type = true> +inline auto one_sample_t_test(Real sample_mean, Real sample_variance, Real num_samples, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(sample_mean, sample_variance, num_samples, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Real sample_mean, Real sample_variance, Real num_samples, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(sample_mean, sample_variance, num_samples, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_t_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(begin, end, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_t_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(begin, end, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_t_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_t_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto two_sample_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto two_sample_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto paired_samples_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::paired_samples_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto paired_samples_t_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::paired_samples_t_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto paired_samples_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::paired_samples_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto paired_samples_t_test(Container const & u, Container const & v) -> std::pair +{ + return detail::paired_samples_t_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // namespace boost::math::statistics +#endif diff --git a/libcxx/src/third-party/boost/math/statistics/univariate_statistics.hpp b/libcxx/src/third-party/boost/math/statistics/univariate_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/univariate_statistics.hpp @@ -0,0 +1,1184 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2020. +// 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_STATISTICS_UNIVARIATE_STATISTICS_HPP +#define BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_EXEC_COMPATIBLE +#include + +namespace boost::math::statistics { + +template +inline auto mean(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::mean_sequential_impl(first, last); + } + else + { + return std::reduce(exec, first, last, 0.0) / std::distance(first, last); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return detail::mean_sequential_impl(first, last); + } + else + { + return std::reduce(exec, first, last, Real(0.0)) / Real(std::distance(first, last)); + } + } +} + +template +inline auto mean(ExecutionPolicy&& exec, Container const & v) +{ + return mean(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean(ForwardIterator first, ForwardIterator last) +{ + return mean(std::execution::seq, first, last); +} + +template +inline auto mean(Container const & v) +{ + return mean(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return std::get<2>(detail::variance_sequential_impl>(first, last)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::get<1>(results) / std::get<4>(results); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + return std::get<2>(detail::variance_sequential_impl>(first, last)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::get<1>(results) / std::get<4>(results); + } + } +} + +template +inline auto variance(ExecutionPolicy&& exec, Container const & v) +{ + return variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto variance(ForwardIterator first, ForwardIterator last) +{ + return variance(std::execution::seq, first, last); +} + +template +inline auto variance(Container const & v) +{ + return variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto sample_variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(exec, first, last)/(n-1); +} + +template +inline auto sample_variance(ExecutionPolicy&& exec, Container const & v) +{ + return sample_variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto sample_variance(ForwardIterator first, ForwardIterator last) +{ + return sample_variance(std::execution::seq, first, last); +} + +template +inline auto sample_variance(Container const & v) +{ + return sample_variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean_and_sample_variance(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<2>(results)*std::get<3>(results)/(std::get<3>(results)-1.0)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<1>(results) / (std::get<4>(results)-1.0)); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<2>(results)*std::get<3>(results)/(std::get<3>(results)-Real(1))); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<1>(results) / (std::get<4>(results)-Real(1))); + } + } +} + +template +inline auto mean_and_sample_variance(ExecutionPolicy&& exec, Container const & v) +{ + return mean_and_sample_variance(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto mean_and_sample_variance(ForwardIterator first, ForwardIterator last) +{ + return mean_and_sample_variance(std::execution::seq, first, last); +} + +template +inline auto mean_and_sample_variance(Container const & v) +{ + return mean_and_sample_variance(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto first_four_moments(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if constexpr (std::is_integral_v) + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + } + else + { + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + else + { + const auto results = detail::first_four_moments_parallel_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); + } + } +} + +template +inline auto first_four_moments(ExecutionPolicy&& exec, Container const & v) +{ + return first_four_moments(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto first_four_moments(ForwardIterator first, ForwardIterator last) +{ + return first_four_moments(std::execution::seq, first, last); +} + +template +inline auto first_four_moments(Container const & v) +{ + return first_four_moments(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +inline auto skewness(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + return detail::skewness_sequential_impl(first, last); + } + else + { + return detail::skewness_sequential_impl(first, last); + } + } + else + { + const auto [M1, M2, M3, M4] = first_four_moments(exec, first, last); + const auto n = std::distance(first, last); + const auto var = M2/(n-1); + + if (M2 == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + if constexpr (std::is_integral_v) + { + return static_cast(0); + } + else + { + return Real(0); + } + } + else + { + return M3/(M2*sqrt(var)) / Real(2); + } + } +} + +template +inline auto skewness(ExecutionPolicy&& exec, Container & v) +{ + return skewness(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto skewness(ForwardIterator first, ForwardIterator last) +{ + return skewness(std::execution::seq, first, last); +} + +template +inline auto skewness(Container const & v) +{ + return skewness(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +// Follows equation 1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +inline auto kurtosis(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + const auto [M1, M2, M3, M4] = first_four_moments(exec, first, last); + if (M2 == 0) + { + return M2; + } + return M4/(M2*M2); +} + +template +inline auto kurtosis(ExecutionPolicy&& exec, Container const & v) +{ + return kurtosis(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto kurtosis(ForwardIterator first, ForwardIterator last) +{ + return kurtosis(std::execution::seq, first, last); +} + +template +inline auto kurtosis(Container const & v) +{ + return kurtosis(std::execution::seq, std::cbegin(v), std::cend(v)); +} + +template +inline auto excess_kurtosis(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + return kurtosis(exec, first, last) - 3; +} + +template +inline auto excess_kurtosis(ExecutionPolicy&& exec, Container const & v) +{ + return excess_kurtosis(exec, std::cbegin(v), std::cend(v)); +} + +template +inline auto excess_kurtosis(ForwardIterator first, ForwardIterator last) +{ + return excess_kurtosis(std::execution::seq, first, last); +} + +template +inline auto excess_kurtosis(Container const & v) +{ + return excess_kurtosis(std::execution::seq, std::cbegin(v), std::cend(v)); +} + + +template +auto median(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(exec, first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(exec, first, middle, last); + std::nth_element(exec, middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + + +template +inline auto median(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return median(exec, std::begin(v), std::end(v)); +} + +template +inline auto median(RandomAccessIterator first, RandomAccessIterator last) +{ + return median(std::execution::seq, first, last); +} + +template +inline auto median(RandomAccessContainer & v) +{ + return median(std::execution::seq, std::begin(v), std::end(v)); +} + +#if 0 +// +// Parallel gini calculation is curently broken, see: +// https://github.com/boostorg/math/issues/585 +// We will fix this at a later date, for now just use a serial implementation: +// +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if(!std::is_sorted(exec, first, last)) + { + std::sort(exec, first, last); + } + + if constexpr (std::is_same_v, decltype(std::execution::seq)>) + { + if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_sequential_impl(first, last); + } + else + { + return detail::gini_coefficient_sequential_impl(first, last); + } + } + + else if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_parallel_impl(exec, first, last); + } + + else + { + return detail::gini_coefficient_parallel_impl(exec, first, last); + } +} +#else +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + + if (!std::is_sorted(exec, first, last)) + { + std::sort(exec, first, last); + } + + if constexpr (std::is_integral_v) + { + return detail::gini_coefficient_sequential_impl(first, last); + } + else + { + return detail::gini_coefficient_sequential_impl(first, last); + } +} +#endif + +template +inline auto gini_coefficient(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return gini_coefficient(exec, std::begin(v), std::end(v)); +} + +template +inline auto gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + return gini_coefficient(std::execution::seq, first, last); +} + +template +inline auto gini_coefficient(RandomAccessContainer & v) +{ + return gini_coefficient(std::execution::seq, std::begin(v), std::end(v)); +} + +template +inline auto sample_gini_coefficient(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(exec, first, last)/(n-1); +} + +template +inline auto sample_gini_coefficient(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return sample_gini_coefficient(exec, std::begin(v), std::end(v)); +} + +template +inline auto sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + return sample_gini_coefficient(std::execution::seq, first, last); +} + +template +inline auto sample_gini_coefficient(RandomAccessContainer & v) +{ + return sample_gini_coefficient(std::execution::seq, std::begin(v), std::end(v)); +} + +template +auto median_absolute_deviation(ExecutionPolicy&& exec, RandomAccessIterator first, RandomAccessIterator last, + typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using Real = typename std::iterator_traits::value_type; + using std::isnan; + if (isnan(center)) + { + center = boost::math::statistics::median(exec, first, last); + } + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(exec, first, middle, last, comparator); + return abs(*middle); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(exec, first, middle, last, comparator); + std::nth_element(exec, middle, middle+1, last, comparator); + return (abs(*middle) + abs(*(middle+1)))/abs(static_cast(2)); + } +} + +template +inline auto median_absolute_deviation(ExecutionPolicy&& exec, RandomAccessContainer & v, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(exec, std::begin(v), std::end(v), center); +} + +template +inline auto median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, + typename RandomAccessIterator::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::execution::seq, first, last, center); +} + +template +inline auto median_absolute_deviation(RandomAccessContainer & v, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::execution::seq, std::begin(v), std::end(v), center); +} + +template +auto interquartile_range(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + static_assert(!std::is_integral_v, "Integer values have not yet been implemented."); + auto m = std::distance(first,last); + BOOST_MATH_ASSERT_MSG(m >= 3, "At least 3 samples are required to compute the interquartile range."); + auto k = m/4; + auto j = m - (4*k); + // m = 4k+j. + // If j = 0 or j = 1, then there are an even number of samples below the median, and an even number above the median. + // Then we must average adjacent elements to get the quartiles. + // If j = 2 or j = 3, there are an odd number of samples above and below the median, these elements may be directly extracted to get the quartiles. + + if (j==2 || j==3) + { + auto q1 = first + k; + auto q3 = first + 3*k + j - 1; + std::nth_element(exec, first, q1, last); + Real Q1 = *q1; + std::nth_element(exec, q1, q3, last); + Real Q3 = *q3; + return Q3 - Q1; + } else { + // j == 0 or j==1: + auto q1 = first + k - 1; + auto q3 = first + 3*k - 1 + j; + std::nth_element(exec, first, q1, last); + Real a = *q1; + std::nth_element(exec, q1, q1 + 1, last); + Real b = *(q1 + 1); + Real Q1 = (a+b)/2; + std::nth_element(exec, q1, q3, last); + a = *q3; + std::nth_element(exec, q3, q3 + 1, last); + b = *(q3 + 1); + Real Q3 = (a+b)/2; + return Q3 - Q1; + } +} + +template +inline auto interquartile_range(ExecutionPolicy&& exec, RandomAccessContainer & v) +{ + return interquartile_range(exec, std::begin(v), std::end(v)); +} + +template +inline auto interquartile_range(RandomAccessIterator first, RandomAccessIterator last) +{ + return interquartile_range(std::execution::seq, first, last); +} + +template +inline auto interquartile_range(RandomAccessContainer & v) +{ + return interquartile_range(std::execution::seq, std::begin(v), std::end(v)); +} + +template +inline OutputIterator mode(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(exec, first, last)) + { + if constexpr (std::is_same_v::iterator_category(), std::random_access_iterator_tag>) + { + std::sort(exec, first, last); + } + else + { + BOOST_MATH_ASSERT("Data must be sorted for sequential mode calculation"); + } + } + + return detail::mode_impl(first, last, output); +} + +template +inline OutputIterator mode(ExecutionPolicy&& exec, Container & v, OutputIterator output) +{ + return mode(exec, std::begin(v), std::end(v), output); +} + +template +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + return mode(std::execution::seq, first, last, output); +} + +// Requires enable_if_t to not clash with impl that returns std::list +// Very ugly. std::is_execution_policy_v returns false for the std::execution objects and decltype of the objects (e.g. std::execution::seq) +template && + !std::is_convertible_v && + !std::is_convertible_v + #if __cpp_lib_execution > 201900 + && !std::is_convertible_v + #endif + , bool> = true> +inline OutputIterator mode(Container & v, OutputIterator output) +{ + return mode(std::execution::seq, std::begin(v), std::end(v), output); +} + +// std::list is the return type for the proposed STL stats library + +template::value_type> +inline auto mode(ExecutionPolicy&& exec, ForwardIterator first, ForwardIterator last) +{ + std::list modes; + mode(exec, first, last, std::inserter(modes, modes.begin())); + return modes; +} + +template +inline auto mode(ExecutionPolicy&& exec, Container & v) +{ + return mode(exec, std::begin(v), std::end(v)); +} + +template +inline auto mode(ForwardIterator first, ForwardIterator last) +{ + return mode(std::execution::seq, first, last); +} + +template +inline auto mode(Container & v) +{ + return mode(std::execution::seq, std::begin(v), std::end(v)); +} + +} // Namespace boost::math::statistics + +#else // Backwards compatible bindings for C++11 or execution is not implemented + +namespace boost { namespace math { namespace statistics { + +template +using enable_if_t = typename std::enable_if::type; + +template::value_type, + enable_if_t::value, bool> = true> +inline double mean(const ForwardIterator first, const ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + return detail::mean_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double mean(const Container& c) +{ + return mean(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real mean(const ForwardIterator first, const ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + return detail::mean_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real mean(const Container& c) +{ + return mean(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double variance(const ForwardIterator first, const ForwardIterator last) +{ + return std::get<2>(detail::variance_sequential_impl>(first, last)); +} + +template::value, bool> = true> +inline double variance(const Container& c) +{ + return variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real variance(const ForwardIterator first, const ForwardIterator last) +{ + return std::get<2>(detail::variance_sequential_impl>(first, last)); + +} + +template::value, bool> = true> +inline Real variance(const Container& c) +{ + return variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template::value, bool> = true> +inline double sample_variance(const Container& c) +{ + return sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template::value, bool> = true> +inline Real sample_variance(const Container& c) +{ + return sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::pair mean_and_sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<3>(results)*std::get<2>(results)/(std::get<3>(results)-1.0)); +} + +template::value, bool> = true> +inline std::pair mean_and_sample_variance(const Container& c) +{ + return mean_and_sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::pair mean_and_sample_variance(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::variance_sequential_impl>(first, last); + return std::make_pair(std::get<0>(results), std::get<3>(results)*std::get<2>(results)/(std::get<3>(results)-Real(1))); +} + +template::value, bool> = true> +inline std::pair mean_and_sample_variance(const Container& c) +{ + return mean_and_sample_variance(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::tuple first_four_moments(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); +} + +template::value, bool> = true> +inline std::tuple first_four_moments(const Container& c) +{ + return first_four_moments(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline std::tuple first_four_moments(const ForwardIterator first, const ForwardIterator last) +{ + const auto results = detail::first_four_moments_sequential_impl>(first, last); + return std::make_tuple(std::get<0>(results), std::get<1>(results) / std::get<4>(results), std::get<2>(results) / std::get<4>(results), + std::get<3>(results) / std::get<4>(results)); +} + +template::value, bool> = true> +inline std::tuple first_four_moments(const Container& c) +{ + return first_four_moments(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double skewness(const ForwardIterator first, const ForwardIterator last) +{ + return detail::skewness_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double skewness(const Container& c) +{ + return skewness(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real skewness(const ForwardIterator first, const ForwardIterator last) +{ + return detail::skewness_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real skewness(const Container& c) +{ + return skewness(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + std::tuple M = first_four_moments(first, last); + + if(std::get<1>(M) == 0) + { + return std::get<1>(M); + } + else + { + return std::get<3>(M)/(std::get<1>(M)*std::get<1>(M)); + } +} + +template::value, bool> = true> +inline double kurtosis(const Container& c) +{ + return kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + std::tuple M = first_four_moments(first, last); + + if(std::get<1>(M) == 0) + { + return std::get<1>(M); + } + else + { + return std::get<3>(M)/(std::get<1>(M)*std::get<1>(M)); + } +} + +template::value, bool> = true> +inline Real kurtosis(const Container& c) +{ + return kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double excess_kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template::value, bool> = true> +inline double excess_kurtosis(const Container& c) +{ + return excess_kurtosis(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real excess_kurtosis(const ForwardIterator first, const ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template::value, bool> = true> +inline Real excess_kurtosis(const Container& c) +{ + return excess_kurtosis(std::begin(c), std::end(c)); +} + +template::value_type> +Real median(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last); + std::nth_element(middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + +template +inline Real median(RandomAccessContainer& c) +{ + return median(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::gini_coefficient_sequential_impl(first, last); +} + +template::value, bool> = true> +inline double gini_coefficient(RandomAccessContainer& c) +{ + return gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::gini_coefficient_sequential_impl(first, last); +} + +template::value, bool> = true> +inline Real gini_coefficient(RandomAccessContainer& c) +{ + return gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline double sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template::value, bool> = true> +inline double sample_gini_coefficient(RandomAccessContainer& c) +{ + return sample_gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type, + enable_if_t::value, bool> = true> +inline Real sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + const auto n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template::value, bool> = true> +inline Real sample_gini_coefficient(RandomAccessContainer& c) +{ + return sample_gini_coefficient(std::begin(c), std::end(c)); +} + +template::value_type> +Real median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, + typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using std::isnan; + if (isnan(center)) + { + center = boost::math::statistics::median(first, last); + } + const auto num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last, comparator); + return abs(*middle); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last, comparator); + std::nth_element(middle, middle+1, last, comparator); + return (abs(*middle) + abs(*(middle+1)))/abs(static_cast(2)); + } +} + +template +inline Real median_absolute_deviation(RandomAccessContainer& c, + typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(std::begin(c), std::end(c), center); +} + +template::value_type> +Real interquartile_range(ForwardIterator first, ForwardIterator last) +{ + static_assert(!std::is_integral::value, "Integer values have not yet been implemented."); + auto m = std::distance(first,last); + BOOST_MATH_ASSERT_MSG(m >= 3, "At least 3 samples are required to compute the interquartile range."); + auto k = m/4; + auto j = m - (4*k); + // m = 4k+j. + // If j = 0 or j = 1, then there are an even number of samples below the median, and an even number above the median. + // Then we must average adjacent elements to get the quartiles. + // If j = 2 or j = 3, there are an odd number of samples above and below the median, these elements may be directly extracted to get the quartiles. + + if (j==2 || j==3) + { + auto q1 = first + k; + auto q3 = first + 3*k + j - 1; + std::nth_element(first, q1, last); + Real Q1 = *q1; + std::nth_element(q1, q3, last); + Real Q3 = *q3; + return Q3 - Q1; + } + else + { + // j == 0 or j==1: + auto q1 = first + k - 1; + auto q3 = first + 3*k - 1 + j; + std::nth_element(first, q1, last); + Real a = *q1; + std::nth_element(q1, q1 + 1, last); + Real b = *(q1 + 1); + Real Q1 = (a+b)/2; + std::nth_element(q1, q3, last); + a = *q3; + std::nth_element(q3, q3 + 1, last); + b = *(q3 + 1); + Real Q3 = (a+b)/2; + return Q3 - Q1; + } +} + +template +Real interquartile_range(Container& c) +{ + return interquartile_range(std::begin(c), std::end(c)); +} + +template::iterator_category(), std::random_access_iterator_tag>::value, bool> = true> +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(first, last)) + { + std::sort(first, last); + } + + return detail::mode_impl(first, last, output); +} + +template::iterator_category(), std::random_access_iterator_tag>::value, bool> = true> +inline OutputIterator mode(ForwardIterator first, ForwardIterator last, OutputIterator output) +{ + if(!std::is_sorted(first, last)) + { + BOOST_MATH_ASSERT("Data must be sorted for mode calculation"); + } + + return detail::mode_impl(first, last, output); +} + +template +inline OutputIterator mode(Container& c, OutputIterator output) +{ + return mode(std::begin(c), std::end(c), output); +} + +template::value_type> +inline std::list mode(ForwardIterator first, ForwardIterator last) +{ + std::list modes; + mode(first, last, std::inserter(modes, modes.begin())); + return modes; +} + +template +inline std::list mode(Container& c) +{ + return mode(std::begin(c), std::end(c)); +} +}}} +#endif +#endif // BOOST_MATH_STATISTICS_UNIVARIATE_STATISTICS_HPP diff --git a/libcxx/src/third-party/boost/math/statistics/z_test.hpp b/libcxx/src/third-party/boost/math/statistics/z_test.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/statistics/z_test.hpp @@ -0,0 +1,161 @@ +// (C) Copyright Matt Borland 2021. +// 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_STATISTICS_Z_TEST_HPP +#define BOOST_MATH_STATISTICS_Z_TEST_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace math { namespace statistics { namespace detail { + +template +ReturnType one_sample_z_test_impl(T sample_mean, T sample_variance, T sample_size, T assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + + Real test_statistic = (sample_mean - assumed_mean) / (sample_variance / sqrt(sample_size)); + auto z = boost::math::normal_distribution(sample_size - 1); + Real pvalue; + if(test_statistic > 0) + { + pvalue = 2*boost::math::cdf(z, -test_statistic); + } + else + { + pvalue = 2*boost::math::cdf(z, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType one_sample_z_test_impl(ForwardIterator begin, ForwardIterator end, typename std::iterator_traits::value_type assumed_mean) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + std::pair temp = mean_and_sample_variance(begin, end); + Real mu = std::get<0>(temp); + Real s_sq = std::get<1>(temp); + return one_sample_z_test_impl(mu, s_sq, Real(std::distance(begin, end)), Real(assumed_mean)); +} + +template +ReturnType two_sample_z_test_impl(T mean_1, T variance_1, T size_1, T mean_2, T variance_2, T size_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + using no_promote_policy = boost::math::policies::policy, boost::math::policies::promote_double>; + + Real test_statistic = (mean_1 - mean_2) / sqrt(variance_1/size_1 + variance_2/size_2); + auto z = boost::math::normal_distribution(size_1 + size_2 - 1); + Real pvalue; + if(test_statistic > 0) + { + pvalue = 2*boost::math::cdf(z, -test_statistic); + } + else + { + pvalue = 2*boost::math::cdf(z, test_statistic); + } + + return std::make_pair(test_statistic, pvalue); +} + +template +ReturnType two_sample_z_test_impl(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) +{ + using Real = typename std::tuple_element<0, ReturnType>::type; + using std::sqrt; + auto n1 = std::distance(begin_1, end_1); + auto n2 = std::distance(begin_2, end_2); + + ReturnType temp_1 = mean_and_sample_variance(begin_1, end_1); + Real mean_1 = std::get<0>(temp_1); + Real variance_1 = std::get<1>(temp_1); + + ReturnType temp_2 = mean_and_sample_variance(begin_2, end_2); + Real mean_2 = std::get<0>(temp_2); + Real variance_2 = std::get<1>(temp_2); + + return two_sample_z_test_impl(mean_1, variance_1, Real(n1), mean_2, variance_2, Real(n2)); +} + +} // detail + +template::value, bool>::type = true> +inline auto one_sample_z_test(Real sample_mean, Real sample_variance, Real sample_size, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(sample_mean, sample_variance, sample_size, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Real sample_mean, Real sample_variance, Real sample_size, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(sample_mean, sample_variance, sample_size, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_z_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(begin, end, assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto one_sample_z_test(ForwardIterator begin, ForwardIterator end, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(begin, end, assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value, bool>::type = true> +inline auto one_sample_z_test(Container const & v, Real assumed_mean) -> std::pair +{ + return detail::one_sample_z_test_impl>(std::begin(v), std::end(v), assumed_mean); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_z_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_z_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value_type, + typename std::enable_if::value, bool>::type = true> +inline auto two_sample_z_test(ForwardIterator begin_1, ForwardIterator end_1, ForwardIterator begin_2, ForwardIterator end_2) -> std::pair +{ + return detail::two_sample_z_test_impl>(begin_1, end_1, begin_2, end_2); +} + +template::value, bool>::type = true> +inline auto two_sample_z_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_z_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +template::value, bool>::type = true> +inline auto two_sample_z_test(Container const & u, Container const & v) -> std::pair +{ + return detail::two_sample_z_test_impl>(std::begin(u), std::end(u), std::begin(v), std::end(v)); +} + +}}} // boost::math::statistics + +#endif // BOOST_MATH_STATISTICS_Z_TEST_HPP diff --git a/libcxx/src/third-party/boost/math/tools/agm.hpp b/libcxx/src/third-party/boost/math/tools/agm.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/agm.hpp @@ -0,0 +1,47 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_AGM_HPP +#define BOOST_MATH_TOOLS_AGM_HPP +#include +#include + +namespace boost { namespace math { namespace tools { + +template +Real agm(Real a, Real g) +{ + using std::sqrt; + + if (a < g) + { + // Mathematica, mpfr, and mpmath are all symmetric functions: + return agm(g, a); + } + // Use: M(rx, ry) = rM(x,y) + if (a <= 0 || g <= 0) { + if (a < 0 || g < 0) { + return std::numeric_limits::quiet_NaN(); + } + return Real(0); + } + + // The number of correct digits doubles on each iteration. + // Divide by 512 for some leeway: + const Real scale = sqrt(std::numeric_limits::epsilon())/512; + while (a-g > scale*g) + { + Real anp1 = (a + g)/2; + g = sqrt(a*g); + a = anp1; + } + + // Final cleanup iteration recovers down to ~2ULPs: + return (a + g)/2; +} + + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/assert.hpp b/libcxx/src/third-party/boost/math/tools/assert.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/assert.hpp @@ -0,0 +1,34 @@ +// (C) Copyright Matt Borland 2021. +// 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) +// +// We deliberately use assert in here: +// +// boost-no-inspect + +#ifndef BOOST_MATH_TOOLS_ASSERT_HPP +#define BOOST_MATH_TOOLS_ASSERT_HPP + +#include + +#ifndef BOOST_MATH_STANDALONE + +#include +#include +#define BOOST_MATH_ASSERT(expr) BOOST_ASSERT(expr) +#define BOOST_MATH_ASSERT_MSG(expr, msg) BOOST_ASSERT_MSG(expr, msg) +#define BOOST_MATH_STATIC_ASSERT(expr) BOOST_STATIC_ASSERT(expr) +#define BOOST_MATH_STATIC_ASSERT_MSG(expr, msg) BOOST_STATIC_ASSERT_MSG(expr, msg) + +#else // Standalone mode - use cassert + +#include +#define BOOST_MATH_ASSERT(expr) assert(expr) +#define BOOST_MATH_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#define BOOST_MATH_STATIC_ASSERT(expr) static_assert(expr, #expr " failed") +#define BOOST_MATH_STATIC_ASSERT_MSG(expr, msg) static_assert(expr, msg) + +#endif + +#endif // BOOST_MATH_TOOLS_ASSERT_HPP diff --git a/libcxx/src/third-party/boost/math/tools/atomic.hpp b/libcxx/src/third-party/boost/math/tools/atomic.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/atomic.hpp @@ -0,0 +1,50 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2017 John Maddock +// Distributed under 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_ATOMIC_DETAIL_HPP +#define BOOST_MATH_ATOMIC_DETAIL_HPP + +#include +#include + +#ifdef BOOST_HAS_THREADS +#include + +namespace boost { + namespace math { + namespace detail { +#if (ATOMIC_INT_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_counter_type; + typedef std::atomic atomic_unsigned_type; + typedef int atomic_integer_type; + typedef unsigned atomic_unsigned_integer_type; +#elif (ATOMIC_SHORT_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_counter_type; + typedef std::atomic atomic_unsigned_type; + typedef short atomic_integer_type; + typedef unsigned short atomic_unsigned_type; +#elif (ATOMIC_LONG_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_unsigned_integer_type; + typedef std::atomic atomic_unsigned_type; + typedef unsigned long atomic_unsigned_type; + typedef long atomic_integer_type; +#elif (ATOMIC_LLONG_LOCK_FREE == 2) && !defined(BOOST_MATH_NO_ATOMIC_INT) + typedef std::atomic atomic_unsigned_integer_type; + typedef std::atomic atomic_unsigned_type; + typedef long long atomic_integer_type; + typedef unsigned long long atomic_unsigned_integer_type; +#elif !defined(BOOST_MATH_NO_ATOMIC_INT) +# define BOOST_MATH_NO_ATOMIC_INT +#endif + } // Namespace detail + } // Namespace math +} // Namespace boost + +#else +# define BOOST_MATH_NO_ATOMIC_INT +#endif // BOOST_HAS_THREADS + +#endif // BOOST_MATH_ATOMIC_DETAIL_HPP diff --git a/libcxx/src/third-party/boost/math/tools/big_constant.hpp b/libcxx/src/third-party/boost/math/tools/big_constant.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/big_constant.hpp @@ -0,0 +1,98 @@ + +// Copyright (c) 2011 John Maddock +// 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_TOOLS_BIG_CONSTANT_HPP +#define BOOST_MATH_TOOLS_BIG_CONSTANT_HPP + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +#include +#include +#include + +namespace boost{ namespace math{ + +namespace tools{ + +template +struct numeric_traits : public std::numeric_limits< T > {}; + +#ifdef BOOST_MATH_USE_FLOAT128 +typedef __float128 largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x##Q +template <> +struct numeric_traits<__float128> +{ + static const int digits = 113; + static const int digits10 = 33; + static const int max_exponent = 16384; + static const bool is_specialized = true; +}; +#elif LDBL_DIG > DBL_DIG +typedef long double largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x##L +#else +typedef double largest_float; +#define BOOST_MATH_LARGEST_FLOAT_C(x) x +#endif + +template +inline constexpr T make_big_value(largest_float v, const char*, std::true_type const&, std::false_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return static_cast(v); +} +template +inline constexpr T make_big_value(largest_float v, const char*, std::true_type const&, std::true_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return static_cast(v); +} +#ifndef BOOST_MATH_NO_LEXICAL_CAST +template +inline T make_big_value(largest_float, const char* s, std::false_type const&, std::false_type const&) +{ + return boost::lexical_cast(s); +} +#else +template +inline T make_big_value(largest_float, const char* s, std::false_type const&, std::false_type const&) +{ + static_assert(sizeof(T) == 0, "Type is unsupported in standalone mode. Please disable and try again."); +} +#endif +template +inline constexpr T make_big_value(largest_float, const char* s, std::false_type const&, std::true_type const&) BOOST_MATH_NOEXCEPT(T) +{ + return T(s); +} + +// +// For constants which might fit in a long double (if it's big enough): +// +#define BOOST_MATH_BIG_CONSTANT(T, D, x)\ + boost::math::tools::make_big_value(\ + BOOST_MATH_LARGEST_FLOAT_C(x), \ + BOOST_STRINGIZE(x), \ + std::integral_constant::value) && \ + ((D <= boost::math::tools::numeric_traits::digits) \ + || std::is_floating_point::value \ + || (boost::math::tools::numeric_traits::is_specialized && \ + (boost::math::tools::numeric_traits::digits10 <= boost::math::tools::numeric_traits::digits10))) >(), \ + std::is_constructible()) +// +// For constants too huge for any conceivable long double (and which generate compiler errors if we try and declare them as such): +// +#define BOOST_MATH_HUGE_CONSTANT(T, D, x)\ + boost::math::tools::make_big_value(0.0L, BOOST_STRINGIZE(x), \ + std::integral_constant::value || (boost::math::tools::numeric_traits::is_specialized && boost::math::tools::numeric_traits::max_exponent <= boost::math::tools::numeric_traits::max_exponent && boost::math::tools::numeric_traits::digits <= boost::math::tools::numeric_traits::digits)>(), \ + std::is_constructible()) + +}}} // namespaces + +#endif + diff --git a/libcxx/src/third-party/boost/math/tools/bivariate_statistics.hpp b/libcxx/src/third-party/boost/math/tools/bivariate_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/bivariate_statistics.hpp @@ -0,0 +1,96 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_BIVARIATE_STATISTICS_HPP +#define BOOST_MATH_TOOLS_BIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost{ namespace math{ namespace tools { + +template +auto means_and_covariance(Container const & u, Container const & v) +{ + using Real = typename Container::value_type; + using std::size; + BOOST_MATH_ASSERT_MSG(size(u) == size(v), "The size of each vector must be the same to compute covariance."); + BOOST_MATH_ASSERT_MSG(size(u) > 0, "Computing covariance requires at least one sample."); + + // See Equation III.9 of "Numerically Stable, Single-Pass, Parallel Statistics Algorithms", Bennet et al. + Real cov = 0; + Real mu_u = u[0]; + Real mu_v = v[0]; + + for(size_t i = 1; i < size(u); ++i) + { + Real u_tmp = (u[i] - mu_u)/(i+1); + Real v_tmp = v[i] - mu_v; + cov += i*u_tmp*v_tmp; + mu_u = mu_u + u_tmp; + mu_v = mu_v + v_tmp/(i+1); + } + + return std::make_tuple(mu_u, mu_v, cov/size(u)); +} + +template +auto covariance(Container const & u, Container const & v) +{ + auto [mu_u, mu_v, cov] = boost::math::tools::means_and_covariance(u, v); + return cov; +} + +template +auto correlation_coefficient(Container const & u, Container const & v) +{ + using Real = typename Container::value_type; + using std::size; + BOOST_MATH_ASSERT_MSG(size(u) == size(v), "The size of each vector must be the same to compute covariance."); + BOOST_MATH_ASSERT_MSG(size(u) > 0, "Computing covariance requires at least two samples."); + + Real cov = 0; + Real mu_u = u[0]; + Real mu_v = v[0]; + Real Qu = 0; + Real Qv = 0; + + for(size_t i = 1; i < size(u); ++i) + { + Real u_tmp = u[i] - mu_u; + Real v_tmp = v[i] - mu_v; + Qu = Qu + (i*u_tmp*u_tmp)/(i+1); + Qv = Qv + (i*v_tmp*v_tmp)/(i+1); + cov += i*u_tmp*v_tmp/(i+1); + mu_u = mu_u + u_tmp/(i+1); + mu_v = mu_v + v_tmp/(i+1); + } + + // If one dataset is constant, then they have no correlation: + // See https://stats.stackexchange.com/questions/23676/normalized-correlation-with-a-constant-vector + // Thanks to zbjornson for pointing this out. + if (Qu == 0 || Qv == 0) + { + return std::numeric_limits::quiet_NaN(); + } + + // Make sure rho in [-1, 1], even in the presence of numerical noise. + Real rho = cov/sqrt(Qu*Qv); + if (rho > 1) { + rho = 1; + } + if (rho < -1) { + rho = -1; + } + return rho; +} + +}}} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/centered_continued_fraction.hpp b/libcxx/src/third-party/boost/math/tools/centered_continued_fraction.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/centered_continued_fraction.hpp @@ -0,0 +1,166 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_CENTERED_CONTINUED_FRACTION_HPP +#define BOOST_MATH_TOOLS_CENTERED_CONTINUED_FRACTION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace boost::math::tools { + +template +class centered_continued_fraction { +public: + centered_continued_fraction(Real x) : x_{x} { + static_assert(std::is_integral_v && std::is_signed_v, + "Centered continued fractions require signed integer types."); + using std::round; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into continued fractions."); + } + b_.reserve(50); + Real bj = round(x); + b_.push_back(static_cast(bj)); + if (bj == x) + { + b_.shrink_to_fit(); + return; + } + x = 1/(x-bj); + Real f = bj; + if (bj == 0) + { + f = 16*(std::numeric_limits::min)(); + } + Real C = f; + Real D = 0; + int i = 0; + while (abs(f - x_) >= (1 + i++)*std::numeric_limits::epsilon()*abs(x_)) + { + bj = round(x); + b_.push_back(static_cast(bj)); + x = 1/(x-bj); + D += bj; + if (D == 0) { + D = 16*(std::numeric_limits::min)(); + } + C = bj + 1/C; + if (C==0) + { + C = 16*(std::numeric_limits::min)(); + } + D = 1/D; + f *= (C*D); + } + // Deal with non-uniqueness of continued fractions: [a0; a1, ..., an, 1] = a0; a1, ..., an + 1]. + if (b_.size() > 2 && b_.back() == 1) + { + b_[b_.size() - 2] += 1; + b_.resize(b_.size() - 1); + } + b_.shrink_to_fit(); + + for (size_t i = 1; i < b_.size(); ++i) + { + if (b_[i] == 0) { + std::ostringstream oss; + oss << "Found a zero partial denominator: b[" << i << "] = " << b_[i] << "." + #ifndef BOOST_MATH_STANDALONE + << " This means the integer type '" << boost::core::demangle(typeid(Z).name()) + #else + << " This means the integer type '" << typeid(Z).name() + #endif + << "' has overflowed and you need to use a wider type," + << " or there is a bug."; + throw std::overflow_error(oss.str()); + } + } + } + + Real khinchin_geometric_mean() const { + if (b_.size() == 1) + { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + using std::abs; + const std::array logs{std::numeric_limits::quiet_NaN(), Real(0), log(static_cast(2)), log(static_cast(3)), log(static_cast(4)), log(static_cast(5)), log(static_cast(6))}; + Real log_prod = 0; + for (size_t i = 1; i < b_.size(); ++i) + { + if (abs(b_[i]) < static_cast(logs.size())) + { + log_prod += logs[abs(b_[i])]; + } + else + { + log_prod += log(static_cast(abs(b_[i]))); + } + } + log_prod /= (b_.size()-1); + return exp(log_prod); + } + + const std::vector& partial_denominators() const { + return b_; + } + + template + friend std::ostream& operator<<(std::ostream& out, centered_continued_fraction& ccf); + +private: + const Real x_; + std::vector b_; +}; + + +template +std::ostream& operator<<(std::ostream& out, centered_continued_fraction& scf) { + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(scf.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "[" << scf.b_.front(); + if (scf.b_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < scf.b_.size() -1; ++i) + { + out << scf.b_[i] << ", "; + } + out << scf.b_.back(); + } + out << "]"; + return out; +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/cohen_acceleration.hpp b/libcxx/src/third-party/boost/math/tools/cohen_acceleration.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/cohen_acceleration.hpp @@ -0,0 +1,50 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_COHEN_ACCELERATION_HPP +#define BOOST_MATH_TOOLS_COHEN_ACCELERATION_HPP +#include +#include +#include + +namespace boost::math::tools { + +// Algorithm 1 of https://people.mpim-bonn.mpg.de/zagier/files/exp-math-9/fulltext.pdf +// Convergence Acceleration of Alternating Series: Henri Cohen, Fernando Rodriguez Villegas, and Don Zagier +template +auto cohen_acceleration(G& generator, std::int64_t n = -1) +{ + using Real = decltype(generator()); + // This test doesn't pass for float128, sad! + //static_assert(std::is_floating_point_v, "Real must be a floating point type."); + using std::log; + using std::pow; + using std::ceil; + using std::sqrt; + auto n_ = static_cast(n); + if (n < 0) + { + // relative error grows as 2*5.828^-n; take 5.828^-n < eps/4 => -nln(5.828) < ln(eps/4) => n > ln(4/eps)/ln(5.828). + // Is there a way to do it rapidly with std::log2? (Yes, of course; but for primitive types it's computed at compile-time anyway.) + n_ = static_cast(ceil(log(4/std::numeric_limits::epsilon())*0.5672963285532555)); + n = static_cast(n_); + } + // d can get huge and overflow if you pick n too large: + auto d = static_cast(pow(3 + sqrt(Real(8)), n)); + d = (d + 1/d)/2; + Real b = -1; + Real c = -d; + Real s = 0; + for (Real k = 0; k < n_; ++k) { + c = b - c; + s += c*generator(); + b = (k+n_)*(k-n_)*b/((k+Real(1)/Real(2))*(k+1)); + } + + return s/d; +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/color_maps.hpp b/libcxx/src/third-party/boost/math/tools/color_maps.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/color_maps.hpp @@ -0,0 +1,1943 @@ +// (C) Copyright Nick Thompson 2021. +// (C) Copyright Matt Borland 2022. +// 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_COLOR_MAPS_HPP +#define BOOST_MATH_COLOR_MAPS_HPP +#include // for std::clamp +#include // for table data +#include // for std::floor +#include // fixed width integer types +#include + +#if __has_include("lodepng.h") + +#include "lodepng.h" +#include +#include +#include + +namespace boost::math::tools { + +// In lodepng, the vector is expected to be row major, with the top row +// specified first. Note that this is a bit confusing sometimes as it's more +// natural to let y increase moving *up*. +unsigned write_png(const std::string &filename, + const std::vector &img, std::size_t width, + std::size_t height) { + unsigned error = lodepng::encode(filename, img, width, height, + LodePNGColorType::LCT_RGBA, 8); + if (error) { + std::cerr << "Error encoding png: " << lodepng_error_text(error) << "\n"; + } + return error; +} + +} // Namespace boost::math::tools +#endif // __has_include("lodepng.h") + +namespace boost::math::tools { + +namespace detail { + +// Data taken from: https://www.kennethmoreland.com/color-advice +template +static constexpr std::array, 256> extended_kindlmann_data_ = {{ + {0.0, 0.0, 0.0}, + {0.01780246283347332, 0.0008750907117329381, 0.01626889466306607}, + {0.03532931821571093, 0.001701802855992888, 0.03371323527689844}, + {0.05144940541667612, 0.0024840651967150905, 0.05129428731410766}, + {0.0645621163212177, 0.0032248645766847638, 0.06656239137344208}, + {0.07579594587865912, 0.0038635326859125735, 0.08040589852559868}, + {0.08560873187665013, 0.004465497712210337, 0.0932078727850277}, + {0.0942303824351094, 0.005050242022804749, 0.10546097842833466}, + {0.10126270743754426, 0.005684892741078179, 0.1185281778831713}, + {0.10670728559557496, 0.006372379780229372, 0.1327264977880264}, + {0.11057848107867363, 0.00711002225409038, 0.1481009557210271}, + {0.11345334766875653, 0.007801930722079915, 0.16375632363209905}, + {0.11546967754116774, 0.008551159105416175, 0.17919646921236213}, + {0.11670723282215431, 0.009290109551844812, 0.19453816576504604}, + {0.11719317716660224, 0.010053390003759367, 0.2096941755954832}, + {0.11698590922074067, 0.010738982214965748, 0.2248153138735493}, + {0.11610841583017484, 0.011423659103765034, 0.2397105899482299}, + {0.11462189563389044, 0.012116630983625478, 0.2543011097912221}, + {0.11260886490150057, 0.012821489721377753, 0.26850817678211986}, + {0.11014892407081325, 0.013468369062412165, 0.28238564749171374}, + {0.1073826713115642, 0.014119392392571815, 0.29573128232180523}, + {0.10439994774781663, 0.014757514745798027, 0.3086071932061514}, + {0.10102122555390916, 0.015343280218838306, 0.3215039849422961}, + {0.0973378808050489, 0.015957600087593806, 0.33424777423118057}, + {0.09343083659118528, 0.016584962806154634, 0.34680083232754255}, + {0.08930170392567455, 0.01713482653380763, 0.35927335578767955}, + {0.08525050060408929, 0.0177409908749586, 0.3713432638745381}, + {0.08133294699659654, 0.018315663017042745, 0.3831259644824107}, + {0.07770620978910117, 0.018846472161798116, 0.3945981112365364}, + {0.07453843004300356, 0.019323310547852572, 0.4057423733826484}, + {0.07234014248177378, 0.019905434286220342, 0.4162427930814269}, + {0.07070739337749535, 0.020358202603665252, 0.4265710517267966}, + {0.06795561424010746, 0.020880774373512326, 0.4372263626095861}, + {0.05495344243231267, 0.02153229240969933, 0.4511422122889977}, + {0.03272243214743511, 0.022251621841318136, 0.4663539858995716}, + {0.022542079629107543, 0.030087469482649072, 0.47217057965768244}, + {0.022458068304623265, 0.043510017517847034, 0.47110682779300844}, + {0.022335095562005403, 0.057612064160193856, 0.4678570071198978}, + {0.022116548807623634, 0.07134877081764332, 0.46268236332653717}, + {0.021827538746008197, 0.08452599623053175, 0.4558745921468776}, + {0.02152986717396973, 0.09703540427752388, 0.44774032508967526}, + {0.02094627101890751, 0.1088025513135693, 0.4387215006543877}, + {0.02045606049512309, 0.11985098869691474, 0.4289709820913745}, + {0.02004833311662032, 0.13019611448976093, 0.418764250948481}, + {0.019665629961975118, 0.13987346436551024, 0.4083506364708954}, + {0.019207577360338738, 0.14893167904386712, 0.39794947927856517}, + {0.018537140772831598, 0.15742727919356447, 0.38774823408835746}, + {0.01809424185998195, 0.16542627229987475, 0.3776911843959934}, + {0.01766141281376398, 0.1729786761988682, 0.3679328135626787}, + {0.01730286273144011, 0.18013597770041306, 0.3585022095429489}, + {0.016765513848818806, 0.18694679199155506, 0.3495097966827364}, + {0.016370126207011747, 0.19345202807035153, 0.3408690453055597}, + {0.016125995919003662, 0.19968741140572166, 0.3325877811713702}, + {0.015743835848192653, 0.20569130878531383, 0.32474294907403245}, + {0.01521780170762751, 0.21149505980303446, 0.31731795633577514}, + {0.014826523924383142, 0.21711739930665275, 0.31022963838193685}, + {0.01455583202575653, 0.22257980137551625, 0.3034714591858722}, + {0.014390286122102107, 0.2279012896050861, 0.29703484457819845}, + {0.014011918932944173, 0.23311039219433838, 0.29095765923101685}, + {0.013696545884500274, 0.23821209907670415, 0.28517017024142427}, + {0.013424574431729107, 0.24321964058367318, 0.2796599788292758}, + {0.013175868771764966, 0.2481448283322712, 0.27441390646690217}, + {0.01292963716411873, 0.2529982361555283, 0.2694181731856298}, + {0.012664284210951764, 0.25778935856659907, 0.2646585394556099}, + {0.012715975678052705, 0.26251129306552407, 0.26008624607226105}, + {0.012935277312292002, 0.26721180456135596, 0.25537236409530106}, + {0.013151828277929324, 0.2719132248379506, 0.25038669592493334}, + {0.013365797957379829, 0.2766141217472141, 0.24512715790174772}, + {0.013577263863962, 0.28131308067549815, 0.23959178395846548}, + {0.01378615567948453, 0.2860087090215386, 0.2337787381698218}, + {0.013992194922389659, 0.290699640854686, 0.22768632911662062}, + {0.014194831158161888, 0.2953845417355913, 0.22131302646406403}, + {0.014393175927633691, 0.3000621136791825, 0.21465748025951026}, + {0.014585935863149577, 0.3047311002377708, 0.20771854359069752}, + {0.014771346788489043, 0.3093902916806014, 0.2004952994228159}, + {0.015316330980203078, 0.314019615719643, 0.19303372895005055}, + {0.015485867479267465, 0.318655599270661, 0.18524675366655605}, + {0.015639979963365892, 0.32327849834847494, 0.17717467982889423}, + {0.015774461623191554, 0.32788734271858383, 0.16881795823876974}, + {0.01588440162820881, 0.33248123546361147, 0.16017753232003507}, + {0.016371319978387793, 0.3370394958269932, 0.15133715480703355}, + {0.016424021691114017, 0.34160094506458616, 0.14214299485979426}, + {0.01686035446719742, 0.3461250509254044, 0.13277234235578353}, + {0.016830214158745957, 0.35065150775079285, 0.12304027310946478}, + {0.017189890203442686, 0.3551393166240582, 0.11316410079747846}, + {0.0175057105195252, 0.35960835629733406, 0.10305638071018988}, + {0.017770106546070377, 0.36405841970084374, 0.09273371145052256}, + {0.01797534767005524, 0.3684894220401705, 0.08221895294189338}, + {0.018113811240203243, 0.37290140979305425, 0.07154410587314339}, + {0.01817830121675857, 0.37729457180004805, 0.060754926838460115}, + {0.018678925823257978, 0.3816479795981337, 0.05016037872247533}, + {0.01858851921615119, 0.38600461104105177, 0.039408863532102954}, + {0.018946886533322625, 0.39032256740422405, 0.0299653011886783}, + {0.019234421105765478, 0.3946241249528643, 0.022430553487672214}, + {0.023922664243633134, 0.39873762922211814, 0.019079643738415406}, + {0.032696329777136775, 0.40268821797442356, 0.01927104403025176}, + {0.04029295620970803, 0.40668863206181144, 0.019627058713507277}, + {0.0445051772107334, 0.4108066755028012, 0.019605221754402217}, + {0.05023033461306361, 0.4148702424589703, 0.019837552743924382}, + {0.05751407234865658, 0.4188712020471279, 0.01998429281648217}, + {0.06662959400279314, 0.42277996280066904, 0.020350820236973332}, + {0.07687976931053314, 0.42661141097115085, 0.02061535207978936}, + {0.08808647489550425, 0.4303590557627002, 0.02076563040362206}, + {0.10009395068503488, 0.4340168594615687, 0.020789592249385695}, + {0.11305049861381905, 0.43755751986676594, 0.021011622748947127}, + {0.1265170163106781, 0.440997674167719, 0.021092771828857385}, + {0.14064355039494827, 0.44431106175406876, 0.021367147770030247}, + {0.15509985051348987, 0.4475149894903065, 0.021487010699090946}, + {0.17002834364548297, 0.4505843077306851, 0.02179659002621885}, + {0.18517425344416824, 0.4535369003239919, 0.021939140218683366}, + {0.2005125857975878, 0.4563695433411364, 0.02190396156431214}, + {0.2161609253409036, 0.459058907077816, 0.022051019673724737}, + {0.23193556411255867, 0.46162347760839634, 0.022009915914684375}, + {0.24793825797637276, 0.4640413181325817, 0.022151516874270333}, + {0.26412488725558203, 0.4663117397956657, 0.022482129570858295}, + {0.2803606712938716, 0.4684536010278855, 0.02261757765237555}, + {0.296637938074376, 0.47046590244093683, 0.0225494975844844}, + {0.31302849974924285, 0.47232989838033596, 0.022671977207001336}, + {0.3294300351704986, 0.4740642435062818, 0.0225864988960952}, + {0.3459012409505257, 0.475652007794974, 0.022699138396783294}, + {0.3624157976623936, 0.4770953196310352, 0.02302034933556348}, + {0.37889809766361104, 0.47841222515883747, 0.02313701355469799}, + {0.39534430178227603, 0.4796035027123265, 0.023043880179838123}, + {0.41179003849439816, 0.48065635396111855, 0.023172253504396497}, + {0.42818080415815335, 0.4815874024816033, 0.02309359581707615}, + {0.4445420271983608, 0.48238619597444804, 0.02325212759648816}, + {0.46083197524945735, 0.48306807922963163, 0.023208795520823236}, + {0.477066527169599, 0.4836251567552959, 0.023421052378504333}, + {0.49330882182932195, 0.48404259768616237, 0.02351307077213582}, + {0.5101341569176142, 0.4841269939874597, 0.02474700862397102}, + {0.5276083798119485, 0.4838477594175364, 0.025493073746431755}, + {0.5457675808274345, 0.4831581006215279, 0.026232895897136985}, + {0.5646323060116551, 0.48201590123588106, 0.02698278973250526}, + {0.5842072626155643, 0.4803756805891137, 0.02819024072200311}, + {0.6045266103850581, 0.4781882736718959, 0.028981783530659853}, + {0.6255919000983664, 0.47539734049324306, 0.02979697562508809}, + {0.6473800379403847, 0.47195081918673226, 0.031044032153032777}, + {0.6699068794902967, 0.4677815168730453, 0.03227150878455887}, + {0.6932001837200186, 0.46280562738356607, 0.03304163325898518}, + {0.7171335868744761, 0.4569883986979126, 0.034530544840017025}, + {0.7417906038430161, 0.4502061037239105, 0.035463650965058914}, + {0.7670484685327643, 0.4424084941387379, 0.03656485419201359}, + {0.7927923527600884, 0.4335431093764269, 0.038110096816360045}, + {0.8190538618349916, 0.4234676649184017, 0.03921665123224114}, + {0.845635547462146, 0.4121565351852396, 0.040504503887090086}, + {0.8724273941843113, 0.399532161591502, 0.04177752341186975}, + {0.8993071734347423, 0.38551601321374424, 0.04288218868653492}, + {0.9259938049276442, 0.3701581656966096, 0.0443028413484576}, + {0.95240006413475, 0.3533630589382493, 0.045512688804357486}, + {0.9573302263433631, 0.356573181832402, 0.10485176035519561}, + {0.9593762651267365, 0.3625998458005728, 0.14695621074226434}, + {0.9609003469257634, 0.3691267599755898, 0.17919496865835138}, + {0.9621556849513918, 0.37591169845314204, 0.20542079832986643}, + {0.9631644672895096, 0.3829300179877212, 0.22750885439024698}, + {0.964095792386828, 0.39002737893200634, 0.24632170224175154}, + {0.9648793311938041, 0.3972605885272423, 0.26263686798960245}, + {0.9655077342802952, 0.40462643797868664, 0.2769429329997333}, + {0.9660587860054425, 0.41205105448230417, 0.2895251327064319}, + {0.9665994127853909, 0.4194734509128834, 0.3006180918171856}, + {0.9671516506858119, 0.4268421716026803, 0.31083965567414507}, + {0.9677276657441855, 0.4338269194529401, 0.3245165284653611}, + {0.968504522437997, 0.44042580568421147, 0.33966351784918897}, + {0.9692871734210263, 0.4467701596827656, 0.3565758064426104}, + {0.9702540772004374, 0.45269977328586647, 0.37534236971527246}, + {0.9712179772934669, 0.45837869586824703, 0.39562556319119124}, + {0.9722317464026985, 0.4637976195449472, 0.41693497643767774}, + {0.9732263821032568, 0.46903038930488866, 0.438958844869214}, + {0.9742462614418889, 0.4740678468975709, 0.46139896139324615}, + {0.9750871661398574, 0.4790671203997809, 0.48416548522290065}, + {0.9754147288760454, 0.4842669015553663, 0.5072296427052377}, + {0.9756180439862371, 0.48941330245201103, 0.5302646150938287}, + {0.975842338006588, 0.49442037450446213, 0.5531433026983604}, + {0.9761081874822527, 0.4992854244201668, 0.5758237590340696}, + {0.9763112164847584, 0.5040877038326032, 0.5983033566276463}, + {0.9765888685497933, 0.5087442572698033, 0.6205369331248914}, + {0.9767110237468087, 0.5134164774149236, 0.642535156682777}, + {0.9769336559396905, 0.5179413879764756, 0.6642639445578681}, + {0.97714593184672, 0.5224000733132641, 0.6857254497050739}, + {0.9773578783172437, 0.5267928368807481, 0.7069126158797037}, + {0.9775785758579868, 0.5311203562318053, 0.7278211218920855}, + {0.9778162437300041, 0.5353836351919077, 0.7484486916246914}, + {0.9779596006498089, 0.5396657970725794, 0.7687562310971295}, + {0.9782535179019477, 0.5438049537609145, 0.7888137943375886}, + {0.9784674751508416, 0.5479668227414403, 0.8085390020370261}, + {0.9786094914349676, 0.5521542299695001, 0.8279128914232778}, + {0.978802652274665, 0.5562873882925448, 0.8469838693949315}, + {0.9790515109370453, 0.5603687136966451, 0.8657552952207226}, + {0.9792467908639096, 0.5644843583828043, 0.884150643372716}, + {0.979395255578016, 0.5686380796177348, 0.902153526529961}, + {0.9796145283071062, 0.5727494207545081, 0.9198418221195682}, + {0.9797975302508571, 0.5769060493757885, 0.9371197812002375}, + {0.9799502605574898, 0.581112131921931, 0.9539723226660747}, + {0.9802283260758732, 0.5851928436561017, 0.9708243730936762}, + {0.9738084905670951, 0.5944815591203718, 0.9806690105429076}, + {0.9601472511008894, 0.609371508764095, 0.9813253841505029}, + {0.9478379001570983, 0.6230463820702153, 0.9820290537295789}, + {0.9366516898009005, 0.6357832537301149, 0.9826041912890565}, + {0.926560589527891, 0.647678912888478, 0.9831062604022219}, + {0.917620083682068, 0.6587517109196314, 0.9837253021469462}, + {0.9095356769991322, 0.6692646118840428, 0.9841128740419515}, + {0.9024501226204644, 0.6791460846603548, 0.9845858176159193}, + {0.8962465735427142, 0.6885075377321772, 0.9850533329169425}, + {0.8908928004592865, 0.6973907065167453, 0.9855589168505193}, + {0.8862829519968738, 0.7058867599470733, 0.9859932359170603}, + {0.8823207949642251, 0.7140769556818014, 0.9862329988164894}, + {0.8791184292035925, 0.7218801604700443, 0.9866187467737363}, + {0.876573928783208, 0.729373858466773, 0.9870301106239344}, + {0.8745946211951233, 0.7366283504729199, 0.9873335856528983}, + {0.8732148850190337, 0.7436116593104639, 0.9877197983463958}, + {0.8723449314581001, 0.7503888453166406, 0.9880489690947681}, + {0.871958051266914, 0.7569736347405297, 0.988343697831869}, + {0.8720269380214271, 0.7633787505197638, 0.9886267968388239}, + {0.872524018161346, 0.7696159559904953, 0.9889212756286642}, + {0.8734217880637981, 0.7756960853936921, 0.9892503149320232}, + {0.8746431257299938, 0.7816733363052604, 0.989454685042798}, + {0.8762135041761673, 0.7875116467112275, 0.9897367010924504}, + {0.878107018520635, 0.7932193523390607, 0.9901203210173019}, + {0.880203346150829, 0.798890286193674, 0.9902546300884126}, + {0.8825765528541782, 0.8044436600674107, 0.9905332036399778}, + {0.885156863735442, 0.8099282584935031, 0.9907909519806376}, + {0.8879236719089479, 0.815348848661961, 0.9910495231926625}, + {0.890857185433795, 0.8207097106633178, 0.9913312422092354}, + {0.8939377339865693, 0.8260147864401665, 0.9916599021959583}, + {0.8970530658331168, 0.8313161221171385, 0.9919275427432451}, + {0.8995688302115749, 0.8368229403489976, 0.9920969557419316}, + {0.9019890025620054, 0.8423510813517494, 0.9923144994581347}, + {0.9041189751589628, 0.8479541784289291, 0.992640232246134}, + {0.9058973525369924, 0.8536784698518803, 0.9928660652275899}, + {0.9073992963543378, 0.8594712199063077, 0.9931944239168621}, + {0.9086279741575543, 0.8653520270780298, 0.993459751831716}, + {0.9096655096337553, 0.8712669417189164, 0.9938665873784843}, + {0.9105035986931571, 0.8772607309343242, 0.9940839016190398}, + {0.9112280528710646, 0.8832787634425558, 0.994319531984062}, + {0.9118856791641718, 0.8893033549283489, 0.9945972975280256}, + {0.9125160989249034, 0.8953200253413901, 0.994937094070283}, + {0.9131521110159186, 0.9013364967475651, 0.9952011954414587}, + {0.9138294807228358, 0.907320474034156, 0.9955652276122916}, + {0.9145934489263029, 0.9132934622711121, 0.9957533433444864}, + {0.9154721624193913, 0.9192261671429544, 0.9959406615249712}, + {0.9165162261152294, 0.9251182443147156, 0.9960169412606291}, + {0.9177621627085478, 0.9309558310395318, 0.9960174468690394}, + {0.9192000090908993, 0.9367250258396427, 0.9960919139576695}, + {0.920883428013182, 0.9424235334496841, 0.9961424557894082}, + {0.922780751860871, 0.9480459375852194, 0.9963020587068238}, + {0.9250092107169314, 0.9535821762261815, 0.9963856518750184}, + {0.9275356684808912, 0.9590268903215627, 0.996529920191361}, + {0.9304408284972104, 0.9643654252860402, 0.996676965947248}, + {0.9338239050383462, 0.9695749605431102, 0.9967943472276378}, + {0.9376406019134518, 0.97465362230454, 0.9970154826822965}, + {0.9421630827040032, 0.9795433335221727, 0.9971921136372807}, + {0.9473578426139436, 0.9842358767121905, 0.9974820554788658}, + {0.9536370282349044, 0.9886296256370345, 0.9977639971129887}, + {0.961277626215249, 0.9926367016857381, 0.9981081638729355}, + {0.9706782225332987, 0.996129580837985, 0.9985982664103797}, + {0.982998706722621, 0.9987706424331216, 0.9991799080785383}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> kindlmann_data_ = {{ + {0.0, 0.0, 0.0}, + {0.017846074066284252, 0.0009158559874893362, 0.016056295374498146}, + {0.03572864786642702, 0.0017291229250328806, 0.03302143519907636}, + {0.05220741890989234, 0.002509857835251149, 0.04992588792612627}, + {0.06579320887318146, 0.0031951554951018895, 0.06457251900523656}, + {0.07760358429899875, 0.003724534058880596, 0.07776920342353211}, + {0.08789358790850602, 0.004294574826048965, 0.0897198393739522}, + {0.09712335630575433, 0.004842625166895046, 0.10086394984030281}, + {0.10521029512901023, 0.005373953338851922, 0.11223547956850252}, + {0.11206559338234914, 0.005946169553289608, 0.12432777397900399}, + {0.11777117178354526, 0.006573754050745371, 0.13716171084354922}, + {0.12274092212849055, 0.007190967398920267, 0.15010297798342745}, + {0.12721746956233745, 0.007765930791621213, 0.1628260628965371}, + {0.13120675065695167, 0.008361505755992952, 0.17526973313157249}, + {0.13476383339950823, 0.008965513206303781, 0.1874768588728739}, + {0.1379416850964659, 0.009551513984339633, 0.1995014270040738}, + {0.14078915018940993, 0.010080340518883863, 0.21140807652685528}, + {0.14328800070233533, 0.010654292784112113, 0.22305086172802313}, + {0.1454925697745392, 0.011223945666441406, 0.23450000042491753}, + {0.14744975665550916, 0.01172962096468942, 0.24583568409411483}, + {0.14915607230438568, 0.012265761398485226, 0.2569125532571454}, + {0.15064370028657081, 0.012825896285586958, 0.2678146545485108}, + {0.15192214754665317, 0.013340464397739584, 0.27899859238410224}, + {0.1529680602403743, 0.01383169406084123, 0.29046429953683084}, + {0.15375355050540976, 0.014469905953793126, 0.3019580272214856}, + {0.1542908116514455, 0.014991396474282258, 0.313852441550019}, + {0.15455584740256964, 0.015566553274758022, 0.3258902207027679}, + {0.15454470889937796, 0.01619279407587136, 0.3380624435826929}, + {0.15424074730776174, 0.01677345343135211, 0.3504951935746775}, + {0.15362513362574176, 0.01730005530615292, 0.3631847587056686}, + {0.15272770714157807, 0.017955417060815455, 0.3758470094405716}, + {0.15150259153104584, 0.018542834077193353, 0.3887481108848792}, + {0.14996750216169222, 0.019150121523940637, 0.4017384234617481}, + {0.1481223688773872, 0.019769579646988222, 0.4148055969839783}, + {0.14596849097254724, 0.02039268583437749, 0.42793691410477086}, + {0.14350871584895447, 0.021010135344188375, 0.4411193724446502}, + {0.14081675084553444, 0.021716621813360978, 0.4541885105212106}, + {0.13777021342781093, 0.022293516296525755, 0.4674318891638602}, + {0.13452661891393936, 0.022940593473192553, 0.48053217251642305}, + {0.13103033265010522, 0.023541432666866674, 0.49362776425328886}, + {0.12740778581316103, 0.024195126427194676, 0.5065484866366465}, + {0.12359314328868806, 0.024781571830105195, 0.5194370648731684}, + {0.11974712167592705, 0.025403149292983516, 0.5321219022221657}, + {0.1159404877051333, 0.0260531205128538, 0.5445888017818501}, + {0.11209206787148834, 0.02660656407054731, 0.5569877413493692}, + {0.10842241040440373, 0.02717266184945997, 0.5691469684334989}, + {0.1050253848722921, 0.027746789078543728, 0.5810568608426063}, + {0.101999609017976, 0.02832560680437759, 0.5927097735404816}, + {0.09922826785261996, 0.028779550542447317, 0.6042668353483279}, + {0.09722602817414985, 0.02936178919960733, 0.6153923636579981}, + {0.09528935573037353, 0.029890777438344337, 0.6264955320241609}, + {0.0930823731478326, 0.030438044833523397, 0.6376509097116411}, + {0.0781891239412737, 0.031121586300131683, 0.6525577781586464}, + {0.05857961917089497, 0.031924832133126, 0.6676204841351329}, + {0.03284057845765246, 0.03469657698669593, 0.6813738713631898}, + {0.032679442069734624, 0.04697971049610799, 0.6849034147771731}, + {0.033207560139530704, 0.05995495438213944, 0.6868241583911188}, + {0.033317187200492364, 0.07300667062971217, 0.6874759761236308}, + {0.033087445334472984, 0.08601513051125326, 0.6868754153808352}, + {0.03265381069556877, 0.09888929701373608, 0.6850522082772128}, + {0.03277467744530855, 0.11161079522124029, 0.6818870111240353}, + {0.0325022291000698, 0.1240111603824268, 0.6777553638535389}, + {0.032066045593596146, 0.13606903293962488, 0.6727110790151253}, + {0.03227600851941834, 0.14780096691985975, 0.6666596846794193}, + {0.031649331579416705, 0.15909372791133777, 0.6601264529755937}, + {0.03155801725217711, 0.17001566158899392, 0.6528643797965168}, + {0.0310838330844518, 0.18051935094604918, 0.6452318387821873}, + {0.030432973047734187, 0.19062325974122588, 0.6372784105620277}, + {0.030338619295788537, 0.20036054096647732, 0.6289128168374558}, + {0.029853960367767295, 0.20971568331952556, 0.6204629562646412}, + {0.02966850358552374, 0.2187242415010579, 0.6118301548875958}, + {0.02882374869999708, 0.2273866229818785, 0.603314553849001}, + {0.028500638040224537, 0.2357441994433061, 0.5946825020006182}, + {0.028245919974351025, 0.24380777892174738, 0.5860925629625072}, + {0.02760771294131195, 0.2515940717685919, 0.5776869157187913}, + {0.02717197158834595, 0.25912806556578544, 0.5693601411266609}, + {0.026982221792628543, 0.266427065214078, 0.5611305112918692}, + {0.026559642397133442, 0.27350794101395076, 0.5531226098917067}, + {0.02644787880084816, 0.2803874742418932, 0.5452351099365369}, + {0.02564842515734134, 0.2870852596241667, 0.5376830481507792}, + {0.02570596827933925, 0.29360869815637475, 0.5301627048805485}, + {0.025105902288682952, 0.2999809743840178, 0.5229767137199569}, + {0.024870375536254246, 0.30620709089548, 0.5159307080617925}, + {0.024495137563131944, 0.3123034508268453, 0.5091188274555094}, + {0.02397954323509251, 0.3182816255246543, 0.502536537756261}, + {0.023829708770758788, 0.32414426165027227, 0.4960985638991457}, + {0.023532604704116965, 0.32990776857516413, 0.48988582950117815}, + {0.02307993829976581, 0.3355813090448093, 0.4838916171846975}, + {0.022979595210601424, 0.3411632670690572, 0.47803935490382515}, + {0.022707635361622264, 0.3466702701862077, 0.4723976815702628}, + {0.022250414084789737, 0.352109624090965, 0.4669584702823865}, + {0.022124477998067993, 0.3574761812445124, 0.46165444016667906}, + {0.021791069977336153, 0.3627869887174417, 0.45654262929804507}, + {0.021776256319502838, 0.3680348834809229, 0.45156215250307846}, + {0.02152936248024083, 0.3732373044965933, 0.44676258718151424}, + {0.02158822978060292, 0.37838527471660577, 0.44208955676541317}, + {0.021388037427047302, 0.38349668536630105, 0.43758535324043873}, + {0.020906126379826747, 0.3885760631680783, 0.4332402802381849}, + {0.02070114401850818, 0.3936120031480679, 0.4290098739833766}, + {0.020774708005350834, 0.3986070226842801, 0.4248945065220385}, + {0.020526909471275397, 0.4035800658477305, 0.4209222889365068}, + {0.01993018897938756, 0.4085347069464005, 0.4170831873583663}, + {0.02020289046425452, 0.4134392235922892, 0.41332502021802126}, + {0.020207032023267582, 0.41834155873012324, 0.40954621812568487}, + {0.020205716119178502, 0.42324888777657366, 0.4055896035873459}, + {0.020829051716263414, 0.42814253234088623, 0.4014443452785458}, + {0.020817169253550774, 0.4330580290829061, 0.3971329152020192}, + {0.02143446555544063, 0.437958395126164, 0.3926385324661419}, + {0.02140951927285399, 0.44287991873506705, 0.38796855906767097}, + {0.021375101041108045, 0.4478037488631326, 0.3831160408679206}, + {0.021978368208421244, 0.45271034115960945, 0.3780894735135355}, + {0.021925941019470395, 0.45763704847590275, 0.372873157602702}, + {0.022518324495068114, 0.4625451606740822, 0.3674890229173533}, + {0.0224439650744986, 0.4674727059721964, 0.3619056954025697}, + {0.02302262600613305, 0.47238034113781563, 0.3561610413615427}, + {0.022921527380028887, 0.4773067430685342, 0.350207729192515}, + {0.023482745772902724, 0.4822119663418752, 0.34409988145088766}, + {0.02334902491772799, 0.48713531181669306, 0.3377738746272117}, + {0.023887996465323004, 0.4920362610259304, 0.33130046883268455}, + {0.023714510501347055, 0.4969547158806737, 0.32459934406811614}, + {0.024225153974701766, 0.5018496124079483, 0.3177583627477745}, + {0.024723266142386315, 0.5067407770624851, 0.31073519425545465}, + {0.02447812509827954, 0.5116485921195848, 0.3034698224412634}, + {0.02493648885622696, 0.5165312197695955, 0.2960768968333586}, + {0.0253764023681478, 0.5214089374064284, 0.28850111378145044}, + {0.025795626075147713, 0.5262813821767296, 0.28074244497417117}, + {0.025421474545393858, 0.5311694950761902, 0.2727216863169472}, + {0.025780309667251394, 0.53603048885089, 0.2645922829614648}, + {0.02610999696637235, 0.5408852158877796, 0.25628033494817076}, + {0.026407437583934296, 0.5457333806719771, 0.2477862504464216}, + {0.02666932808870506, 0.5505747064434545, 0.2391105880601489}, + {0.02689217252655957, 0.5554089359982296, 0.2302540772313253}, + {0.027072298940817408, 0.5602358325123109, 0.22121764273058586}, + {0.027205880727598008, 0.5650551803951163, 0.2120024343570966}, + {0.027288963146258696, 0.5698667861810437, 0.20260986337352}, + {0.028204203304642753, 0.5746482086659772, 0.19318007629151898}, + {0.028188559261174452, 0.5794437480873181, 0.18344751604265283}, + {0.0281103207218881, 0.5842311106814237, 0.17354484850307106}, + {0.028896130485080208, 0.5889876510327495, 0.16364429504261102}, + {0.028695320134244477, 0.5937583183864393, 0.1534244803870241}, + {0.029380675523176917, 0.5984978909930776, 0.14324398649586118}, + {0.029041895792470927, 0.6032517278747106, 0.13273404723048013}, + {0.029612109748158165, 0.6079743365463844, 0.12231515476812047}, + {0.030127173837479853, 0.6126885119214123, 0.1118109733754355}, + {0.029563230689198295, 0.6174173890888045, 0.10096978844729684}, + {0.029944189232757292, 0.6221151405821017, 0.09035027988372307}, + {0.030261789165931138, 0.6268049184840729, 0.07974541336580176}, + {0.030514080739125825, 0.6314869729283614, 0.06921734345076924}, + {0.030699652650745195, 0.6361616116842398, 0.05885329347452114}, + {0.0308177148230897, 0.6408292087724975, 0.04877724313606999}, + {0.03086818674766468, 0.6454902160815501, 0.03915677764354433}, + {0.03197034466002908, 0.6501217563441514, 0.031444380194868886}, + {0.046293996677654235, 0.6544720579771781, 0.031637291074855106}, + {0.058794558570863804, 0.6588271549701028, 0.0317521581310916}, + {0.06503863628200135, 0.6633055777623768, 0.03209873268943441}, + {0.07023149742711651, 0.6678120145394701, 0.03183433002082528}, + {0.0767138128414942, 0.6722807177648771, 0.032132076596637124}, + {0.08432067120858369, 0.6767139870108101, 0.032338563602709626}, + {0.09294277780722546, 0.6811085964562938, 0.032444071987208487}, + {0.10305233592409935, 0.6854378106573311, 0.03307401108271617}, + {0.11331609119127764, 0.6897459817142692, 0.03295480891791886}, + {0.12476614069574826, 0.6939830479703625, 0.033353619722170935}, + {0.13673711440841982, 0.6981699856866227, 0.03362590965526557}, + {0.1491636843492167, 0.7023042408994585, 0.033762275984369046}, + {0.16199129317074465, 0.706383361101949, 0.03375336199700755}, + {0.17553308151438088, 0.7103815097863063, 0.03426353710068628}, + {0.18933948484375165, 0.7143200103636559, 0.03462289684303036}, + {0.20338652270943824, 0.7181967154976012, 0.03482214714504671}, + {0.21765378276012448, 0.7220095660591789, 0.0348520554844732}, + {0.23212369587552023, 0.7257565893785501, 0.03470346402383256}, + {0.24702985279407214, 0.7294127796374531, 0.03507444712661609}, + {0.2620775705935113, 0.7329996606625439, 0.035262260320886224}, + {0.2772591134255436, 0.7365155484918555, 0.03525791814557077}, + {0.2927712616124238, 0.7399360689986639, 0.035780536388425606}, + {0.3083781576598969, 0.7432827601590504, 0.03610724156995657}, + {0.3240763123743059, 0.746554228453955, 0.036229314118799705}, + {0.33986207442019495, 0.7497491625691519, 0.03613819725600252}, + {0.3558907708679886, 0.7528442021403842, 0.036581966518590206}, + {0.3718311425153303, 0.7558826557986548, 0.036046421794990055}, + {0.38813047246050614, 0.7587977057098403, 0.03681458696854892}, + {0.4043371221939297, 0.7616541995826684, 0.03658736257615303}, + {0.42072356025646707, 0.7644081013195043, 0.03690635392025313}, + {0.43714739423907745, 0.7670803847862102, 0.03699298731846738}, + {0.45360699836908186, 0.769670380372701, 0.03683987811183992}, + {0.4702051248974935, 0.7721571183110766, 0.03724796925537228}, + {0.4868227556665157, 0.7745610930844775, 0.0374172194555026}, + {0.503458588002791, 0.7768819000929792, 0.03734086718256391}, + {0.5201979969654729, 0.779099877137358, 0.03784362950139135}, + {0.5368601535092656, 0.7812537776842732, 0.03726439057607977}, + {0.5536883905115004, 0.7832866691953926, 0.0381141962950549}, + {0.570436957512631, 0.7852552273306327, 0.03787015508826886}, + {0.5872524511360537, 0.787122879084239, 0.03822846891183527}, + {0.604057585524296, 0.7889082049024678, 0.03833696358570872}, + {0.6208512632987039, 0.7906113236317394, 0.03819060762615894}, + {0.6376323001265665, 0.7922323958682111, 0.03778469202199975}, + {0.654448292617523, 0.7937561555975436, 0.03800948341735075}, + {0.6712409304097, 0.7951995038068883, 0.03798214896623336}, + {0.6880499867367655, 0.7965485565944844, 0.038610111469974305}, + {0.7047891048851465, 0.7978328175913231, 0.03807498680487568}, + {0.7215350356575515, 0.7990249426739793, 0.03820456984010566}, + {0.7382756146491691, 0.8001275152547487, 0.03902092612392253}, + {0.7549478024082115, 0.8011661514812047, 0.03865607007534288}, + {0.7716059891201252, 0.8021178857956822, 0.038989380941084874}, + {0.7882203132421456, 0.8029955440735611, 0.03908165535934637}, + {0.8047902362352904, 0.8037997989252117, 0.03893065650816213}, + {0.8215523268463777, 0.8044555316790379, 0.03926557049926157}, + {0.8387398480023723, 0.8048817689898747, 0.04067065212316836}, + {0.856341544941598, 0.8050796719349672, 0.04123085284140562}, + {0.8743768083538662, 0.8050267567672601, 0.0419261583900458}, + {0.8928528884736874, 0.8047076768017004, 0.0427644722591047}, + {0.911776412947498, 0.8041062177363495, 0.04375041022498651}, + {0.9311533128855841, 0.8032052518345966, 0.044885135667359986}, + {0.9510015669358057, 0.8019861521093661, 0.04532603899543026}, + {0.962930103481011, 0.8014439331866959, 0.22169249312004036}, + {0.9683410354743099, 0.8024669332735311, 0.3358446858430373}, + {0.9719380800534977, 0.8044065772211566, 0.4114102805053895}, + {0.9746751561332506, 0.8069447701330453, 0.46819081680773716}, + {0.9768136632655356, 0.8099358552525316, 0.5140546510678895}, + {0.978649037790159, 0.8132574705132256, 0.5522569503355605}, + {0.9802036704451057, 0.8168594951941832, 0.5851451968636262}, + {0.981554091047551, 0.8206924722262127, 0.6139795814385243}, + {0.9827732625825781, 0.8247142837530934, 0.6395746026568098}, + {0.9839157453834834, 0.8288914274285599, 0.6625186328985215}, + {0.9848784092487323, 0.8332318824714189, 0.6834911738162105}, + {0.9858320115191356, 0.8376808147738173, 0.7025706724123436}, + {0.9866558657916994, 0.8422559436774792, 0.7202399867839039}, + {0.9873677995679001, 0.8469433249862409, 0.7366844886107697}, + {0.9881805379141889, 0.8516804941618812, 0.7518089864773918}, + {0.9887611047789485, 0.8565442781873747, 0.7661909960366566}, + {0.9894043443414985, 0.8614528824718757, 0.7795879261784779}, + {0.9900758649057856, 0.8664087680409848, 0.7921604870664645}, + {0.99059092673338, 0.8714545088111433, 0.8041942791071222}, + {0.9911277189421445, 0.8765391108526217, 0.8155756474332213}, + {0.9916061462381213, 0.8816790723671002, 0.8264519900822266}, + {0.9922158985563451, 0.8868207617131697, 0.836709699896381}, + {0.9925679440918894, 0.8920625188742286, 0.8467473851492474}, + {0.9931424279738416, 0.8972751802406753, 0.8561933859696547}, + {0.9935217736048007, 0.9025652348682511, 0.8654402820837326}, + {0.9938879084327678, 0.9078821573987383, 0.874370338308405}, + {0.99427342946785, 0.9132148454645382, 0.8829927351962013}, + {0.9947111506654817, 0.918552416162813, 0.8913160852881722}, + {0.995056938233056, 0.9239302650640105, 0.8994722486725081}, + {0.995512287532556, 0.9292939740928252, 0.9073439419102849}, + {0.9959250022023757, 0.9346812618630085, 0.9150611281410694}, + {0.9961274042213023, 0.9401333891345969, 0.9227518397011023}, + {0.9965143545143408, 0.9455470167979051, 0.9301752047442942}, + {0.996922153842586, 0.9509629844614244, 0.9374587708548032}, + {0.9971731694726661, 0.9564250004713418, 0.9447286698401807}, + {0.9976825719783714, 0.9618265695993463, 0.9517442599956717}, + {0.9978661370132459, 0.967313947090583, 0.958874650466398}, + {0.9983489942212443, 0.972728972574113, 0.9657569772496776}, + {0.9985297770627254, 0.9782208004653724, 0.9727591013871136}, + {0.9988366714262512, 0.9836818403108719, 0.9796396969161855}, + {0.999287652981863, 0.989107488582374, 0.9864006969015998}, + {0.9994697671436109, 0.9945977204425903, 0.9932874563643866}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> inferno_data_ = {{ + {0.0014619955811715805, 0.0004659913919114934, 0.013866005775115809}, + {0.0022669056023600243, 0.001269897101615975, 0.018569490325902337}, + {0.003299036110031063, 0.0022490183451722313, 0.024239243465136288}, + {0.004546896852350439, 0.0033918841632656804, 0.03090851258977682}, + {0.006006105056993791, 0.004692061241092744, 0.038558624443389096}, + {0.007675918804434457, 0.006135891503856028, 0.046835705273408614}, + {0.009561203394731096, 0.0077131160510677, 0.05514393874236257}, + {0.011662968995142865, 0.0094169153553472, 0.06345998081431048}, + {0.013994707785115502, 0.011224701548363442, 0.07186110007643282}, + {0.01656105637139426, 0.01313595377716254, 0.08028228905271992}, + {0.019372742788596516, 0.01513271743178829, 0.08876637381708319}, + {0.02244719411002579, 0.017198996785303594, 0.09732759285010725}, + {0.02579282311826555, 0.01933074318511054, 0.10592963918696552}, + {0.029432387489373633, 0.02150303695278668, 0.11462190156591848}, + {0.03338491092042817, 0.023701776954208033, 0.12339694246694158}, + {0.03766747608151851, 0.025920506649278047, 0.13223096637532075}, + {0.042253067017337005, 0.028138807463796305, 0.1411412582171954}, + {0.04691458399133113, 0.030323540520811973, 0.15016326468244964}, + {0.05164425209311529, 0.03247382729611796, 0.15925458396315}, + {0.05644871419547314, 0.03456857075460381, 0.16841357852522199}, + {0.06134044494312783, 0.03658982977294056, 0.17764292167289156}, + {0.06633085137688166, 0.038503594004715896, 0.18696190141292804}, + {0.07142826458096291, 0.04029339894981024, 0.19635286429314014}, + {0.07663702254956387, 0.04190461115902603, 0.2057992341013456}, + {0.08196142528164385, 0.043327451450508585, 0.2152881892106146}, + {0.087411214696131, 0.04455560411873583, 0.22481357132253754}, + {0.09298959953890884, 0.04558246689176038, 0.23435752319694075}, + {0.0987024276165075, 0.0464015612109181, 0.24390490595057124}, + {0.1045507907963224, 0.04700744862572622, 0.2534298623464375}, + {0.11053667232221573, 0.04739845362551404, 0.26291322780905574}, + {0.11665600122383982, 0.04757339371302694, 0.27232119603015154}, + {0.12290731198945251, 0.04753536748517837, 0.2816231724086292}, + {0.12928523040832837, 0.04729230240096718, 0.2907885083783503}, + {0.13577751583663375, 0.046855310502846824, 0.29977552118778034}, + {0.14237847430795506, 0.04624117675574093, 0.30855378680836465}, + {0.1490727384829781, 0.04546721023082908, 0.3170848511067041}, + {0.1558507266503708, 0.044558026492337664, 0.32533901695859424}, + {0.1626889760379725, 0.0435530737190721, 0.3332771435961689}, + {0.16957421944883505, 0.042488139902889556, 0.3408733080618529}, + {0.17649322158660016, 0.04140091975980204, 0.3481113785987225}, + {0.18342846019226636, 0.04032795978956832, 0.35497062509269495}, + {0.19036746731312684, 0.03930776663057157, 0.36144755914871207}, + {0.19729670678394517, 0.03839881405885271, 0.3675348910966813}, + {0.20420970925948218, 0.03763066869776516, 0.3732386865741054}, + {0.21109495319112997, 0.0370286796745015, 0.3785631007654439}, + {0.21794820252834113, 0.036613674395490264, 0.38352155568816976}, + {0.22476319518924603, 0.03640357374688182, 0.38812924842856483}, + {0.2315374529310898, 0.03640351817286241, 0.39239977934534576}, + {0.2382734320696066, 0.03661949264330557, 0.3963533531157254}, + {0.2449666980359304, 0.03705338654185691, 0.4000069520159531}, + {0.2516206637792285, 0.037703436097523746, 0.4033784221656792}, + {0.2582339375612672, 0.038569281262784215, 0.4064850812186898}, + {0.2648092188471272, 0.039645098963587894, 0.4093447670552162}, + {0.27134717156688476, 0.040920248896872104, 0.41197616680691795}, + {0.27784945989435444, 0.04235106621674233, 0.41439190152253697}, + {0.2843214014200332, 0.043931272334442044, 0.4166082251959268}, + {0.2907626953161, 0.04564206683863344, 0.41863700244674007}, + {0.2971786279866803, 0.04746832221255668, 0.42049126153840694}, + {0.3035679263767977, 0.04939409900213965, 0.42218207588627776}, + {0.3099342310464275, 0.05140486616668636, 0.4237209077370659}, + {0.3162821544923382, 0.0534881537223529, 0.42511612281358585}, + {0.3226094622720638, 0.05563191003781664, 0.42637698442915734}, + {0.32892138033063256, 0.057825220219243655, 0.4275111514018109}, + {0.33521669037969953, 0.060057968826412046, 0.42852404020939816}, + {0.34150060454122194, 0.06232329248965957, 0.42942516526482805}, + {0.34777091610802874, 0.06461403589398387, 0.43021707827304073}, + {0.35403123226470046, 0.06692277585963113, 0.43090600382653765}, + {0.3602841408353374, 0.06924510666507289, 0.4314970989990494}, + {0.366528457743285, 0.07157684449494817, 0.4319940445656597}, + {0.3727683648145053, 0.0739131776252345, 0.4324001060667602}, + {0.37900068183696356, 0.07625091481761018, 0.432719071099916}, + {0.3852285882170877, 0.07858924726823341, 0.43295510186497294}, + {0.391452904966983, 0.08092498458487726, 0.4331090849213901}, + {0.3976732251941389, 0.08325472094735673, 0.43318307823977154}, + {0.4038941281371945, 0.08557805215845263, 0.4331790858011016}, + {0.4101124478324236, 0.08789378949993748, 0.43309809489281975}, + {0.41633135152767126, 0.09020111672608602, 0.4329430750225925}, + {0.4225486702204431, 0.09249885580078815, 0.43271410026220614}, + {0.42876857492222104, 0.09478817843783055, 0.43241205420979634}, + {0.43498689244861954, 0.09706691940470738, 0.43203909514551403}, + {0.4412077984093083, 0.09933623724389631, 0.4315940236596366}, + {0.447428115165217, 0.10159497990744795, 0.43108007898556605}, + {0.453650434334324, 0.10384572179396404, 0.4304981431533577}, + {0.4598753385411611, 0.10608703735300581, 0.4298460517373555}, + {0.4660996564728312, 0.10831978115925261, 0.42912513104437605}, + {0.47232856222023284, 0.11054509253877559, 0.428334014815688}, + {0.47855787863379246, 0.11276183809637635, 0.42747510913916503}, + {0.4847897859200844, 0.11497214601360681, 0.42654796832755787}, + {0.49102210135850827, 0.11717689277568918, 0.4255520769077051}, + {0.4972564191293403, 0.11937663835804257, 0.42448819407856125}, + {0.5034933248743276, 0.12157294554931822, 0.42335603351162365}, + {0.5097296414881407, 0.12376669200308499, 0.4221561654704694}, + {0.5159675484473075, 0.12595799741934913, 0.42088698041253036}, + {0.522205863946251, 0.1281477445657914, 0.4195491273628126}, + {0.5284447718500154, 0.1303390492990618, 0.41814191774726495}, + {0.5346830866012935, 0.1325317964071948, 0.4166670792419288}, + {0.5409194040751939, 0.13472654160063324, 0.4151232492186141}, + {0.5471573097689081, 0.1369268480746088, 0.41351101955274133}, + {0.5533916265944651, 0.13913159264204145, 0.4118292045095448}, + {0.5596245324931008, 0.14134390081316123, 0.41007795018698034}, + {0.565853849035322, 0.14356464417843176, 0.408258150100951}, + {0.5720817545692755, 0.14579495531212058, 0.40636887114816594}, + {0.5783040710826255, 0.1480366969821801, 0.4044110859921461}, + {0.5845203906718561, 0.15029143569692027, 0.4023853090317509}, + {0.5907342930011564, 0.15256075186424045, 0.40029001001388526}, + {0.5969396129909775, 0.1548454880249755, 0.3981252481044335}, + {0.6031395137899174, 0.15714880993418692, 0.39589092443931145}, + {0.6093298346523712, 0.15947154274866268, 0.3935891773266438}, + {0.6155137330265519, 0.1618148719991605, 0.3912188293792153}, + {0.6216850552354126, 0.1641816008624372, 0.38878109691187235}, + {0.6278463807173074, 0.1665723257656469, 0.3862763730397491}, + {0.6339982745553374, 0.16898966363736537, 0.3837040052607365}, + {0.6401346020827624, 0.17143538357408133, 0.3810652955393134}, + {0.6462604918955885, 0.17391173185514677, 0.3783589039476966}, + {0.6523688217818822, 0.17641844614159138, 0.37558620861598563}, + {0.6584637067856558, 0.17895980652738866, 0.37274779377320805}, + {0.6645400395062868, 0.1815365142239986, 0.36984611221667457}, + {0.6705983762227489, 0.18415021667573447, 0.36687943961906233}, + {0.6766382547106133, 0.18680458958736995, 0.3638490055304848}, + {0.6826555952415246, 0.1894982847225483, 0.3607573457624624}, + {0.6886534667732338, 0.1922366729397742, 0.3576028897156723}, + {0.6946268114822389, 0.19501835963153946, 0.35438824300823807}, + {0.7005766750861048, 0.19784876490425912, 0.35111276552861453}, + {0.7065000246724039, 0.20072544237887552, 0.34777713155969964}, + {0.7123953793054851, 0.20365311312098916, 0.34438350640978904}, + {0.7182642339188836, 0.20663353472537765, 0.34093101094395056}, + {0.7241025940115757, 0.20966719575096354, 0.3374243970752363}, + {0.7299094384556731, 0.21275663751205837, 0.33386088208499215}, + {0.7356828051012506, 0.21590328739196812, 0.3302452795512392}, + {0.7414236378808644, 0.2191097508283441, 0.32657574613398255}, + {0.7471270116731434, 0.2223753888240187, 0.32285615422841446}, + {0.7527948315414559, 0.22570387532426378, 0.31908460363536006}, + {0.7584222127903781, 0.22909450162198797, 0.31526602130047027}, + {0.7640096003184447, 0.23255111985362076, 0.3113994474823908}, + {0.769556407505972, 0.236074626914262, 0.30748488142933444}, + {0.7750588038588068, 0.23966423164432504, 0.3035263167932573}, + {0.780517595641067, 0.24332476411029125, 0.29952273568573573}, + {0.7859290015238034, 0.2470533545534328, 0.29547717944438406}, + {0.7912937764432374, 0.25085391354890735, 0.29138958485956357}, + {0.7966071922843984, 0.25472548987486643, 0.28726403596779526}, + {0.8018706152376446, 0.2586710580118296, 0.28309949569184917}, + {0.8070823747046473, 0.26268963921769606, 0.27889788734079896}, + {0.8122388089759692, 0.26678319189183297, 0.2746613536242391}, + {0.8173415491080798, 0.27095180082645115, 0.27038973420543944}, + {0.8223859952913317, 0.27519433772522317, 0.2660852062616442}, + {0.8273727148541918, 0.2795149750247453, 0.26174957724469494}, + {0.8322991733910813, 0.2839104959497832, 0.25738305415913015}, + {0.8371646398804131, 0.2883820094161365, 0.252988540402642}, + {0.8419693412456319, 0.29293066888944563, 0.2485638989415601}, + {0.846708821213788, 0.29755616578042293, 0.2441133893753179}, + {0.8513844997023888, 0.3022578538064719, 0.23963574040066615}, + {0.855991993845198, 0.3070353341236893, 0.23513323409260284}, + {0.8605336484626919, 0.31189005054876767, 0.230605578997568}, + {0.865006157141607, 0.316819514079576, 0.2260550749407627}, + {0.8694086743123614, 0.3218239712798184, 0.2214825826370368}, + {0.873741308408031, 0.32690370860531126, 0.21688591478628577}, + {0.8780008409852356, 0.33205714927467816, 0.212268424608822}, + {0.8821884493306369, 0.33728491405873967, 0.20762775209164724}, + {0.8863019976673894, 0.3425833384271254, 0.20296826303399285}, + {0.8903415794934312, 0.3479551300484793, 0.19828558691030201}, + {0.894305144045262, 0.3533965381592675, 0.19358409819949085}, + {0.8981917181039129, 0.35890794053186803, 0.1888606247963219}, + {0.902003277546344, 0.36448975074745, 0.18411593340897883}, + {0.9057348680145032, 0.37013713800749826, 0.17935046113406727}, + {0.9093903996647411, 0.3758539732830311, 0.17456276670706064}, + {0.9129660070101344, 0.38163334525219944, 0.1697552941505453}, + {0.9164625104530708, 0.3874792047452722, 0.16492359727200515}, + {0.9198791350013626, 0.39338656173222386, 0.16007012382758104}, + {0.9232147698912994, 0.3993559137889013, 0.1551936703489871}, + {0.9264702498113229, 0.40538678902429115, 0.15029195385198924}, + {0.9296439014941755, 0.41147612778815296, 0.14536750158970949}, + {0.9327373523126056, 0.4176250250322833, 0.14041678247519898}, + {0.9357470217364718, 0.42382835018615, 0.13544032915276746}, + {0.9386754432346461, 0.4300892683482416, 0.13043760827101122}, + {0.9415211303729047, 0.4364025802485547, 0.12540915246812306}, + {0.9442848284617543, 0.4427688880476121, 0.12035472282994122}, + {0.9469652258626157, 0.44918881902600133, 0.11527197615350762}, + {0.9495619408937822, 0.4556571156219838, 0.11016454791032279}, + {0.9520753085089858, 0.4621760654003351, 0.10503080049999589}, + {0.9545060414475516, 0.468741350075834, 0.09987436834002841}, + {0.9568523791775677, 0.4753543175690524, 0.09469462335752518}, + {0.9591141303022052, 0.4820115908490303, 0.08949918430671361}, + {0.9612934380573407, 0.4887145750891598, 0.08428844691950368}, + {0.9633872061002898, 0.4954598384326913, 0.07907300229562086}, + {0.9653969856405892, 0.5022460991811288, 0.07385959127645336}, + {0.9673222685246364, 0.5090760925737746, 0.06865882956308128}, + {0.9691630662078553, 0.5159433430954236, 0.06348840124042007}, + {0.970919318954511, 0.5228513513717987, 0.05836666742473027}, + {0.9725901348141913, 0.529795592113789, 0.053324210911405455}, + {0.9741763574084353, 0.5367786143884726, 0.04839153015610343}, + {0.975677190645675, 0.5437958464199314, 0.043618036090846}, + {0.9770920356520277, 0.5508470769374313, 0.03905055303111867}, + {0.9784222326450961, 0.5579351064433469, 0.034930916546532825}, + {0.979666095876416, 0.5650543281731687, 0.0314092990272324}, + {0.9808242624402922, 0.5722073701062071, 0.028507883553058225}, + {0.9818951440117506, 0.5793895836320366, 0.02625012573179964}, + {0.982881280054488, 0.5866046371076197, 0.024660950197297846}, + {0.9837791795198422, 0.5938468430754209, 0.023770046474572596}, + {0.9845910909683125, 0.6011190480992957, 0.023606059102018802}, + {0.9853152007413414, 0.608420107478453, 0.02420209240341553}, + {0.9859521306674056, 0.6157473052058917, 0.025591934272695092}, + {0.9865022096405148, 0.6231033747802108, 0.027814257478890377}, + {0.9869641579064014, 0.6304825655882533, 0.030907915000313535}, + {0.9873372060008064, 0.6378886447799842, 0.034916559619452406}, + {0.987622172670732, 0.6453178289458518, 0.039886017500422775}, + {0.9878191520033638, 0.6527700129448509, 0.045580403012790684}, + {0.9879261727372323, 0.6602480965501968, 0.05175024605159847}, + {0.9879451706317489, 0.6677452744424257, 0.05832852598609512}, + {0.9878741601998459, 0.675265366380739, 0.06525752407999996}, + {0.9877141765851464, 0.6828045385569567, 0.07248872059669512}, + {0.9874641349558363, 0.690364638021527, 0.07999083430127826}, + {0.9871241697382241, 0.6979418049868507, 0.08773096280857864}, + {0.9866942187047217, 0.7055369718171162, 0.09569310480416554}, + {0.9861751485274827, 0.7131510743985874, 0.103863256330502}, + {0.9855662155788282, 0.7207792367356154, 0.11222834433058854}, + {0.9848651143109276, 0.7284253454782301, 0.12078557949263882}, + {0.9840751996931422, 0.7360845034258754, 0.12952661474987895}, + {0.9831960676449997, 0.7437566173190143, 0.13845392837069237}, + {0.9822281707577935, 0.7514397717174452, 0.14756491297187693}, + {0.9811732892122574, 0.7591319265002779, 0.15686190499859645}, + {0.9800321283245658, 0.7668350414250283, 0.16635325033390524}, + {0.9788062634501479, 0.7745421938654863, 0.1760361942373471}, + {0.9774970739304246, 0.7822563112740953, 0.18592362086777084}, + {0.976108224906952, 0.7899714619636461, 0.1960175103988243}, + {0.9746380082272822, 0.7976905802513132, 0.20633302377351131}, + {0.9730881744707035, 0.8054067300567858, 0.21687685576253862}, + {0.9714683557085738, 0.8131188812721618, 0.2276566805995705}, + {0.9697831130812914, 0.8208229971469754, 0.23868624376433029}, + {0.968041305354793, 0.8285121501431812, 0.24997101177190928}, + {0.9662430438023951, 0.836189261303023, 0.2615346777715621}, + {0.9643942451078572, 0.8438454171701422, 0.273390375539181}, + {0.9625169727369577, 0.8514745194008927, 0.2855471549893648}, + {0.9606261754860036, 0.8590666816140542, 0.29800977930778266}, + {0.9587199044763673, 0.86662276892152, 0.310821685193729}, + {0.9568341051627561, 0.8741269393072385, 0.3239742355406551}, + {0.9549973084887696, 0.8815661177531517, 0.3374737603502378}, + {0.9532150458875698, 0.8889401848892272, 0.3513697543417886}, + {0.9515462272506953, 0.8962233797142661, 0.36562618964558136}, + {0.950018012245954, 0.9034074125145412, 0.3802723264284489}, + {0.9486831530694507, 0.9104706308186431, 0.3952886725437556}, + {0.9475940275601823, 0.9173976138382822, 0.4106669431858655}, + {0.9468091087983127, 0.9241658620670481, 0.4263732130148635}, + {0.9463921563722028, 0.9307581300310862, 0.4423654634949841}, + {0.9464031311450462, 0.9371570608055302, 0.458592798889426}, + {0.9469030741916794, 0.9433453721925603, 0.4749690020361225}, + {0.9479372327167105, 0.9493162253885609, 0.49142738476056075}, + {0.9495450508917115, 0.9550605846153878, 0.5078595779865485}, + {0.9517404201103928, 0.9605853570748163, 0.5242049355302347}, + {0.9545291096426641, 0.9658937621848641, 0.5403611560472134}, + {0.9578957403425837, 0.971000188760133, 0.5562734123813695}, + {0.9618122666687167, 0.9759219036314865, 0.571925695133198}, + {0.966248777481722, 0.980675368253291, 0.5872050182876477}, + {0.9711624870815522, 0.985280023457573, 0.6021551859229256}, + {0.9765108962599102, 0.9897505184610552, 0.6167595818025277}, + {0.9822577545753769, 0.9941071290312428, 0.6310186261682112}, + {0.9883620799212208, 0.9983616470620554, 0.6449240982803861}, +}}; + +template +static constexpr std::array, 256> black_body_data_ = {{ + {0.0, 0.0, 0.0}, + {0.013038855104993618, 0.0037537033758315535, 0.002103027943341456}, + {0.02607771020998725, 0.007507406751663157, 0.004206055886683011}, + {0.03911656531498074, 0.01126111012749475, 0.006309083830024466}, + {0.05111281846889674, 0.0150148135033264, 0.008412111773366015}, + {0.06145201887409168, 0.018768516879157954, 0.010515139716707521}, + {0.07064326337459148, 0.02252222025498951, 0.012618167660048977}, + {0.07897806577026972, 0.026275923630821117, 0.014721195603390481}, + {0.08664361913059343, 0.03002962700665271, 0.016824223546731985}, + {0.09376835672821318, 0.03378333038248431, 0.018927251490073488}, + {0.10044479589169861, 0.03753703375831587, 0.021030279433414945}, + {0.10674212293169041, 0.041271634201045536, 0.02313330737675645}, + {0.11271363536038692, 0.04482597891806931, 0.025236335320097954}, + {0.11840139369546077, 0.048211428422088996, 0.027339363263439456}, + {0.12383926177477003, 0.051448139039433315, 0.029442391206781018}, + {0.12905496821437284, 0.05455261530914037, 0.03154541915012247}, + {0.13415881215680708, 0.05748457013282512, 0.03365241563251253}, + {0.1394282635051205, 0.06009480851170646, 0.035776007200922486}, + {0.1448680365076732, 0.06239658846641056, 0.03791741526748158}, + {0.15046463427844672, 0.06440943575351296, 0.04007701382092898}, + {0.15620567729622375, 0.06614841603004337, 0.042202264001466754}, + {0.1620642871793741, 0.06766725618508368, 0.04427088573012868}, + {0.1679681168976293, 0.06914956019046758, 0.04626676146380417}, + {0.17390879488805058, 0.07061411563078038, 0.048192562428916404}, + {0.17988507705788212, 0.07206107502164819, 0.05005305250836759}, + {0.18589582390636886, 0.073490579693259, 0.0518524382574397}, + {0.19193998883434982, 0.07490276049381833, 0.053594454613670746}, + {0.19801660795994802, 0.07629773842679596, 0.05528243440605366}, + {0.20412479122741767, 0.0776756252290656, 0.05691936524751085}, + {0.21026371462828286, 0.07903652389614257, 0.05850793649497276}, + {0.2164326133809747, 0.08038052915995664, 0.060050578312412416}, + {0.2226307759380115, 0.08170772792393452, 0.06154949439758999}, + {0.22885753870905418, 0.08301819965959711, 0.0630066895818179}, + {0.23511228140445872, 0.08431201676837646, 0.06442399324878009}, + {0.2413944229177235, 0.08558924491193284, 0.06580307931909093}, + {0.24770341767689402, 0.08684994331387272, 0.06714548339482998}, + {0.25403875240487506, 0.08809416503544282, 0.06845261754062515}, + {0.2603999432369943, 0.089321957227491, 0.06972578308625077}, + {0.26678653315130063, 0.09053336136073056, 0.07096618176381639}, + {0.2731980896731617, 0.09172841343612223, 0.07217492543577086}, + {0.2796342028209079, 0.09290714417700069, 0.07335304462466913}, + {0.2860944832637109, 0.09406957920438949, 0.07450149601935155}, + {0.29257856066667054, 0.09521573919680446, 0.07562116910289712}, + {0.29908608220134825, 0.09634564003570609, 0.07671289202394302}, + {0.3056167112027767, 0.09745929293764075, 0.07777743681356081}, + {0.31217012595638344, 0.0985567045740047, 0.07881552403396175}, + {0.31874601860034424, 0.09963787717926836, 0.0798278269321728}, + {0.32534319363742265, 0.10070307071710113, 0.08082304674985791}, + {0.3319596041219896, 0.1017528114823801, 0.08181815186765931}, + {0.3385951481217959, 0.10278707282194993, 0.08281314988265284}, + {0.34524972170116486, 0.10380582517735878, 0.08380805027785368}, + {0.35192321947598326, 0.10480903601879557, 0.08480286230027789}, + {0.35861553489350906, 0.10579666984465097, 0.08579759496848993}, + {0.36532656048179657, 0.10676868817762619, 0.08679225707984467}, + {0.3720561880720667, 0.10772504955741516, 0.08778685721743867}, + {0.3788043089969579, 0.10866570952997373, 0.08878140375678456}, + {0.38557081426725, 0.10959062063337968, 0.08977590487222206}, + {0.392355594729354, 0.11049973238028288, 0.09077036854307868}, + {0.3991585412055988, 0.1113929912369285, 0.09176480255959146}, + {0.40597954461911684, 0.11227034059873503, 0.09275921452860061}, + {0.41281849610493104, 0.1131317207623947, 0.09375361187902712}, + {0.4196752871086668, 0.11397706889445536, 0.09474800186714263}, + {0.4265498094741573, 0.11480631899633567, 0.0957423915816421}, + {0.4334419555210749, 0.11561940186571482, 0.09673678794852814}, + {0.44035161811359996, 0.11641624505422682, 0.09773119773581507}, + {0.44727869072102816, 0.11719677282138305, 0.09872562755806155}, + {0.45422306747112823, 0.11796090608463114, 0.09972008388073797}, + {0.46118464319697156, 0.11870856236545602, 0.10071457302443804}, + {0.4681633134778857, 0.11943965573140711, 0.1017091011689388}, + {0.47515897467511364, 0.12015409673393382, 0.10270367435711814}, + {0.4821715239627041, 0.1208517923418958, 0.10369829849873419}, + {0.4892008593541031, 0.12153264587059787, 0.1046929793740726}, + {0.49624687972487286, 0.12219655690619557, 0.10568772263746884}, + {0.5033094848319175, 0.12284342122529493, 0.10668253382070847}, + {0.5103885753295632, 0.12347313070955779, 0.10767741833631286}, + {0.5174840527828012, 0.12408557325511224, 0.10867238148071282}, + {0.5245958196779755, 0.12468063267654717, 0.10966742843731633}, + {0.5317237794311703, 0.12525818860524965, 0.11066256427947438}, + {0.5388678363945218, 0.12581811638183757, 0.1116577939733483}, + {0.5460278958606667, 0.12636028694240006, 0.11265312238068345}, + {0.5532038640655134, 0.12688456669826084, 0.11364855426149251}, + {0.5603956481895038, 0.12739081740893254, 0.11464409427665198}, + {0.5676031563575221, 0.12787889604792488, 0.11563974699041571}, + {0.5748262976375883, 0.12834865466103332, 0.11663551687284723}, + {0.5820649820384645, 0.12879994021670815, 0.11763140830217725}, + {0.5893191205062877, 0.1292325944480741, 0.11862742556708483}, + {0.5965886249203336, 0.12964645368613567, 0.11962357286890879}, + {0.6038734080880022, 0.13004134868367784, 0.12061985432379002}, + {0.6111733837391209, 0.13041710442930957, 0.12161627396474861}, + {0.618488466519628, 0.1307735399510897, 0.12261283574369633}, + {0.6258185719847208, 0.13111046810909502, 0.12360954353338896}, + {0.6331636165915261, 0.13142769537626633, 0.12460640112931987}, + {0.6405235176913502, 0.13172502160680363, 0.125603412251556}, + {0.6478981935215649, 0.13200223979132508, 0.12660058054652026}, + {0.6552875631971755, 0.13225913579794255, 0.1275979095887203}, + {0.6626915467021134, 0.13249548809833553, 0.1285954028824274}, + {0.6701100648802979, 0.13271106747782782, 0.12959306386330607}, + {0.6775430394264935, 0.13290563672840347, 0.13059089589999584}, + {0.6849903928770076, 0.133078950323475, 0.13158890229564854}, + {0.6924520486002461, 0.13323075407316545, 0.13258708628942104}, + {0.6990269444289148, 0.13526285713010114, 0.13312878204163103}, + {0.7029385031056067, 0.14276164252353424, 0.13230087174729266}, + {0.706849160518104, 0.15003367886528432, 0.13144472110159658}, + {0.7107589339135043, 0.1571072636984418, 0.13055959687730143}, + {0.7146678402982333, 0.16400574341929422, 0.12964472942353197}, + {0.7185758964424839, 0.17074862440458652, 0.1286993099989257}, + {0.7224831188845541, 0.1773523851612915, 0.12772248784920406}, + {0.7263895239350789, 0.18383108192179715, 0.12671336699848523}, + {0.7302951276811657, 0.19019680820853718, 0.12567100271919956}, + {0.7341999459904341, 0.19646004903982417, 0.12459439764026739}, + {0.7381039945149617, 0.20262995773846548, 0.12348249744706852}, + {0.742007288695138, 0.20871457496055673, 0.12233418611951721}, + {0.7459098437634323, 0.21472100396010463, 0.1211482806460144}, + {0.7498116747480748, 0.22065555226824157, 0.11992352514088764}, + {0.7537127964766552, 0.22652384728976455, 0.11865858428082418}, + {0.7576132235796376, 0.23233093142236372, 0.11735203596128549}, + {0.7615129704938024, 0.2380813409383808, 0.11600236305643169}, + {0.7654120514656042, 0.24377917187260056, 0.11460794414495701}, + {0.7693104805544623, 0.24942813542336495, 0.11316704303859387}, + {0.7732082716359728, 0.25503160482399895, 0.11167779691868823}, + {0.7771054384050546, 0.260592655225706, 0.11013820284777173}, + {0.7810019943790253, 0.266114097815743, 0.1085461023755086}, + {0.784897952900607, 0.27159850915024936, 0.10689916389931109}, + {0.7887933271408747, 0.2770482564911545, 0.10519486236601067}, + {0.792688130102133, 0.28246551978783785, 0.10343045580787474}, + {0.7965823746207359, 0.28785231082677337, 0.1016029580881492}, + {0.8004760733698467, 0.2932104899790604, 0.09970910708026909}, + {0.8043692388621376, 0.2985417809010483, 0.09774532731012447}, + {0.8082618834524321, 0.30384778348310415, 0.09570768583739653}, + {0.8121540193402956, 0.30912998529284585, 0.09359183981917277}, + {0.8160456585725648, 0.31438977171944593, 0.09139297375735872}, + {0.8199368130458352, 0.31962843499310634, 0.08910572383870971}, + {0.8238274945088833, 0.32484718222701414, 0.0867240859712489}, + {0.8277177145650534, 0.33004714260695417, 0.08424130301309385}, + {0.8316074846745842, 0.33522937383533186, 0.08164972514342614}, + {0.8354968161568933, 0.3403948679210186, 0.07894063513317165}, + {0.8393857201928158, 0.3455445563935293, 0.07610402711123557}, + {0.8432742078267932, 0.350679315009233, 0.07312832277504416}, + {0.8471622899690239, 0.35579996800812036, 0.07000000201860399}, + {0.8510499773975676, 0.3609072919719153, 0.06670311423184544}, + {0.8549372807604048, 0.3660020193276998, 0.06321861961083997}, + {0.8588242105774635, 0.37108484153559657, 0.05952348231757188}, + {0.8627107772425975, 0.37615641199422883, 0.05558939105319657}, + {0.8665969910255304, 0.38121734869353224, 0.0513809015925008}, + {0.870482862073761, 0.3862682366409203, 0.046852647240651586}, + {0.8743684004144292, 0.39130963008373454, 0.04194497518373403}, + {0.8782536159561499, 0.39634205454821875, 0.03662194288964867}, + {0.8821385184908072, 0.40136600871296174, 0.03117410153953512}, + {0.8860231176953159, 0.40638196613271077, 0.025643215104659372}, + {0.8899074231333507, 0.4113903768267081, 0.020028781568071516}, + {0.891065382338744, 0.4184635684621956, 0.021466471088552607}, + {0.8919871230973406, 0.4256470552949243, 0.02354603033215587}, + {0.8928908994946323, 0.4327756220188152, 0.02570095483314324}, + {0.8937766259341077, 0.4398522418561916, 0.027932126084511257}, + {0.8946442158848376, 0.4468796753940895, 0.030240425579256377}, + {0.8954935818622007, 0.4538604904909103, 0.032626734810374966}, + {0.8963246354082741, 0.4607970798827202, 0.03509193527086419}, + {0.8971372870718866, 0.4676916768037213, 0.037636908453718976}, + {0.8979314463883195, 0.4745463688860316, 0.04026253585193785}, + {0.8987070218586405, 0.48136311056322806, 0.042883774659142816}, + {0.899463920928664, 0.4881437341684682, 0.045483032991513316}, + {0.9002020499675142, 0.49488995989000545, 0.048065003458762835}, + {0.9009213142457936, 0.5016034047235632, 0.05063130309097131}, + {0.9016216179133228, 0.5082855905414284, 0.053183371551623206}, + {0.9023028639764596, 0.5149379513816515, 0.055722495847998925}, + {0.902964954274961, 0.5215618400467861, 0.05824983088146562}, + {0.9036077894583927, 0.5281585340897971, 0.060766416652818796}, + {0.9042312689620561, 0.5347292412547051, 0.06327319275680962}, + {0.9048352909824239, 0.5412751044309391, 0.06577101066369245}, + {0.9054197524520664, 0.5477972061730271, 0.0682606441818552}, + {0.9059845490140521, 0.5542965728309169, 0.07074279841591524}, + {0.9065295749958051, 0.5607741783307898, 0.07321811747290291}, + {0.9070547233823978, 0.5672309476415033, 0.07568719112093336}, + {0.9075598857892664, 0.5736677599577373, 0.07815056056678477}, + {0.9080449524343264, 0.5800854516273583, 0.08060872348871567}, + {0.9085098121094662, 0.5864848188474415, 0.083062138436825}, + {0.9089543521514049, 0.5928666201506813, 0.08551122869395478}, + {0.9093784584118849, 0.5992315787015761, 0.08795638567456415}, + {0.909782015227184, 0.6055803844196885, 0.09039797192630794}, + {0.9101649053869216, 0.6119136959454732, 0.09283632378872866}, + {0.9105270101021349, 0.6182321424625531, 0.09527175375494526}, + {0.9108682089726016, 0.6245363253889187, 0.09770455257523358}, + {0.9111883799533859, 0.630826819948256, 0.10013499113555632}, + {0.9114873993205763, 0.6371041766315243, 0.10256332213928446}, + {0.9117651416361977, 0.6433689225578914, 0.10498978161628147}, + {0.9120214797122554, 0.649621562743278, 0.10741459028014497}, + {0.912256284573901, 0.6558625812839713, 0.1098379547515301}, + {0.91246942542167, 0.6620924424620748, 0.11226006866305718}, + {0.9126607695927773, 0.6683115917789337, 0.11468111365925662}, + {0.9128301825214254, 0.6745204569221216, 0.11710126030325854}, + {0.9129775276981008, 0.6807194486710708, 0.11952066890043198}, + {0.9131026666278179, 0.6869089617459752, 0.12193949024790668}, + {0.9132054587872768, 0.6930893756041974, 0.12435786631781182}, + {0.9132857615808976, 0.6992610551880414, 0.1267759308811086}, + {0.9133434302956924, 0.7054243516274225, 0.12919381007809072}, + {0.9133783180549305, 0.7115796029006738, 0.13161162294090045}, + {0.9133902757705612, 0.7177271344564569, 0.13402948187280572}, + {0.9133791520943453, 0.7238672597994953, 0.13644749308843845}, + {0.913344793367654, 0.7300002810426419, 0.13886575701873277}, + {0.9132870435698786, 0.7361264894275755, 0.1412843686838794}, + {0.9132057442654163, 0.7422461658162536, 0.1437034180372798}, + {0.913100734549166, 0.7483595811550647, 0.1461229902831289}, + {0.9129718509904932, 0.7544669969134981, 0.14854316617002308}, + {0.9128189275755945, 0.7605686654989812, 0.15096402226269828}, + {0.9126417956482176, 0.7666648306494336, 0.15338563119383095}, + {0.9124402838486693, 0.7727557278049575, 0.1558080618976074}, + {0.9122142180510416, 0.778841584459982, 0.15823137982661514}, + {0.9119634212986102, 0.7849226204970876, 0.16065564715346278}, + {0.9116877137373088, 0.7909990485036371, 0.16308092295837506}, + {0.9113869125472361, 0.797071074072276, 0.16550726340392827}, + {0.9110608318720959, 0.803138896086265, 0.16793472189794498}, + {0.9107092827465118, 0.8092027069905707, 0.1703633492455004}, + {0.9103320730211178, 0.8152626930495434, 0.17279319379088973}, + {0.909929007285357, 0.8213190345919861, 0.17522430155033844}, + {0.9094998867878827, 0.8273719062443313, 0.17765671633615956}, + {0.9090445093544782, 0.8334214771526294, 0.1800904798730111}, + {0.9085626693033965, 0.8394679111939684, 0.18252563190683574}, + {0.9080541573580172, 0.8455113671779366, 0.18496221030703314}, + {0.9075187605567102, 0.8515519990386777, 0.18740025116234627}, + {0.9069562621598014, 0.8575899560180628, 0.18983978887092715}, + {0.9063664415535179, 0.8636253828404642, 0.19228085622498767}, + {0.9057490741507888, 0.8696584198795938, 0.19472348449042068}, + {0.9051039312887829, 0.875689203317828, 0.197167703481744}, + {0.9044307801230321, 0.8817178652984231, 0.19961354163268363}, + {0.9037293835180177, 0.8877445340709991, 0.2020610260626995}, + {0.9029994999340526, 0.8937693341306414, 0.20451018263972115}, + {0.9022408833103207, 0.8997923863509576, 0.2069610360393544}, + {0.9059888943947992, 0.9040221289848984, 0.2345476432758713}, + {0.9121353668077321, 0.9072538390291374, 0.2723959319742808}, + {0.918103004002936, 0.910496798148879, 0.30707485069273716}, + {0.9238889872583352, 0.913751436869596, 0.3395892760133458}, + {0.9294904738341414, 0.9170181766931385, 0.3705416931634215}, + {0.9349045893736176, 0.9202974302069179, 0.4003237614900562}, + {0.9401284204049521, 0.9235896011902338, 0.4292051255044417}, + {0.9451590068972918, 0.9268950847179593, 0.45737955986332374}, + {0.9499933348250024, 0.9302142672617891, 0.4849910259595919}, + {0.9546283286947478, 0.9335475267892457, 0.5121493527958956}, + {0.9590608439900784, 0.936895232860618, 0.5389401619772186}, + {0.9632876594878218, 0.9402577467240134, 0.5654314125128757}, + {0.9673054693997428, 0.9436354214086733, 0.5916778659454154}, + {0.971110875291573, 0.9470286018167143, 0.6177242212867308}, + {0.9747003777296833, 0.9504376248134289, 0.6436073706776709}, + {0.9780703676032384, 0.9538628193162827, 0.6693580571761435}, + {0.9812171170667078, 0.9573045063827349, 0.6950021159198041}, + {0.9841367700439326, 0.9607629992969943, 0.7205614186521087}, + {0.9868253322306101, 0.9642386036558243, 0.7460546029896806}, + {0.9892786605268938, 0.9677316174534963, 0.7714976428174245}, + {0.9914924518257658, 0.9712423311659882, 0.7969042996355301}, + {0.9934622310757725, 0.9747710278345115, 0.8222864834722017}, + {0.9951833385285259, 0.9783179831484546, 0.8476545442427741}, + {0.9966509160718274, 0.9818834655278131, 0.873017509008704}, + {0.9978598925382617, 0.9854677362051741, 0.8983832767211907}, + {0.9988049678662737, 0.9890710493073268, 0.9237587792366369}, + {0.999480595975958, 0.9926936519365445, 0.9491501153416039}, + {0.9998809662045313, 0.9963357842516011, 0.9745626630050933}, + {1.0, 1.0, 1.0}, +}}; + +template +static constexpr std::array, 256> plasma_data_ = {{ + {0.05038205347059877, 0.029801736499741757, 0.5279751010495176}, + {0.06353382706361996, 0.028424851177690835, 0.5331235351456174}, + {0.07535267397875561, 0.027204618108821313, 0.5380072654878371}, + {0.08622056271327161, 0.02612369628606181, 0.5426577546250408}, + {0.09637909234021627, 0.02516351238474626, 0.5471034027913018}, + {0.10597907050045527, 0.02430756301203486, 0.5513679345503644}, + {0.11512442337588075, 0.0235544144422598, 0.5554685209574166}, + {0.12390246837508934, 0.022876443394988937, 0.5594230869193363}, + {0.13237958264924907, 0.022256467283011946, 0.5632496670754658}, + {0.14060280627862978, 0.02168533317299063, 0.5669592160880329}, + {0.14860595337659185, 0.021152345584078584, 0.5705618203562642}, + {0.1564211065006705, 0.020649224182780333, 0.5740653310686394}, + {0.16406928001421978, 0.020169228789859318, 0.5774779563374444}, + {0.17157438178522647, 0.019704113165841947, 0.5808064352016079}, + {0.1789495767422052, 0.019250113119147653, 0.584054078695406}, + {0.18621180115469324, 0.018801112566559006, 0.5872277307558299}, + {0.19337385391747602, 0.018351995878840264, 0.5903301881492813}, + {0.20044409185351197, 0.01789999393180025, 0.593363854926767}, + {0.20743511639383128, 0.01743987460850466, 0.5963332877187512}, + {0.21434936531465415, 0.016970872739093673, 0.5992389686439623}, + {0.22119736746683188, 0.016494748620846298, 0.6020833788659872}, + {0.22798262579984302, 0.01600474729153228, 0.6048670732620841}, + {0.23471390034056855, 0.015499747535836161, 0.6075917748304479}, + {0.24139587735519374, 0.014976616724022502, 0.6102591681981376}, + {0.24803115851643903, 0.01443661887416811, 0.6128678816678474}, + {0.25462712204192733, 0.013879480363965033, 0.6154192540143766}, + {0.26118240815987454, 0.013305484446440807, 0.6179109803957406}, + {0.2677033607536392, 0.012713338432089919, 0.6203463317006325}, + {0.27419065115382085, 0.012106344331753975, 0.6227220708698477}, + {0.2806485945135714, 0.011485191704992936, 0.625038400861471}, + {0.2870758894612177, 0.010852198594472949, 0.6272951521878755}, + {0.29347719408360684, 0.010210206090003579, 0.6294899111444117}, + {0.2998551242452729, 0.009558047948332786, 0.6316242235777169}, + {0.30620943129674466, 0.008899055475505046, 0.6336939963015096}, + {0.3125433553743016, 0.008235893717416108, 0.6357002857590853}, + {0.31885566464941756, 0.007572899889250414, 0.6376400727865161}, + {0.3251505835029789, 0.0069117371894770714, 0.6395123380850828}, + {0.3314258950888549, 0.006257740755607049, 0.6413161393477004}, + {0.3376822144299248, 0.005614742031369818, 0.643048949066938}, + {0.343925123616484, 0.00498757999986155, 0.6447101941536691}, + {0.35014944433050965, 0.004378575729205644, 0.6462980198153693}, + {0.3563593495264177, 0.0037944194657679817, 0.6478102381291251}, + {0.3625526716933222, 0.0032394075990651583, 0.6492450805997739}, + {0.3687335729955321, 0.002720261374452697, 0.6506012705463909}, + {0.3748968968242403, 0.002241239865606646, 0.6518761301685362}, + {0.38104622727684795, 0.001810210773066439, 0.6530679993306958}, + {0.3871831206545137, 0.0014300761021609504, 0.6541771655986202}, + {0.3933034524768182, 0.0011100331980040906, 0.6551990534286212}, + {0.39941134218209506, 0.0008549181444151815, 0.6561331884791302}, + {0.40550267547562835, 0.0006738585958816878, 0.656977095844568}, + {0.4115805613352908, 0.0005727689276359682, 0.6577301981873359}, + {0.4176418962835305, 0.000559689848675834, 0.6583901257368883}, + {0.4236882377452387, 0.0006415963809730485, 0.6589560636788017}, + {0.4297191157868382, 0.0008265327400941048, 0.6594251390708742}, + {0.43573345912178957, 0.0011224144971593696, 0.6597970982982151}, + {0.4417323328094361, 0.0015353882778950684, 0.6600691382766763}, + {0.4477136781734527, 0.002075242343276844, 0.6602401195491348}, + {0.45367754705516167, 0.0027502600296914884, 0.6603101230367315}, + {0.45962289480536683, 0.003569082980411755, 0.6602771266757947}, + {0.4655492492356133, 0.004539882193632057, 0.6601391424818946}, + {0.4714571093971736, 0.005672943386802442, 0.6598971161567793}, + {0.4773434667747343, 0.0069747060416045946, 0.6595491544709485}, + {0.48321032105464906, 0.00845482487303384, 0.6590950901585111}, + {0.4890546814926811, 0.010121547209062692, 0.6585341518234636}, + {0.49487752945710545, 0.011984730267283644, 0.6578650488841956}, + {0.5006778931801235, 0.01404940920364397, 0.6570881342241002}, + {0.5064532641572821, 0.016327053582825775, 0.6562022327592171}, + {0.512206101996081, 0.018827299101003524, 0.6552090987935029}, + {0.517932476985869, 0.021556895188755264, 0.6541092197088938}, + {0.5236333071472989, 0.02452621873336916, 0.6529010471797861}, + {0.5293056865203295, 0.02774076220334348, 0.651586191657666}, + {0.5349525083091329, 0.031211170127490386, 0.6501649809244013}, + {0.5405698921735111, 0.034943657938542025, 0.6486401484123572}, + {0.5461562839529602, 0.03894709993862434, 0.6470103291518646}, + {0.5517150940137298, 0.04312993669146801, 0.6452770884507062}, + {0.5572424908996385, 0.04732473166532047, 0.6434432899905641}, + {0.5627382914453162, 0.05153956982770822, 0.6415090129244055}, + {0.5682006939186361, 0.05577231508140689, 0.639477236154527}, + {0.5736324841026456, 0.06002312768941918, 0.6373489241079173}, + {0.5790288922820648, 0.06429083299444488, 0.635126168256215}, + {0.5843916716197954, 0.06857462612193421, 0.6328118231142932}, + {0.5897190859433459, 0.07287330061804262, 0.6304080857996939}, + {0.5950105087389658, 0.07718497188889406, 0.627917359511397}, + {0.600266274548656, 0.08151172798904885, 0.6253419897153364}, + {0.6054847038259513, 0.08584937397306835, 0.6226862814869409}, + {0.6106674577942587, 0.09020012029057023, 0.6199508828839105}, + {0.6158118936935632, 0.09455974518910823, 0.6171401916106442}, + {0.6209196353232503, 0.09893048328312148, 0.6142567668402714}, + {0.625987078238522, 0.10330809138750463, 0.6113050903371116}, + {0.6310165297116345, 0.10769470016602048, 0.6082874219554474}, + {0.6360082571946242, 0.11208841745759027, 0.6052049784133696}, + {0.6409587158624425, 0.11648801193763364, 0.6020653233567386}, + {0.6458724305886356, 0.120894724408147, 0.5988668588802512}, + {0.6507458962880415, 0.1253053066756304, 0.5956172158180971}, + {0.65558059804725, 0.12972201477991677, 0.59231673323355}, + {0.6603740711643852, 0.13414058702631182, 0.5889711004114799}, + {0.6651285526432004, 0.1385621615837031, 0.5855824728255514}, + {0.669845240296135, 0.1429888560980906, 0.582153977816893}, + {0.6745217289587141, 0.14741542201076516, 0.5786883585907729}, + {0.6791604036855876, 0.15184511348395324, 0.5751888508715063}, + {0.6837578997178535, 0.1562746720253843, 0.5716602384468066}, + {0.6883185616652895, 0.16070636061039098, 0.5681027207214548}, + {0.6928400648216108, 0.16513791277492407, 0.5645221138655818}, + {0.6973235757805955, 0.1695694677210192, 0.5609195098635373}, + {0.7017692243107729, 0.1740021467142358, 0.5572959855617685}, + {0.7061777422578236, 0.17843369623403554, 0.5536573853799269}, + {0.7105493783435904, 0.18286537302055275, 0.5500038553740142}, + {0.7148829033672169, 0.1872959178727836, 0.5463382579948199}, + {0.7191815273421805, 0.19172659246702414, 0.5426627244615733}, + {0.7234440590934259, 0.196155133293472, 0.5389811286444972}, + {0.7276695980921538, 0.20058267652430906, 0.5352935340967259}, + {0.7318622095195731, 0.20501034405621088, 0.5316009984849964}, + {0.7360187549600071, 0.20943588386264006, 0.527908404300108}, + {0.7401433549469377, 0.2138615497973006, 0.5242158683817802}, + {0.7442319068498962, 0.2182850864322064, 0.520524273866664}, + {0.7482894956274093, 0.22270875088361386, 0.516833738969623}, + {0.7523120538611476, 0.2271302847089524, 0.5131491434259574}, + {0.7563036182318114, 0.23155182037018107, 0.509468548147597}, + {0.760264196042346, 0.23597347976619776, 0.505794013908438}, + {0.7641927663268164, 0.24039301314981837, 0.5021264170700042}, + {0.7680903336977949, 0.24481467160443043, 0.49846488562080354}, + {0.7719579098239822, 0.24923420250548467, 0.494813286735782}, + {0.7757964670137317, 0.2536558602885356, 0.49117075886112754}, + {0.7796040489503765, 0.2580753889528994, 0.487539157444613}, + {0.7833826364367662, 0.262496918855311, 0.48391855557538205}, + {0.7871331836672137, 0.2669195732674377, 0.4803070299618413}, + {0.7908547764917832, 0.2713421013551332, 0.4767064258861618}, + {0.7945493142314948, 0.2757677557136531, 0.47311690432863956}, + {0.7982159123706819, 0.2801942814938595, 0.4695382974681735}, + {0.801855440805233, 0.28462393619999926, 0.46597078035645983}, + {0.8054670443253337, 0.28905445984517764, 0.46241517054928255}, + {0.8090525637702202, 0.2934891151740604, 0.4588696581516773}, + {0.8126121722311862, 0.29792563692815727, 0.4553380455774297}, + {0.8161437857429269, 0.3023651595826911, 0.45181643298028346}, + {0.8196512962080388, 0.30680981323456863, 0.44830592266123775}, + {0.8231319147062668, 0.31125833345906073, 0.4448063071891859}, + {0.8265884164961489, 0.31571198854333155, 0.4413158011478088}, + {0.8300180400348914, 0.3201695064581668, 0.43783618296069426}, + {0.8334225331012705, 0.3246331633551905, 0.43436568094830924}, + {0.8368011616192005, 0.3291026789528604, 0.4309050603621552}, + {0.8401547945201179, 0.33357719515430856, 0.42745544005358527}, + {0.8434842793132458, 0.33805985158665625, 0.42401293964429126}, + {0.8467879171814312, 0.3425483651134692, 0.42057931701643003}, + {0.8500663933256695, 0.3470460241716122, 0.41715281999997633}, + {0.853319036312829, 0.35155053489832117, 0.4137341950926385}, + {0.8565475037861691, 0.35606419689875035, 0.4103217013252645}, + {0.8597501517507731, 0.3605857048991911, 0.4069170743064185}, + {0.8629268039532411, 0.36511621303625214, 0.40351944853543975}, + {0.8660782631128492, 0.36965787597771715, 0.4001259551388744}, + {0.8692029205728464, 0.3742093808977564, 0.3967383275867196}, + {0.8723033707464051, 0.37877204764837713, 0.39335483663056486}, + {0.8753760334959819, 0.38334454940566526, 0.38997620732417515}, + {0.8784234745450857, 0.3879302203109463, 0.3865997186779487}, + {0.8814431427224427, 0.3925267186370576, 0.38322908763780417}, + {0.8844358150168464, 0.39713621668929217, 0.3798604589983262}, + {0.8874022475255273, 0.4017598897994324, 0.3764939692996154}, + {0.8903399254603347, 0.40639538423669647, 0.3731303392842935}, + {0.8932503482591801, 0.41104606226907536, 0.3697678512068009}, + {0.8961310320776956, 0.41570955292043654, 0.3664072199362221}, + {0.8989844448210237, 0.42039023641999307, 0.36304673325600695}, + {0.9018071346530614, 0.4250847229961323, 0.35968810073229274}, + {0.9046008288037846, 0.4297942088907302, 0.35632947125103215}, + {0.9073652324299479, 0.4345218955954952, 0.3529699824197478}, + {0.9100979328220618, 0.43926537724749737, 0.3496103521951318}, + {0.9128003257007559, 0.4440270702284773, 0.3462508642176817}, + {0.9154710325568927, 0.4488045475293247, 0.3428902329848131}, + {0.9181094141599885, 0.45360124699433185, 0.3395287458827024}, + {0.9207141279319739, 0.45841471975818476, 0.3361661136226204}, + {0.9232868464124966, 0.463248191094171, 0.3328014851212701}, + {0.9258252179695905, 0.46810089493647095, 0.3294349948733575}, + {0.928328943461609, 0.4729723618415593, 0.32606736582761625}, + {0.9307983028156818, 0.4778650729009944, 0.32269687622031573}, + {0.9332320356689454, 0.48277753475654456, 0.31932524626654357}, + {0.935630382313249, 0.4877102534916354, 0.3159517572279356}, + {0.9379901229720649, 0.4926647102078156, 0.3125751263224191}, + {0.94031286905006, 0.4976391653394365, 0.30919749958566495}, + {0.9425982043994484, 0.5026368889510107, 0.3058160067766645}, + {0.9448439581861301, 0.507655339193432, 0.30243337976158996}, + {0.9470512797767, 0.5126970710073548, 0.2990488875873464}, + {0.9492170420289342, 0.5177605158051324, 0.29566225939396684}, + {0.9513443493064214, 0.5228482560427825, 0.2922747680564989}, + {0.95342812024145, 0.5279576952925963, 0.2888831386174737}, + {0.9554704126542967, 0.5330914441820193, 0.28548964857337034}, + {0.9574691920662094, 0.5382478782970336, 0.2820960181641041}, + {0.9594239777856378, 0.5434283103460965, 0.27870139293719676}, + {0.9613362570153808, 0.5486340651043815, 0.27530489863581714}, + {0.9632030520719662, 0.5538624913974601, 0.2719092715909324}, + {0.9650243153126318, 0.5591162551393607, 0.26851277921609085}, + {0.9667981202444841, 0.5643936755766422, 0.2651181499385089}, + {0.9685263667936735, 0.5696984485228503, 0.26172065963235575}, + {0.9702051814086846, 0.5750258633596333, 0.258325028790098}, + {0.9718350028152128, 0.5803792760776375, 0.25493140399836905}, + {0.973416234677147, 0.5857590553651805, 0.2515399093896209}, + {0.9749470666071361, 0.5911624621207934, 0.24815128177724166}, + {0.9764282806289234, 0.5965932508399702, 0.24476679063210272}, + {0.9778561235005537, 0.6020486514176712, 0.24138715955646184}, + {0.9792333190737449, 0.6075304496592373, 0.23801267291982608}, + {0.980556172868528, 0.6130368443483086, 0.23464603815019064}, + {0.9818260338342485, 0.618569237111758, 0.2312874100772107}, + {0.983041213251059, 0.6241290418881347, 0.2279369200964918}, + {0.984199086129537, 0.6297154282611285, 0.22459528753260782}, + {0.9853012455753073, 0.6353282428938619, 0.22126480373791835}, + {0.9863451305526932, 0.6409666230896872, 0.2179481656192832}, + {0.987332269632511, 0.6466314474784756, 0.21464768988345995}, + {0.988260166889663, 0.6523228213835303, 0.2113640451754461}, + {0.9891280720682684, 0.6580401935630623, 0.20810040712251393}, + {0.989935193134965, 0.6637850245048573, 0.2048589308368297}, + {0.9906811112647872, 0.6695553903969398, 0.20164228467841383}, + {0.9913652104916543, 0.675353231166615, 0.19845282041957812}, + {0.9919851419644327, 0.681176590770927, 0.19529516473738912}, + {0.9925412186450403, 0.6870284413732891, 0.19216971523394297}, + {0.9930321637354537, 0.6929047946873668, 0.18908404856516375}, + {0.9934561180556553, 0.6988071461016482, 0.18604138565745748}, + {0.9938141746253392, 0.7047390032802133, 0.18304294167742508}, + {0.9941031429791255, 0.7106953484789053, 0.18009726563511483}, + {0.9943241754734297, 0.7166792156038955, 0.17720784326567807}, + {0.9944741584952311, 0.7226885545120336, 0.17438115112347216}, + {0.9945531662213939, 0.7287264314705092, 0.17162175513054803}, + {0.994561164165776, 0.7347887640856848, 0.16893804446424532}, + {0.9944951727911301, 0.7408770946176795, 0.16633533149747243}, + {0.9943551582286289, 0.7469929781194636, 0.16382095249343898}, + {0.9941411819033531, 0.7531343027240105, 0.16140421771177754}, + {0.993851140881807, 0.7593021960529095, 0.1590918763664673}, + {0.9934821808433413, 0.7654965143680154, 0.15689111532223957}, + {0.9930331122322037, 0.7717184174350065, 0.15480781781660563}, + {0.9925051688188334, 0.7779647295700995, 0.15285502755098562}, + {0.9918972375664695, 0.7842360395514291, 0.15104222448313137}, + {0.9912091443124736, 0.7905349489016323, 0.1493769620239061}, + {0.9904392291943233, 0.7968562534486284, 0.1478701260432203}, + {0.9895871071514554, 0.8032031721875696, 0.14652892189857109}, + {0.9886482096752364, 0.8095764705517057, 0.1453570476879498}, + {0.9876210577245915, 0.815976398662919, 0.14436290762709728}, + {0.986509178197983, 0.8223986911764639, 0.14355699253114637}, + {0.9853139963633676, 0.8288446279885695, 0.14294492163758302}, + {0.9840311334696324, 0.8353129155540111, 0.14252796680830504}, + {0.9826532853628255, 0.8418092005650518, 0.14230298881977124}, + {0.9811900755223993, 0.8483271434249618, 0.14227897296255487}, + {0.9796442447131871, 0.854863423552606, 0.1424529510156046}, + {0.9779950043835023, 0.8614303744688768, 0.14280800468858543}, + {0.9762651924699953, 0.8680136489692144, 0.14335094248589855}, + {0.9744429204121595, 0.8746206082101065, 0.14406105658536314}, + {0.972530126666216, 0.8812478776950604, 0.14492296106549138}, + {0.9705333468892211, 0.8878931459431306, 0.14591884881454822}, + {0.968443047163475, 0.8945621097233081, 0.14701399877638566}, + {0.9662712851816472, 0.901246373209881, 0.14817986820470014}, + {0.964020955903533, 0.9079483440427187, 0.1493700336843369}, + {0.9616812107840874, 0.9146696029935507, 0.1505199051295305}, + {0.959275857396244, 0.9214055790441742, 0.15156603392174148}, + {0.9568081246010715, 0.9281498350816461, 0.1524089373934798}, + {0.9542874028057909, 0.934905090703852, 0.15292087802256293}, + {0.9517260321586368, 0.9416690683960072, 0.15292489914850274}, + {0.9491513146628231, 0.9484323225943193, 0.1521779775289114}, + {0.9466019493393495, 0.9551882982848324, 0.15032766414862223}, + {0.9441522165792432, 0.9619135560223769, 0.14686103617160504}, + {0.9418959241387963, 0.9685885113553053, 0.14095488309848805}, + {0.9400151278782742, 0.9751557856205376, 0.131325887773911}, +}}; + +template +static constexpr std::array, 256> smooth_cool_warm_data_ = { + {{0.22999950386952345, 0.2989989340493756, 0.754000138575591}, + {0.23451750918602265, 0.30586471825124395, 0.760211287847582}, + {0.23905139222321087, 0.31271835359723077, 0.7663613706951183}, + {0.2436017365913441, 0.3195596165920886, 0.7724494083708939}, + {0.24816908043486074, 0.3263882334026712, 0.7784744332927407}, + {0.25275391815771386, 0.33320388462766504, 0.7844354891865984}, + {0.2573567020073366, 0.34000620954660093, 0.7903316312278389}, + {0.2619778435347082, 0.34679480991553485, 0.7961619261808826}, + {0.26661771494573344, 0.3535692533668808, 0.8019254525370478}, + {0.271276650357161, 0.3603290764626063, 0.8076213006505808}, + {0.27595494696856954, 0.3670737874430388, 0.813248572872804}, + {0.28065286616048707, 0.37380286870769464, 0.8188063836843368}, + {0.28537063452740463, 0.3805157790595848, 0.8242938598253321}, + {0.29010844485334814, 0.3872119557402635, 0.829710140423685}, + {0.29486645703670583, 0.3938908162793105, 0.8350543771211604}, + {0.2996447989701334, 0.4005517601788923, 0.8403257341974003}, + {0.30444356738064665, 0.4071941704514421, 0.8455233886917599}, + {0.3092628286343541, 0.41381741502624314, 0.8506465305229377}, + {0.31410261950970153, 0.42042084803879193, 0.8556943626063482}, + {0.3189629479426216, 0.4270038110151302, 0.8606661009692109}, + {0.32384379374653405, 0.43356563396190284, 0.8655609748633052}, + {0.32874510930975565, 0.4401056363716498, 0.8703782268753609}, + {0.33366682027256384, 0.4466231281517378, 0.8751171130350492}, + {0.33860882618583127, 0.45311741048440196, 0.8797769029205332}, + {0.3435710011529169, 0.45958777662452927, 0.8843568797615591}, + {0.3485531944562718, 0.46603351264108767, 0.8888563405400349}, + {0.3535552311699886, 0.47245389810747423, 0.8932745960880898}, + {0.3585769127594044, 0.47884820674548473, 0.8976109711835649}, + {0.3636180176686533, 0.4852157070271205, 0.9018648046429221}, + {0.3686783018969878, 0.49155566273800605, 0.9060354494115308}, + {0.37375749956453747, 0.49786733350580864, 0.9101222726513168}, + {0.37885532346808715, 0.5041499752967064, 0.9141246558257436}, + {0.38397146562736917, 0.5104028408826495, 0.918041994782103}, + {0.38910559782229387, 0.5166251802818846, 0.9218736998310882}, + {0.39425737212145806, 0.5228162411749818, 0.9256191958236355}, + {0.39942642140225487, 0.5289752692983762, 0.9292779222250065}, + {0.4046123598628117, 0.5351015088172548, 0.9328493331860931}, + {0.4098147835259849, 0.541194202679442, 0.9363328976119261}, + {0.41503327073558766, 0.5472525929517891, 0.9397280992273693}, + {0.4202673826449946, 0.5532759211404236, 0.943034436639982}, + {0.42551666369825586, 0.5592634284961118, 0.9462514234000324}, + {0.43078064210382544, 0.5652143563058468, 0.9493785880576479}, + {0.43605883030099185, 0.5711279461717078, 0.9524154742170866}, + {0.44135072541910086, 0.5770034402779125, 0.9553616405881157}, + {0.4466558097296202, 0.5828400816469308, 0.9582166610344868}, + {0.4519735510911263, 0.5886371143854353, 0.960980124619491}, + {0.457303403387259, 0.5943937839208078, 0.9636516356485881}, + {0.46264480695769356, 0.6001093372288535, 0.9662308137090968}, + {0.4679971890221843, 0.6057830230533238, 0.968717293706932}, + {0.4733599640977317, 0.6114140921177984, 0.9711107259003909}, + {0.4787325344089037, 0.6170017973304325, 0.9734107759309701}, + {0.48411429029138214, 0.6225453939820256, 0.9756171248512094}, + {0.48950461058876166, 0.6280441399378467, 0.9777294691495587}, + {0.49490286304267245, 0.6334972958235978, 0.9797475207722576}, + {0.5003084046762621, 0.6389041252058836, 0.9816710071422271}, + {0.5057205821711058, 0.644263894767512, 0.983499671174965}, + {0.511138732237593, 0.6495758744779339, 0.9852332712914448}, + {0.5165621819788595, 0.654839337759102, 0.9868715814280132}, + {0.5219902492483212, 0.6600535616470082, 0.9884143910432847}, + {0.5274222430008886, 0.6652178269491371, 0.9898615051220324}, + {0.5328574636379119, 0.670331418398056, 0.9912127441760742}, + {0.5382952033459485, 0.6753936248013475, 0.9924679442421503}, + {0.5437347464294153, 0.6804037391880692, 0.9936269568768029}, + {0.5491753696372063, 0.685361058951912, 0.9946896491482432}, + {0.5546163424833603, 0.690264885991224, 0.9956559036252249}, + {0.5600569275618472, 0.695114526846042, 0.9965256183629146}, + {0.5654963808555731, 0.6999092928322662, 0.9972987068857656}, + {0.5709339520396719, 0.7046485001731109, 0.9979750981673984}, + {0.5763688847791901, 0.7093314701279408, 0.9985547366074979}, + {0.5818004170212294, 0.7139575291186055, 0.9990375820057199}, + {0.5872277812816606, 0.7185260088533676, 0.9994236095326229}, + {0.5926502049264796, 0.7230362464485207, 0.9997128096976274}, + {0.5980669104479099, 0.7274875845477786, 0.9999051883140077}, + {0.603477115735333, 0.7318793714395154, 1.0}, + {0.6088800343411463, 0.7362109611719294, 0.9999995804425049}, + {0.6142748757416401, 0.7404817136661965, 0.9999016817439826}, + {0.6196608455929782, 0.7446909948276748, 0.9997071369848932}, + {0.6250371459823868, 0.7488381766552155, 0.9994160278693497}, + {0.6304029756746347, 0.7529226373486367, 0.9990284511333963}, + {0.6357575303538953, 0.7569437614144018, 0.9985445184894549}, + {0.6411000028610946, 0.7609009397695506, 0.9979643565678705}, + {0.6464295834268168, 0.7647935698439208, 0.9972881068555687}, + {0.6517454598998733, 0.7686210556806996, 0.9965159256318358}, + {0.6570468179716188, 0.7723828080353353, 0.9956479839012286}, + {0.6623328413960967, 0.7760782444728409, 0.9946844673236305}, + {0.6676027122061123, 0.7797067894635203, 0.9936255761414589}, + {0.6728556109253114, 0.7832678744771355, 0.9924715251040422}, + {0.6780907167763519, 0.7867609380755451, 0.9912225433891731}, + {0.683307207885253, 0.7901854260038265, 0.9898788745218482}, + {0.6885042614820046, 0.7935407912799094, 0.988440776290216}, + {0.6936810540975126, 0.7968264942827246, 0.9869085206587308}, + {0.6988367617569751, 0.8000420028388932, 0.9852823936785383}, + {0.7039705601697447, 0.8031867923079613, 0.983562695395095}, + {0.7090816249157784, 0.8062603456661956, 0.9817497397530396}, + {0.714169131628733, 0.8092621535889422, 0.9798438544983238}, + {0.7192322561757896, 0.8121917145315617, 0.9778453810776183}, + {0.7242701748342745, 0.8150485348089448, 0.9757546745350029}, + {0.7292820644651583, 0.8178321286736122, 0.9735721034059553}, + {0.7342671026834836, 0.8205420183923986, 0.971298049608644}, + {0.7392244680258144, 0.8231777343217284, 0.9689329083325428}, + {0.7441533401147525, 0.8257388149814784, 0.9664770879243741}, + {0.7490528998206014, 0.8282248071274302, 0.9639310097713906}, + {0.7539223294202332, 0.8306352658223072, 0.9612951081820061}, + {0.7587608127532254, 0.8329697545053927, 0.9585698302637836}, + {0.7635675353753275, 0.8352278450607313, 0.9557556357987903}, + {0.7683416847093205, 0.8374091178838983, 0.9528529971163268}, + {0.7730824501933197, 0.8395131619473374, 0.9498623989630331}, + {0.7777890234265885, 0.8415395748642601, 0.9467843383703861}, + {0.7824605983129111, 0.8434879629510917, 0.9436193245195849}, + {0.7870963712015859, 0.8453579412884608, 0.9403678786038298}, + {0.7916955410260809, 0.8471491337807205, 0.9370305336880028}, + {0.7962573094404225, 0.8488611732139871, 0.933607834565744}, + {0.8007808809533457, 0.8504937013126886, 0.9301003376139276}, + {0.8052654630602748, 0.8520463687946024, 0.9265086106445327}, + {0.8097102663731715, 0.8535188354243787, 0.9228332327539112}, + {0.8141145047483038, 0.854910770065524, 0.9190747941694408}, + {0.8184773954119764, 0.8562218507308311, 0.9152338960935597}, + {0.822798159084272, 0.857451764631246, 0.9113111505451725}, + {0.827076020100851, 0.8586002082231403, 0.9073071801984174}, + {0.8313102065328385, 0.8596668872539794, 0.9032226182187731}, + {0.8354999503048602, 0.8606515168063638, 0.8990581080965018}, + {0.8396444873112505, 0.8615538213404197, 0.8948143034773921}, + {0.8437430575304858, 0.8623735347345196, 0.8904918679907933}, + {0.8477949051378751, 0.8631104003243038, 0.8860914750749006}, + {0.8517992786165454, 0.8637641709399845, 0.8816138077992733}, + {0.8557554308667662, 0.8643346089419015, 0.8770595586845422}, + {0.8596626193136427, 0.8648214862543027, 0.8724294295192715}, + {0.8635201060132168, 0.8652245843973202, 0.8677241311739308}, + {0.8676431881102519, 0.8645140349150363, 0.8626161485985507}, + {0.8719973001889246, 0.8626912788780988, 0.8571344116931553}, + {0.8762551679574422, 0.8607866996599632, 0.8516174449794455}, + {0.8804169678453379, 0.8588005566711197, 0.8460661683343939}, + {0.8844828646854237, 0.8567331182372422, 0.8404815005112565}, + {0.8884530127026752, 0.8545846614985785, 0.834864358985154}, + {0.892327556446231, 0.8523554723065947, 0.829215659800157}, + {0.8961066316684723, 0.8500458451177988, 0.8235363174178995}, + {0.8997903661548088, 0.8476560828846528, 0.8178272445677435}, + {0.9033788805075311, 0.8451864969434798, 0.812089352098517}, + {0.9068722888867912, 0.8426374068992736, 0.8063235488318476}, + {0.910270699711566, 0.8400091405073019, 0.8005307414171138}, + {0.9135742163232042, 0.8373020335514, 0.7947118341880348}, + {0.9167829376139871, 0.8345164297188294, 0.7888677290209213}, + {0.9198969586229171, 0.8316526804715908, 0.7829993251946056}, + {0.9229163711008167, 0.8287111449140491, 0.7771075192520753}, + {0.9258412640466325, 0.8256921896567365, 0.7711932048638259}, + {0.9286717242167226, 0.822596188676188, 0.7652572726929551}, + {0.9314078366087624, 0.8194235231706464, 0.7593006102620192}, + {0.9340496849217929, 0.8161745814114749, 0.7533241018216675}, + {0.9365973519938281, 0.8128497585900935, 0.7473286282210768}, + {0.9390509202183217, 0.8094494566602553, 0.7413150667802011}, + {0.9414104719407324, 0.8059740841754534, 0.7352842911638605}, + {0.9436760898363059, 0.8024240561212462, 0.7292371712576793}, + {0.9458478572701444, 0.7987997937422701, 0.7231745730458999}, + {0.9479258586405416, 0.7951017243636899, 0.717097358491085}, + {0.9499101797065052, 0.7913302812068249, 0.7110063854157246}, + {0.951800907900325, 0.7874859031986702, 0.7049025073857709}, + {0.953598132625986, 0.7835690347750057, 0.6987865735961123}, + {0.9553019455441706, 0.7795801256767763, 0.6926594287580068}, + {0.9569124408445594, 0.7755196307393911, 0.6865219129884912}, + {0.9584297155060683, 0.7713880096745724, 0.6803748617017831}, + {0.9598538695456499, 0.7671857268443542, 0.6742191055026909}, + {0.9611850062562218, 0.7629132510268043, 0.6680554700820523}, + {0.9624232324342575, 0.758571055173009, 0.6618847761142137}, + {0.9635686585975486, 0.7541596161548229, 0.6557078391565709}, + {0.9646213991936067, 0.7496794145028565, 0.6495254695511868}, + {0.9655815727991436, 0.7451309341341271, 0.6433384723285004}, + {0.9664493023110522, 0.7405146620687538, 0.6371476471131512}, + {0.9672247151292687, 0.7358310881350345, 0.6309537880319284}, + {0.9679079433318883, 0.7310807046621858, 0.6247576836238656}, + {0.9684991238428787, 0.7262640061599712, 0.6185601167525033}, + {0.9689983985927076, 0.7213814889843815, 0.612361864520328}, + {0.9694059146721955, 0.7164336509884588, 0.6061636981854146}, + {0.9697218244798756, 0.7114209911572899, 0.5999663830802852}, + {0.9699462858631324, 0.7063440092261024, 0.5937706785330095}, + {0.9700794622533694, 0.7012032052803152, 0.5875773377905578}, + {0.9701215227954475, 0.6959990793362977, 0.5813871079444363}, + {0.9700726424716136, 0.6907321309014792, 0.5752007298586196}, + {0.9699330022201408, 0.6854028585123331, 0.5690189380998024}, + {0.9697027890488664, 0.6800117592486405, 0.5628424608699958}, + {0.9693821961438281, 0.6745593282222776, 0.556672019941486}, + {0.9689714229731695, 0.6690460580386323, 0.5505083305941867}, + {0.968470675386481, 0.663472438228566, 0.5443521015554007}, + {0.9678801657097379, 0.65783895464866, 0.5382040349420275}, + {0.9672001128359847, 0.6521460888472544, 0.5320648262052324}, + {0.9664307423119013, 0.6463943173935754, 0.5259351640776159}, + {0.9655722864203883, 0.6405841111669635, 0.5198157305229032}, + {0.964624984259297, 0.6347159346029446, 0.5137072006881956}, + {0.9635890818164178, 0.6287902448925465, 0.507610242858806}, + {0.9624648320408441, 0.6228074911309212, 0.5015255184157178}, + {0.9612524949108144, 0.6167681134109175, 0.4954536817957061}, + {0.9599523374981328, 0.6106725418568123, 0.4893953804541488}, + {0.9585646340292623, 0.6045211955929051, 0.4833512548305818}, + {0.9570896659431806, 0.5983144816411149, 0.4773219383170267}, + {0.9555277219460815, 0.5920527937410947, 0.47130805722914443}, + {0.9538790980630029, 0.5857365110856726, 0.4653102307802585}, + {0.9521440976864516, 0.5793659969636203, 0.4593290710582975}, + {0.9503230316221086, 0.57294159730086, 0.4533651830057083}, + {0.948416218131665, 0.5664636390902013, 0.4474191644024001}, + {0.9464239829728659, 0.5599324286985411, 0.44149160585177294}, + {0.9443466594368136, 0.5533482500391552, 0.4355830907698924}, + {0.9421845883825966, 0.546711362595224, 0.42969419537788606}, + {0.9399381182692833, 0.5400219992790316, 0.4238254886976179}, + {0.9376076051853501, 0.533280364109342, 0.4179775325507263}, + {0.9351934128755736, 0.5264866296872404, 0.4121508815610997}, + {0.9326959127654463, 0.5196409344481697, 0.40634608316087356}, + {0.9301154839831494, 0.5127433796649743, 0.40056367760003836}, + {0.9274525133791317, 0.5057940261733677, 0.39480419795975347}, + {0.9247073955433249, 0.49879289078734274, 0.38906817016946776}, + {0.9218805328200373, 0.4917399423674949, 0.38335611302795025}, + {0.9189723353205592, 0.4846350974999652, 0.37766853822834884}, + {0.9159832209335118, 0.47747821573754495, 0.37200595038739454}, + {0.9129136153329698, 0.47026909434728564, 0.3663688470788784}, + {0.90976395198439, 0.46300746250050845, 0.36075771887154084}, + {0.9065346721483711, 0.4556929748311352, 0.35517304937151345}, + {0.9032262248822704, 0.44832520427650463, 0.34961531526947287}, + {0.8998390670397057, 0.44090363410085304, 0.34408498639266283}, + {0.896373663267962, 0.43342764898501834, 0.3385825257619646}, + {0.8928304860033279, 0.42589652504602493, 0.33310838965420186}, + {0.8892100154643842, 0.41830941862630455, 0.32766302766986616}, + {0.8855127396432578, 0.4106653536635276, 0.32224688280648867}, + {0.8817391542948727, 0.4029632074170497, 0.31686039153786477}, + {0.8778897629242048, 0.3952016942845104, 0.3115039838993836}, + {0.8739650767715597, 0.3873793473900178, 0.30617808357969667}, + {0.8699656147959004, 0.37949449756134346, 0.30088310801901375}, + {0.8658919036562271, 0.37154524923423027, 0.2956194685142945}, + {0.8617444776910301, 0.3635294527231879, 0.29038757033164536}, + {0.8575238788958367, 0.35544467217440223, 0.2851878128262474}, + {0.8532306568988527, 0.3472881483602095, 0.2800205895701496}, + {0.8488653689347272, 0.33905675527607415, 0.27488628848829755}, + {0.844428579816439, 0.33074694924673165, 0.2697852920031808}, + {0.8399208619053304, 0.3223547089197083, 0.26471797718851403}, + {0.835342795079293, 0.3138754640964424, 0.2596847159323806}, + {0.8306949666991194, 0.30530401078823033, 0.25468587511031116}, + {0.825977971573034, 0.2966344091359757, 0.24972181676877747}, + {0.8211924119194148, 0.28785985982733997, 0.2447928983196327}, + {0.8163388973277163, 0.2789725532777859, 0.23989947274604145}, + {0.8114180447176049, 0.2699634839588782, 0.2350418888204895}, + {0.8064304782963232, 0.2608222196264688, 0.230220491335487}, + {0.8013768295142913, 0.25153661146923556, 0.2254356213476219}, + {0.7962577370189533, 0.24209242581295431, 0.22068761643565016}, + {0.7910738466068946, 0.2324728700992567, 0.21597681097335308}, + {0.785825811174225, 0.22265797397565007, 0.2113035364179236}, + {0.7805142906652605, 0.21262376808227257, 0.20666812161469034}, + {0.7751399520194979, 0.20234117434687338, 0.2020708931190197}, + {0.7697034691169152, 0.19177447487857652, 0.19751217553628297}, + {0.7642055227215985, 0.18087914808905534, 0.19299229188080813}, + {0.7586468004237221, 0.16959872367321424, 0.18851156395477772}, + {0.7530279965798936, 0.15786005774647732, 0.18407031274806854}, + {0.7473498122518853, 0.1455659466237694, 0.17966885886006054}, + {0.7416129551437725, 0.13258300379739485, 0.1753075229444704}, + {0.7358181395374971, 0.11872050682883606, 0.17098662617829208}, + {0.729966086226886, 0.1036904371731237, 0.16670649075593325}, + {0.7240575224501452, 0.08702339888581809, 0.1624674404096517}, + {0.7180931818208612, 0.06786174152286231, 0.15826980095738155}, + {0.712073804257538, 0.04430319728532283, 0.15411390087901955}, + {0.7060001359117047, 0.015991824033980695, 0.15000007192220008}}}; + +template +static constexpr std::array, 256> viridis_data_ = { + {{0.2670039853213788, 0.0048725657145795975, 0.32941506855247793}, + {0.26850981914385313, 0.009602990407952114, 0.33542640725404194}, + {0.2699440291511295, 0.014623657659867702, 0.34137927634304566}, + {0.271304877824855, 0.01994002237673082, 0.3472686291318146}, + {0.27259406260318486, 0.0255617891189931, 0.3530934750332732}, + {0.27380892621369024, 0.03149509118386225, 0.3588528426972369}, + {0.27495208578509805, 0.03775096330071057, 0.36454366367333946}, + {0.27602196419599767, 0.04416532238909473, 0.3701640471152313}, + {0.2770178542655486, 0.050341751402647274, 0.37571443702683854}, + {0.2779409905222335, 0.05632269668695442, 0.381191238867294}, + {0.2787908952957126, 0.06214312525024266, 0.386591645366443}, + {0.27956600607518295, 0.06783500475980075, 0.39191741935399227}, + {0.2802669260610985, 0.07341543578584622, 0.3971628433351474}, + {0.2808940110629919, 0.07890627296909186, 0.402329588370124}, + {0.2814459462121492, 0.08431870698834085, 0.4074140304183279}, + {0.2819238934697361, 0.08966415929405766, 0.4124144814203868}, + {0.2823269547340802, 0.09495395414045926, 0.4173312035070467}, + {0.28265591676374746, 0.10019440706631136, 0.42215967285462885}, + {0.2829099523467409, 0.10539218382981966, 0.42690236327520725}, + {0.2830909293924702, 0.11055163703080462, 0.43155385240026206}, + {0.2831969393871863, 0.11567940038180258, 0.4361155100499537}, + {0.2832289314889045, 0.1207758539544326, 0.4405840195472734}, + {0.2831869362255922, 0.1258463172454443, 0.4449595399107695}, + {0.28307192228564804, 0.13089406218358995, 0.4492411716459423}, + {0.28288394120635924, 0.1359185257084681, 0.45342671165618736}, + {0.2826229022373855, 0.1409252633679265, 0.4575173087262126}, + {0.28228993571972105, 0.14591072658175047, 0.46150987016675354}, + {0.28188687220607433, 0.1508804582163323, 0.46540543189260436}, + {0.2814119198278991, 0.15583292129399035, 0.4692010151483717}, + {0.28086783263625503, 0.16077064757597467, 0.4728995412212838}, + {0.28025489346354565, 0.16569211148611415, 0.47649814467710355}, + {0.2795739667261627, 0.17059758179728512, 0.47999676019204823}, + {0.2788258570423396, 0.1754892977307652, 0.48339725816565043}, + {0.27801194338413965, 0.1803657682817326, 0.4866968956818299}, + {0.27713381181214125, 0.18522747944269774, 0.4898983578428951}, + {0.27619391034977797, 0.19007295088871226, 0.49300101709660177}, + {0.2751907580349635, 0.19490465707076896, 0.49600544367769356}, + {0.2741278682015853, 0.19972012989770083, 0.4989111236465034}, + {0.2730059901819072, 0.20451860824383267, 0.501720814888259}, + {0.2718278175684958, 0.2093023055918103, 0.5044342141093779}, + {0.270594950010942, 0.21406778548878086, 0.5070519265124999}, + {0.269307759397765, 0.21881747729569145, 0.5095772914792083}, + {0.26796790172934454, 0.22354795925559695, 0.5120080244602125}, + {0.26657969502130613, 0.22826164495517987, 0.5143493563955112}, + {0.2651448458327315, 0.23295512949133207, 0.5165991088272563}, + {0.2636630077044143, 0.23762961892442647, 0.518761871180001}, + {0.2621377837546321, 0.2422852962306279, 0.5208371781925083}, + {0.2605709530063988, 0.2469207884353261, 0.5228279594551629}, + {0.2589647163025411, 0.25153645885437026, 0.5247362360674637}, + {0.25732189181335147, 0.2561289544795441, 0.526563035336139}, + {0.2556446444203948, 0.2607026175814763, 0.5283122832934375}, + {0.25393482507335086, 0.26525311670734747, 0.529983099667603}, + {0.2521940157752079, 0.2697816202890161, 0.5315789243388298}, + {0.25042475493562577, 0.27428927505771267, 0.5331031508732055}, + {0.24862894949587117, 0.27877378236392025, 0.5345559912288645}, + {0.2468106816724398, 0.2832364292997213, 0.535941192655048}, + {0.24497187865778625, 0.28767394082010833, 0.5372600476888723}, + {0.24311260591427697, 0.2920915797036902, 0.5385162258554254}, + {0.24123680455606578, 0.29648409536913767, 0.5397090946733651}, + {0.23934601183850307, 0.30085361498147906, 0.5408439702969619}, + {0.23744072960970264, 0.3052012458833173, 0.54192113151443}, + {0.23552593740524197, 0.30952576959302097, 0.5429440191062838}, + {0.23360265375847195, 0.3138273924379346, 0.5439141607822711}, + {0.2316738606254108, 0.31810492063632195, 0.5448340596245334}, + {0.22973857739190007, 0.3223605353157074, 0.545706183707169}, + {0.22780178259701628, 0.3265930678980134, 0.5465320928009385}, + {0.2258629950192772, 0.3308036038834664, 0.547314007363377}, + {0.22392470580707102, 0.33499321123505194, 0.5480531185864527}, + {0.22198891605799553, 0.33915975136273824, 0.5487520417750932}, + {0.22005663012512805, 0.34330635098841344, 0.5494131386548431}, + {0.2181298368119725, 0.34743089526543186, 0.550038069892983}, + {0.21620955549289145, 0.3515344874402382, 0.5506271540883877}, + {0.21429775792403594, 0.3556180358438001, 0.5511840927098516}, + {0.21239496605173308, 0.3596815871313281, 0.5517100354247325}, + {0.21050268170035974, 0.36372617292766, 0.5522061103879761}, + {0.20862288591525807, 0.36775072789850616, 0.5526750588505742}, + {0.20675560837319001, 0.3717573067826811, 0.5531171238472018}, + {0.20490280700807212, 0.3757448655138847, 0.5535330780419422}, + {0.203062536964648, 0.3797154379631177, 0.5539251341179698}, + {0.20123872979412472, 0.3836690001875795, 0.554294093380729}, + {0.1994294675547129, 0.3876065665572156, 0.5546421417067892}, + {0.19763565582691228, 0.39152713200801975, 0.5549691052245624}, + {0.1958598486981541, 0.39543169955970453, 0.5552760714931869}, + {0.19409958576782552, 0.3993222611485653, 0.5555651140662646}, + {0.19235677239756216, 0.40319783169922974, 0.5558360841919235}, + {0.19063051802725675, 0.4070603881536437, 0.5560891205440711}, + {0.18892269821185473, 0.41090896152858886, 0.5563260943031525}, + {0.18723045233808386, 0.4147455132535933, 0.5565471249886993}, + {0.185555627191317, 0.4185690891632772, 0.5567531019269415}, + {0.18389780714307888, 0.42238166634427127, 0.5569440809497231}, + {0.18225556044836397, 0.4261832146898191, 0.5571201071543374}, + {0.1806287343914301, 0.4299737941881375, 0.5572820892587651}, + {0.17901849569766765, 0.43375533862493676, 0.5574301104997077}, + {0.1774226636398102, 0.4375259202510252, 0.55756509546256}, + {0.17584043270381128, 0.4412894613100537, 0.5576851118285253}, + {0.17427359528182015, 0.4450430447202011, 0.557792099701029}, + {0.17271876393003963, 0.4487896287788335, 0.557885089501858}, + {0.1711755310919842, 0.45252916766885326, 0.5579651016381476}, + {0.1696456943850158, 0.4562607533360476, 0.5580300944043132}, + {0.1681254681463012, 0.4599872896301423, 0.5580821016030234}, + {0.1666166265008438, 0.46370687659642523, 0.5581190973303202}, + {0.16511640601237285, 0.46742241082026353, 0.5581410993753088}, + {0.1636245598287687, 0.47113199888460483, 0.5581480982786068}, + {0.1621417205544945, 0.4748365872638394, 0.5581400991890099}, + {0.16066449675721917, 0.4785391201733818, 0.5581150965608792}, + {0.15919365349458042, 0.48223570943504873, 0.5580731010879704}, + {0.15772843426155927, 0.48593124098759627, 0.5580130923782937}, + {0.1562695869579672, 0.4896228308128307, 0.5579361006261909}, + {0.1548143719173188, 0.49331236133238937, 0.5578400853105705}, + {0.1533635209362011, 0.4969989517366848, 0.5577240977120556}, + {0.1519176771981809, 0.5006835421001327, 0.5575871128989297}, + {0.15047545758720676, 0.504368072136516, 0.557430091404037}, + {0.14903861048813108, 0.5080496628380102, 0.5572501110986087}, + {0.1476063950561745, 0.5117321922659829, 0.5570490817856095}, + {0.14617954401090907, 0.5154117832267491, 0.5568231063967104}, + {0.14475833306803976, 0.519092312358787, 0.5565720684276931}, + {0.14334247788386512, 0.522771903366683, 0.5562950984952888}, + {0.141934629618203, 0.5264514940838813, 0.5559911321954153}, + {0.14053541463564725, 0.5301310233517843, 0.5556590862704173}, + {0.13914656229528236, 0.5338106140906136, 0.555298125858835}, + {0.13776935391441048, 0.5374911432800976, 0.5549060695018647}, + {0.13640749570156585, 0.5411717339632349, 0.5544831157469011}, + {0.13506529616957136, 0.544852263189304, 0.554029048083696}, + {0.13374243075510836, 0.5485338538220298, 0.5535411013024801}, + {0.13244357030675505, 0.5522144442800521, 0.553018159322021}, + {0.13117137121614486, 0.5558979736087772, 0.5524590815222541}, + {0.12993250302214393, 0.5595805638443141, 0.5518641468320762}, + {0.12872831884644725, 0.5632640933331003, 0.5512290558865701}, + {0.12756743939839627, 0.5669476835219266, 0.5505561295873137}, + {0.12645227472350737, 0.5706322130377723, 0.5498410244005342}, + {0.12539338154311577, 0.5743168031831126, 0.5490861069146677}, + {0.12439424184336756, 0.5780013325949876, 0.5482869865182912}, + {0.12346233479357416, 0.5816859227477941, 0.5474450777703374}, + {0.122605426766972, 0.5853695126930177, 0.5465571752923358}, + {0.12183030409088419, 0.5890540421334565, 0.5456230413386914}, + {0.1211473750007544, 0.592737632144662, 0.5446411489781364}, + {0.12056429075653713, 0.5964211612480832, 0.5436109978665574}, + {0.12009133699819924, 0.6001027515502533, 0.5425301161500574}, + {0.11973729926029653, 0.6037842799987541, 0.541399947187814}, + {0.11951131929191963, 0.6074628706490315, 0.5402180758379009}, + {0.11942233180714437, 0.6111394611583431, 0.5389822116295199}, + {0.11948233048502255, 0.6148159892453784, 0.537692026866569}, + {0.11969830860262576, 0.6184885802617517, 0.5363471743826108}, + {0.12008036996652452, 0.6221601072840744, 0.5349459699054088}, + {0.12063730989641286, 0.6258266990315783, 0.5334881295553462}, + {0.1213794417235072, 0.6294912247800063, 0.5319729045347256}, + {0.12231134108889466, 0.6331518172152074, 0.5303980764654408}, + {0.1234432274542607, 0.6368074097895444, 0.5287632561537092}, + {0.12477941321977204, 0.6404599344231255, 0.5270680133779303}, + {0.12632525332983902, 0.6441055281645606, 0.5253112061650272}, + {0.1280865204366354, 0.6477480507159987, 0.5234909414076758}, + {0.1300663115014182, 0.6513826457355586, 0.5216081476931036}, + {0.13226766345372454, 0.6550131658699597, 0.5196608602452112}, + {0.1346914034616326, 0.6586347623899736, 0.5176490803131216}, + {0.13733813187439356, 0.6622503590720668, 0.5155713087695435}, + {0.1402095413205375, 0.6658578775169739, 0.5134270017152724}, + {0.14330221816701194, 0.6694574760216492, 0.511215244517751}, + {0.14661571262857995, 0.6730489911445044, 0.5089359136232384}, + {0.15014733747892414, 0.6766295918037593, 0.5065891708280766}, + {0.1538939151679172, 0.6802021032660456, 0.5041718156197705}, + {0.15785048833835377, 0.6837637060778221, 0.5016860876044946}, + {0.162015053737826, 0.6873143096440719, 0.49912936913057365}, + {0.1663826794355118, 0.6908548182506177, 0.49650199274870527}, + {0.17094719748923695, 0.6943824243247052, 0.4938032891165472}, + {0.1757068993715085, 0.6978989283401605, 0.4910328874274477}, + {0.18065236935056878, 0.7014005373289202, 0.4881891991816308}, + {0.18578314370608157, 0.704890036301888, 0.48527277191686385}, + {0.19108956697744361, 0.7083646483099804, 0.48228409897291785}, + {0.19656998786638302, 0.7118252614850998, 0.4792214366155811}, + {0.20221879696964223, 0.7152707565867668, 0.47608398702197946}, + {0.2080291781284243, 0.7186993731402823, 0.47287333975819085}, + {0.21400005157818647, 0.7221128620832928, 0.4695878639271211}, + {0.22012339076765558, 0.7255074824139881, 0.46622623255251056}, + {0.22639732501345455, 0.7288869647642494, 0.46278873032462237}, + {0.2328146240063111, 0.7322455890831692, 0.45927711461163473}, + {0.2393729244291451, 0.7355862151598742, 0.4556885106741981}, + {0.2460698827335157, 0.7389086924367883, 0.452023984943217}, + {0.25289815079190964, 0.742209322598094, 0.44828439600718756}, + {0.2598571632843528, 0.745490792270686, 0.4444668436999196}, + {0.2669403953805219, 0.7487494270612788, 0.44057327076578856}, + {0.27414945925613216, 0.7519868887012355, 0.43660069156818965}, + {0.28147665665716626, 0.755201528324013, 0.43255213457796365}, + {0.2889217691195198, 0.7583929812556258, 0.42842552870164097}, + {0.2964789382360529, 0.7615596257155389, 0.4242229866985808}, + {0.3041471124530943, 0.7647022727239619, 0.41994345744752104}, + {0.31192524014449496, 0.7678207187194435, 0.41558582710182396}, + {0.31980838304287407, 0.7709123713051562, 0.41115231354707876}, + {0.32779655496333804, 0.7739788075712202, 0.40663965647349865}, + {0.33588466791449195, 0.7770164660401522, 0.4020491587042435}, + {0.34407488193371133, 0.7800278920656099, 0.3973804752308849}, + {0.3523599689997323, 0.7830095562872507, 0.3926359923281875}, + {0.36074006346245197, 0.7859622236060678, 0.3878145232212208}, + {0.36921428939455786, 0.7888866412701451, 0.38291381435701694}, + {0.37777835651210034, 0.7917793150973379, 0.37793936040098913}, + {0.3864336209519174, 0.7946427215203885, 0.3728856256306759}, + {0.3951736619954228, 0.797473402038798, 0.3677571865876491}, + {0.4040019632351159, 0.8002737966998706, 0.3625514261814766}, + {0.4129129804482464, 0.8030394840252982, 0.3572690015831872}, + {0.4219070059826357, 0.805772174900056, 0.3519105924567475}, + {0.4309833172715677, 0.8084715598896897, 0.3464758054878499}, + {0.4401363189373519, 0.8111362580724669, 0.34096741055434293}, + {0.44936866381374757, 0.8137666304213753, 0.3353835991203212}, + {0.458673642833963, 0.8163613360822743, 0.32972721765157326}, + {0.46805401938353625, 0.8189196953983692, 0.3239973827222524}, + {0.47750397699915853, 0.8214424087022711, 0.3181950138984179}, + {0.48702494316955264, 0.8239271261653897, 0.31232166294182256}, + {0.49661532811633474, 0.8263744743966721, 0.306376800619062}, + {0.5062702739767431, 0.8287841998369972, 0.3003624619571904}, + {0.5159926874598648, 0.8311565342261135, 0.2942785778807102}, + {0.5257756141542576, 0.8334892678013092, 0.28812725033290043}, + {0.5356220541188685, 0.8357835879688815, 0.28190734645112897}, + {0.5455239631257167, 0.838037329833802, 0.2756260283833135}, + {0.5554828787549823, 0.8402520764412206, 0.2692817313403921}, + {0.5654983251339641, 0.8424283847332169, 0.2628767994071899}, + {0.5755622254006186, 0.8445641394621258, 0.25641551104548627}, + {0.5856786942007215, 0.8466594333420596, 0.24989656346356887}, + {0.5958385796727564, 0.8487151964088427, 0.2433292811877542}, + {0.6060460684908495, 0.8507314758177834, 0.2367113216835447}, + {0.616292940650758, 0.8527072471488548, 0.23005204277336477}, + {0.6265778183939344, 0.8546430238400886, 0.2233537871857682}, + {0.6369023105271391, 0.8565402909227283, 0.2166198017460239}, + {0.6472561782044223, 0.8583980753432965, 0.2098615478515251}, + {0.6576426853779066, 0.8602173283504794, 0.20308155987152815}, + {0.6680535433907611, 0.8619971207604976, 0.19629330158139313}, + {0.6784900623681449, 0.8637403601361504, 0.18950231977185272}, + {0.6889439127328617, 0.86544616002535, 0.18272505128011118}, + {0.6994137684819729, 0.8671149653844072, 0.17597180349415806}, + {0.7098982863987701, 0.868749193048019, 0.1692568079838667}, + {0.7203901380970731, 0.8703480050687866, 0.16260354455700873}, + {0.7308896616716263, 0.8719142204262896, 0.1560285800997179}, + {0.7413875101130836, 0.873447039008859, 0.1495612865358065}, + {0.7518850354669301, 0.8749492431662675, 0.14322737498076443}, + {0.7623728828501631, 0.8764220675983936, 0.13706403823168214}, + {0.7728534061279669, 0.8778662616531304, 0.13110820913488913}, + {0.7833152551224711, 0.8792830913055214, 0.1254048217206159}, + {0.7937591112086629, 0.880675925144139, 0.12000541978485552}, + {0.8041826246822775, 0.8820441108502998, 0.11496466377053949}, + {0.8145754845039437, 0.8833909489919768, 0.11034716773962891}, + {0.8249409891695173, 0.8847181273467387, 0.10621658195896774}, + {0.8352698545299048, 0.8860269688856748, 0.1026459672214125}, + {0.8455623467619914, 0.8873201416511192, 0.09970160643955417}, + {0.8558102197403156, 0.8885989857373076, 0.09745185636949635}, + {0.8660121015321746, 0.8898658327014707, 0.09595302142849352}, + {0.876168577861264, 0.8911230006650279, 0.09524987622820644}, + {0.8862704693847823, 0.8923718488516762, 0.09537386433165168}, + {0.8963209276849421, 0.8936140145545759, 0.09633501924437288}, + {0.9063108305457804, 0.8948528630958348, 0.0981248266153556}, + {0.916243267627844, 0.8960890285051739, 0.10071727474383468}, + {0.9261061834911258, 0.8973278764153646, 0.10407091253184719}, + {0.9359031089867296, 0.8985677257631529, 0.10813047743488122}, + {0.9456365256783655, 0.899812890310841, 0.112838121119233}, + {0.9552994651064829, 0.9010627378634819, 0.11812754907477127}, + {0.9648948576822979, 0.9023209051300205, 0.12394140017411451}, + {0.9744168120052771, 0.9035877501583347, 0.13021471316475502}, + {0.9838691793408701, 0.9048649215326077, 0.13689772464133854}, + {0.9932481489335602, 0.9061547634208059, 0.14393594366968385}}}; + +template +inline std::array +color_map_(Real scalar, std::array, 256> const &table) { + static_assert(std::is_floating_point_v, + "Color tables are only implemented in floating point " + "arithmetic. If you require bytes please submit an issue or " + "pull request"); + + using boost::math::isnan; + + if ((isnan)(scalar)) + { + scalar = static_cast(0); + } + else + { + scalar = std::clamp(scalar, static_cast(0), static_cast(1)); + } + + if (scalar == static_cast(1)) { + return table.back(); + } + + Real s = (table.size() - 1) * scalar; + Real ii = std::floor(s); + Real t = s - ii; + auto i = static_cast(ii); + auto const &rgb0 = table[i]; + auto const &rgb1 = table[i + 1]; + return {(1 - t) * rgb0[0] + t * rgb1[0], (1 - t) * rgb0[1] + t * rgb1[1], + (1 - t) * rgb0[2] + t * rgb1[2]}; +} +} // namespace detail + +template std::array viridis(Real x) { + return detail::color_map_(x, detail::viridis_data_); +} + +template std::array smooth_cool_warm(Real x) { + return detail::color_map_(x, detail::smooth_cool_warm_data_); +} + +template std::array plasma(Real x) { + return detail::color_map_(x, detail::plasma_data_); +} + +template std::array black_body(Real x) { + return detail::color_map_(x, detail::black_body_data_); +} + +template std::array inferno(Real x) { + return detail::color_map_(x, detail::inferno_data_); +} + +template std::array kindlmann(Real x) { + return detail::color_map_(x, detail::kindlmann_data_); +} + +template +std::array extended_kindlmann(Real x) { + return detail::color_map_(x, detail::extended_kindlmann_data_); +} + +template +std::array to_8bit_rgba(const std::array &v) { + using std::sqrt; + std::array pixel {}; + for (auto i = 0; i < 3; ++i) { + // Apply gamma correction here: + Real u = sqrt(v[i]); + pixel[i] = 255 * std::clamp(u, static_cast(0), static_cast(1)); + } + + pixel[3] = 255; + return pixel; +} + +} // Namespace boost::math::tools + +#endif // BOOST_MATH_COLOR_MAPS_HPP diff --git a/libcxx/src/third-party/boost/math/tools/complex.hpp b/libcxx/src/third-party/boost/math/tools/complex.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/complex.hpp @@ -0,0 +1,76 @@ +// Copyright John Maddock 2018. +// 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) + +// +// Tools for operator on complex as well as scalar types. +// + +#ifndef BOOST_MATH_TOOLS_COMPLEX_HPP +#define BOOST_MATH_TOOLS_COMPLEX_HPP + +#include +#include + +namespace boost { + namespace math { + namespace tools { + + namespace detail { + template + struct is_complex_type_impl + { + static constexpr bool value = false; + }; + + template + struct is_complex_type_impl().real()), + decltype(std::declval().imag())>> + { + static constexpr bool value = true; + }; + } // Namespace detail + + template + struct is_complex_type : public detail::is_complex_type_impl {}; + + // + // Use this trait to typecast integer literals to something + // that will interoperate with T: + // + template ::value> + struct integer_scalar_type + { + typedef int type; + }; + template + struct integer_scalar_type + { + typedef typename T::value_type type; + }; + template ::value> + struct unsigned_scalar_type + { + typedef unsigned type; + }; + template + struct unsigned_scalar_type + { + typedef typename T::value_type type; + }; + template ::value> + struct scalar_type + { + typedef T type; + }; + template + struct scalar_type + { + typedef typename T::value_type type; + }; + + +} } } + +#endif // BOOST_MATH_TOOLS_COMPLEX_HPP diff --git a/libcxx/src/third-party/boost/math/tools/concepts.hpp b/libcxx/src/third-party/boost/math/tools/concepts.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/concepts.hpp @@ -0,0 +1,24 @@ +// (C) Copyright Matt Borland 2022. +// 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) +// +// Macros that substitute for STL concepts or typename depending on availability of + +#ifndef BOOST_MATH_TOOLS_CONCEPTS_HPP +#define BOOST_MATH_TOOLS_CONCEPTS_HPP + +// LLVM clang supports concepts but apple's clang does not fully support at version 13 +// See: https://en.cppreference.com/w/cpp/compiler_support/20 +#if (__cplusplus > 202000L || _MSVC_LANG > 202000L) +# if __has_include() && (!defined(__APPLE__) || (defined(__APPLE__) && defined(__clang__) && __clang__ > 13)) +# include +# define BOOST_MATH_FLOATING_POINT_TYPE std::floating_point +# else +# define BOOST_MATH_FLOATING_POINT_TYPE typename +# endif +#else +# define BOOST_MATH_FLOATING_POINT_TYPE typename +#endif + +#endif // BOOST_MATH_TOOLS_CONCEPTS_HPP diff --git a/libcxx/src/third-party/boost/math/tools/condition_numbers.hpp b/libcxx/src/third-party/boost/math/tools/condition_numbers.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/condition_numbers.hpp @@ -0,0 +1,143 @@ +// (C) Copyright Nick Thompson 2019. +// 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_TOOLS_CONDITION_NUMBERS_HPP +#define BOOST_MATH_TOOLS_CONDITION_NUMBERS_HPP +#include +#include +#include + +namespace boost::math::tools { + +template +class summation_condition_number { +public: + summation_condition_number(Real const x = 0) + { + using std::abs; + m_l1 = abs(x); + m_sum = x; + m_c = 0; + } + + void operator+=(Real const & x) + { + using std::abs; + // No need to Kahan the l1 calc; it's well conditioned: + m_l1 += abs(x); + if constexpr(kahan) + { + Real y = x - m_c; + Real t = m_sum + y; + m_c = (t-m_sum) -y; + m_sum = t; + } + else + { + m_sum += x; + } + } + + inline void operator-=(Real const & x) + { + this->operator+=(-x); + } + + // Is operator*= relevant? Presumably everything gets rescaled, + // (m_sum -> k*m_sum, m_l1->k*m_l1, m_c->k*m_c), + // but is this sensible? More important is it useful? + // In addition, it might change the condition number. + + [[nodiscard]] Real operator()() const + { + using std::abs; + if (m_sum == Real(0) && m_l1 != Real(0)) + { + return std::numeric_limits::infinity(); + } + return m_l1/abs(m_sum); + } + + [[nodiscard]] Real sum() const + { + // Higham, 1993, "The Accuracy of Floating Point Summation": + // "In [17] and [18], Kahan describes a variation of compensated summation in which the final sum is also corrected + // thus s=s+e is appended to the algorithm above)." + return m_sum + m_c; + } + + [[nodiscard]] Real l1_norm() const + { + return m_l1; + } + +private: + Real m_l1; + Real m_sum; + Real m_c; +}; + +template +Real evaluation_condition_number(F const & f, Real const & x) +{ + using std::abs; + using std::isnan; + using std::sqrt; + using boost::math::differentiation::finite_difference_derivative; + + Real fx = f(x); + if (isnan(fx)) + { + return std::numeric_limits::quiet_NaN(); + } + bool caught_exception = false; + Real fp; +#ifndef BOOST_NO_EXCEPTIONS + try + { +#endif + fp = finite_difference_derivative(f, x); +#ifndef BOOST_NO_EXCEPTIONS + } + catch(...) + { + caught_exception = true; + } +#endif + if (isnan(fp) || caught_exception) + { + // Check if the right derivative exists: + fp = finite_difference_derivative(f, x); + if (isnan(fp)) + { + // Check if a left derivative exists: + const Real eps = (std::numeric_limits::epsilon)(); + Real h = - 2 * sqrt(eps); + h = boost::math::differentiation::detail::make_xph_representable(x, h); + Real yh = f(x + h); + Real y0 = f(x); + Real diff = yh - y0; + fp = diff / h; + if (isnan(fp)) + { + return std::numeric_limits::quiet_NaN(); + } + } + } + + if (fx == 0) + { + if (x==0 || fp==0) + { + return std::numeric_limits::quiet_NaN(); + } + return std::numeric_limits::infinity(); + } + + return abs(x*fp/fx); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/config.hpp b/libcxx/src/third-party/boost/math/tools/config.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/config.hpp @@ -0,0 +1,604 @@ +// Copyright (c) 2006-7 John Maddock +// Copyright (c) 2021 Matt Borland +// 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_TOOLS_CONFIG_HPP +#define BOOST_MATH_TOOLS_CONFIG_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +// Minimum language standard transition +#ifdef _MSVC_LANG +# if _MSVC_LANG < 201402L +# pragma warning("The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)"); +# endif +#else +# if __cplusplus < 201402L +# warning "The minimum language standard to use Boost.Math will be C++14 starting in July 2023 (Boost 1.82 release)" +# endif +#endif + +#ifndef BOOST_MATH_STANDALONE +#include + +#else // Things from boost/config that are required, and easy to replicate + +#define BOOST_PREVENT_MACRO_SUBSTITUTION +#define BOOST_MATH_NO_REAL_CONCEPT_TESTS +#define BOOST_MATH_NO_DISTRIBUTION_CONCEPT_TESTS +#define BOOST_MATH_NO_LEXICAL_CAST + +// Since Boost.Multiprecision is in active development some tests do not fully cooperate yet. +#define BOOST_MATH_NO_MP_TESTS + +#if (__cplusplus > 201400L || _MSVC_LANG > 201400L) +#define BOOST_CXX14_CONSTEXPR constexpr +#else +#define BOOST_CXX14_CONSTEXPR +#define BOOST_NO_CXX14_CONSTEXPR +#endif // BOOST_CXX14_CONSTEXPR + +#if (__cplusplus > 201700L || _MSVC_LANG > 201700L) +#define BOOST_IF_CONSTEXPR if constexpr + +// Clang on mac provides the execution header with none of the functionality. TODO: Check back on this +// https://en.cppreference.com/w/cpp/compiler_support "Standardization of Parallelism TS" +#if !__has_include() || (defined(__APPLE__) && defined(__clang__)) +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif +#else +#define BOOST_IF_CONSTEXPR if +#define BOOST_NO_CXX17_IF_CONSTEXPR +#define BOOST_NO_CXX17_HDR_EXECUTION +#endif + +#if __cpp_lib_gcd_lcm >= 201606L +#define BOOST_MATH_HAS_CXX17_NUMERIC +#endif + +#define BOOST_JOIN(X, Y) BOOST_DO_JOIN(X, Y) +#define BOOST_DO_JOIN(X, Y) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2(X, Y) X##Y + +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +#ifdef BOOST_DISABLE_THREADS // No threads, do nothing +// Detect thread support via STL implementation +#elif defined(__has_include) +# if !__has_include() || !__has_include() || !__has_include() || !__has_include() +# define BOOST_DISABLE_THREADS +# else +# define BOOST_HAS_THREADS +# endif +#else +# define BOOST_HAS_THREADS // The default assumption is that the machine has threads +#endif // Thread Support + +#ifdef BOOST_DISABLE_THREADS +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif // BOOST_DISABLE_THREADS + +#ifdef __GNUC__ +# if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +# endif + // + // Make sure we have some std lib headers included so we can detect __GXX_RTTI: + // +# include // for min and max +# include +# ifndef __GXX_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif +# endif +#endif + +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // nvcc doesn't always parse __noinline__, + // see: https://svn.boost.org/trac/boost/ticket/9392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# elif defined(__HIP__) + // See https://github.com/boostorg/config/issues/392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# else +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# endif +# else +# define BOOST_NOINLINE +# endif +#endif + +#if !defined(BOOST_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_FORCEINLINE inline +# endif +#endif + +#endif // BOOST_MATH_STANDALONE + +// Support compilers with P0024R2 implemented without linking TBB +// https://en.cppreference.com/w/cpp/compiler_support +#if !defined(BOOST_NO_CXX17_HDR_EXECUTION) && defined(BOOST_HAS_THREADS) +# define BOOST_MATH_EXEC_COMPATIBLE +#endif + +// Attributes from C++14 and newer +#ifdef __has_cpp_attribute + +// C++17 +#if (__cplusplus >= 201703L || _MSVC_LANG >= 201703L) +# if __has_cpp_attribute(maybe_unused) +# define BOOST_MATH_MAYBE_UNUSED [[maybe_unused]] +# endif +#endif + +#endif + +// If attributes are not defined make sure we don't have compiler errors +#ifndef BOOST_MATH_MAYBE_UNUSED +# define BOOST_MATH_MAYBE_UNUSED +#endif + +#include // for min and max +#include +#include +#include +#include +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) +# include +#endif + +#include + +#if (defined(__NetBSD__) || defined(__EMSCRIPTEN__)\ + || (defined(__hppa) && !defined(__OpenBSD__)) || (defined(__NO_LONG_DOUBLE_MATH) && (DBL_MANT_DIG != LDBL_MANT_DIG))) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +//# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif + +#ifdef __IBMCPP__ +// +// For reasons I don't understand, the tests with IMB's compiler all +// pass at long double precision, but fail with real_concept, those tests +// are disabled for now. (JM 2012). +#ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS +# define BOOST_MATH_NO_REAL_CONCEPT_TESTS +#endif // BOOST_MATH_NO_REAL_CONCEPT_TESTS +#endif +#ifdef sun +// Any use of __float128 in program startup code causes a segfault (tested JM 2015, Solaris 11). +# define BOOST_MATH_DISABLE_FLOAT128 +#endif +#ifdef __HAIKU__ +// +// Not sure what's up with the math detection on Haiku, but linking fails with +// float128 code enabled, and we don't have an implementation of __expl, so +// disabling long double functions for now as well. +# define BOOST_MATH_DISABLE_FLOAT128 +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +// +// Darwin's rather strange "double double" is rather hard to +// support, it should be possible given enough effort though... +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) && (LDBL_MANT_DIG == 106) && (LDBL_MIN_EXP > DBL_MIN_EXP) +// +// Generic catch all case for gcc's "double-double" long double type. +// We do not support this as it's not even remotely IEEE conforming: +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if defined(unix) && defined(__INTEL_COMPILER) && (__INTEL_COMPILER <= 1000) && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +// +// Intel compiler prior to version 10 has sporadic problems +// calling the long double overloads of the std lib math functions: +// calling ::powl is OK, but std::pow(long double, long double) +// may segfault depending upon the value of the arguments passed +// and the specific Linux distribution. +// +// We'll be conservative and disable long double support for this compiler. +// +// Comment out this #define and try building the tests to determine whether +// your Intel compiler version has this issue or not. +// +# define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +#endif +#if defined(unix) && defined(__INTEL_COMPILER) +// +// Intel compiler has sporadic issues compiling std::fpclassify depending on +// the exact OS version used. Use our own code for this as we know it works +// well on Intel processors: +// +#define BOOST_MATH_DISABLE_STD_FPCLASSIFY +#endif + +#if defined(_MSC_VER) && !defined(_WIN32_WCE) + // Better safe than sorry, our tests don't support hardware exceptions: +# define BOOST_MATH_CONTROL_FP _control87(MCW_EM,MCW_EM) +#endif + +#ifdef __IBMCPP__ +# define BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS +#endif + +#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)) +# define BOOST_MATH_USE_C99 +#endif + +#if (defined(__hpux) && !defined(__hppa)) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(__GNUC__) && defined(_GLIBCXX_USE_C99) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(_LIBCPP_VERSION) && !defined(_MSC_VER) +# define BOOST_MATH_USE_C99 +#endif + +#if defined(__CYGWIN__) || defined(__HP_aCC) || defined(__INTEL_COMPILER) \ + || defined(BOOST_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY) \ + || (defined(__GNUC__) && !defined(BOOST_MATH_USE_C99))\ + || defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_MATH_NO_NATIVE_LONG_DOUBLE_FP_CLASSIFY +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x590) + +namespace boost { namespace math { namespace tools { namespace detail { +template +struct type {}; + +template +struct non_type {}; +}}}} // Namespace boost, math tools, detail + +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) boost::math::tools::detail::type* = 0 +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::math::tools::detail::type* +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::math::tools::detail::non_type* = 0 +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::math::tools::detail::non_type* + +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \ + , BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +#else + +// no workaround needed: expand to nothing + +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + + +#endif // __SUNPRO_CC + +#if (defined(__SUNPRO_CC) || defined(__hppa) || defined(__GNUC__)) && !defined(BOOST_MATH_SMALL_CONSTANT) +// Sun's compiler emits a hard error if a constant underflows, +// as does aCC on PA-RISC, while gcc issues a large number of warnings: +# define BOOST_MATH_SMALL_CONSTANT(x) 0.0 +#else +# define BOOST_MATH_SMALL_CONSTANT(x) x +#endif + +// +// Tune performance options for specific compilers: +// +#ifdef _MSC_VER +# define BOOST_MATH_POLY_METHOD 2 +#if _MSC_VER <= 1900 +# define BOOST_MATH_RATIONAL_METHOD 1 +#else +# define BOOST_MATH_RATIONAL_METHOD 2 +#endif +#if _MSC_VER > 1900 +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L +#endif + +#elif defined(__INTEL_COMPILER) +# define BOOST_MATH_POLY_METHOD 2 +# define BOOST_MATH_RATIONAL_METHOD 1 + +#elif defined(__GNUC__) +#if __GNUC__ < 4 +# define BOOST_MATH_POLY_METHOD 3 +# define BOOST_MATH_RATIONAL_METHOD 3 +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L +#else +# define BOOST_MATH_POLY_METHOD 3 +# define BOOST_MATH_RATIONAL_METHOD 3 +#endif + +#elif defined(__clang__) + +#if __clang__ > 6 +# define BOOST_MATH_POLY_METHOD 3 +# define BOOST_MATH_RATIONAL_METHOD 3 +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) RT +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##.0L +#endif + +#endif + +// +// noexcept support: +// +#include +#define BOOST_MATH_NOEXCEPT(T) noexcept(std::is_floating_point::value) +#define BOOST_MATH_IS_FLOAT(T) (std::is_floating_point::value) + +// +// The maximum order of polynomial that will be evaluated +// via an unrolled specialisation: +// +#ifndef BOOST_MATH_MAX_POLY_ORDER +# define BOOST_MATH_MAX_POLY_ORDER 20 +#endif +// +// Set the method used to evaluate polynomials and rationals: +// +#ifndef BOOST_MATH_POLY_METHOD +# define BOOST_MATH_POLY_METHOD 2 +#endif +#ifndef BOOST_MATH_RATIONAL_METHOD +# define BOOST_MATH_RATIONAL_METHOD 1 +#endif +// +// decide whether to store constants as integers or reals: +// +#ifndef BOOST_MATH_INT_TABLE_TYPE +# define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT +#endif +#ifndef BOOST_MATH_INT_VALUE_SUFFIX +# define BOOST_MATH_INT_VALUE_SUFFIX(RV, SUF) RV##SUF +#endif +// +// And then the actual configuration: +// +#if defined(BOOST_MATH_STANDALONE) && defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) && !defined(__STRICT_ANSI__) \ + && !defined(BOOST_MATH_DISABLE_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128) +# define BOOST_MATH_USE_FLOAT128 +#elif defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MATH_USE_FLOAT128) +# define BOOST_MATH_USE_FLOAT128 +#endif +#ifdef BOOST_MATH_USE_FLOAT128 +// +// Only enable this when the compiler really is GCC as clang and probably +// intel too don't support __float128 yet :-( +// +# if defined(__INTEL_COMPILER) && defined(__GNUC__) +# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) +# define BOOST_MATH_FLOAT128_TYPE __float128 +# endif +# elif defined(__GNUC__) +# define BOOST_MATH_FLOAT128_TYPE __float128 +# endif + +# ifndef BOOST_MATH_FLOAT128_TYPE +# define BOOST_MATH_FLOAT128_TYPE _Quad +# endif +#endif +// +// Check for WinCE with no iostream support: +// +#if defined(_WIN32_WCE) && !defined(__SGI_STL_PORT) +# define BOOST_MATH_NO_LEXICAL_CAST +#endif + +// +// Helper macro for controlling the FP behaviour: +// +#ifndef BOOST_MATH_CONTROL_FP +# define BOOST_MATH_CONTROL_FP +#endif +// +// Helper macro for using statements: +// +#define BOOST_MATH_STD_USING_CORE \ + using std::abs;\ + using std::acos;\ + using std::cos;\ + using std::fmod;\ + using std::modf;\ + using std::tan;\ + using std::asin;\ + using std::cosh;\ + using std::frexp;\ + using std::pow;\ + using std::tanh;\ + using std::atan;\ + using std::exp;\ + using std::ldexp;\ + using std::sin;\ + using std::atan2;\ + using std::fabs;\ + using std::log;\ + using std::sinh;\ + using std::ceil;\ + using std::floor;\ + using std::log10;\ + using std::sqrt; + +#define BOOST_MATH_STD_USING BOOST_MATH_STD_USING_CORE + +namespace boost{ namespace math{ +namespace tools +{ + +template +inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c) BOOST_MATH_NOEXCEPT(T) +{ + return (std::max)((std::max)(a, b), c); +} + +template +inline T max BOOST_PREVENT_MACRO_SUBSTITUTION(T a, T b, T c, T d) BOOST_MATH_NOEXCEPT(T) +{ + return (std::max)((std::max)(a, b), (std::max)(c, d)); +} + +} // namespace tools + +template +void suppress_unused_variable_warning(const T&) BOOST_MATH_NOEXCEPT(T) +{ +} + +namespace detail{ + +template +struct is_integer_for_rounding +{ + static constexpr bool value = std::is_integral::value || (std::numeric_limits::is_specialized && std::numeric_limits::is_integer); +}; + +} + +}} // namespace boost namespace math + +#ifdef __GLIBC_PREREQ +# if __GLIBC_PREREQ(2,14) +# define BOOST_MATH_HAVE_FIXED_GLIBC +# endif +#endif + +#if ((defined(__linux__) && !defined(__UCLIBC__) && !defined(BOOST_MATH_HAVE_FIXED_GLIBC)) || defined(__QNX__) || defined(__IBMCPP__)) +// +// This code was introduced in response to this glibc bug: http://sourceware.org/bugzilla/show_bug.cgi?id=2445 +// Basically powl and expl can return garbage when the result is small and certain exception flags are set +// on entrance to these functions. This appears to have been fixed in Glibc 2.14 (May 2011). +// Much more information in this message thread: https://groups.google.com/forum/#!topic/boost-list/ZT99wtIFlb4 +// + +#include + +# ifdef FE_ALL_EXCEPT + +namespace boost{ namespace math{ + namespace detail + { + struct fpu_guard + { + fpu_guard() + { + fegetexceptflag(&m_flags, FE_ALL_EXCEPT); + feclearexcept(FE_ALL_EXCEPT); + } + ~fpu_guard() + { + fesetexceptflag(&m_flags, FE_ALL_EXCEPT); + } + private: + fexcept_t m_flags; + }; + + } // namespace detail + }} // namespaces + +# define BOOST_FPU_EXCEPTION_GUARD boost::math::detail::fpu_guard local_guard_object; +# define BOOST_MATH_INSTRUMENT_FPU do{ fexcept_t cpu_flags; fegetexceptflag(&cpu_flags, FE_ALL_EXCEPT); BOOST_MATH_INSTRUMENT_VARIABLE(cpu_flags); } while(0); + +# else + +# define BOOST_FPU_EXCEPTION_GUARD +# define BOOST_MATH_INSTRUMENT_FPU + +# endif + +#else // All other platforms. +# define BOOST_FPU_EXCEPTION_GUARD +# define BOOST_MATH_INSTRUMENT_FPU +#endif + +#ifdef BOOST_MATH_INSTRUMENT + +# include +# include +# include + +# define BOOST_MATH_INSTRUMENT_CODE(x) \ + std::cout << std::setprecision(35) << __FILE__ << ":" << __LINE__ << " " << x << std::endl; +# define BOOST_MATH_INSTRUMENT_VARIABLE(name) BOOST_MATH_INSTRUMENT_CODE(#name << " = " << name) + +#else + +# define BOOST_MATH_INSTRUMENT_CODE(x) +# define BOOST_MATH_INSTRUMENT_VARIABLE(name) + +#endif + +// +// Thread local storage: +// +#ifndef BOOST_DISABLE_THREADS +# define BOOST_MATH_THREAD_LOCAL thread_local +#else +# define BOOST_MATH_THREAD_LOCAL +#endif + +// +// Some mingw flavours have issues with thread_local and types with non-trivial destructors +// See https://sourceforge.net/p/mingw-w64/bugs/527/ +// +#if (defined(__MINGW32__) && (__GNUC__ < 9) && !defined(__clang__)) +# define BOOST_MATH_NO_THREAD_LOCAL_WITH_NON_TRIVIAL_TYPES +#endif + + +// +// Can we have constexpr tables? +// +#if (!defined(BOOST_NO_CXX14_CONSTEXPR)) || (defined(_MSC_VER) && _MSC_VER >= 1910) +#define BOOST_MATH_HAVE_CONSTEXPR_TABLES +#define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION constexpr +#else +#define BOOST_MATH_CONSTEXPR_TABLE_FUNCTION +#endif + + +#endif // BOOST_MATH_TOOLS_CONFIG_HPP + + + + diff --git a/libcxx/src/third-party/boost/math/tools/convert_from_string.hpp b/libcxx/src/third-party/boost/math/tools/convert_from_string.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/convert_from_string.hpp @@ -0,0 +1,54 @@ +// Copyright John Maddock 2016. +// 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_TOOLS_CONVERT_FROM_STRING_INCLUDED +#define BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace boost{ namespace math{ namespace tools{ + + template + struct convert_from_string_result + { + typedef typename std::conditional::value, const char*, T>::type type; + }; + + template + Real convert_from_string(const char* p, const std::false_type&) + { +#ifdef BOOST_MATH_NO_LEXICAL_CAST + // This function should not compile, we don't have the necessary functionality to support it: + static_assert(sizeof(Real) == 0, "boost.lexical_cast is not supported in standalone mode."); + (void)p; // Supresses -Wunused-parameter + return Real(0); +#else + return boost::lexical_cast(p); +#endif + } + template + constexpr const char* convert_from_string(const char* p, const std::true_type&) noexcept + { + return p; + } + template + constexpr typename convert_from_string_result::type convert_from_string(const char* p) noexcept((std::is_constructible::value)) + { + return convert_from_string(p, std::is_constructible()); + } + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_CONVERT_FROM_STRING_INCLUDED + diff --git a/libcxx/src/third-party/boost/math/tools/cubic_roots.hpp b/libcxx/src/third-party/boost/math/tools/cubic_roots.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/cubic_roots.hpp @@ -0,0 +1,176 @@ +// (C) Copyright Nick Thompson 2021. +// 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_TOOLS_CUBIC_ROOTS_HPP +#define BOOST_MATH_TOOLS_CUBIC_ROOTS_HPP +#include +#include +#include +#include + +namespace boost::math::tools { + +// Solves ax^3 + bx^2 + cx + d = 0. +// Only returns the real roots, as types get weird for real coefficients and +// complex roots. Follows Numerical Recipes, Chapter 5, section 6. NB: A better +// algorithm apparently exists: Algorithm 954: An Accurate and Efficient Cubic +// and Quartic Equation Solver for Physical Applications However, I don't have +// access to that paper! +template +std::array cubic_roots(Real a, Real b, Real c, Real d) { + using std::abs; + using std::acos; + using std::cbrt; + using std::cos; + using std::fma; + using std::sqrt; + std::array roots = {std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN()}; + if (a == 0) { + // bx^2 + cx + d = 0: + if (b == 0) { + // cx + d = 0: + if (c == 0) { + if (d != 0) { + // No solutions: + return roots; + } + roots[0] = 0; + roots[1] = 0; + roots[2] = 0; + return roots; + } + roots[0] = -d / c; + return roots; + } + auto [x0, x1] = quadratic_roots(b, c, d); + roots[0] = x0; + roots[1] = x1; + return roots; + } + if (d == 0) { + auto [x0, x1] = quadratic_roots(a, b, c); + roots[0] = x0; + roots[1] = x1; + roots[2] = 0; + std::sort(roots.begin(), roots.end()); + return roots; + } + Real p = b / a; + Real q = c / a; + Real r = d / a; + Real Q = (p * p - 3 * q) / 9; + Real R = (2 * p * p * p - 9 * p * q + 27 * r) / 54; + if (R * R < Q * Q * Q) { + Real rtQ = sqrt(Q); + Real theta = acos(R / (Q * rtQ)) / 3; + Real st = sin(theta); + Real ct = cos(theta); + roots[0] = -2 * rtQ * ct - p / 3; + roots[1] = -rtQ * (-ct + sqrt(Real(3)) * st) - p / 3; + roots[2] = rtQ * (ct + sqrt(Real(3)) * st) - p / 3; + } else { + // In Numerical Recipes, Chapter 5, Section 6, it is claimed that we + // only have one real root if R^2 >= Q^3. But this isn't true; we can + // even see this from equation 5.6.18. The condition for having three + // real roots is that A = B. It *is* the case that if we're in this + // branch, and we have 3 real roots, two are a double root. Take + // (x+1)^2(x-2) = x^3 - 3x -2 as an example. This clearly has a double + // root at x = -1, and it gets sent into this branch. + Real arg = R * R - Q * Q * Q; + Real A = (R >= 0 ? -1 : 1) * cbrt(abs(R) + sqrt(arg)); + Real B = 0; + if (A != 0) { + B = Q / A; + } + roots[0] = A + B - p / 3; + // Yes, we're comparing floats for equality: + // Any perturbation pushes the roots into the complex plane; out of the + // bailiwick of this routine. + if (A == B || arg == 0) { + roots[1] = -A - p / 3; + roots[2] = -A - p / 3; + } + } + // Root polishing: + for (auto &r : roots) { + // Horner's method. + // Here I'll take John Gustaffson's opinion that the fma is a *distinct* + // operation from a*x +b: Make sure to compile these fmas into a single + // instruction and not a function call! (I'm looking at you Windows.) + Real f = fma(a, r, b); + f = fma(f, r, c); + f = fma(f, r, d); + Real df = fma(3 * a, r, 2 * b); + df = fma(df, r, c); + if (df != 0) { + Real d2f = fma(6 * a, r, 2 * b); + Real denom = 2 * df * df - f * d2f; + if (denom != 0) { + r -= 2 * f * df / denom; + } else { + r -= f / df; + } + } + } + std::sort(roots.begin(), roots.end()); + return roots; +} + +// Computes the empirical residual p(r) (first element) and expected residual +// eps*|rp'(r)| (second element) for a root. Recall that for a numerically +// computed root r satisfying r = r_0(1+eps) of a function p, |p(r)| <= +// eps|rp'(r)|. +template +std::array cubic_root_residual(Real a, Real b, Real c, Real d, + Real root) { + using std::abs; + using std::fma; + std::array out; + Real residual = fma(a, root, b); + residual = fma(residual, root, c); + residual = fma(residual, root, d); + + out[0] = residual; + + // The expected residual is: + // eps*[4|ar^3| + 3|br^2| + 2|cr| + |d|] + // This can be demonstrated by assuming the coefficients and the root are + // perturbed according to the rounding model of floating point arithmetic, + // and then working through the inequalities. + root = abs(root); + Real expected_residual = fma(4 * abs(a), root, 3 * abs(b)); + expected_residual = fma(expected_residual, root, 2 * abs(c)); + expected_residual = fma(expected_residual, root, abs(d)); + out[1] = expected_residual * std::numeric_limits::epsilon(); + return out; +} + +// Computes the condition number of rootfinding. This is defined in Corless, A +// Graduate Introduction to Numerical Methods, Section 3.2.1. +template +Real cubic_root_condition_number(Real a, Real b, Real c, Real d, Real root) { + using std::abs; + using std::fma; + // There are *absolute* condition numbers that can be defined when r = 0; + // but they basically reduce to the residual computed above. + if (root == static_cast(0)) { + return std::numeric_limits::infinity(); + } + + Real numerator = fma(abs(a), abs(root), abs(b)); + numerator = fma(numerator, abs(root), abs(c)); + numerator = fma(numerator, abs(root), abs(d)); + Real denominator = fma(3 * a, root, 2 * b); + denominator = fma(denominator, root, c); + if (denominator == static_cast(0)) { + return std::numeric_limits::infinity(); + } + denominator *= root; + return numerator / abs(denominator); +} + +} // namespace boost::math::tools +#endif diff --git a/libcxx/src/third-party/boost/math/tools/cxx03_warn.hpp b/libcxx/src/third-party/boost/math/tools/cxx03_warn.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/cxx03_warn.hpp @@ -0,0 +1,95 @@ +// Copyright (c) 2020 John Maddock +// 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_TOOLS_CXX03_WARN_HPP +#define BOOST_MATH_TOOLS_CXX03_WARN_HPP + +#include + +#if defined(BOOST_NO_CXX11_NOEXCEPT) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NOEXCEPT" +#endif +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_RVALUE_REFERENCES" +#endif +#if defined(BOOST_NO_SFINAE_EXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_SFINAE_EXPR" +#endif +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_AUTO_DECLARATIONS" +#endif +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_LAMBDAS" +#endif +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX" +#endif +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_TUPLE" +#endif +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_INITIALIZER_LIST" +#endif +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_CHRONO" +#endif +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_CONSTEXPR" +#endif +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NULLPTR" +#endif +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_NUMERIC_LIMITS" +#endif +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_DECLTYPE" +#endif +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_HDR_ARRAY" +#endif +#if defined(BOOST_NO_CXX11_ALLOCATOR) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_ALLOCATOR" +#endif +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_MATH_SHOW_CXX03_WARNING) +# define BOOST_MATH_SHOW_CXX03_WARNING +# define BOOST_MATH_CXX03_WARN_REASON "BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS" +#endif + +#ifdef BOOST_MATH_SHOW_CXX03_WARNING +// +// The above list includes everything we use, plus a few we're likely to use soon. +// As from March 2020, C++03 support is deprecated, and as from March 2021 will be removed, +// so mark up as such: +// +// March 2021(mborland): C++03 support has been removed. Replace warning with hard error. +// +#error Support for C++03 has been removed. The minimum requirement for this library is fully compliant C++11. +#endif + +#endif diff --git a/libcxx/src/third-party/boost/math/tools/detail/is_const_iterable.hpp b/libcxx/src/third-party/boost/math/tools/detail/is_const_iterable.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/is_const_iterable.hpp @@ -0,0 +1,38 @@ +// (C) Copyright John Maddock 2018. +// 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_TOOLS_IS_CONST_ITERABLE_HPP +#define BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP + +#include + +#define BOOST_MATH_HAS_IS_CONST_ITERABLE + +#include +#include + +namespace boost { + namespace math { + namespace tools { + namespace detail { + + template + using begin_t = decltype(std::declval().begin()); + template + using end_t = decltype(std::declval().end()); + template + using const_iterator_t = typename T::const_iterator; + + template + struct is_const_iterable + : public std::integral_constant::value + && is_detected::value + && is_detected::value + > {}; + +} } } } + +#endif // BOOST_MATH_TOOLS_IS_CONST_ITERABLE_HPP diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_10.hpp @@ -0,0 +1,84 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_11.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_12.hpp @@ -0,0 +1,96 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_13.hpp @@ -0,0 +1,102 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_14.hpp @@ -0,0 +1,108 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_15.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_16.hpp @@ -0,0 +1,120 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_17.hpp @@ -0,0 +1,126 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_18.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_19.hpp @@ -0,0 +1,138 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_2.hpp @@ -0,0 +1,36 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_20.hpp @@ -0,0 +1,144 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_3.hpp @@ -0,0 +1,42 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_5.hpp @@ -0,0 +1,54 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_6.hpp @@ -0,0 +1,60 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_7.hpp @@ -0,0 +1,66 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_8.hpp @@ -0,0 +1,72 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner1_9.hpp @@ -0,0 +1,78 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_10.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_11.hpp @@ -0,0 +1,97 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_12.hpp @@ -0,0 +1,104 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_13.hpp @@ -0,0 +1,111 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_14.hpp @@ -0,0 +1,118 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_15.hpp @@ -0,0 +1,125 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_16.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_17.hpp @@ -0,0 +1,139 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_18.hpp @@ -0,0 +1,146 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_19.hpp @@ -0,0 +1,153 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_20.hpp @@ -0,0 +1,160 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_5.hpp @@ -0,0 +1,55 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_6.hpp @@ -0,0 +1,62 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_7.hpp @@ -0,0 +1,69 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_8.hpp @@ -0,0 +1,76 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner2_9.hpp @@ -0,0 +1,83 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast(((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + return static_cast((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_10.hpp @@ -0,0 +1,156 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_10_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_11.hpp @@ -0,0 +1,181 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_11_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_12.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_12_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_13.hpp @@ -0,0 +1,237 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_13_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_14.hpp @@ -0,0 +1,268 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_14_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_15.hpp @@ -0,0 +1,301 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_15_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_16.hpp @@ -0,0 +1,336 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_16_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_17.hpp @@ -0,0 +1,373 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_17_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_18.hpp @@ -0,0 +1,412 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_18_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_19.hpp @@ -0,0 +1,453 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_19_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[18] * x2 + a[16]); + t[1] = static_cast(a[17] * x2 + a[15]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_2_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_20.hpp @@ -0,0 +1,496 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[10] * x2 + a[8]); + t[1] = static_cast(a[9] * x2 + a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[12] * x2 + a[10]); + t[1] = static_cast(a[11] * x2 + a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[14] * x2 + a[12]); + t[1] = static_cast(a[13] * x2 + a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[16] * x2 + a[14]); + t[1] = static_cast(a[15] * x2 + a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[18] * x2 + a[16]); + t[1] = static_cast(a[17] * x2 + a[15]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[19] * x2 + a[17]; + t[1] = a[18] * x2 + a[16]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[15]); + t[1] += static_cast(a[14]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_3_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_4_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_5.hpp @@ -0,0 +1,61 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_5_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_6.hpp @@ -0,0 +1,76 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_6_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_7.hpp @@ -0,0 +1,93 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_7_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_8.hpp @@ -0,0 +1,112 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_8_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/polynomial_horner3_9.hpp @@ -0,0 +1,133 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Unrolled polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_EVAL_9_HPP +#define BOOST_MATH_TOOLS_POLY_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[1] * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[2] * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[3] * x + a[2]) * x + a[1]) * x + a[0]); +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[4] * x2 + a[2]); + t[1] = static_cast(a[3] * x2 + a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[6] * x2 + a[4]); + t[1] = static_cast(a[5] * x2 + a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[0] *= x; + return t[0] + t[1]; +} + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + V x2 = x * x; + V t[2]; + t[0] = static_cast(a[8] * x2 + a[6]); + t[1] = static_cast(a[7] * x2 + a[5]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[0] *= x2; + t[1] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[0] *= x2; + t[0] += static_cast(a[0]); + t[1] *= x; + return t[0] + t[1]; +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_10.hpp @@ -0,0 +1,138 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_10_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_11.hpp @@ -0,0 +1,150 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_11_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_12.hpp @@ -0,0 +1,162 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_12_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_13.hpp @@ -0,0 +1,174 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_13_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_14.hpp @@ -0,0 +1,186 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_14_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_15.hpp @@ -0,0 +1,198 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_15_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_16.hpp @@ -0,0 +1,210 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_16_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_17.hpp @@ -0,0 +1,222 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_17_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_18.hpp @@ -0,0 +1,234 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_18_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_19.hpp @@ -0,0 +1,246 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_19_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_2.hpp @@ -0,0 +1,42 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_2_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_20.hpp @@ -0,0 +1,258 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_20_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((a[9] * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((b[9] * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) / (((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((a[10] * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((b[10] * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) / ((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((a[11] * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((b[11] * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) / (((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((a[12] * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((b[12] * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) / ((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((a[13] * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((b[13] * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) / (((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((a[14] * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((b[14] * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) / ((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((a[15] * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((b[15] * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) / (((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((a[16] * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((b[16] * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) / ((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((((a[17] * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((b[17] * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) / (((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((((((((((((a[18] * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((((((((((((b[18] * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) / ((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((((((((((((((a[19] * x + a[18]) * x + a[17]) * x + a[16]) * x + a[15]) * x + a[14]) * x + a[13]) * x + a[12]) * x + a[11]) * x + a[10]) * x + a[9]) * x + a[8]) * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((((((((((((((b[19] * x + b[18]) * x + b[17]) * x + b[16]) * x + b[15]) * x + b[14]) * x + b[13]) * x + b[12]) * x + b[11]) * x + b[10]) * x + b[9]) * x + b[8]) * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((((((((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) * z + a[9]) * z + a[10]) * z + a[11]) * z + a[12]) * z + a[13]) * z + a[14]) * z + a[15]) * z + a[16]) * z + a[17]) * z + a[18]) * z + a[19]) / (((((((((((((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8]) * z + b[9]) * z + b[10]) * z + b[11]) * z + b[12]) * z + b[13]) * z + b[14]) * z + b[15]) * z + b[16]) * z + b[17]) * z + b[18]) * z + b[19])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_3.hpp @@ -0,0 +1,54 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_3_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_4.hpp @@ -0,0 +1,66 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_4_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_5.hpp @@ -0,0 +1,78 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_5_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_6.hpp @@ -0,0 +1,90 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_6_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_7.hpp @@ -0,0 +1,102 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_7_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_8.hpp @@ -0,0 +1,114 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_8_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner1_9.hpp @@ -0,0 +1,126 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using Horners rule +#ifndef BOOST_MATH_TOOLS_POLY_RAT_9_HPP +#define BOOST_MATH_TOOLS_POLY_RAT_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); + else + { + V z = 1 / x; + return static_cast((a[0] * z + a[1]) / (b[0] * z + b[1])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((a[0] * z + a[1]) * z + a[2]) / ((b[0] * z + b[1]) * z + b[2])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) / (((b[0] * z + b[1]) * z + b[2]) * z + b[3])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((a[4] * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((b[4] * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) / ((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((a[5] * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((b[5] * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) / (((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((a[6] * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((b[6] * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) / ((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast((((((((a[7] * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / (((((((b[7] * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) / (((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + return static_cast(((((((((a[8] * x + a[7]) * x + a[6]) * x + a[5]) * x + a[4]) * x + a[3]) * x + a[2]) * x + a[1]) * x + a[0]) / ((((((((b[8] * x + b[7]) * x + b[6]) * x + b[5]) * x + b[4]) * x + b[3]) * x + b[2]) * x + b[1]) * x + b[0])); + else + { + V z = 1 / x; + return static_cast(((((((((a[0] * z + a[1]) * z + a[2]) * z + a[3]) * z + a[4]) * z + a[5]) * z + a[6]) * z + a[7]) * z + a[8]) / ((((((((b[0] * z + b[1]) * z + b[2]) * z + b[3]) * z + b[4]) * z + b[5]) * z + b[6]) * z + b[7]) * z + b[8])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_10.hpp @@ -0,0 +1,144 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_11.hpp @@ -0,0 +1,160 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_12.hpp @@ -0,0 +1,176 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_13.hpp @@ -0,0 +1,192 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_14.hpp @@ -0,0 +1,208 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_15.hpp @@ -0,0 +1,224 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_16.hpp @@ -0,0 +1,240 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_17.hpp @@ -0,0 +1,256 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_18.hpp @@ -0,0 +1,272 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_19.hpp @@ -0,0 +1,288 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_20.hpp @@ -0,0 +1,304 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((a[9] * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((b[9] * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10] + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z) / (((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10] + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((a[10] * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((b[10] * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z + ((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z + ((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((a[11] * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((b[11] * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12] + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z) / ((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12] + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((a[12] * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((b[12] * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z + (((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z + (((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((a[13] * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((b[13] * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14] + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z) / (((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14] + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((a[14] * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((b[14] * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z + ((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z + ((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((((((a[15] * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((((((b[15] * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16] + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z) / ((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16] + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + (((((((a[16] * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / (((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + (((((((b[16] * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z + (((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z + (((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((((((((a[17] * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / (((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((((((((b[17] * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18] + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z) / (((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18] + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((((((((a[19] * x2 + a[17]) * x2 + a[15]) * x2 + a[13]) * x2 + a[11]) * x2 + a[9]) * x2 + a[7]) * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((((((((a[18] * x2 + a[16]) * x2 + a[14]) * x2 + a[12]) * x2 + a[10]) * x2 + a[8]) * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((((((((b[19] * x2 + b[17]) * x2 + b[15]) * x2 + b[13]) * x2 + b[11]) * x2 + b[9]) * x2 + b[7]) * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((((((((b[18] * x2 + b[16]) * x2 + b[14]) * x2 + b[12]) * x2 + b[10]) * x2 + b[8]) * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((((((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8]) * z2 + a[10]) * z2 + a[12]) * z2 + a[14]) * z2 + a[16]) * z2 + a[18]) * z + ((((((((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z2 + a[9]) * z2 + a[11]) * z2 + a[13]) * z2 + a[15]) * z2 + a[17]) * z2 + a[19]) / ((((((((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8]) * z2 + b[10]) * z2 + b[12]) * z2 + b[14]) * z2 + b[16]) * z2 + b[18]) * z + ((((((((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z2 + b[9]) * z2 + b[11]) * z2 + b[13]) * z2 + b[15]) * z2 + b[17]) * z2 + b[19])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_5.hpp @@ -0,0 +1,64 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_6.hpp @@ -0,0 +1,80 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_7.hpp @@ -0,0 +1,96 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_8.hpp @@ -0,0 +1,112 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner2_9.hpp @@ -0,0 +1,128 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((a[4] * x2 + a[2]) * x2 + a[0] + (a[3] * x2 + a[1]) * x) / ((b[4] * x2 + b[2]) * x2 + b[0] + (b[3] * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((a[0] * z2 + a[2]) * z2 + a[4] + (a[1] * z2 + a[3]) * z) / ((b[0] * z2 + b[2]) * z2 + b[4] + (b[1] * z2 + b[3]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[5] * x2 + a[3]) * x2 + a[1]) * x + (a[4] * x2 + a[2]) * x2 + a[0]) / (((b[5] * x2 + b[3]) * x2 + b[1]) * x + (b[4] * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z + (a[1] * z2 + a[3]) * z2 + a[5]) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z + (b[1] * z2 + b[3]) * z2 + b[5])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast((((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + ((a[5] * x2 + a[3]) * x2 + a[1]) * x) / (((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + ((b[5] * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6] + ((a[1] * z2 + a[3]) * z2 + a[5]) * z) / (((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6] + ((b[1] * z2 + b[3]) * z2 + b[5]) * z)); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x + ((a[6] * x2 + a[4]) * x2 + a[2]) * x2 + a[0]) / ((((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x + ((b[6] * x2 + b[4]) * x2 + b[2]) * x2 + b[0])); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z + ((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z + ((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7])); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + return static_cast(((((a[8] * x2 + a[6]) * x2 + a[4]) * x2 + a[2]) * x2 + a[0] + (((a[7] * x2 + a[5]) * x2 + a[3]) * x2 + a[1]) * x) / ((((b[8] * x2 + b[6]) * x2 + b[4]) * x2 + b[2]) * x2 + b[0] + (((b[7] * x2 + b[5]) * x2 + b[3]) * x2 + b[1]) * x)); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + return static_cast(((((a[0] * z2 + a[2]) * z2 + a[4]) * z2 + a[6]) * z2 + a[8] + (((a[1] * z2 + a[3]) * z2 + a[5]) * z2 + a[7]) * z) / ((((b[0] * z2 + b[2]) * z2 + b[4]) * z2 + b[6]) * z2 + b[8] + (((b[1] * z2 + b[3]) * z2 + b[5]) * z2 + b[7]) * z)); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_10.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_10.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_10.hpp @@ -0,0 +1,396 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_10_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_10_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_11.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_11.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_11.hpp @@ -0,0 +1,482 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_11_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_11_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_12.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_12.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_12.hpp @@ -0,0 +1,576 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_12_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_12_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_13.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_13.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_13.hpp @@ -0,0 +1,678 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_13_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_13_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_14.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_14.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_14.hpp @@ -0,0 +1,788 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_14_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_14_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_15.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_15.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_15.hpp @@ -0,0 +1,906 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_15_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_15_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_16.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_16.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_16.hpp @@ -0,0 +1,1032 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_16_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_16_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_17.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_17.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_17.hpp @@ -0,0 +1,1166 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_17_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_17_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_18.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_18.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_18.hpp @@ -0,0 +1,1308 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_18_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_18_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_19.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_19.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_19.hpp @@ -0,0 +1,1458 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_19_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_19_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[18] * x2 + a[16]; + t[1] = a[17] * x2 + a[15]; + t[2] = b[18] * x2 + b[16]; + t[3] = b[17] * x2 + b[15]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[13]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[18]); + t[2] += static_cast(b[18]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_2.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_2.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_2.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_2_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_2_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_20.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_20.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_20.hpp @@ -0,0 +1,1616 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_20_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[9] * x2 + a[7]; + t[1] = a[8] * x2 + a[6]; + t[2] = b[9] * x2 + b[7]; + t[3] = b[8] * x2 + b[6]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[10] * x2 + a[8]; + t[1] = a[9] * x2 + a[7]; + t[2] = b[10] * x2 + b[8]; + t[3] = b[9] * x2 + b[7]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[10]); + t[2] += static_cast(b[10]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[11] * x2 + a[9]; + t[1] = a[10] * x2 + a[8]; + t[2] = b[11] * x2 + b[9]; + t[3] = b[10] * x2 + b[8]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[12] * x2 + a[10]; + t[1] = a[11] * x2 + a[9]; + t[2] = b[12] * x2 + b[10]; + t[3] = b[11] * x2 + b[9]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[12]); + t[2] += static_cast(b[12]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[13] * x2 + a[11]; + t[1] = a[12] * x2 + a[10]; + t[2] = b[13] * x2 + b[11]; + t[3] = b[12] * x2 + b[10]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[14] * x2 + a[12]; + t[1] = a[13] * x2 + a[11]; + t[2] = b[14] * x2 + b[12]; + t[3] = b[13] * x2 + b[11]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[14]); + t[2] += static_cast(b[14]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[15] * x2 + a[13]; + t[1] = a[14] * x2 + a[12]; + t[2] = b[15] * x2 + b[13]; + t[3] = b[14] * x2 + b[12]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[16] * x2 + a[14]; + t[1] = a[15] * x2 + a[13]; + t[2] = b[16] * x2 + b[14]; + t[3] = b[15] * x2 + b[13]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[16]); + t[2] += static_cast(b[16]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[17] * x2 + a[15]; + t[1] = a[16] * x2 + a[14]; + t[2] = b[17] * x2 + b[15]; + t[3] = b[16] * x2 + b[14]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[18] * x2 + a[16]; + t[1] = a[17] * x2 + a[15]; + t[2] = b[18] * x2 + b[16]; + t[3] = b[17] * x2 + b[15]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[13]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[11]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[9]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[7]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[5]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[18]); + t[2] += static_cast(b[18]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[19] * x2 + a[17]; + t[1] = a[18] * x2 + a[16]; + t[2] = b[19] * x2 + b[17]; + t[3] = b[18] * x2 + b[16]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[15]); + t[1] += static_cast(a[14]); + t[2] += static_cast(b[15]); + t[3] += static_cast(b[14]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[13]); + t[1] += static_cast(a[12]); + t[2] += static_cast(b[13]); + t[3] += static_cast(b[12]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[11]); + t[1] += static_cast(a[10]); + t[2] += static_cast(b[11]); + t[3] += static_cast(b[10]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[9]); + t[1] += static_cast(a[8]); + t[2] += static_cast(b[9]); + t[3] += static_cast(b[8]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[7]); + t[1] += static_cast(a[6]); + t[2] += static_cast(b[7]); + t[3] += static_cast(b[6]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[5]); + t[1] += static_cast(a[4]); + t[2] += static_cast(b[5]); + t[3] += static_cast(b[4]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[8]); + t[1] += static_cast(a[9]); + t[2] += static_cast(b[8]); + t[3] += static_cast(b[9]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[10]); + t[1] += static_cast(a[11]); + t[2] += static_cast(b[10]); + t[3] += static_cast(b[11]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[12]); + t[1] += static_cast(a[13]); + t[2] += static_cast(b[12]); + t[3] += static_cast(b[13]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[14]); + t[1] += static_cast(a[15]); + t[2] += static_cast(b[14]); + t[3] += static_cast(b[15]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[16]); + t[1] += static_cast(a[17]); + t[2] += static_cast(b[16]); + t[3] += static_cast(b[17]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[18]); + t[1] += static_cast(a[19]); + t[2] += static_cast(b[18]); + t[3] += static_cast(b[19]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_3.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_3.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_3.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_3_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_3_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_4.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_4.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_4.hpp @@ -0,0 +1,48 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_4_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_4_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_5.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_5.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_5.hpp @@ -0,0 +1,86 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_5_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_5_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_6.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_6.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_6.hpp @@ -0,0 +1,132 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_6_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_6_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_7.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_7.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_7.hpp @@ -0,0 +1,186 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_7_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_7_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_8.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_8.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_8.hpp @@ -0,0 +1,248 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_8_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_8_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_9.hpp b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_9.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/detail/rational_horner3_9.hpp @@ -0,0 +1,318 @@ +// (C) Copyright John Maddock 2007. +// 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) +// +// This file is machine generated, do not edit by hand + +// Polynomial evaluation using second order Horners rule +#ifndef BOOST_MATH_TOOLS_RAT_EVAL_9_HPP +#define BOOST_MATH_TOOLS_RAT_EVAL_9_HPP + +namespace boost{ namespace math{ namespace tools{ namespace detail{ + +template +inline V evaluate_rational_c_imp(const T*, const U*, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(0); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(a[0]) / static_cast(b[0]); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((a[1] * x + a[0]) / (b[1] * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + return static_cast((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0])); +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[4] * x2 + a[2]; + t[1] = a[3] * x2 + a[1]; + t[2] = b[4] * x2 + b[2]; + t[3] = b[3] * x2 + b[1]; + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[4]); + t[2] += static_cast(b[4]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[5] * x2 + a[3]; + t[1] = a[4] * x2 + a[2]; + t[2] = b[5] * x2 + b[3]; + t[3] = b[4] * x2 + b[2]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[6] * x2 + a[4]; + t[1] = a[5] * x2 + a[3]; + t[2] = b[6] * x2 + b[4]; + t[3] = b[5] * x2 + b[3]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[6]); + t[2] += static_cast(b[6]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[7] * x2 + a[5]; + t[1] = a[6] * x2 + a[4]; + t[2] = b[7] * x2 + b[5]; + t[3] = b[6] * x2 + b[4]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[3]); + t[1] += static_cast(a[2]); + t[2] += static_cast(b[3]); + t[3] += static_cast(b[2]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[1]); + t[1] += static_cast(a[0]); + t[2] += static_cast(b[1]); + t[3] += static_cast(b[0]); + t[0] *= x; + t[2] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z; + t[2] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + +template +inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const std::integral_constant*) BOOST_MATH_NOEXCEPT(V) +{ + if(x <= 1) + { + V x2 = x * x; + V t[4]; + t[0] = a[8] * x2 + a[6]; + t[1] = a[7] * x2 + a[5]; + t[2] = b[8] * x2 + b[6]; + t[3] = b[7] * x2 + b[5]; + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[3]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[3]); + t[0] *= x2; + t[1] *= x2; + t[2] *= x2; + t[3] *= x2; + t[0] += static_cast(a[2]); + t[1] += static_cast(a[1]); + t[2] += static_cast(b[2]); + t[3] += static_cast(b[1]); + t[0] *= x2; + t[2] *= x2; + t[0] += static_cast(a[0]); + t[2] += static_cast(b[0]); + t[1] *= x; + t[3] *= x; + return (t[0] + t[1]) / (t[2] + t[3]); + } + else + { + V z = 1 / x; + V z2 = 1 / (x * x); + V t[4]; + t[0] = a[0] * z2 + a[2]; + t[1] = a[1] * z2 + a[3]; + t[2] = b[0] * z2 + b[2]; + t[3] = b[1] * z2 + b[3]; + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[4]); + t[1] += static_cast(a[5]); + t[2] += static_cast(b[4]); + t[3] += static_cast(b[5]); + t[0] *= z2; + t[1] *= z2; + t[2] *= z2; + t[3] *= z2; + t[0] += static_cast(a[6]); + t[1] += static_cast(a[7]); + t[2] += static_cast(b[6]); + t[3] += static_cast(b[7]); + t[0] *= z2; + t[2] *= z2; + t[0] += static_cast(a[8]); + t[2] += static_cast(b[8]); + t[1] *= z; + t[3] *= z; + return (t[0] + t[1]) / (t[2] + t[3]); + } +} + + +}}}} // namespaces + +#endif // include guard + diff --git a/libcxx/src/third-party/boost/math/tools/engel_expansion.hpp b/libcxx/src/third-party/boost/math/tools/engel_expansion.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/engel_expansion.hpp @@ -0,0 +1,116 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_ENGEL_EXPANSION_HPP +#define BOOST_MATH_TOOLS_ENGEL_EXPANSION_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace boost::math::tools { + +template +class engel_expansion { +public: + engel_expansion(Real x) : x_{x} + { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into an Engel expansion."); + } + + if(x==0) + { + throw std::domain_error("Zero does not have an Engel expansion."); + } + a_.reserve(64); + // Let the error bound grow by 1 ULP/iteration. + // I haven't done the error analysis to show that this is an expected rate of error growth, + // but if you don't do this, you can easily get into an infinite loop. + Real i = 1; + Real computed = 0; + Real term = 1; + Real scale = std::numeric_limits::epsilon()*abs(x_)/2; + Real u = x; + while (abs(x_ - computed) > (i++)*scale) + { + Real recip = 1/u; + Real ak = ceil(recip); + a_.push_back(static_cast(ak)); + u = u*ak - 1; + if (u==0) + { + break; + } + term /= ak; + computed += term; + } + + for (size_t j = 1; j < a_.size(); ++j) + { + // Sanity check: This should only happen when wraparound occurs: + if (a_[j] < a_[j-1]) + { + throw std::domain_error("The digits of an Engel expansion must form a non-decreasing sequence; consider increasing the wide of the integer type."); + } + // Watch out for saturating behavior: + if (a_[j] == (std::numeric_limits::max)()) + { + throw std::domain_error("The integer type Z does not have enough width to hold the terms of the Engel expansion; please widen the type."); + } + } + a_.shrink_to_fit(); + } + + + const std::vector& digits() const + { + return a_; + } + + template + friend std::ostream& operator<<(std::ostream& out, engel_expansion& eng); + +private: + Real x_; + std::vector a_; +}; + + +template +std::ostream& operator<<(std::ostream& out, engel_expansion& engel) +{ + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(engel.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "{"; + for (size_t i = 0; i < engel.a_.size() - 1; ++i) + { + out << engel.a_[i] << ", "; + } + out << engel.a_.back(); + out << "}"; + return out; +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/fraction.hpp b/libcxx/src/third-party/boost/math/tools/fraction.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/fraction.hpp @@ -0,0 +1,287 @@ +// (C) Copyright John Maddock 2005-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_TOOLS_FRACTION_INCLUDED +#define BOOST_MATH_TOOLS_FRACTION_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +namespace detail +{ + + template + struct is_pair : public std::false_type{}; + + template + struct is_pair> : public std::true_type{}; + + template + struct fraction_traits_simple + { + using result_type = typename Gen::result_type; + using value_type = typename Gen::result_type; + + static result_type a(const value_type&) BOOST_MATH_NOEXCEPT(value_type) + { + return 1; + } + static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v; + } + }; + + template + struct fraction_traits_pair + { + using value_type = typename Gen::result_type; + using result_type = typename value_type::first_type; + + static result_type a(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v.first; + } + static result_type b(const value_type& v) BOOST_MATH_NOEXCEPT(value_type) + { + return v.second; + } + }; + + template + struct fraction_traits + : public std::conditional< + is_pair::value, + fraction_traits_pair, + fraction_traits_simple>::type + { + }; + + template ::value> + struct tiny_value + { + // For float, double, and long double, 1/min_value() is finite. + // But for mpfr_float and cpp_bin_float, 1/min_value() is inf. + // Multiply the min by 16 so that the reciprocal doesn't overflow. + static T get() { + return 16*tools::min_value(); + } + }; + template + struct tiny_value + { + using value_type = typename T::value_type; + static T get() { + return 16*tools::min_value(); + } + }; + +} // namespace detail + +// +// continued_fraction_b +// Evaluates: +// +// b0 + a1 +// --------------- +// b1 + a2 +// ---------- +// b2 + a3 +// ----- +// b3 + ... +// +// Note that the first a0 returned by generator Gen is discarded. +// +template +inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, const U& factor, std::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + using value_type = typename traits::value_type; + using integer_type = typename integer_scalar_type::type; + using scalar_type = typename scalar_type::type; + + integer_type const zero(0), one(1); + + result_type tiny = detail::tiny_value::get(); + scalar_type terminator = abs(factor); + + value_type v = g(); + + result_type f, C, D, delta; + f = traits::b(v); + if(f == zero) + f = tiny; + C = f; + D = 0; + + std::uintmax_t counter(max_terms); + do{ + v = g(); + D = traits::b(v) + traits::a(v) * D; + if(D == result_type(0)) + D = tiny; + C = traits::b(v) + traits::a(v) / C; + if(C == zero) + C = tiny; + D = one/D; + delta = C*D; + f = f * delta; + }while((abs(delta - one) > terminator) && --counter); + + max_terms = max_terms - counter; + + return f; +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, const U& factor) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + std::uintmax_t max_terms = (std::numeric_limits::max)(); + return continued_fraction_b(g, factor, max_terms); +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, int bits) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits); + std::uintmax_t max_terms = (std::numeric_limits::max)(); + return continued_fraction_b(g, factor, max_terms); +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_b(Gen& g, int bits, std::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1 - bits); // 1 / pow(result_type(2), bits); + return continued_fraction_b(g, factor, max_terms); +} + +// +// continued_fraction_a +// Evaluates: +// +// a1 +// --------------- +// b1 + a2 +// ---------- +// b2 + a3 +// ----- +// b3 + ... +// +// Note that the first a1 and b1 returned by generator Gen are both used. +// +template +inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, const U& factor, std::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + using value_type = typename traits::value_type; + using integer_type = typename integer_scalar_type::type; + using scalar_type = typename scalar_type::type; + + integer_type const zero(0), one(1); + + result_type tiny = detail::tiny_value::get(); + scalar_type terminator = abs(factor); + + value_type v = g(); + + result_type f, C, D, delta, a0; + f = traits::b(v); + a0 = traits::a(v); + if(f == zero) + f = tiny; + C = f; + D = 0; + + std::uintmax_t counter(max_terms); + + do{ + v = g(); + D = traits::b(v) + traits::a(v) * D; + if(D == zero) + D = tiny; + C = traits::b(v) + traits::a(v) / C; + if(C == zero) + C = tiny; + D = one/D; + delta = C*D; + f = f * delta; + }while((abs(delta - one) > terminator) && --counter); + + max_terms = max_terms - counter; + + return a0/f; +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, const U& factor) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + std::uintmax_t max_iter = (std::numeric_limits::max)(); + return continued_fraction_a(g, factor, max_iter); +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, int bits) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + typedef detail::fraction_traits traits; + typedef typename traits::result_type result_type; + + result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits); + std::uintmax_t max_iter = (std::numeric_limits::max)(); + + return continued_fraction_a(g, factor, max_iter); +} + +template +inline typename detail::fraction_traits::result_type continued_fraction_a(Gen& g, int bits, std::uintmax_t& max_terms) + noexcept(BOOST_MATH_IS_FLOAT(typename detail::fraction_traits::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING // ADL of std names + + using traits = detail::fraction_traits; + using result_type = typename traits::result_type; + + result_type factor = ldexp(1.0f, 1-bits); // 1 / pow(result_type(2), bits); + return continued_fraction_a(g, factor, max_terms); +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_FRACTION_INCLUDED diff --git a/libcxx/src/third-party/boost/math/tools/header_deprecated.hpp b/libcxx/src/third-party/boost/math/tools/header_deprecated.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/header_deprecated.hpp @@ -0,0 +1,27 @@ +// (C) Copyright Matt Borland 2021. +// 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_TOOLS_HEADER_DEPRECATED +#define BOOST_MATH_TOOLS_HEADER_DEPRECATED + +#ifndef BOOST_MATH_STANDALONE + +# include +# define BOOST_MATH_HEADER_DEPRECATED(expr) BOOST_HEADER_DEPRECATED(expr) + +#else + +# ifdef _MSC_VER +// Expands to "This header is deprecated; use expr instead." +# define BOOST_MATH_HEADER_DEPRECATED(expr) __pragma("This header is deprecated; use " expr " instead.") +# else // GNU, Clang, Intel, IBM, etc. +// Expands to "This header is deprecated use expr instead" +# define BOOST_MATH_HEADER_DEPRECATED_MESSAGE(expr) _Pragma(#expr) +# define BOOST_MATH_HEADER_DEPRECATED(expr) BOOST_MATH_HEADER_DEPRECATED_MESSAGE(message "This header is deprecated use " expr " instead") +# endif + +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_TOOLS_HEADER_DEPRECATED diff --git a/libcxx/src/third-party/boost/math/tools/is_constant_evaluated.hpp b/libcxx/src/third-party/boost/math/tools/is_constant_evaluated.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/is_constant_evaluated.hpp @@ -0,0 +1,51 @@ +// Copyright John Maddock 2011-2021. +// 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_TOOLS_IS_CONSTANT_EVALUATED_HPP +#define BOOST_MATH_TOOLS_IS_CONSTANT_EVALUATED_HPP + +#include + +#ifdef __has_include +# if __has_include() +# include +# ifdef __cpp_lib_is_constant_evaluated +# include +# define BOOST_MATH_HAS_IS_CONSTANT_EVALUATED +# endif +# endif +#endif + +#ifdef __has_builtin +# if __has_builtin(__builtin_is_constant_evaluated) && !defined(BOOST_NO_CXX14_CONSTEXPR) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +# endif +#endif +// +// MSVC also supports __builtin_is_constant_evaluated if it's recent enough: +// +#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 192528326) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif +// +// As does GCC-9: +// +#if !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 9) && !defined(BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED) +# define BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED +#endif + +#if defined(BOOST_MATH_HAS_IS_CONSTANT_EVALUATED) && !defined(BOOST_NO_CXX14_CONSTEXPR) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) std::is_constant_evaluated() +#elif defined(BOOST_MATH_HAS_BUILTIN_IS_CONSTANT_EVALUATED) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) __builtin_is_constant_evaluated() +#elif !defined(BOOST_NO_CXX14_CONSTEXPR) && (__GNUC__ >= 6) +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) __builtin_constant_p(x) +# define BOOST_MATH_USING_BUILTIN_CONSTANT_P +#else +# define BOOST_MATH_IS_CONSTANT_EVALUATED(x) false +# define BOOST_MATH_NO_CONSTEXPR_DETECTION +#endif + +#endif // BOOST_MATH_TOOLS_IS_CONSTANT_EVALUATED_HPP diff --git a/libcxx/src/third-party/boost/math/tools/is_detected.hpp b/libcxx/src/third-party/boost/math/tools/is_detected.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/is_detected.hpp @@ -0,0 +1,56 @@ +// Copyright Matt Borland 2021. +// 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) +// +// https://en.cppreference.com/w/cpp/experimental/is_detected + +#ifndef BOOST_MATH_TOOLS_IS_DETECTED_HPP +#define BOOST_MATH_TOOLS_IS_DETECTED_HPP + +#include + +namespace boost { namespace math { namespace tools { + +template +using void_t = void; + +namespace detail { + +template class Op, typename... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, typename... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +} // Namespace detail + +// Special type to indicate detection failure +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(const nonesuch&) = delete; + void operator=(const nonesuch&) = delete; +}; + +template class Op, typename... Args> +using is_detected = typename detail::detector::value_t; + +template class Op, typename... Args> +using detected_t = typename detail::detector::type; + +template class Op, typename... Args> +using detected_or = detail::detector; + +}}} // Namespaces boost math tools + +#endif // BOOST_MATH_TOOLS_IS_DETECTED_HPP diff --git a/libcxx/src/third-party/boost/math/tools/is_standalone.hpp b/libcxx/src/third-party/boost/math/tools/is_standalone.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/is_standalone.hpp @@ -0,0 +1,18 @@ +// Copyright Matt Borland 2021. +// 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_TOOLS_IS_STANDALONE_HPP +#define BOOST_MATH_TOOLS_IS_STANDALONE_HPP + +#ifdef __has_include +#if !__has_include() || !__has_include() || !__has_include() || \ + !__has_include() || !__has_include() +# ifndef BOOST_MATH_STANDALONE +# define BOOST_MATH_STANDALONE +# endif +#endif +#endif + +#endif // BOOST_MATH_TOOLS_IS_STANDALONE_HPP diff --git a/libcxx/src/third-party/boost/math/tools/luroth_expansion.hpp b/libcxx/src/third-party/boost/math/tools/luroth_expansion.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/luroth_expansion.hpp @@ -0,0 +1,138 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_LUROTH_EXPANSION_HPP +#define BOOST_MATH_TOOLS_LUROTH_EXPANSION_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost::math::tools { + +template +class luroth_expansion { +public: + luroth_expansion(Real x) : x_{x} + { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) + { + throw std::domain_error("Cannot convert non-finites into a Luroth representation."); + } + d_.reserve(50); + Real dn1 = floor(x); + d_.push_back(static_cast(dn1)); + if (dn1 == x) + { + d_.shrink_to_fit(); + return; + } + // This attempts to follow the notation of: + // "Khinchine's constant for Luroth Representation", by Sophia Kalpazidou. + x = x - dn1; + Real computed = dn1; + Real prod = 1; + // Let the error bound grow by 1 ULP/iteration. + // I haven't done the error analysis to show that this is an expected rate of error growth, + // but if you don't do this, you can easily get into an infinite loop. + Real i = 1; + Real scale = std::numeric_limits::epsilon()*abs(x_)/2; + while (abs(x_ - computed) > (i++)*scale) + { + Real recip = 1/x; + Real dn = floor(recip); + // x = n + 1/k => lur(x) = ((n; k - 1)) + // Note that this is a bit different than Kalpazidou (examine the half-open interval of definition carefully). + // One way to examine this definition is better for rationals (it never happens for irrationals) + // is to consider i + 1/3. If you follow Kalpazidou, then you get ((i, 3, 0)); a zero digit! + // That's bad since it destroys uniqueness and also breaks the computation of the geometric mean. + if (recip == dn) { + d_.push_back(static_cast(dn - 1)); + break; + } + d_.push_back(static_cast(dn)); + Real tmp = 1/(dn+1); + computed += prod*tmp; + prod *= tmp/dn; + x = dn*(dn+1)*(x - tmp); + } + + for (size_t i = 1; i < d_.size(); ++i) + { + // Sanity check: + if (d_[i] <= 0) + { + throw std::domain_error("Found a digit <= 0; this is an error."); + } + } + d_.shrink_to_fit(); + } + + + const std::vector& digits() const { + return d_; + } + + // Under the assumption of 'randomness', this mean converges to 2.2001610580. + // See Finch, Mathematical Constants, section 1.8.1. + Real digit_geometric_mean() const { + if (d_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + Real g = 0; + for (size_t i = 1; i < d_.size(); ++i) { + g += log(static_cast(d_[i])); + } + return exp(g/(d_.size() - 1)); + } + + template + friend std::ostream& operator<<(std::ostream& out, luroth_expansion& scf); + +private: + const Real x_; + std::vector d_; +}; + + +template +std::ostream& operator<<(std::ostream& out, luroth_expansion& luroth) +{ + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) + { + out << std::setprecision(luroth.x_.backend().precision()); + } + else + { + out << std::setprecision(p); + } + + out << "((" << luroth.d_.front(); + if (luroth.d_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < luroth.d_.size() -1; ++i) + { + out << luroth.d_[i] << ", "; + } + out << luroth.d_.back(); + } + out << "))"; + return out; +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/minima.hpp b/libcxx/src/third-party/boost/math/tools/minima.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/minima.hpp @@ -0,0 +1,154 @@ +// (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_TOOLS_MINIMA_HPP +#define BOOST_MATH_TOOLS_MINIMA_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +std::pair brent_find_minima(F f, T min, T max, int bits, std::uintmax_t& max_iter) + noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + BOOST_MATH_STD_USING + bits = (std::min)(policies::digits >() / 2, bits); + T tolerance = static_cast(ldexp(1.0, 1-bits)); + T x; // minima so far + T w; // second best point + T v; // previous value of w + T u; // most recent evaluation point + T delta; // The distance moved in the last step + T delta2; // The distance moved in the step before last + T fu, fv, fw, fx; // function evaluations at u, v, w, x + T mid; // midpoint of min and max + T fract1, fract2; // minimal relative movement in x + + static const T golden = 0.3819660f; // golden ratio, don't need too much precision here! + + x = w = v = max; + fw = fv = fx = f(x); + delta2 = delta = 0; + + uintmax_t count = max_iter; + + do{ + // get midpoint + mid = (min + max) / 2; + // work out if we're done already: + fract1 = tolerance * fabs(x) + tolerance / 4; + fract2 = 2 * fract1; + if(fabs(x - mid) <= (fract2 - (max - min) / 2)) + break; + + if(fabs(delta2) > fract1) + { + // try and construct a parabolic fit: + T r = (x - w) * (fx - fv); + T q = (x - v) * (fx - fw); + T p = (x - v) * q - (x - w) * r; + q = 2 * (q - r); + if(q > 0) + p = -p; + q = fabs(q); + T td = delta2; + delta2 = delta; + // determine whether a parabolic step is acceptable or not: + if((fabs(p) >= fabs(q * td / 2)) || (p <= q * (min - x)) || (p >= q * (max - x))) + { + // nope, try golden section instead + delta2 = (x >= mid) ? min - x : max - x; + delta = golden * delta2; + } + else + { + // whew, parabolic fit: + delta = p / q; + u = x + delta; + if(((u - min) < fract2) || ((max- u) < fract2)) + delta = (mid - x) < 0 ? (T)-fabs(fract1) : (T)fabs(fract1); + } + } + else + { + // golden section: + delta2 = (x >= mid) ? min - x : max - x; + delta = golden * delta2; + } + // update current position: + u = (fabs(delta) >= fract1) ? T(x + delta) : (delta > 0 ? T(x + fabs(fract1)) : T(x - fabs(fract1))); + fu = f(u); + if(fu <= fx) + { + // good new point is an improvement! + // update brackets: + if(u >= x) + min = x; + else + max = x; + // update control points: + v = w; + w = x; + x = u; + fv = fw; + fw = fx; + fx = fu; + } + else + { + // Oh dear, point u is worse than what we have already, + // even so it *must* be better than one of our endpoints: + if(u < x) + min = u; + else + max = u; + if((fu <= fw) || (w == x)) + { + // however it is at least second best: + v = w; + w = u; + fv = fw; + fw = fu; + } + else if((fu <= fv) || (v == x) || (v == w)) + { + // third best: + v = u; + fv = fu; + } + } + + }while(--count); + + max_iter -= count; + + return std::make_pair(x, fx); +} + +template +inline std::pair brent_find_minima(F f, T min, T max, int digits) + noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return brent_find_minima(f, min, max, digits, m); +} + +}}} // namespaces + +#endif + + + + diff --git a/libcxx/src/third-party/boost/math/tools/mp.hpp b/libcxx/src/third-party/boost/math/tools/mp.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/mp.hpp @@ -0,0 +1,439 @@ +// Copyright Peter Dimov 2015-2021. +// Copyright Matt Borland 2021. +// 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) +// +// Template metaprogramming classes and functions to replace MPL +// Source: http://www.pdimov.com/cpp2/simple_cxx11_metaprogramming.html +// Source: https://github.com/boostorg/mp11/ + +#ifndef BOOST_MATH_TOOLS_MP +#define BOOST_MATH_TOOLS_MP + +#include +#include +#include + +namespace boost { namespace math { namespace tools { namespace meta_programming { + +// Types: +// Typelist +template +struct mp_list {}; + +// Size_t +template +using mp_size_t = std::integral_constant; + +// Boolean +template +using mp_bool = std::integral_constant; + +// Identity +template +struct mp_identity +{ + using type = T; +}; + +// Turns struct into quoted metafunction +template class F> +struct mp_quote_trait +{ + template + using fn = typename F::type; +}; + +namespace detail { +// Size +template +struct mp_size_impl {}; + +template class L, typename... T> // Template template parameter must use class +struct mp_size_impl> +{ + using type = std::integral_constant; +}; +} + +template +using mp_size = typename detail::mp_size_impl::type; + +namespace detail { +// Front +template +struct mp_front_impl {}; + +template class L, typename T1, typename... T> +struct mp_front_impl> +{ + using type = T1; +}; +} + +template +using mp_front = typename detail::mp_front_impl::type; + +namespace detail { +// At +// TODO - Use tree based lookup for larger typelists +// http://odinthenerd.blogspot.com/2017/04/tree-based-lookup-why-kvasirmpl-is.html +template +struct mp_at_c {}; + +template class L, typename T0, typename... T> +struct mp_at_c, 0> +{ + using type = T0; +}; + +template class L, typename T0, typename T1, typename... T> +struct mp_at_c, 1> +{ + using type = T1; +}; + +template class L, typename T0, typename T1, typename T2, typename... T> +struct mp_at_c, 2> +{ + using type = T2; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename... T> +struct mp_at_c, 3> +{ + using type = T3; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename... T> +struct mp_at_c, 4> +{ + using type = T4; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename... T> +struct mp_at_c, 5> +{ + using type = T5; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename... T> +struct mp_at_c, 6> +{ + using type = T6; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename... T> +struct mp_at_c, 7> +{ + using type = T7; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename... T> +struct mp_at_c, 8> +{ + using type = T8; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename... T> +struct mp_at_c, 9> +{ + using type = T9; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename... T> +struct mp_at_c, 10> +{ + using type = T10; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename T11, typename... T> +struct mp_at_c, 11> +{ + using type = T11; +}; + +template class L, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, + typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename... T> +struct mp_at_c, 12> +{ + using type = T12; +}; +} + +template +using mp_at_c = typename detail::mp_at_c::type; + +template +using mp_at = typename detail::mp_at_c::type; + +// Back +template +using mp_back = mp_at_c::value - 1>; + +namespace detail { +// Push back +template +struct mp_push_back_impl {}; + +template class L, typename... U, typename... T> +struct mp_push_back_impl, T...> +{ + using type = L; +}; +} + +template +using mp_push_back = typename detail::mp_push_back_impl::type; + +namespace detail { +// Push front +template +struct mp_push_front_impl {}; + +template class L, typename... U, typename... T> +struct mp_push_front_impl, T...> +{ + using type = L; +}; +} + +template +using mp_push_front = typename detail::mp_push_front_impl::type; + +namespace detail{ +// If +template +struct mp_if_c_impl{}; + +template +struct mp_if_c_impl +{ + using type = T; +}; + +template +struct mp_if_c_impl +{ + using type = E; +}; +} + +template +using mp_if_c = typename detail::mp_if_c_impl::type; + +template +using mp_if = typename detail::mp_if_c_impl(C::value), T, E...>::type; + +namespace detail { +// Find if +template class P> +struct mp_find_if_impl {}; + +template class L, template class P> +struct mp_find_if_impl, P> +{ + using type = mp_size_t<0>; +}; + +template class P> +struct mp_find_if_impl_2 +{ + using r = typename mp_find_if_impl::type; + using type = mp_size_t<1 + r::value>; +}; + +template class L, typename T1, typename... T, template class P> +struct mp_find_if_impl, P> +{ + using type = typename mp_if, mp_identity>, mp_find_if_impl_2, P>>::type; +}; +} + +template class P> +using mp_find_if = typename detail::mp_find_if_impl::type; + +template +using mp_find_if_q = mp_find_if; + +namespace detail { +// Append +template +struct mp_append_impl {}; + +template<> +struct mp_append_impl<> +{ + using type = mp_list<>; +}; + +template class L, typename... T> +struct mp_append_impl> +{ + using type = L; +}; + +template class L1, typename... T1, template class L2, typename... T2> +struct mp_append_impl, L2> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3> +struct mp_append_impl, L2, L3> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3, template class L4, typename... T4> +struct mp_append_impl, L2, L3, L4> +{ + using type = L1; +}; + +template class L1, typename... T1, template class L2, typename... T2, + template class L3, typename... T3, template class L4, typename... T4, + template class L5, typename... T5, typename... Lr> +struct mp_append_impl, L2, L3, L4, L5, Lr...> +{ + using type = typename mp_append_impl, Lr...>::type; +}; +} + +template +using mp_append = typename detail::mp_append_impl::type; + +namespace detail { +// Remove if +template class P> +struct mp_remove_if_impl{}; + +template class L, typename... T, template class P> +struct mp_remove_if_impl, P> +{ + template + struct _f + { + using type = mp_if, mp_list<>, mp_list>; + }; + + using type = mp_append, typename _f::type...>; +}; +} + +template class P> +using mp_remove_if = typename detail::mp_remove_if_impl::type; + +template +using mp_remove_if_q = mp_remove_if; + +// Index sequence +// Use C++14 index sequence if available +#if defined(__cpp_lib_integer_sequence) && (__cpp_lib_integer_sequence >= 201304) +template +using index_sequence = std::index_sequence; + +template +using make_index_sequence = std::make_index_sequence; + +template +using index_sequence_for = std::index_sequence_for; + +#else + +template +struct integer_sequence {}; + +template +using index_sequence = integer_sequence; + +namespace detail { + +template +struct iseq_if_c_impl {}; + +template +struct iseq_if_c_impl +{ + using type = T; +}; + +template +struct iseq_if_c_impl +{ + using type = F; +}; + +template +using iseq_if_c = typename iseq_if_c_impl::type; + +template +struct iseq_identity +{ + using type = T; +}; + +template +struct append_integer_sequence {}; + +template +struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence; +}; + +template +struct make_integer_sequence_impl; + +template +class make_integer_sequence_impl_ +{ +private: + static_assert(N >= 0, "N must not be negative"); + + static constexpr T M = N / 2; + static constexpr T R = N % 2; + + using seq1 = typename make_integer_sequence_impl::type; + using seq2 = typename append_integer_sequence::type; + using seq3 = typename make_integer_sequence_impl::type; + using seq4 = typename append_integer_sequence::type; + +public: + using type = seq4; +}; + +template +struct make_integer_sequence_impl +{ + using type = typename iseq_if_c>, + iseq_if_c>, + make_integer_sequence_impl_>>::type; +}; + +} // namespace detail + +template +using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +template +using make_index_sequence = make_integer_sequence; + +template +using index_sequence_for = make_integer_sequence; + +#endif + +}}}} // namespaces + +#endif // BOOST_MATH_TOOLS_MP diff --git a/libcxx/src/third-party/boost/math/tools/norms.hpp b/libcxx/src/third-party/boost/math/tools/norms.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/norms.hpp @@ -0,0 +1,630 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_NORMS_HPP +#define BOOST_MATH_TOOLS_NORMS_HPP +#include +#include +#include +#include +#include +#include + + +namespace boost::math::tools { + +// Mallat, "A Wavelet Tour of Signal Processing", equation 2.60: +template +auto total_variation(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "At least two samples are required to compute the total variation."); + auto it = first; + if constexpr (std::is_unsigned::value) + { + T tmp = *it; + double tv = 0; + while (++it != last) + { + if (*it > tmp) + { + tv += *it - tmp; + } + else + { + tv += tmp - *it; + } + tmp = *it; + } + return tv; + } + else if constexpr (std::is_integral::value) + { + double tv = 0; + double tmp = *it; + while(++it != last) + { + double tmp2 = *it; + tv += abs(tmp2 - tmp); + tmp = *it; + } + return tv; + } + else + { + T tmp = *it; + T tv = 0; + while (++it != last) + { + tv += abs(*it - tmp); + tmp = *it; + } + return tv; + } +} + +template +inline auto total_variation(Container const & v) +{ + return total_variation(v.cbegin(), v.cend()); +} + + +template +auto sup_norm(ForwardIterator first, ForwardIterator last) +{ + BOOST_MATH_ASSERT_MSG(first != last, "At least one value is required to compute the sup norm."); + using T = typename std::iterator_traits::value_type; + using std::abs; + if constexpr (boost::math::tools::is_complex_type::value) + { + auto it = std::max_element(first, last, [](T a, T b) { return abs(b) > abs(a); }); + return abs(*it); + } + else if constexpr (std::is_unsigned::value) + { + return *std::max_element(first, last); + } + else + { + auto pair = std::minmax_element(first, last); + if (abs(*pair.first) > abs(*pair.second)) + { + return abs(*pair.first); + } + else + { + return abs(*pair.second); + } + } +} + +template +inline auto sup_norm(Container const & v) +{ + return sup_norm(v.cbegin(), v.cend()); +} + +template +auto l1_norm(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + if constexpr (std::is_unsigned::value) + { + double l1 = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + } + return l1; + } + else if constexpr (std::is_integral::value) + { + double l1 = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + l1 += abs(tmp); + } + return l1; + } + else + { + decltype(abs(*first)) l1 = 0; + for (auto it = first; it != last; ++it) + { + l1 += abs(*it); + } + return l1; + } + +} + +template +inline auto l1_norm(Container const & v) +{ + return l1_norm(v.cbegin(), v.cend()); +} + + +template +auto l2_norm(ForwardIterator first, ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + if constexpr (boost::math::tools::is_complex_type::value) + { + typedef typename T::value_type Real; + Real l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += norm(*it); + } + Real result = sqrt(l2); + if (!isfinite(result)) + { + Real a = sup_norm(first, last); + l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += norm(*it/a); + } + return a*sqrt(l2); + } + return result; + } + else if constexpr (is_floating_point::value || + std::numeric_limits::max_exponent) + { + T l2 = 0; + for (auto it = first; it != last; ++it) + { + l2 += (*it)*(*it); + } + T result = sqrt(l2); + // Higham, Accuracy and Stability of Numerical Algorithms, + // Problem 27.5 presents a different algorithm to deal with overflow. + // The algorithm used here takes 3 passes *if* there is overflow. + // Higham's algorithm is 1 pass, but more requires operations than the no overflow case. + // I'm operating under the assumption that overflow is rare since the dynamic range of floating point numbers is huge. + if (!isfinite(result)) + { + T a = sup_norm(first, last); + l2 = 0; + for (auto it = first; it != last; ++it) + { + T tmp = *it/a; + l2 += tmp*tmp; + } + return a*sqrt(l2); + } + return result; + } + else + { + double l2 = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + l2 += tmp*tmp; + } + return sqrt(l2); + } +} + +template +inline auto l2_norm(Container const & v) +{ + return l2_norm(v.cbegin(), v.cend()); +} + +template +size_t l0_pseudo_norm(ForwardIterator first, ForwardIterator last) +{ + using RealOrComplex = typename std::iterator_traits::value_type; + size_t count = 0; + for (auto it = first; it != last; ++it) + { + if (*it != RealOrComplex(0)) + { + ++count; + } + } + return count; +} + +template +inline size_t l0_pseudo_norm(Container const & v) +{ + return l0_pseudo_norm(v.cbegin(), v.cend()); +} + +template +size_t hamming_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + size_t count = 0; + auto it1 = first1; + auto it2 = first2; + while (it1 != last1) + { + if (*it1++ != *it2++) + { + ++count; + } + } + return count; +} + +template +inline size_t hamming_distance(Container const & v, Container const & w) +{ + return hamming_distance(v.cbegin(), v.cend(), w.cbegin()); +} + +template +auto lp_norm(ForwardIterator first, ForwardIterator last, unsigned p) +{ + using std::abs; + using std::pow; + using std::is_floating_point; + using std::isfinite; + using RealOrComplex = typename std::iterator_traits::value_type; + if constexpr (boost::math::tools::is_complex_type::value) + { + using std::norm; + using Real = typename RealOrComplex::value_type; + Real lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it), p); + } + + auto result = pow(lp, Real(1)/Real(p)); + if (!isfinite(result)) + { + auto a = boost::math::tools::sup_norm(first, last); + Real lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it)/a, p); + } + result = a*pow(lp, Real(1)/Real(p)); + } + return result; + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + BOOST_MATH_ASSERT_MSG(p >= 0, "For p < 0, the lp norm is not a norm"); + RealOrComplex lp = 0; + + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it), p); + } + + RealOrComplex result = pow(lp, RealOrComplex(1)/RealOrComplex(p)); + if (!isfinite(result)) + { + RealOrComplex a = boost::math::tools::sup_norm(first, last); + lp = 0; + for (auto it = first; it != last; ++it) + { + lp += pow(abs(*it)/a, p); + } + result = a*pow(lp, RealOrComplex(1)/RealOrComplex(p)); + } + return result; + } + else + { + double lp = 0; + + for (auto it = first; it != last; ++it) + { + double tmp = *it; + lp += pow(abs(tmp), p); + } + double result = pow(lp, 1.0/static_cast(p)); + if (!isfinite(result)) + { + double a = boost::math::tools::sup_norm(first, last); + lp = 0; + for (auto it = first; it != last; ++it) + { + double tmp = *it; + lp += pow(abs(tmp)/a, p); + } + result = a*pow(lp, static_cast(1)/static_cast(p)); + } + return result; + } +} + +template +inline auto lp_norm(Container const & v, unsigned p) +{ + return lp_norm(v.cbegin(), v.cend(), p); +} + + +template +auto lp_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, unsigned p) +{ + using std::pow; + using std::abs; + using std::is_floating_point; + using std::isfinite; + using RealOrComplex = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename RealOrComplex::value_type; + using std::norm; + Real dist = 0; + while(it1 != last1) + { + auto tmp = *it1++ - *it2++; + dist += pow(abs(tmp), p); + } + return pow(dist, Real(1)/Real(p)); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + RealOrComplex dist = 0; + while(it1 != last1) + { + auto tmp = *it1++ - *it2++; + dist += pow(abs(tmp), p); + } + return pow(dist, RealOrComplex(1)/RealOrComplex(p)); + } + else + { + double dist = 0; + while(it1 != last1) + { + double tmp1 = *it1++; + double tmp2 = *it2++; + // Naively you'd expect the integer subtraction to be faster, + // but this can overflow or wraparound: + //double tmp = *it1++ - *it2++; + dist += pow(abs(tmp1 - tmp2), p); + } + return pow(dist, 1.0/static_cast(p)); + } +} + +template +inline auto lp_distance(Container const & v, Container const & w, unsigned p) +{ + return lp_distance(v.cbegin(), v.cend(), w.cbegin(), p); +} + + +template +auto l1_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sum = 0; + while (it1 != last1) { + sum += abs(*it1++ - *it2++); + } + return sum; + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sum = 0; + while (it1 != last1) + { + sum += abs(*it1++ - *it2++); + } + return sum; + } + else if constexpr (std::is_unsigned::value) + { + double sum = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + if (x1 > x2) + { + sum += (x1 - x2); + } + else + { + sum += (x2 - x1); + } + } + return sum; + } + else if constexpr (std::is_integral::value) + { + double sum = 0; + while(it1 != last1) + { + double x1 = *it1++; + double x2 = *it2++; + sum += abs(x1-x2); + } + return sum; + } + else + { + BOOST_MATH_ASSERT_MSG(false, "Could not recognize type."); + } + +} + +template +auto l1_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "L1 distance requires both containers to have the same number of elements"); + return l1_distance(v.cbegin(), v.cend(), w.begin()); +} + +template +auto l2_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sum = 0; + while (it1 != last1) { + sum += norm(*it1++ - *it2++); + } + return sqrt(sum); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sum = 0; + while (it1 != last1) + { + T tmp = *it1++ - *it2++; + sum += tmp*tmp; + } + return sqrt(sum); + } + else if constexpr (std::is_unsigned::value) + { + double sum = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + if (x1 > x2) + { + double tmp = x1-x2; + sum += tmp*tmp; + } + else + { + double tmp = x2 - x1; + sum += tmp*tmp; + } + } + return sqrt(sum); + } + else + { + double sum = 0; + while(it1 != last1) + { + double x1 = *it1++; + double x2 = *it2++; + double tmp = x1-x2; + sum += tmp*tmp; + } + return sqrt(sum); + } +} + +template +auto l2_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "L2 distance requires both containers to have the same number of elements"); + return l2_distance(v.cbegin(), v.cend(), w.begin()); +} + +template +auto sup_distance(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2) +{ + using std::abs; + using std::norm; + using std::sqrt; + using std::is_floating_point; + using std::isfinite; + using T = typename std::iterator_traits::value_type; + auto it1 = first1; + auto it2 = first2; + if constexpr (boost::math::tools::is_complex_type::value) + { + using Real = typename T::value_type; + Real sup_sq = 0; + while (it1 != last1) { + Real tmp = norm(*it1++ - *it2++); + if (tmp > sup_sq) { + sup_sq = tmp; + } + } + return sqrt(sup_sq); + } + else if constexpr (is_floating_point::value || std::numeric_limits::max_exponent) + { + T sup = 0; + while (it1 != last1) + { + T tmp = *it1++ - *it2++; + if (sup < abs(tmp)) + { + sup = abs(tmp); + } + } + return sup; + } + else // integral values: + { + double sup = 0; + while(it1 != last1) + { + T x1 = *it1++; + T x2 = *it2++; + double tmp; + if (x1 > x2) + { + tmp = x1-x2; + } + else + { + tmp = x2 - x1; + } + if (sup < tmp) { + sup = tmp; + } + } + return sup; + } +} + +template +auto sup_distance(Container const & v, Container const & w) +{ + using std::size; + BOOST_MATH_ASSERT_MSG(size(v) == size(w), + "sup distance requires both containers to have the same number of elements"); + return sup_distance(v.cbegin(), v.cend(), w.begin()); +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/nothrow.hpp b/libcxx/src/third-party/boost/math/tools/nothrow.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/nothrow.hpp @@ -0,0 +1,27 @@ +// (C) Copyright Antony Polukhin 2022. +// 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_TOOLS_NOTHROW_HPP +#define BOOST_MATH_TOOLS_NOTHROW_HPP + +#include + +#ifndef BOOST_MATH_STANDALONE + +#include + +#define BOOST_MATH_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW + +#else // Standalone mode - use noexcept or throw() + +#if __cplusplus >= 201103L +#define BOOST_MATH_NOTHROW noexcept +#else +#define BOOST_MATH_NOTHROW throw() +#endif + +#endif + +#endif // BOOST_MATH_TOOLS_NOTHROW_HPP diff --git a/libcxx/src/third-party/boost/math/tools/numerical_differentiation.hpp b/libcxx/src/third-party/boost/math/tools/numerical_differentiation.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/numerical_differentiation.hpp @@ -0,0 +1,12 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_NUMERICAL_DIFFERENTIATION_HPP +#define BOOST_MATH_TOOLS_NUMERICAL_DIFFERENTIATION_HPP +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +#endif diff --git a/libcxx/src/third-party/boost/math/tools/polynomial.hpp b/libcxx/src/third-party/boost/math/tools/polynomial.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/polynomial.hpp @@ -0,0 +1,862 @@ +// (C) Copyright John Maddock 2006. +// (C) Copyright Jeremy William Murphy 2015. + + +// 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_TOOLS_POLYNOMIAL_HPP +#define BOOST_MATH_TOOLS_POLYNOMIAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +T chebyshev_coefficient(unsigned n, unsigned m) +{ + BOOST_MATH_STD_USING + if(m > n) + return 0; + if((n & 1) != (m & 1)) + return 0; + if(n == 0) + return 1; + T result = T(n) / 2; + unsigned r = n - m; + r /= 2; + + BOOST_MATH_ASSERT(n - 2 * r == m); + + if(r & 1) + result = -result; + result /= n - r; + result *= boost::math::binomial_coefficient(n - r, r); + result *= ldexp(1.0f, m); + return result; +} + +template +Seq polynomial_to_chebyshev(const Seq& s) +{ + // Converts a Polynomial into Chebyshev form: + typedef typename Seq::value_type value_type; + typedef typename Seq::difference_type difference_type; + Seq result(s); + difference_type order = s.size() - 1; + difference_type even_order = order & 1 ? order - 1 : order; + difference_type odd_order = order & 1 ? order : order - 1; + + for(difference_type i = even_order; i >= 0; i -= 2) + { + value_type val = s[i]; + for(difference_type k = even_order; k > i; k -= 2) + { + val -= result[k] * chebyshev_coefficient(static_cast(k), static_cast(i)); + } + val /= chebyshev_coefficient(static_cast(i), static_cast(i)); + result[i] = val; + } + result[0] *= 2; + + for(difference_type i = odd_order; i >= 0; i -= 2) + { + value_type val = s[i]; + for(difference_type k = odd_order; k > i; k -= 2) + { + val -= result[k] * chebyshev_coefficient(static_cast(k), static_cast(i)); + } + val /= chebyshev_coefficient(static_cast(i), static_cast(i)); + result[i] = val; + } + return result; +} + +template +T evaluate_chebyshev(const Seq& a, const T& x) +{ + // Clenshaw's formula: + typedef typename Seq::difference_type difference_type; + T yk2 = 0; + T yk1 = 0; + T yk = 0; + for(difference_type i = a.size() - 1; i >= 1; --i) + { + yk2 = yk1; + yk1 = yk; + yk = 2 * x * yk1 - yk2 + a[i]; + } + return a[0] / 2 + yk * x - yk1; +} + + +template +class polynomial; + +namespace detail { + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Chapter 4.6.1, Algorithm D: Division of polynomials over a field. +* +* @tparam T Coefficient type, must be not be an integer. +* +* Template-parameter T actually must be a field but we don't currently have that +* subtlety of distinction. +*/ +template +typename std::enable_if::is_integer, void >::type +division_impl(polynomial &q, polynomial &u, const polynomial& v, N n, N k) +{ + q[k] = u[n + k] / v[n]; + for (N j = n + k; j > k;) + { + j--; + u[j] -= q[k] * v[j - k]; + } +} + +template +T integer_power(T t, N n) +{ + switch(n) + { + case 0: + return static_cast(1u); + case 1: + return t; + case 2: + return t * t; + case 3: + return t * t * t; + } + T result = integer_power(t, n / 2); + result *= result; + if(n & 1) + result *= t; + return result; +} + + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Chapter 4.6.1, Algorithm R: Pseudo-division of polynomials. +* +* @tparam T Coefficient type, must be an integer. +* +* Template-parameter T actually must be a unique factorization domain but we +* don't currently have that subtlety of distinction. +*/ +template +typename std::enable_if::is_integer, void >::type +division_impl(polynomial &q, polynomial &u, const polynomial& v, N n, N k) +{ + q[k] = u[n + k] * integer_power(v[n], k); + for (N j = n + k; j > 0;) + { + j--; + u[j] = v[n] * u[j] - (j < k ? T(0) : u[n + k] * v[j - k]); + } +} + + +/** + * Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 + * Chapter 4.6.1, Algorithm D and R: Main loop. + * + * @param u Dividend. + * @param v Divisor. + */ +template +std::pair< polynomial, polynomial > +division(polynomial u, const polynomial& v) +{ + BOOST_MATH_ASSERT(v.size() <= u.size()); + BOOST_MATH_ASSERT(v); + BOOST_MATH_ASSERT(u); + + typedef typename polynomial::size_type N; + + N const m = u.size() - 1, n = v.size() - 1; + N k = m - n; + polynomial q; + q.data().resize(m - n + 1); + + do + { + division_impl(q, u, v, n, k); + } + while (k-- != 0); + u.data().resize(n); + u.normalize(); // Occasionally, the remainder is zeroes. + return std::make_pair(q, u); +} + +// +// These structures are the same as the void specializations of the functors of the same name +// in the std lib from C++14 onwards: +// +struct negate +{ + template + T operator()(T const &x) const + { + return -x; + } +}; + +struct plus +{ + template + T operator()(T const &x, U const& y) const + { + return x + y; + } +}; + +struct minus +{ + template + T operator()(T const &x, U const& y) const + { + return x - y; + } +}; + +} // namespace detail + +/** + * Returns the zero element for multiplication of polynomials. + */ +template +polynomial zero_element(std::multiplies< polynomial >) +{ + return polynomial(); +} + +template +polynomial identity_element(std::multiplies< polynomial >) +{ + return polynomial(T(1)); +} + +/* Calculates a / b and a % b, returning the pair (quotient, remainder) together + * because the same amount of computation yields both. + * This function is not defined for division by zero: user beware. + */ +template +std::pair< polynomial, polynomial > +quotient_remainder(const polynomial& dividend, const polynomial& divisor) +{ + BOOST_MATH_ASSERT(divisor); + if (dividend.size() < divisor.size()) + return std::make_pair(polynomial(), dividend); + return detail::division(dividend, divisor); +} + + +template +class polynomial +{ +public: + // typedefs: + typedef typename std::vector::value_type value_type; + typedef typename std::vector::size_type size_type; + + // construct: + polynomial()= default; + + template + polynomial(const U* data, unsigned order) + : m_data(data, data + order + 1) + { + normalize(); + } + + template + polynomial(I first, I last) + : m_data(first, last) + { + normalize(); + } + + template + polynomial(I first, unsigned length) + : m_data(first, std::next(first, length + 1)) + { + normalize(); + } + + polynomial(std::vector&& p) : m_data(std::move(p)) + { + normalize(); + } + + template ::value, bool>::type = true> + explicit polynomial(const U& point) + { + if (point != U(0)) + m_data.push_back(point); + } + + // move: + polynomial(polynomial&& p) noexcept + : m_data(std::move(p.m_data)) { } + + // copy: + polynomial(const polynomial& p) + : m_data(p.m_data) { } + + template + polynomial(const polynomial& p) + { + m_data.resize(p.size()); + for(unsigned i = 0; i < p.size(); ++i) + { + m_data[i] = boost::math::tools::real_cast(p[i]); + } + } +#ifdef BOOST_MATH_HAS_IS_CONST_ITERABLE + template ::value, bool>::type = true> + explicit polynomial(const Range& r) + : polynomial(r.begin(), r.end()) + { + } +#endif + polynomial(std::initializer_list l) : polynomial(std::begin(l), std::end(l)) + { + } + + polynomial& + operator=(std::initializer_list l) + { + m_data.assign(std::begin(l), std::end(l)); + normalize(); + return *this; + } + + + // access: + size_type size() const { return m_data.size(); } + size_type degree() const + { + if (size() == 0) + BOOST_MATH_THROW_EXCEPTION(std::logic_error("degree() is undefined for the zero polynomial.")); + return m_data.size() - 1; + } + value_type& operator[](size_type i) + { + return m_data[i]; + } + const value_type& operator[](size_type i) const + { + return m_data[i]; + } + + T evaluate(T z) const + { + return this->operator()(z); + } + + T operator()(T z) const + { + return m_data.size() > 0 ? boost::math::tools::evaluate_polynomial((m_data).data(), z, m_data.size()) : T(0); + } + std::vector chebyshev() const + { + return polynomial_to_chebyshev(m_data); + } + + std::vector const& data() const + { + return m_data; + } + + std::vector & data() + { + return m_data; + } + + polynomial prime() const + { +#ifdef _MSC_VER + // Disable int->float conversion warning: +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if (m_data.size() == 0) + { + return polynomial({}); + } + + std::vector p_data(m_data.size() - 1); + for (size_t i = 0; i < p_data.size(); ++i) { + p_data[i] = m_data[i+1]*static_cast(i+1); + } + return polynomial(std::move(p_data)); +#ifdef _MSC_VER +#pragma warning(pop) +#endif + } + + polynomial integrate() const + { + std::vector i_data(m_data.size() + 1); + // Choose integration constant such that P(0) = 0. + i_data[0] = T(0); + for (size_t i = 1; i < i_data.size(); ++i) + { + i_data[i] = m_data[i-1]/static_cast(i); + } + return polynomial(std::move(i_data)); + } + + // operators: + polynomial& operator =(polynomial&& p) noexcept + { + m_data = std::move(p.m_data); + return *this; + } + + polynomial& operator =(const polynomial& p) + { + m_data = p.m_data; + return *this; + } + + template + typename std::enable_if::value, polynomial&>::type operator +=(const U& value) + { + addition(value); + normalize(); + return *this; + } + + template + typename std::enable_if::value, polynomial&>::type operator -=(const U& value) + { + subtraction(value); + normalize(); + return *this; + } + + template + typename std::enable_if::value, polynomial&>::type operator *=(const U& value) + { + multiplication(value); + normalize(); + return *this; + } + + template + typename std::enable_if::value, polynomial&>::type operator /=(const U& value) + { + division(value); + normalize(); + return *this; + } + + template + typename std::enable_if::value, polynomial&>::type operator %=(const U& /*value*/) + { + // We can always divide by a scalar, so there is no remainder: + this->set_zero(); + return *this; + } + + template + polynomial& operator +=(const polynomial& value) + { + addition(value); + normalize(); + return *this; + } + + template + polynomial& operator -=(const polynomial& value) + { + subtraction(value); + normalize(); + return *this; + } + + template + void multiply(const polynomial& a, const polynomial& b) { + if (!a || !b) + { + this->set_zero(); + return; + } + std::vector prod(a.size() + b.size() - 1, T(0)); + for (unsigned i = 0; i < a.size(); ++i) + for (unsigned j = 0; j < b.size(); ++j) + prod[i+j] += a.m_data[i] * b.m_data[j]; + m_data.swap(prod); + } + + template + polynomial& operator *=(const polynomial& value) + { + this->multiply(*this, value); + return *this; + } + + template + polynomial& operator /=(const polynomial& value) + { + *this = quotient_remainder(*this, value).first; + return *this; + } + + template + polynomial& operator %=(const polynomial& value) + { + *this = quotient_remainder(*this, value).second; + return *this; + } + + template + polynomial& operator >>=(U const &n) + { + BOOST_MATH_ASSERT(n <= m_data.size()); + m_data.erase(m_data.begin(), m_data.begin() + n); + return *this; + } + + template + polynomial& operator <<=(U const &n) + { + m_data.insert(m_data.begin(), n, static_cast(0)); + normalize(); + return *this; + } + + // Convenient and efficient query for zero. + bool is_zero() const + { + return m_data.empty(); + } + + // Conversion to bool. + inline explicit operator bool() const + { + return !m_data.empty(); + } + + // Fast way to set a polynomial to zero. + void set_zero() + { + m_data.clear(); + } + + /** Remove zero coefficients 'from the top', that is for which there are no + * non-zero coefficients of higher degree. */ + void normalize() + { + m_data.erase(std::find_if(m_data.rbegin(), m_data.rend(), [](const T& x)->bool { return x != T(0); }).base(), m_data.end()); + } + +private: + template + polynomial& addition(const U& value, R op) + { + if(m_data.size() == 0) + m_data.resize(1, 0); + m_data[0] = op(m_data[0], value); + return *this; + } + + template + polynomial& addition(const U& value) + { + return addition(value, detail::plus()); + } + + template + polynomial& subtraction(const U& value) + { + return addition(value, detail::minus()); + } + + template + polynomial& addition(const polynomial& value, R op) + { + if (m_data.size() < value.size()) + m_data.resize(value.size(), 0); + for(size_type i = 0; i < value.size(); ++i) + m_data[i] = op(m_data[i], value[i]); + return *this; + } + + template + polynomial& addition(const polynomial& value) + { + return addition(value, detail::plus()); + } + + template + polynomial& subtraction(const polynomial& value) + { + return addition(value, detail::minus()); + } + + template + polynomial& multiplication(const U& value) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x * value; }); + return *this; + } + + template + polynomial& division(const U& value) + { + std::transform(m_data.begin(), m_data.end(), m_data.begin(), [&](const T& x)->T { return x / value; }); + return *this; + } + + std::vector m_data; +}; + + +template +inline polynomial operator + (const polynomial& a, const polynomial& b) +{ + polynomial result(a); + result += b; + return result; +} + +template +inline polynomial operator + (polynomial&& a, const polynomial& b) +{ + a += b; + return std::move(a); +} +template +inline polynomial operator + (const polynomial& a, polynomial&& b) +{ + b += a; + return b; +} +template +inline polynomial operator + (polynomial&& a, polynomial&& b) +{ + a += b; + return a; +} + +template +inline polynomial operator - (const polynomial& a, const polynomial& b) +{ + polynomial result(a); + result -= b; + return result; +} + +template +inline polynomial operator - (polynomial&& a, const polynomial& b) +{ + a -= b; + return a; +} +template +inline polynomial operator - (const polynomial& a, polynomial&& b) +{ + b -= a; + return -b; +} +template +inline polynomial operator - (polynomial&& a, polynomial&& b) +{ + a -= b; + return a; +} + +template +inline polynomial operator * (const polynomial& a, const polynomial& b) +{ + polynomial result; + result.multiply(a, b); + return result; +} + +template +inline polynomial operator / (const polynomial& a, const polynomial& b) +{ + return quotient_remainder(a, b).first; +} + +template +inline polynomial operator % (const polynomial& a, const polynomial& b) +{ + return quotient_remainder(a, b).second; +} + +template +inline typename std::enable_if::value, polynomial >::type operator + (polynomial a, const U& b) +{ + a += b; + return a; +} + +template +inline typename std::enable_if::value, polynomial >::type operator - (polynomial a, const U& b) +{ + a -= b; + return a; +} + +template +inline typename std::enable_if::value, polynomial >::type operator * (polynomial a, const U& b) +{ + a *= b; + return a; +} + +template +inline typename std::enable_if::value, polynomial >::type operator / (polynomial a, const U& b) +{ + a /= b; + return a; +} + +template +inline typename std::enable_if::value, polynomial >::type operator % (const polynomial&, const U&) +{ + // Since we can always divide by a scalar, result is always an empty polynomial: + return polynomial(); +} + +template +inline typename std::enable_if::value, polynomial >::type operator + (const U& a, polynomial b) +{ + b += a; + return b; +} + +template +inline typename std::enable_if::value, polynomial >::type operator - (const U& a, polynomial b) +{ + b -= a; + return -b; +} + +template +inline typename std::enable_if::value, polynomial >::type operator * (const U& a, polynomial b) +{ + b *= a; + return b; +} + +template +bool operator == (const polynomial &a, const polynomial &b) +{ + return a.data() == b.data(); +} + +template +bool operator != (const polynomial &a, const polynomial &b) +{ + return a.data() != b.data(); +} + +template +polynomial operator >> (polynomial a, const U& b) +{ + a >>= b; + return a; +} + +template +polynomial operator << (polynomial a, const U& b) +{ + a <<= b; + return a; +} + +// Unary minus (negate). +template +polynomial operator - (polynomial a) +{ + std::transform(a.data().begin(), a.data().end(), a.data().begin(), detail::negate()); + return a; +} + +template +bool odd(polynomial const &a) +{ + return a.size() > 0 && a[0] != static_cast(0); +} + +template +bool even(polynomial const &a) +{ + return !odd(a); +} + +template +polynomial pow(polynomial base, int exp) +{ + if (exp < 0) + return policies::raise_domain_error( + "boost::math::tools::pow<%1%>", + "Negative powers are not supported for polynomials.", + base, policies::policy<>()); + // if the policy is ignore_error or errno_on_error, raise_domain_error + // will return std::numeric_limits>::quiet_NaN(), which + // defaults to polynomial(), which is the zero polynomial + polynomial result(T(1)); + if (exp & 1) + result = base; + /* "Exponentiation by squaring" */ + while (exp >>= 1) + { + base *= base; + if (exp & 1) + result *= base; + } + return result; +} + +template +inline std::basic_ostream& operator << (std::basic_ostream& os, const polynomial& poly) +{ + os << "{ "; + for(unsigned i = 0; i < poly.size(); ++i) + { + if(i) os << ", "; + os << poly[i]; + } + os << " }"; + return os; +} + +} // namespace tools +} // namespace math +} // namespace boost + +// +// Polynomial specific overload of gcd algorithm: +// +#include + +#endif // BOOST_MATH_TOOLS_POLYNOMIAL_HPP diff --git a/libcxx/src/third-party/boost/math/tools/polynomial_gcd.hpp b/libcxx/src/third-party/boost/math/tools/polynomial_gcd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/polynomial_gcd.hpp @@ -0,0 +1,268 @@ +// (C) Copyright Jeremy William Murphy 2016. +// (C) Copyright Matt Borland 2021. +// 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_TOOLS_POLYNOMIAL_GCD_HPP +#define BOOST_MATH_TOOLS_POLYNOMIAL_GCD_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include + +#else +#include +#include +#include +#include +#include + +namespace boost { namespace integer { + +namespace gcd_detail { + +template +inline EuclideanDomain Euclid_gcd(EuclideanDomain a, EuclideanDomain b) noexcept(std::is_arithmetic::value) +{ + using std::swap; + while (b != EuclideanDomain(0)) + { + a %= b; + swap(a, b); + } + return a; +} + +enum method_type +{ + method_euclid = 0, + method_binary = 1, + method_mixed = 2 +}; + +} // gcd_detail + +template ::value_type> +std::pair gcd_range(Iter first, Iter last) noexcept(std::is_arithmetic::value) +{ + BOOST_MATH_ASSERT(first != last); + + T d = *first; + ++first; + while (d != T(1) && first != last) + { + #ifdef BOOST_MATH_HAS_CXX17_NUMERIC + d = std::gcd(d, *first); + #else + d = gcd_detail::Euclid_gcd(d, *first); + #endif + ++first; + } + return std::make_pair(d, first); +} + +}} // namespace boost::integer +#endif + +namespace boost{ + + namespace integer { + + namespace gcd_detail { + + template + struct gcd_traits; + + template + struct gcd_traits > + { + inline static const boost::math::tools::polynomial& abs(const boost::math::tools::polynomial& val) { return val; } + + static const method_type method = method_euclid; + }; + + } +} + +namespace math{ namespace tools{ + +/* From Knuth, 4.6.1: +* +* We may write any nonzero polynomial u(x) from R[x] where R is a UFD as +* +* u(x) = cont(u) . pp(u(x)) +* +* where cont(u), the content of u, is an element of S, and pp(u(x)), the primitive +* part of u(x), is a primitive polynomial over S. +* When u(x) = 0, it is convenient to define cont(u) = pp(u(x)) = O. +*/ + +template +T content(polynomial const &x) +{ + return x ? boost::integer::gcd_range(x.data().begin(), x.data().end()).first : T(0); +} + +// Knuth, 4.6.1 +template +polynomial primitive_part(polynomial const &x, T const &cont) +{ + return x ? x / cont : polynomial(); +} + + +template +polynomial primitive_part(polynomial const &x) +{ + return primitive_part(x, content(x)); +} + + +// Trivial but useful convenience function referred to simply as l() in Knuth. +template +T leading_coefficient(polynomial const &x) +{ + return x ? x.data().back() : T(0); +} + + +namespace detail +{ + /* Reduce u and v to their primitive parts and return the gcd of their + * contents. Used in a couple of gcd algorithms. + */ + template + T reduce_to_primitive(polynomial &u, polynomial &v) + { + T const u_cont = content(u), v_cont = content(v); + u /= u_cont; + v /= v_cont; + + #ifdef BOOST_MATH_HAS_CXX17_NUMERIC + return std::gcd(u_cont, v_cont); + #else + return boost::integer::gcd_detail::Euclid_gcd(u_cont, v_cont); + #endif + } +} + + +/** +* Knuth, The Art of Computer Programming: Volume 2, Third edition, 1998 +* Algorithm 4.6.1C: Greatest common divisor over a unique factorization domain. +* +* The subresultant algorithm by George E. Collins [JACM 14 (1967), 128-142], +* later improved by W. S. Brown and J. F. Traub [JACM 18 (1971), 505-514]. +* +* Although step C3 keeps the coefficients to a "reasonable" size, they are +* still potentially several binary orders of magnitude larger than the inputs. +* Thus, this algorithm should only be used where T is a multi-precision type. +* +* @tparam T Polynomial coefficient type. +* @param u First polynomial. +* @param v Second polynomial. +* @return Greatest common divisor of polynomials u and v. +*/ +template +typename std::enable_if< std::numeric_limits::is_integer, polynomial >::type +subresultant_gcd(polynomial u, polynomial v) +{ + using std::swap; + BOOST_MATH_ASSERT(u || v); + + if (!u) + return v; + if (!v) + return u; + + typedef typename polynomial::size_type N; + + if (u.degree() < v.degree()) + swap(u, v); + + T const d = detail::reduce_to_primitive(u, v); + T g = 1, h = 1; + polynomial r; + while (true) + { + BOOST_MATH_ASSERT(u.degree() >= v.degree()); + // Pseudo-division. + r = u % v; + if (!r) + return d * primitive_part(v); // Attach the content. + if (r.degree() == 0) + return d * polynomial(T(1)); // The content is the result. + N const delta = u.degree() - v.degree(); + // Adjust remainder. + u = v; + v = r / (g * detail::integer_power(h, delta)); + g = leading_coefficient(u); + T const tmp = detail::integer_power(g, delta); + if (delta <= N(1)) + h = tmp * detail::integer_power(h, N(1) - delta); + else + h = tmp / detail::integer_power(h, delta - N(1)); + } +} + + +/** + * @brief GCD for polynomials with unbounded multi-precision integral coefficients. + * + * The multi-precision constraint is enforced via numeric_limits. + * + * Note that intermediate terms in the evaluation can grow arbitrarily large, hence the need for + * unbounded integers, otherwise numeric loverflow would break the algorithm. + * + * @tparam T A multi-precision integral type. + */ +template +typename std::enable_if::is_integer && !std::numeric_limits::is_bounded, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + return subresultant_gcd(u, v); +} +// GCD over bounded integers is not currently allowed: +template +typename std::enable_if::is_integer && std::numeric_limits::is_bounded, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + static_assert(sizeof(v) == 0, "GCD on polynomials of bounded integers is disallowed due to the excessive growth in the size of intermediate terms."); + return subresultant_gcd(u, v); +} +// GCD over polynomials of floats can go via the Euclid algorithm: +template +typename std::enable_if::is_integer && (std::numeric_limits::min_exponent != std::numeric_limits::max_exponent) && !std::numeric_limits::is_exact, polynomial >::type +gcd(polynomial const &u, polynomial const &v) +{ + return boost::integer::gcd_detail::Euclid_gcd(u, v); +} + +} +// +// Using declaration so we overload the default implementation in this namespace: +// +using boost::math::tools::gcd; + +} + +namespace integer +{ + // + // Using declaration so we overload the default implementation in this namespace: + // + using boost::math::tools::gcd; +} + +} // namespace boost::math::tools + +#endif diff --git a/libcxx/src/third-party/boost/math/tools/precision.hpp b/libcxx/src/third-party/boost/math/tools/precision.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/precision.hpp @@ -0,0 +1,395 @@ +// Copyright John Maddock 2005-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_TOOLS_PRECISION_INCLUDED +#define BOOST_MATH_TOOLS_PRECISION_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include // LDBL_MANT_DIG + +namespace boost{ namespace math +{ +namespace tools +{ +// If T is not specialized, the functions digits, max_value and min_value, +// all get synthesised automatically from std::numeric_limits. +// However, if numeric_limits is not specialised for type RealType, +// for example with NTL::RR type, then you will get a compiler error +// when code tries to use these functions, unless you explicitly specialise them. + +// For example if the precision of RealType varies at runtime, +// then numeric_limits support may not be appropriate, +// see boost/math/tools/ntl.hpp for examples like +// template <> NTL::RR max_value ... +// See Conceptual Requirements for Real Number Types. + +template +inline constexpr int digits(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept +{ + static_assert( ::std::numeric_limits::is_specialized, "Type T must be specialized"); + static_assert( ::std::numeric_limits::radix == 2 || ::std::numeric_limits::radix == 10, "Type T must have a radix of 2 or 10"); + + return std::numeric_limits::radix == 2 + ? std::numeric_limits::digits + : ((std::numeric_limits::digits + 1) * 1000L) / 301L; +} + +template +inline constexpr T max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + static_assert( ::std::numeric_limits::is_specialized, "Type T must be specialized"); + return (std::numeric_limits::max)(); +} // Also used as a finite 'infinite' value for - and +infinity, for example: +// -max_value = -1.79769e+308, max_value = 1.79769e+308. + +template +inline constexpr T min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + static_assert( ::std::numeric_limits::is_specialized, "Type T must be specialized"); + + return (std::numeric_limits::min)(); +} + +namespace detail{ +// +// Logarithmic limits come next, note that although +// we can compute these from the log of the max value +// that is not in general thread safe (if we cache the value) +// so it's better to specialise these: +// +// For type float first: +// +template +inline constexpr T log_max_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return 88.0f; +} + +template +inline constexpr T log_min_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return -87.0f; +} +// +// Now double: +// +template +inline constexpr T log_max_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return 709.0; +} + +template +inline constexpr T log_min_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return -708.0; +} +// +// 80 and 128-bit long doubles: +// +template +inline constexpr T log_max_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return 11356.0L; +} + +template +inline constexpr T log_min_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return -11355.0L; +} + +template +inline T log_max_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + static const T m = boost::math::tools::max_value(); + static const T val = log(m); +#else + static const T val = log(boost::math::tools::max_value()); +#endif + return val; +} + +template +inline T log_min_value(const std::integral_constant& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + BOOST_MATH_STD_USING +#ifdef __SUNPRO_CC + static const T m = boost::math::tools::min_value(); + static const T val = log(m); +#else + static const T val = log(boost::math::tools::min_value()); +#endif + return val; +} + +template +inline constexpr T epsilon(const std::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(std::is_floating_point::value) +{ + return std::numeric_limits::epsilon(); +} + +#if defined(__GNUC__) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) +template <> +inline constexpr long double epsilon(const std::true_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(long double)) noexcept(std::is_floating_point::value) +{ + // numeric_limits on Darwin (and elsewhere) tells lies here: + // the issue is that long double on a few platforms is + // really a "double double" which has a non-contiguous + // mantissa: 53 bits followed by an unspecified number of + // zero bits, followed by 53 more bits. Thus the apparent + // precision of the type varies depending where it's been. + // Set epsilon to the value that a 106 bit fixed mantissa + // type would have, as that will give us sensible behaviour everywhere. + // + // This static assert fails for some unknown reason, so + // disabled for now... + // static_assert(std::numeric_limits::digits == 106); + return 2.4651903288156618919116517665087e-32L; +} +#endif + +template +inline T epsilon(const std::false_type& BOOST_MATH_APPEND_EXPLICIT_TEMPLATE_TYPE(T)) +{ + // Note: don't cache result as precision may vary at runtime: + BOOST_MATH_STD_USING // for ADL of std names + return ldexp(static_cast(1), 1-policies::digits >()); +} + +template +struct log_limit_traits +{ + typedef typename std::conditional< + (std::numeric_limits::radix == 2) && + (std::numeric_limits::max_exponent == 128 + || std::numeric_limits::max_exponent == 1024 + || std::numeric_limits::max_exponent == 16384), + std::integral_constant::max_exponent > INT_MAX ? INT_MAX : static_cast(std::numeric_limits::max_exponent))>, + std::integral_constant + >::type tag_type; + static constexpr bool value = tag_type::value ? true : false; + static_assert(::std::numeric_limits::is_specialized || (value == 0), "Type T must be specialized or equal to 0"); +}; + +template struct log_limit_noexcept_traits_imp : public log_limit_traits {}; +template struct log_limit_noexcept_traits_imp : public std::integral_constant {}; + +template +struct log_limit_noexcept_traits : public log_limit_noexcept_traits_imp::value> {}; + +} // namespace detail + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4309) +#endif + +template +inline constexpr T log_max_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits::value) +{ +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::log_max_value(typename detail::log_limit_traits::tag_type()); +#else + BOOST_MATH_ASSERT(::std::numeric_limits::is_specialized); + BOOST_MATH_STD_USING + static const T val = log((std::numeric_limits::max)()); + return val; +#endif +} + +template +inline constexpr T log_min_value(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE(T)) noexcept(detail::log_limit_noexcept_traits::value) +{ +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::log_min_value(typename detail::log_limit_traits::tag_type()); +#else + BOOST_MATH_ASSERT(::std::numeric_limits::is_specialized); + BOOST_MATH_STD_USING + static const T val = log((std::numeric_limits::min)()); + return val; +#endif +} + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +template +inline constexpr T epsilon(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(T)) noexcept(std::is_floating_point::value) +{ +#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS + return detail::epsilon(std::integral_constant::is_specialized>()); +#else + return ::std::numeric_limits::is_specialized ? + detail::epsilon(std::true_type()) : + detail::epsilon(std::false_type()); +#endif +} + +namespace detail{ + +template +inline constexpr T root_epsilon_imp(const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.00034526698300124390839884978618400831996329879769945L); +} + +template +inline constexpr T root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.1490116119384765625e-7L); +} + +template +inline constexpr T root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.32927225399135962333569506281281311031656150598474e-9L); +} + +template +inline constexpr T root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.1387778780781445675529539585113525390625e-16L); +} + +template +inline T root_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING + static const T r_eps = sqrt(tools::epsilon()); + return r_eps; +} + +template +inline T root_epsilon_imp(const T*, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + return sqrt(tools::epsilon()); +} + +template +inline constexpr T cbrt_epsilon_imp(const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.0049215666011518482998719164346805794944150447839903L); +} + +template +inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(6.05545445239333906078989272793696693569753008995e-6L); +} + +template +inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(4.76837158203125e-7L); +} + +template +inline constexpr T cbrt_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(5.7749313854154005630396773604745549542403508090496e-12L); +} + +template +inline T cbrt_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING; + static const T cbrt_eps = pow(tools::epsilon(), T(1) / 3); + return cbrt_eps; +} + +template +inline T cbrt_epsilon_imp(const T*, const std::integral_constant&) +{ + BOOST_MATH_STD_USING; + return pow(tools::epsilon(), T(1) / 3); +} + +template +inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.018581361171917516667460937040007436176452688944747L); +} + +template +inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.0001220703125L); +} + +template +inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.18145860519450699870567321328132261891067079047605e-4L); +} + +template +inline constexpr T forth_root_epsilon_imp(const T*, const std::integral_constant&) noexcept(std::is_floating_point::value) +{ + return static_cast(0.37252902984619140625e-8L); +} + +template +inline T forth_root_epsilon_imp(const T*, const Tag&) +{ + BOOST_MATH_STD_USING + static const T r_eps = sqrt(sqrt(tools::epsilon())); + return r_eps; +} + +template +inline T forth_root_epsilon_imp(const T*, const std::integral_constant&) +{ + BOOST_MATH_STD_USING + return sqrt(sqrt(tools::epsilon())); +} + +template +struct root_epsilon_traits +{ + typedef std::integral_constant::radix == 2) && (::std::numeric_limits::digits != INT_MAX) ? std::numeric_limits::digits : 0> tag_type; + static constexpr bool has_noexcept = (tag_type::value == 113) || (tag_type::value == 64) || (tag_type::value == 53) || (tag_type::value == 24); +}; + +} + +template +inline constexpr T root_epsilon() noexcept(std::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::root_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +template +inline constexpr T cbrt_epsilon() noexcept(std::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::cbrt_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +template +inline constexpr T forth_root_epsilon() noexcept(std::is_floating_point::value && detail::root_epsilon_traits::has_noexcept) +{ + return detail::forth_root_epsilon_imp(static_cast(nullptr), typename detail::root_epsilon_traits::tag_type()); +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_PRECISION_INCLUDED + diff --git a/libcxx/src/third-party/boost/math/tools/promotion.hpp b/libcxx/src/third-party/boost/math/tools/promotion.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/promotion.hpp @@ -0,0 +1,180 @@ +// boost\math\tools\promotion.hpp + +// Copyright John Maddock 2006. +// Copyright Paul A. Bristow 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) + +// Promote arguments functions to allow math functions to have arguments +// provided as integer OR real (floating-point, built-in or UDT) +// (called ArithmeticType in functions that use promotion) +// that help to reduce the risk of creating multiple instantiations. +// Allows creation of an inline wrapper that forwards to a foo(RT, RT) function, +// so you never get to instantiate any mixed foo(RT, IT) functions. + +#ifndef BOOST_MATH_PROMOTION_HPP +#define BOOST_MATH_PROMOTION_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include + +namespace boost +{ + namespace math + { + namespace tools + { + // If either T1 or T2 is an integer type, + // pretend it was a double (for the purposes of further analysis). + // Then pick the wider of the two floating-point types + // as the actual signature to forward to. + // For example: + // foo(int, short) -> double foo(double, double); + // foo(int, float) -> double foo(double, double); + // Note: NOT float foo(float, float) + // foo(int, double) -> foo(double, double); + // foo(double, float) -> double foo(double, double); + // foo(double, float) -> double foo(double, double); + // foo(any-int-or-float-type, long double) -> foo(long double, long double); + // but ONLY float foo(float, float) is unchanged. + // So the only way to get an entirely float version is to call foo(1.F, 2.F), + // But since most (all?) the math functions convert to double internally, + // probably there would not be the hoped-for gain by using float here. + + // This follows the C-compatible conversion rules of pow, etc + // where pow(int, float) is converted to pow(double, double). + + template + struct promote_arg + { // If T is integral type, then promote to double. + using type = typename std::conditional::value, double, T>::type; + }; + // These full specialisations reduce std::conditional usage and speed up + // compilation: + template <> struct promote_arg { using type = float; }; + template <> struct promote_arg{ using type = double; }; + template <> struct promote_arg { using type = long double; }; + template <> struct promote_arg { using type = double; }; + + template + using promote_arg_t = typename promote_arg::type; + + template + struct promote_args_2 + { // Promote, if necessary, & pick the wider of the two floating-point types. + // for both parameter types, if integral promote to double. + using T1P = typename promote_arg::type; // T1 perhaps promoted. + using T2P = typename promote_arg::type; // T2 perhaps promoted. + + using type = typename std::conditional< + std::is_floating_point::value && std::is_floating_point::value, // both T1P and T2P are floating-point? +#ifdef BOOST_MATH_USE_FLOAT128 + typename std::conditional::value || std::is_same<__float128, T2P>::value, // either long double? + __float128, +#endif + typename std::conditional::value || std::is_same::value, // either long double? + long double, // then result type is long double. + typename std::conditional::value || std::is_same::value, // either double? + double, // result type is double. + float // else result type is float. + >::type +#ifdef BOOST_MATH_USE_FLOAT128 + >::type +#endif + >::type, + // else one or the other is a user-defined type: + typename std::conditional::value && std::is_convertible::value, T2P, T1P>::type>::type; + }; // promote_arg2 + // These full specialisations reduce std::conditional usage and speed up + // compilation: + template <> struct promote_args_2 { using type = float; }; + template <> struct promote_args_2{ using type = double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + template <> struct promote_args_2 { using type = long double; }; + + template + using promote_args_2_t = typename promote_args_2::type; + + template + struct promote_args + { + using type = typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, typename std::remove_cv::type + >::type + >::type + >::type + >::type + >::type; + +#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS + // + // Guard against use of long double if it's not supported: + // + static_assert((0 == std::is_same::value), "Sorry, but this platform does not have sufficient long double support for the special functions to be reliably implemented."); +#endif + }; + + template + using promote_args_t = typename promote_args::type; + + // + // This struct is the same as above, but has no static assert on long double usage, + // it should be used only on functions that can be implemented for long double + // even when std lib support is missing or broken for that type. + // + template + struct promote_args_permissive + { + using type = typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, + typename promote_args_2< + typename std::remove_cv::type, typename std::remove_cv::type + >::type + >::type + >::type + >::type + >::type; + }; + + template + using promote_args_permissive_t = typename promote_args_permissive::type; + + } // namespace tools + } // namespace math +} // namespace boost + +#endif // BOOST_MATH_PROMOTION_HPP + diff --git a/libcxx/src/third-party/boost/math/tools/quartic_roots.hpp b/libcxx/src/third-party/boost/math/tools/quartic_roots.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/quartic_roots.hpp @@ -0,0 +1,157 @@ +// (C) Copyright Nick Thompson 2021. +// 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_TOOLS_QUARTIC_ROOTS_HPP +#define BOOST_MATH_TOOLS_QUARTIC_ROOTS_HPP +#include +#include +#include + +namespace boost::math::tools { + +namespace detail { + +// Make sure the nans are always at the back of the array: +template +bool comparator(Real r1, Real r2) { + using std::isnan; + if (isnan(r1)) { return false; } + if (isnan(r2)) { return true; } + return r1 < r2; +} + +template +std::array polish_and_sort(Real a, Real b, Real c, Real d, Real e, std::array& roots) { + // Polish the roots with a Halley iterate. + using std::fma; + using std::abs; + for (auto &r : roots) { + Real df = fma(4*a, r, 3*b); + df = fma(df, r, 2*c); + df = fma(df, r, d); + Real d2f = fma(12*a, r, 6*b); + d2f = fma(d2f, r, 2*c); + Real f = fma(a, r, b); + f = fma(f,r,c); + f = fma(f,r,d); + f = fma(f,r,e); + Real denom = 2*df*df - f*d2f; + if (abs(denom) > (std::numeric_limits::min)()) + { + r -= 2*f*df/denom; + } + } + std::sort(roots.begin(), roots.end(), detail::comparator); + return roots; +} + +} +// Solves ax^4 + bx^3 + cx^2 + dx + e = 0. +// Only returns the real roots, as these are the only roots of interest in ray intersection problems. +// Follows Graphics Gems V: https://github.com/erich666/GraphicsGems/blob/master/gems/Roots3And4.c +template +std::array quartic_roots(Real a, Real b, Real c, Real d, Real e) { + using std::abs; + using std::sqrt; + auto nan = std::numeric_limits::quiet_NaN(); + std::array roots{nan, nan, nan, nan}; + if (abs(a) <= (std::numeric_limits::min)()) { + auto cbrts = cubic_roots(b, c, d, e); + roots[0] = cbrts[0]; + roots[1] = cbrts[1]; + roots[2] = cbrts[2]; + if (b == 0 && c == 0 && d == 0 && e == 0) { + roots[3] = 0; + } + return detail::polish_and_sort(a, b, c, d, e, roots); + } + if (abs(e) <= (std::numeric_limits::min)()) { + auto v = cubic_roots(a, b, c, d); + roots[0] = v[0]; + roots[1] = v[1]; + roots[2] = v[2]; + roots[3] = 0; + return detail::polish_and_sort(a, b, c, d, e, roots); + } + // Now solve x^4 + Ax^3 + Bx^2 + Cx + D = 0. + Real A = b/a; + Real B = c/a; + Real C = d/a; + Real D = e/a; + Real Asq = A*A; + // Let x = y - A/4: + // Mathematica: Expand[(y - A/4)^4 + A*(y - A/4)^3 + B*(y - A/4)^2 + C*(y - A/4) + D] + // We now solve the depressed quartic y^4 + py^2 + qy + r = 0. + Real p = B - 3*Asq/8; + Real q = C - A*B/2 + Asq*A/8; + Real r = D - A*C/4 + Asq*B/16 - 3*Asq*Asq/256; + if (abs(r) <= (std::numeric_limits::min)()) { + auto [r1, r2, r3] = cubic_roots(Real(1), Real(0), p, q); + r1 -= A/4; + r2 -= A/4; + r3 -= A/4; + roots[0] = r1; + roots[1] = r2; + roots[2] = r3; + roots[3] = -A/4; + return detail::polish_and_sort(a, b, c, d, e, roots); + } + // Biquadratic case: + if (abs(q) <= (std::numeric_limits::min)()) { + auto [r1, r2] = quadratic_roots(Real(1), p, r); + if (r1 >= 0) { + Real rtr = sqrt(r1); + roots[0] = rtr - A/4; + roots[1] = -rtr - A/4; + } + if (r2 >= 0) { + Real rtr = sqrt(r2); + roots[2] = rtr - A/4; + roots[3] = -rtr - A/4; + } + return detail::polish_and_sort(a, b, c, d, e, roots); + } + + // Now split the depressed quartic into two quadratics: + // y^4 + py^2 + qy + r = (y^2 + sy + u)(y^2 - sy + v) = y^4 + (v+u-s^2)y^2 + s(v - u)y + uv + // So p = v+u-s^2, q = s(v - u), r = uv. + // Then (v+u)^2 - (v-u)^2 = 4uv = 4r = (p+s^2)^2 - q^2/s^2. + // Multiply through by s^2 to get s^2(p+s^2)^2 - q^2 - 4rs^2 = 0, which is a cubic in s^2. + // Then we let z = s^2, to get + // z^3 + 2pz^2 + (p^2 - 4r)z - q^2 = 0. + auto z_roots = cubic_roots(Real(1), 2*p, p*p - 4*r, -q*q); + // z = s^2, so s = sqrt(z). + // Hence we require a root > 0, and for the sake of sanity we should take the largest one: + Real largest_root = std::numeric_limits::lowest(); + for (auto z : z_roots) { + if (z > largest_root) { + largest_root = z; + } + } + // No real roots: + if (largest_root <= 0) { + return roots; + } + Real s = sqrt(largest_root); + // s is nonzero, because we took care of the biquadratic case. + Real v = (p + s*s + q/s)/2; + Real u = v - q/s; + // Now solve y^2 + sy + u = 0: + auto [root0, root1] = quadratic_roots(Real(1), s, u); + + // Now solve y^2 - sy + v = 0: + auto [root2, root3] = quadratic_roots(Real(1), -s, v); + roots[0] = root0; + roots[1] = root1; + roots[2] = root2; + roots[3] = root3; + + for (auto& r : roots) { + r -= A/4; + } + return detail::polish_and_sort(a, b, c, d, e, roots); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/random_vector.hpp b/libcxx/src/third-party/boost/math/tools/random_vector.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/random_vector.hpp @@ -0,0 +1,101 @@ +// (C) Copyright Nick Thompson 2018. +// (C) Copyright Matt Borland 2021. +// 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) + +#include +#include +#include +#include + +namespace boost { namespace math { + +// To stress test, set global_seed = 0, global_size = huge. +static constexpr std::size_t global_seed = 0; +static constexpr std::size_t global_size = 128; + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + std::normal_distribution dis(0, 1); + for(std::size_t i = 0; i < v.size(); ++i) + { + v[i] = dis(gen); + } + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_uniform_vector(std::size_t size, std::size_t seed, T lower_bound = T(0), T upper_bound = T(1)) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + std::uniform_real_distribution dis(lower_bound, upper_bound); + + for (auto& i : v) + { + i = dis(gen); + } + + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed, T mean, T stddev) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + std::normal_distribution dis(mean, stddev); + for (std::size_t i = 0; i < v.size(); ++i) + { + v[i] = dis(gen); + } + return v; +} + +template::value, bool>::type = true> +std::vector generate_random_vector(std::size_t size, std::size_t seed) +{ + if (seed == 0) + { + std::random_device rd; + seed = rd(); + } + std::vector v(size); + + std::mt19937 gen(seed); + + // Rescaling by larger than 2 is UB! + std::uniform_int_distribution dis(std::numeric_limits::lowest()/2, (std::numeric_limits::max)()/2); + for (std::size_t i = 0; i < v.size(); ++i) + { + v[i] = dis(gen); + } + return v; +} + +}} // Namespaces diff --git a/libcxx/src/third-party/boost/math/tools/rational.hpp b/libcxx/src/third-party/boost/math/tools/rational.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/rational.hpp @@ -0,0 +1,333 @@ +// (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_TOOLS_RATIONAL_HPP +#define BOOST_MATH_TOOLS_RATIONAL_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +#if BOOST_MATH_POLY_METHOD == 1 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_POLY_METHOD == 2 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_POLY_METHOD == 3 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#endif +#if BOOST_MATH_RATIONAL_METHOD == 1 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_RATIONAL_METHOD == 2 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#elif BOOST_MATH_RATIONAL_METHOD == 3 +# define BOOST_HEADER() +# include BOOST_HEADER() +# undef BOOST_HEADER +#endif + +#if 0 +// +// This just allows dependency trackers to find the headers +// used in the above PP-magic. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +namespace boost{ namespace math{ namespace tools{ + +// +// Forward declaration to keep two phase lookup happy: +// +template +U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U); + +namespace detail{ + +template +inline V evaluate_polynomial_c_imp(const T* a, const V& val, const Tag*) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, val, Tag::value); +} + +} // namespace detail + +// +// Polynomial evaluation with runtime size. +// This requires a for-loop which may be more expensive than +// the loop expanded versions above: +// +template +inline U evaluate_polynomial(const T* poly, U const& z, std::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + BOOST_MATH_ASSERT(count > 0); + U sum = static_cast(poly[count - 1]); + for(int i = static_cast(count) - 2; i >= 0; --i) + { + sum *= z; + sum += static_cast(poly[i]); + } + return sum; +} +// +// Compile time sized polynomials, just inline forwarders to the +// implementations above: +// +template +inline V evaluate_polynomial(const T(&a)[N], const V& val) BOOST_MATH_NOEXCEPT(V) +{ + typedef std::integral_constant tag_type; + return detail::evaluate_polynomial_c_imp(static_cast(a), val, static_cast(nullptr)); +} + +template +inline V evaluate_polynomial(const std::array& a, const V& val) BOOST_MATH_NOEXCEPT(V) +{ + typedef std::integral_constant tag_type; + return detail::evaluate_polynomial_c_imp(static_cast(a.data()), val, static_cast(nullptr)); +} +// +// Even polynomials are trivial: just square the argument! +// +template +inline U evaluate_even_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + return evaluate_polynomial(poly, U(z*z), count); +} + +template +inline V evaluate_even_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, V(z*z)); +} + +template +inline V evaluate_even_polynomial(const std::array& a, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return evaluate_polynomial(a, V(z*z)); +} +// +// Odd polynomials come next: +// +template +inline U evaluate_odd_polynomial(const T* poly, U z, std::size_t count) BOOST_MATH_NOEXCEPT(U) +{ + return poly[0] + z * evaluate_polynomial(poly+1, U(z*z), count-1); +} + +template +inline V evaluate_odd_polynomial(const T(&a)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + typedef std::integral_constant tag_type; + return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast(a) + 1, V(z*z), static_cast(nullptr)); +} + +template +inline V evaluate_odd_polynomial(const std::array& a, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + typedef std::integral_constant tag_type; + return a[0] + z * detail::evaluate_polynomial_c_imp(static_cast(a.data()) + 1, V(z*z), static_cast(nullptr)); +} + +template +V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V); + +namespace detail{ + +template +inline V evaluate_rational_c_imp(const T* num, const U* denom, const V& z, const Tag*) BOOST_MATH_NOEXCEPT(V) +{ + return boost::math::tools::evaluate_rational(num, denom, z, Tag::value); +} + +} +// +// Rational functions: numerator and denominator must be +// equal in size. These always have a for-loop and so may be less +// efficient than evaluating a pair of polynomials. However, there +// are some tricks we can use to prevent overflow that might otherwise +// occur in polynomial evaluation, if z is large. This is important +// in our Lanczos code for example. +// +template +V evaluate_rational(const T* num, const U* denom, const V& z_, std::size_t count) BOOST_MATH_NOEXCEPT(V) +{ + V z(z_); + V s1, s2; + if(z <= 1) + { + s1 = static_cast(num[count-1]); + s2 = static_cast(denom[count-1]); + for(int i = (int)count - 2; i >= 0; --i) + { + s1 *= z; + s2 *= z; + s1 += num[i]; + s2 += denom[i]; + } + } + else + { + z = 1 / z; + s1 = static_cast(num[0]); + s2 = static_cast(denom[0]); + for(unsigned i = 1; i < count; ++i) + { + s1 *= z; + s2 *= z; + s1 += num[i]; + s2 += denom[i]; + } + } + return s1 / s2; +} + +template +inline V evaluate_rational(const T(&a)[N], const U(&b)[N], const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return detail::evaluate_rational_c_imp(a, b, z, static_cast*>(nullptr)); +} + +template +inline V evaluate_rational(const std::array& a, const std::array& b, const V& z) BOOST_MATH_NOEXCEPT(V) +{ + return detail::evaluate_rational_c_imp(a.data(), b.data(), z, static_cast*>(nullptr)); +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_RATIONAL_HPP + + + + diff --git a/libcxx/src/third-party/boost/math/tools/real_cast.hpp b/libcxx/src/third-party/boost/math/tools/real_cast.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/real_cast.hpp @@ -0,0 +1,31 @@ +// 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_TOOLS_REAL_CAST_HPP +#define BOOST_MATH_TOOLS_REAL_CAST_HPP + +#include + +#ifdef _MSC_VER +#pragma once +#endif + +namespace boost{ namespace math +{ + namespace tools + { + template + inline constexpr To real_cast(T t) noexcept(BOOST_MATH_IS_FLOAT(T) && BOOST_MATH_IS_FLOAT(To)) + { + return static_cast(t); + } + } // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_REAL_CAST_HPP + + + diff --git a/libcxx/src/third-party/boost/math/tools/recurrence.hpp b/libcxx/src/third-party/boost/math/tools/recurrence.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/recurrence.hpp @@ -0,0 +1,328 @@ +// (C) Copyright Anton Bikineev 2014 +// 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_TOOLS_RECURRENCE_HPP_ +#define BOOST_MATH_TOOLS_RECURRENCE_HPP_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace math { + namespace tools { + namespace detail{ + + // + // Function ratios directly from recurrence relations: + // H. Shintan, Note on Miller's recurrence algorithm, J. Sci. Hiroshima Univ. Ser. A-I + // Math., 29 (1965), pp. 121 - 133. + // and: + // COMPUTATIONAL ASPECTS OF THREE-TERM RECURRENCE RELATIONS + // WALTER GAUTSCHI + // SIAM REVIEW Vol. 9, No. 1, January, 1967 + // + template + struct function_ratio_from_backwards_recurrence_fraction + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + typedef std::pair result_type; + function_ratio_from_backwards_recurrence_fraction(const Recurrence& r) : r(r), k(0) {} + + result_type operator()() + { + value_type a, b, c; + std::tie(a, b, c) = r(k); + ++k; + // an and bn defined as per Gauchi 1.16, not the same + // as the usual continued fraction a' and b's. + value_type bn = a / c; + value_type an = b / c; + return result_type(-bn, an); + } + + private: + function_ratio_from_backwards_recurrence_fraction operator=(const function_ratio_from_backwards_recurrence_fraction&) = delete; + + Recurrence r; + int k; + }; + + template + struct recurrence_reverser + { + recurrence_reverser(const R& r) : r(r) {} + std::tuple operator()(int i) + { + using std::swap; + std::tuple t = r(-i); + swap(std::get<0>(t), std::get<2>(t)); + return t; + } + R r; + }; + + template + struct recurrence_offsetter + { + typedef decltype(std::declval()(0)) result_type; + recurrence_offsetter(Recurrence const& rr, int offset) : r(rr), k(offset) {} + result_type operator()(int i) + { + return r(i + k); + } + private: + Recurrence r; + int k; + }; + + + + } // namespace detail + + // + // Given a stable backwards recurrence relation: + // a f_n-1 + b f_n + c f_n+1 = 0 + // returns the ratio f_n / f_n-1 + // + // Recurrence: a functor that returns a tuple of the factors (a,b,c). + // factor: Convergence criteria, should be no less than machine epsilon. + // max_iter: Maximum iterations to use solving the continued fraction. + // + template + T function_ratio_from_backwards_recurrence(const Recurrence& r, const T& factor, std::uintmax_t& max_iter) + { + detail::function_ratio_from_backwards_recurrence_fraction f(r); + return boost::math::tools::continued_fraction_a(f, factor, max_iter); + } + + // + // Given a stable forwards recurrence relation: + // a f_n-1 + b f_n + c f_n+1 = 0 + // returns the ratio f_n / f_n+1 + // + // Note that in most situations where this would be used, we're relying on + // pseudo-convergence, as in most cases f_n will not be minimal as N -> -INF + // as long as we reach convergence on the continued-fraction before f_n + // switches behaviour, we should be fine. + // + // Recurrence: a functor that returns a tuple of the factors (a,b,c). + // factor: Convergence criteria, should be no less than machine epsilon. + // max_iter: Maximum iterations to use solving the continued fraction. + // + template + T function_ratio_from_forwards_recurrence(const Recurrence& r, const T& factor, std::uintmax_t& max_iter) + { + boost::math::tools::detail::function_ratio_from_backwards_recurrence_fraction > f(r); + return boost::math::tools::continued_fraction_a(f, factor, max_iter); + } + + + + // solves usual recurrence relation for homogeneous + // difference equation in stable forward direction + // a(n)w(n-1) + b(n)w(n) + c(n)w(n+1) = 0 + // + // Params: + // get_coefs: functor returning a tuple, where + // get<0>() is a(n); get<1>() is b(n); get<2>() is c(n); + // last_index: index N to be found; + // first: w(-1); + // second: w(0); + // + template + inline T apply_recurrence_relation_forward(const NextCoefs& get_coefs, unsigned number_of_steps, T first, T second, long long* log_scaling = nullptr, T* previous = nullptr) + { + BOOST_MATH_STD_USING + using std::tuple; + using std::get; + using std::swap; + + T third; + T a, b, c; + + for (unsigned k = 0; k < number_of_steps; ++k) + { + tie(a, b, c) = get_coefs(k); + + if ((log_scaling) && + ((fabs(tools::max_value() * (c / (a * 2048))) < fabs(first)) + || (fabs(tools::max_value() * (c / (b * 2048))) < fabs(second)) + || (fabs(tools::min_value() * (c * 2048 / a)) > fabs(first)) + || (fabs(tools::min_value() * (c * 2048 / b)) > fabs(second)) + )) + + { + // Rescale everything: + long long log_scale = lltrunc(log(fabs(second))); + T scale = exp(T(-log_scale)); + second *= scale; + first *= scale; + *log_scaling += log_scale; + } + // scale each part separately to avoid spurious overflow: + third = (a / -c) * first + (b / -c) * second; + BOOST_MATH_ASSERT((boost::math::isfinite)(third)); + + + swap(first, second); + swap(second, third); + } + + if (previous) + *previous = first; + + return second; + } + + // solves usual recurrence relation for homogeneous + // difference equation in stable backward direction + // a(n)w(n-1) + b(n)w(n) + c(n)w(n+1) = 0 + // + // Params: + // get_coefs: functor returning a tuple, where + // get<0>() is a(n); get<1>() is b(n); get<2>() is c(n); + // number_of_steps: index N to be found; + // first: w(1); + // second: w(0); + // + template + inline T apply_recurrence_relation_backward(const NextCoefs& get_coefs, unsigned number_of_steps, T first, T second, long long* log_scaling = nullptr, T* previous = nullptr) + { + BOOST_MATH_STD_USING + using std::tuple; + using std::get; + using std::swap; + + T next; + T a, b, c; + + for (unsigned k = 0; k < number_of_steps; ++k) + { + tie(a, b, c) = get_coefs(-static_cast(k)); + + if ((log_scaling) && (second != 0) && + ( (fabs(tools::max_value() * (a / b) / 2048) < fabs(second)) + || (fabs(tools::max_value() * (a / c) / 2048) < fabs(first)) + || (fabs(tools::min_value() * (a / b) * 2048) > fabs(second)) + || (fabs(tools::min_value() * (a / c) * 2048) > fabs(first)) + )) + { + // Rescale everything: + int log_scale = itrunc(log(fabs(second))); + T scale = exp(T(-log_scale)); + second *= scale; + first *= scale; + *log_scaling += log_scale; + } + // scale each part separately to avoid spurious overflow: + next = (b / -a) * second + (c / -a) * first; + BOOST_MATH_ASSERT((boost::math::isfinite)(next)); + + swap(first, second); + swap(second, next); + } + + if (previous) + *previous = first; + + return second; + } + + template + struct forward_recurrence_iterator + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + + forward_recurrence_iterator(const Recurrence& r, value_type f_n_minus_1, value_type f_n) + : f_n_minus_1(f_n_minus_1), f_n(f_n), coef(r), k(0) {} + + forward_recurrence_iterator(const Recurrence& r, value_type f_n) + : f_n(f_n), coef(r), k(0) + { + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations >(); + f_n_minus_1 = f_n * boost::math::tools::function_ratio_from_forwards_recurrence(detail::recurrence_offsetter(r, -1), value_type(boost::math::tools::epsilon() * 2), max_iter); + boost::math::policies::check_series_iterations("forward_recurrence_iterator<>::forward_recurrence_iterator", max_iter, boost::math::policies::policy<>()); + } + + forward_recurrence_iterator& operator++() + { + using std::swap; + value_type a, b, c; + std::tie(a, b, c) = coef(k); + value_type f_n_plus_1 = a * f_n_minus_1 / -c + b * f_n / -c; + swap(f_n_minus_1, f_n); + swap(f_n, f_n_plus_1); + ++k; + return *this; + } + + forward_recurrence_iterator operator++(int) + { + forward_recurrence_iterator t(*this); + ++(*this); + return t; + } + + value_type operator*() { return f_n; } + + value_type f_n_minus_1, f_n; + Recurrence coef; + int k; + }; + + template + struct backward_recurrence_iterator + { + typedef typename std::remove_reference(std::declval()(0)))>::type value_type; + + backward_recurrence_iterator(const Recurrence& r, value_type f_n_plus_1, value_type f_n) + : f_n_plus_1(f_n_plus_1), f_n(f_n), coef(r), k(0) {} + + backward_recurrence_iterator(const Recurrence& r, value_type f_n) + : f_n(f_n), coef(r), k(0) + { + std::uintmax_t max_iter = boost::math::policies::get_max_series_iterations >(); + f_n_plus_1 = f_n * boost::math::tools::function_ratio_from_backwards_recurrence(detail::recurrence_offsetter(r, 1), value_type(boost::math::tools::epsilon() * 2), max_iter); + boost::math::policies::check_series_iterations("backward_recurrence_iterator<>::backward_recurrence_iterator", max_iter, boost::math::policies::policy<>()); + } + + backward_recurrence_iterator& operator++() + { + using std::swap; + value_type a, b, c; + std::tie(a, b, c) = coef(k); + value_type f_n_minus_1 = c * f_n_plus_1 / -a + b * f_n / -a; + swap(f_n_plus_1, f_n); + swap(f_n, f_n_minus_1); + --k; + return *this; + } + + backward_recurrence_iterator operator++(int) + { + backward_recurrence_iterator t(*this); + ++(*this); + return t; + } + + value_type operator*() { return f_n; } + + value_type f_n_plus_1, f_n; + Recurrence coef; + int k; + }; + + } + } +} // namespaces + +#endif // BOOST_MATH_TOOLS_RECURRENCE_HPP_ diff --git a/libcxx/src/third-party/boost/math/tools/roots.hpp b/libcxx/src/third-party/boost/math/tools/roots.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/roots.hpp @@ -0,0 +1,986 @@ +// (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_TOOLS_NEWTON_SOLVER_HPP +#define BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP + +#ifdef _MSC_VER +#pragma once +#endif +#include // test for multiprecision types in complex Newton + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace boost { +namespace math { +namespace tools { + +namespace detail { + +namespace dummy { + + template + typename T::value_type get(const T&) BOOST_MATH_NOEXCEPT(T); +} + +template +void unpack_tuple(const Tuple& t, T& a, T& b) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Use ADL to find the right overload for get: + a = get<0>(t); + b = get<1>(t); +} +template +void unpack_tuple(const Tuple& t, T& a, T& b, T& c) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Use ADL to find the right overload for get: + a = get<0>(t); + b = get<1>(t); + c = get<2>(t); +} + +template +inline void unpack_0(const Tuple& t, T& val) BOOST_MATH_NOEXCEPT(T) +{ + using dummy::get; + // Rely on ADL to find the correct overload of get: + val = get<0>(t); +} + +template +inline void unpack_tuple(const std::pair& p, V& a, V& b) BOOST_MATH_NOEXCEPT(T) +{ + a = p.first; + b = p.second; +} +template +inline void unpack_0(const std::pair& p, V& a) BOOST_MATH_NOEXCEPT(T) +{ + a = p.first; +} + +template +void handle_zero_derivative(F f, + T& last_f0, + const T& f0, + T& delta, + T& result, + T& guess, + const T& min, + const T& max) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + if (last_f0 == 0) + { + // this must be the first iteration, pretend that we had a + // previous one at either min or max: + if (result == min) + { + guess = max; + } + else + { + guess = min; + } + unpack_0(f(guess), last_f0); + delta = guess - result; + } + if (sign(last_f0) * sign(f0) < 0) + { + // we've crossed over so move in opposite direction to last step: + if (delta < 0) + { + delta = (result - min) / 2; + } + else + { + delta = (result - max) / 2; + } + } + else + { + // move in same direction as last step: + if (delta < 0) + { + delta = (result - max) / 2; + } + else + { + delta = (result - min) / 2; + } + } +} + +} // namespace + +template +std::pair bisect(F f, T min, T max, Tol tol, std::uintmax_t& max_iter, const Policy& pol) noexcept(policies::is_noexcept_error_policy::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + T fmin = f(min); + T fmax = f(max); + if (fmin == 0) + { + max_iter = 2; + return std::make_pair(min, min); + } + if (fmax == 0) + { + max_iter = 2; + return std::make_pair(max, max); + } + + // + // Error checking: + // + static const char* function = "boost::math::tools::bisect<%1%>"; + if (min >= max) + { + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, + "Arguments in wrong order in boost::math::tools::bisect (first arg=%1%)", min, pol)); + } + if (fmin * fmax >= 0) + { + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, + "No change of sign in boost::math::tools::bisect, either there is no root to find, or there are multiple roots in the interval (f(min) = %1%).", fmin, pol)); + } + + // + // Three function invocations so far: + // + std::uintmax_t count = max_iter; + if (count < 3) + count = 0; + else + count -= 3; + + while (count && (0 == tol(min, max))) + { + T mid = (min + max) / 2; + T fmid = f(mid); + if ((mid == max) || (mid == min)) + break; + if (fmid == 0) + { + min = max = mid; + break; + } + else if (sign(fmid) * sign(fmin) < 0) + { + max = mid; + } + else + { + min = mid; + fmin = fmid; + } + --count; + } + + max_iter -= count; + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Bisection required " << max_iter << " iterations.\n"; +#endif + + return std::make_pair(min, max); +} + +template +inline std::pair bisect(F f, T min, T max, Tol tol, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return bisect(f, min, max, tol, max_iter, policies::policy<>()); +} + +template +inline std::pair bisect(F f, T min, T max, Tol tol) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return bisect(f, min, max, tol, m, policies::policy<>()); +} + + +template +T newton_raphson_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + BOOST_MATH_STD_USING + + static const char* function = "boost::math::tools::newton_raphson_iterate<%1%>"; + if (min > max) + { + return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::newton_raphson_iterate(first arg=%1%)", min, boost::math::policies::policy<>()); + } + + T f0(0), f1, last_f0(0); + T result = guess; + + T factor = static_cast(ldexp(1.0, 1 - digits)); + T delta = tools::max_value(); + T delta1 = tools::max_value(); + T delta2 = tools::max_value(); + + // + // We use these to sanity check that we do actually bracket a root, + // we update these to the function value when we update the endpoints + // of the range. Then, provided at some point we update both endpoints + // checking that max_range_f * min_range_f <= 0 verifies there is a root + // to be found somewhere. Note that if there is no root, and we approach + // a local minima, then the derivative will go to zero, and hence the next + // step will jump out of bounds (or at least past the minima), so this + // check *should* happen in pathological cases. + // + T max_range_f = 0; + T min_range_f = 0; + + std::uintmax_t count(max_iter); + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton_raphson_iterate, guess = " << guess << ", min = " << min << ", max = " << max + << ", digits = " << digits << ", max_iter = " << max_iter << "\n"; +#endif + + do { + last_f0 = f0; + delta2 = delta1; + delta1 = delta; + detail::unpack_tuple(f(result), f0, f1); + --count; + if (0 == f0) + break; + if (f1 == 0) + { + // Oops zero derivative!!! + detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max); + } + else + { + delta = f0 / f1; + } +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton iteration " << max_iter - count << ", delta = " << delta << ", residual = " << f0 << "\n"; +#endif + if (fabs(delta * 2) > fabs(delta2)) + { + // Last two steps haven't converged. + T shift = (delta > 0) ? (result - min) / 2 : (result - max) / 2; + if ((result != 0) && (fabs(shift) > fabs(result))) + { + delta = sign(delta) * fabs(result) * 1.1f; // Protect against huge jumps! + //delta = sign(delta) * result; // Protect against huge jumps! Failed for negative result. https://github.com/boostorg/math/issues/216 + } + else + delta = shift; + // reset delta1/2 so we don't take this branch next time round: + delta1 = 3 * delta; + delta2 = 3 * delta; + } + guess = result; + result -= delta; + if (result <= min) + { + delta = 0.5F * (guess - min); + result = guess - delta; + if ((result == min) || (result == max)) + break; + } + else if (result >= max) + { + delta = 0.5F * (guess - max); + result = guess - delta; + if ((result == min) || (result == max)) + break; + } + // Update brackets: + if (delta > 0) + { + max = guess; + max_range_f = f0; + } + else + { + min = guess; + min_range_f = f0; + } + // + // Sanity check that we bracket the root: + // + if (max_range_f * min_range_f > 0) + { + return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>()); + } + }while(count && (fabs(result * factor) < fabs(delta))); + + max_iter -= count; + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Newton Raphson required " << max_iter << " iterations\n"; +#endif + + return result; +} + +template +inline T newton_raphson_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return newton_raphson_iterate(f, guess, min, max, digits, m); +} + +namespace detail { + + struct halley_step + { + template + static T step(const T& /*x*/, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T)) + { + using std::fabs; + T denom = 2 * f0; + T num = 2 * f1 - f0 * (f2 / f1); + T delta; + + BOOST_MATH_INSTRUMENT_VARIABLE(denom); + BOOST_MATH_INSTRUMENT_VARIABLE(num); + + if ((fabs(num) < 1) && (fabs(denom) >= fabs(num) * tools::max_value())) + { + // possible overflow, use Newton step: + delta = f0 / f1; + } + else + delta = denom / num; + return delta; + } + }; + + template + T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))); + + template + T bracket_root_towards_max(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + using std::fabs; + if(count < 2) + return guess - (max + min) / 2; // Not enough counts left to do anything!! + // + // Move guess towards max until we bracket the root, updating min and max as we go: + // + T guess0 = guess; + T multiplier = 2; + T f_current = f0; + if (fabs(min) < fabs(max)) + { + while (--count && ((f_current < 0) == (f0 < 0))) + { + min = guess; + guess *= multiplier; + if (guess > max) + { + guess = max; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= 2; + unpack_0(f(guess), f_current); + } + } + else + { + // + // If min and max are negative we have to divide to head towards max: + // + while (--count && ((f_current < 0) == (f0 < 0))) + { + min = guess; + guess /= multiplier; + if (guess > max) + { + guess = max; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= 2; + unpack_0(f(guess), f_current); + } + } + + if (count) + { + max = guess; + if (multiplier > 16) + return (guess0 - guess) + bracket_root_towards_min(f, guess, f_current, min, max, count); + } + return guess0 - (max + min) / 2; + } + + template + T bracket_root_towards_min(F f, T guess, const T& f0, T& min, T& max, std::uintmax_t& count) noexcept(BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + using std::fabs; + if (count < 2) + return guess - (max + min) / 2; // Not enough counts left to do anything!! + // + // Move guess towards min until we bracket the root, updating min and max as we go: + // + T guess0 = guess; + T multiplier = 2; + T f_current = f0; + + if (fabs(min) < fabs(max)) + { + while (--count && ((f_current < 0) == (f0 < 0))) + { + max = guess; + guess /= multiplier; + if (guess < min) + { + guess = min; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= 2; + unpack_0(f(guess), f_current); + } + } + else + { + // + // If min and max are negative we have to multiply to head towards min: + // + while (--count && ((f_current < 0) == (f0 < 0))) + { + max = guess; + guess *= multiplier; + if (guess < min) + { + guess = min; + f_current = -f_current; // There must be a change of sign! + break; + } + multiplier *= 2; + unpack_0(f(guess), f_current); + } + } + + if (count) + { + min = guess; + if (multiplier > 16) + return (guess0 - guess) + bracket_root_towards_max(f, guess, f_current, min, max, count); + } + return guess0 - (max + min) / 2; + } + + template + T second_order_root_finder(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) + { + BOOST_MATH_STD_USING + +#ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, guess = " << guess << ", min = " << min << ", max = " << max + << ", digits = " << digits << ", max_iter = " << max_iter << "\n"; +#endif + static const char* function = "boost::math::tools::halley_iterate<%1%>"; + if (min >= max) + { + return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::halley_iterate(first arg=%1%)", min, boost::math::policies::policy<>()); + } + + T f0(0), f1, f2; + T result = guess; + + T factor = ldexp(static_cast(1.0), 1 - digits); + T delta = (std::max)(T(10000000 * guess), T(10000000)); // arbitrarily large delta + T last_f0 = 0; + T delta1 = delta; + T delta2 = delta; + bool out_of_bounds_sentry = false; + + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, limit = " << factor << "\n"; + #endif + + // + // We use these to sanity check that we do actually bracket a root, + // we update these to the function value when we update the endpoints + // of the range. Then, provided at some point we update both endpoints + // checking that max_range_f * min_range_f <= 0 verifies there is a root + // to be found somewhere. Note that if there is no root, and we approach + // a local minima, then the derivative will go to zero, and hence the next + // step will jump out of bounds (or at least past the minima), so this + // check *should* happen in pathological cases. + // + T max_range_f = 0; + T min_range_f = 0; + + std::uintmax_t count(max_iter); + + do { + last_f0 = f0; + delta2 = delta1; + delta1 = delta; + detail::unpack_tuple(f(result), f0, f1, f2); + --count; + + BOOST_MATH_INSTRUMENT_VARIABLE(f0); + BOOST_MATH_INSTRUMENT_VARIABLE(f1); + BOOST_MATH_INSTRUMENT_VARIABLE(f2); + + if (0 == f0) + break; + if (f1 == 0) + { + // Oops zero derivative!!! + detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max); + } + else + { + if (f2 != 0) + { + delta = Stepper::step(result, f0, f1, f2); + if (delta * f1 / f0 < 0) + { + // Oh dear, we have a problem as Newton and Halley steps + // disagree about which way we should move. Probably + // there is cancelation error in the calculation of the + // Halley step, or else the derivatives are so small + // that their values are basically trash. We will move + // in the direction indicated by a Newton step, but + // by no more than twice the current guess value, otherwise + // we can jump way out of bounds if we're not careful. + // See https://svn.boost.org/trac/boost/ticket/8314. + delta = f0 / f1; + if (fabs(delta) > 2 * fabs(guess)) + delta = (delta < 0 ? -1 : 1) * 2 * fabs(guess); + } + } + else + delta = f0 / f1; + } + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root iteration, delta = " << delta << ", residual = " << f0 << "\n"; + #endif + T convergence = fabs(delta / delta2); + if ((convergence > 0.8) && (convergence < 2)) + { + // last two steps haven't converged. + delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2; + if ((result != 0) && (fabs(delta) > result)) + delta = sign(delta) * fabs(result) * 0.9f; // protect against huge jumps! + // reset delta2 so that this branch will *not* be taken on the + // next iteration: + delta2 = delta * 3; + delta1 = delta * 3; + BOOST_MATH_INSTRUMENT_VARIABLE(delta); + } + guess = result; + result -= delta; + BOOST_MATH_INSTRUMENT_VARIABLE(result); + + // check for out of bounds step: + if (result < min) + { + T diff = ((fabs(min) < 1) && (fabs(result) > 1) && (tools::max_value() / fabs(result) < fabs(min))) + ? T(1000) + : (fabs(min) < 1) && (fabs(tools::max_value() * min) < fabs(result)) + ? ((min < 0) != (result < 0)) ? -tools::max_value() : tools::max_value() : T(result / min); + if (fabs(diff) < 1) + diff = 1 / diff; + if (!out_of_bounds_sentry && (diff > 0) && (diff < 3)) + { + // Only a small out of bounds step, lets assume that the result + // is probably approximately at min: + delta = 0.99f * (guess - min); + result = guess - delta; + out_of_bounds_sentry = true; // only take this branch once! + } + else + { + if (fabs(float_distance(min, max)) < 2) + { + result = guess = (min + max) / 2; + break; + } + delta = bracket_root_towards_min(f, guess, f0, min, max, count); + result = guess - delta; + guess = min; + continue; + } + } + else if (result > max) + { + T diff = ((fabs(max) < 1) && (fabs(result) > 1) && (tools::max_value() / fabs(result) < fabs(max))) ? T(1000) : T(result / max); + if (fabs(diff) < 1) + diff = 1 / diff; + if (!out_of_bounds_sentry && (diff > 0) && (diff < 3)) + { + // Only a small out of bounds step, lets assume that the result + // is probably approximately at min: + delta = 0.99f * (guess - max); + result = guess - delta; + out_of_bounds_sentry = true; // only take this branch once! + } + else + { + if (fabs(float_distance(min, max)) < 2) + { + result = guess = (min + max) / 2; + break; + } + delta = bracket_root_towards_max(f, guess, f0, min, max, count); + result = guess - delta; + guess = min; + continue; + } + } + // update brackets: + if (delta > 0) + { + max = guess; + max_range_f = f0; + } + else + { + min = guess; + min_range_f = f0; + } + // + // Sanity check that we bracket the root: + // + if (max_range_f * min_range_f > 0) + { + return policies::raise_evaluation_error(function, "There appears to be no root to be found in boost::math::tools::newton_raphson_iterate, perhaps we have a local minima near current best guess of %1%", guess, boost::math::policies::policy<>()); + } + } while(count && (fabs(result * factor) < fabs(delta))); + + max_iter -= count; + + #ifdef BOOST_MATH_INSTRUMENT + std::cout << "Second order root finder required " << max_iter << " iterations.\n"; + #endif + + return result; + } +} // T second_order_root_finder + +template +T halley_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T halley_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return halley_iterate(f, guess, min, max, digits, m); +} + +namespace detail { + + struct schroder_stepper + { + template + static T step(const T& x, const T& f0, const T& f1, const T& f2) noexcept(BOOST_MATH_IS_FLOAT(T)) + { + using std::fabs; + T ratio = f0 / f1; + T delta; + if ((x != 0) && (fabs(ratio / x) < 0.1)) + { + delta = ratio + (f2 / (2 * f1)) * ratio * ratio; + // check second derivative doesn't over compensate: + if (delta * ratio < 0) + delta = ratio; + } + else + delta = ratio; // fall back to Newton iteration. + return delta; + } + }; + +} + +template +T schroder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T schroder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return schroder_iterate(f, guess, min, max, digits, m); +} +// +// These two are the old spelling of this function, retained for backwards compatibility just in case: +// +template +T schroeder_iterate(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + return detail::second_order_root_finder(f, guess, min, max, digits, max_iter); +} + +template +inline T schroeder_iterate(F f, T guess, T min, T max, int digits) noexcept(policies::is_noexcept_error_policy >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval()(std::declval()))) +{ + std::uintmax_t m = (std::numeric_limits::max)(); + return schroder_iterate(f, guess, min, max, digits, m); +} + +#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS +/* + * Why do we set the default maximum number of iterations to the number of digits in the type? + * Because for double roots, the number of digits increases linearly with the number of iterations, + * so this default should recover full precision even in this somewhat pathological case. + * For isolated roots, the problem is so rapidly convergent that this doesn't matter at all. + */ +template +Complex complex_newton(F g, Complex guess, int max_iterations = std::numeric_limits::digits) +{ + typedef typename Complex::value_type Real; + using std::norm; + using std::abs; + using std::max; + // z0, z1, and z2 cannot be the same, in case we immediately need to resort to Muller's Method: + Complex z0 = guess + Complex(1, 0); + Complex z1 = guess + Complex(0, 1); + Complex z2 = guess; + + do { + auto pair = g(z2); + if (norm(pair.second) == 0) + { + // Muller's method. Notation follows Numerical Recipes, 9.5.2: + Complex q = (z2 - z1) / (z1 - z0); + auto P0 = g(z0); + auto P1 = g(z1); + Complex qp1 = static_cast(1) + q; + Complex A = q * (pair.first - qp1 * P1.first + q * P0.first); + + Complex B = (static_cast(2) * q + static_cast(1)) * pair.first - qp1 * qp1 * P1.first + q * q * P0.first; + Complex C = qp1 * pair.first; + Complex rad = sqrt(B * B - static_cast(4) * A * C); + Complex denom1 = B + rad; + Complex denom2 = B - rad; + Complex correction = (z1 - z2) * static_cast(2) * C; + if (norm(denom1) > norm(denom2)) + { + correction /= denom1; + } + else + { + correction /= denom2; + } + + z0 = z1; + z1 = z2; + z2 = z2 + correction; + } + else + { + z0 = z1; + z1 = z2; + z2 = z2 - (pair.first / pair.second); + } + + // See: https://math.stackexchange.com/questions/3017766/constructing-newton-iteration-converging-to-non-root + // If f' is continuous, then convergence of x_n -> x* implies f(x*) = 0. + // This condition approximates this convergence condition by requiring three consecutive iterates to be clustered. + Real tol = (max)(abs(z2) * std::numeric_limits::epsilon(), std::numeric_limits::epsilon()); + bool real_close = abs(z0.real() - z1.real()) < tol && abs(z0.real() - z2.real()) < tol && abs(z1.real() - z2.real()) < tol; + bool imag_close = abs(z0.imag() - z1.imag()) < tol && abs(z0.imag() - z2.imag()) < tol && abs(z1.imag() - z2.imag()) < tol; + if (real_close && imag_close) + { + return z2; + } + + } while (max_iterations--); + + // The idea is that if we can get abs(f) < eps, we should, but if we go through all these iterations + // and abs(f) < sqrt(eps), then roundoff error simply does not allow that we can evaluate f to < eps + // This is somewhat awkward as it isn't scale invariant, but using the Daubechies coefficient example code, + // I found this condition generates correct roots, whereas the scale invariant condition discussed here: + // https://scicomp.stackexchange.com/questions/30597/defining-a-condition-number-and-termination-criteria-for-newtons-method + // allows nonroots to be passed off as roots. + auto pair = g(z2); + if (abs(pair.first) < sqrt(std::numeric_limits::epsilon())) + { + return z2; + } + + return { std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN() }; +} +#endif + + +#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR) +// https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711 +namespace detail +{ +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) +inline float fma_workaround(float x, float y, float z) { return ::fmaf(x, y, z); } +inline double fma_workaround(double x, double y, double z) { return ::fma(x, y, z); } +#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +inline long double fma_workaround(long double x, long double y, long double z) { return ::fmal(x, y, z); } +#endif +#endif +template +inline T discriminant(T const& a, T const& b, T const& c) +{ + T w = 4 * a * c; +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) + T e = fma_workaround(-c, 4 * a, w); + T f = fma_workaround(b, b, -w); +#else + T e = std::fma(-c, 4 * a, w); + T f = std::fma(b, b, -w); +#endif + return f + e; +} + +template +std::pair quadratic_roots_imp(T const& a, T const& b, T const& c) +{ +#if defined(BOOST_GNU_STDLIB) && !defined(_GLIBCXX_USE_C99_MATH_TR1) + using boost::math::copysign; +#else + using std::copysign; +#endif + using std::sqrt; + if constexpr (std::is_floating_point::value) + { + T nan = std::numeric_limits::quiet_NaN(); + if (a == 0) + { + if (b == 0 && c != 0) + { + return std::pair(nan, nan); + } + else if (b == 0 && c == 0) + { + return std::pair(0, 0); + } + return std::pair(-c / b, -c / b); + } + if (b == 0) + { + T x0_sq = -c / a; + if (x0_sq < 0) { + return std::pair(nan, nan); + } + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + T discriminant = detail::discriminant(a, b, c); + // Is there a sane way to flush very small negative values to zero? + // If there is I don't know of it. + if (discriminant < 0) + { + return std::pair(nan, nan); + } + T q = -(b + copysign(sqrt(discriminant), b)) / T(2); + T x0 = q / a; + T x1 = c / q; + if (x0 < x1) + { + return std::pair(x0, x1); + } + return std::pair(x1, x0); + } + else if constexpr (boost::math::tools::is_complex_type::value) + { + typename T::value_type nan = std::numeric_limits::quiet_NaN(); + if (a.real() == 0 && a.imag() == 0) + { + using std::norm; + if (b.real() == 0 && b.imag() && norm(c) != 0) + { + return std::pair({ nan, nan }, { nan, nan }); + } + else if (b.real() == 0 && b.imag() && c.real() == 0 && c.imag() == 0) + { + return std::pair({ 0,0 }, { 0,0 }); + } + return std::pair(-c / b, -c / b); + } + if (b.real() == 0 && b.imag() == 0) + { + T x0_sq = -c / a; + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + // There's no fma for complex types: + T discriminant = b * b - T(4) * a * c; + T q = -(b + sqrt(discriminant)) / T(2); + return std::pair(q / a, c / q); + } + else // Most likely the type is a boost.multiprecision. + { //There is no fma for multiprecision, and in addition it doesn't seem to be useful, so revert to the naive computation. + T nan = std::numeric_limits::quiet_NaN(); + if (a == 0) + { + if (b == 0 && c != 0) + { + return std::pair(nan, nan); + } + else if (b == 0 && c == 0) + { + return std::pair(0, 0); + } + return std::pair(-c / b, -c / b); + } + if (b == 0) + { + T x0_sq = -c / a; + if (x0_sq < 0) { + return std::pair(nan, nan); + } + T x0 = sqrt(x0_sq); + return std::pair(-x0, x0); + } + T discriminant = b * b - 4 * a * c; + if (discriminant < 0) + { + return std::pair(nan, nan); + } + T q = -(b + copysign(sqrt(discriminant), b)) / T(2); + T x0 = q / a; + T x1 = c / q; + if (x0 < x1) + { + return std::pair(x0, x1); + } + return std::pair(x1, x0); + } +} +} // namespace detail + +template +inline std::pair::type, typename tools::promote_args::type> quadratic_roots(T1 const& a, T2 const& b, T3 const& c) +{ + typedef typename tools::promote_args::type value_type; + return detail::quadratic_roots_imp(static_cast(a), static_cast(b), static_cast(c)); +} + +#endif + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP diff --git a/libcxx/src/third-party/boost/math/tools/series.hpp b/libcxx/src/third-party/boost/math/tools/series.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/series.hpp @@ -0,0 +1,184 @@ +// (C) Copyright John Maddock 2005-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_TOOLS_SERIES_INCLUDED +#define BOOST_MATH_TOOLS_SERIES_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +// +// Simple series summation come first: +// +template +inline typename Functor::result_type sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms, const V& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + std::uintmax_t counter = max_terms; + + result_type result = init_value; + result_type next_term; + do{ + next_term = func(); + result += next_term; + } + while((abs(factor * result) < abs(next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + +template +inline typename Functor::result_type sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + typename Functor::result_type init_value = 0; + return sum_series(func, factor, max_terms, init_value); +} + +template +inline typename Functor::result_type sum_series(Functor& func, int bits, std::uintmax_t& max_terms, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + result_type factor = ldexp(result_type(1), 1 - bits); + return sum_series(func, factor, max_terms, init_value); +} + +template +inline typename Functor::result_type sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + std::uintmax_t iters = (std::numeric_limits::max)(); + result_type init_val = 0; + return sum_series(func, bits, iters, init_val); +} + +template +inline typename Functor::result_type sum_series(Functor& func, int bits, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + typedef typename Functor::result_type result_type; + result_type init_val = 0; + return sum_series(func, bits, max_terms, init_val); +} + +template +inline typename Functor::result_type sum_series(Functor& func, int bits, const U& init_value) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + std::uintmax_t iters = (std::numeric_limits::max)(); + return sum_series(func, bits, iters, init_value); +} +// +// Checked summation: +// +template +inline typename Functor::result_type checked_sum_series(Functor& func, const U& factor, std::uintmax_t& max_terms, const V& init_value, V& norm) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + std::uintmax_t counter = max_terms; + + result_type result = init_value; + result_type next_term; + do { + next_term = func(); + result += next_term; + norm += fabs(next_term); + } while ((abs(factor * result) < abs(next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + + +// +// Algorithm kahan_sum_series invokes Functor func until the N'th +// term is too small to have any effect on the total, the terms +// are added using the Kahan summation method. +// +// CAUTION: Optimizing compilers combined with extended-precision +// machine registers conspire to render this algorithm partly broken: +// double rounding of intermediate terms (first to a long double machine +// register, and then to a double result) cause the rounding error computed +// by the algorithm to be off by up to 1ulp. However this occurs rarely, and +// in any case the result is still much better than a naive summation. +// +template +inline typename Functor::result_type kahan_sum_series(Functor& func, int bits) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + result_type factor = pow(result_type(2), bits); + result_type result = func(); + result_type next_term, y, t; + result_type carry = 0; + do{ + next_term = func(); + y = next_term - carry; + t = result + y; + carry = t - result; + carry -= y; + result = t; + } + while(fabs(result) < fabs(factor * next_term)); + return result; +} + +template +inline typename Functor::result_type kahan_sum_series(Functor& func, int bits, std::uintmax_t& max_terms) noexcept(BOOST_MATH_IS_FLOAT(typename Functor::result_type) && noexcept(std::declval()())) +{ + BOOST_MATH_STD_USING + + typedef typename Functor::result_type result_type; + + std::uintmax_t counter = max_terms; + + result_type factor = ldexp(result_type(1), bits); + result_type result = func(); + result_type next_term, y, t; + result_type carry = 0; + do{ + next_term = func(); + y = next_term - carry; + t = result + y; + carry = t - result; + carry -= y; + result = t; + } + while((fabs(result) < fabs(factor * next_term)) && --counter); + + // set max_terms to the actual number of terms of the series evaluated: + max_terms = max_terms - counter; + + return result; +} + +} // namespace tools +} // namespace math +} // namespace boost + +#endif // BOOST_MATH_TOOLS_SERIES_INCLUDED + diff --git a/libcxx/src/third-party/boost/math/tools/signal_statistics.hpp b/libcxx/src/third-party/boost/math/tools/signal_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/signal_statistics.hpp @@ -0,0 +1,345 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_SIGNAL_STATISTICS_HPP +#define BOOST_MATH_TOOLS_SIGNAL_STATISTICS_HPP + +#include +#include +#include +#include +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost::math::tools { + +template +auto absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + using std::abs; + using RealOrComplex = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last, [](RealOrComplex a, RealOrComplex b) { return abs(b) > abs(a); }); + + + decltype(abs(*first)) i = 1; + decltype(abs(*first)) num = 0; + decltype(abs(*first)) denom = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + num += tmp*i; + denom += tmp; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + decltype(abs(*first)) zero = 0; + return zero; + } + return ((2*num)/denom - i)/(i-1); +} + +template +inline auto absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::tools::absolute_gini_coefficient(v.begin(), v.end()); +} + +template +auto sample_absolute_gini_coefficient(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + return n*boost::math::tools::absolute_gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_absolute_gini_coefficient(RandomAccessContainer & v) +{ + return boost::math::tools::sample_absolute_gini_coefficient(v.begin(), v.end()); +} + + +// The Hoyer sparsity measure is defined in: +// https://arxiv.org/pdf/0811.4706.pdf +template +auto hoyer_sparsity(const ForwardIterator first, const ForwardIterator last) +{ + using T = typename std::iterator_traits::value_type; + using std::abs; + using std::sqrt; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Hoyer sparsity requires at least two samples."); + + if constexpr (std::is_unsigned::value) + { + T l1 = 0; + T l2 = 0; + size_t n = 0; + for (auto it = first; it != last; ++it) + { + l1 += *it; + l2 += (*it)*(*it); + n += 1; + } + + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else { + decltype(abs(*first)) l1 = 0; + decltype(abs(*first)) l2 = 0; + // We wouldn't need to count the elements if it was a random access iterator, + // but our only constraint is that it's a forward iterator. + size_t n = 0; + for (auto it = first; it != last; ++it) + { + decltype(abs(*first)) tmp = abs(*it); + l1 += tmp; + l2 += tmp*tmp; + n += 1; + } + if constexpr (std::is_integral::value) + { + double rootn = sqrt(n); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + else + { + decltype(abs(*first)) rootn = sqrt(static_cast(n)); + return (rootn - l1/sqrt(l2) )/ (rootn - 1); + } + } +} + +template +inline auto hoyer_sparsity(Container const & v) +{ + return boost::math::tools::hoyer_sparsity(v.cbegin(), v.cend()); +} + + +template +auto oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), + "Signal and noisy_signal must be have the same number of elements."); + if constexpr (std::is_integral::value) + { + double numerator = 0; + double denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (noisy_signal[i] - signal[i])*(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + return numerator/denominator; + } + else if constexpr (boost::math::tools::is_complex_type::value) + + { + using std::norm; + typename Real::value_type numerator = 0; + typename Real::value_type denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += norm(signal[i]); + denominator += norm(noisy_signal[i] - signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } + else + { + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + numerator += signal[i]*signal[i]; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + } +} + +template +auto mean_invariant_oracle_snr(Container const & signal, Container const & noisy_signal) +{ + using Real = typename Container::value_type; + BOOST_MATH_ASSERT_MSG(signal.size() == noisy_signal.size(), "Signal and noisy signal must be have the same number of elements."); + + Real mu = boost::math::tools::mean(signal); + Real numerator = 0; + Real denominator = 0; + for (size_t i = 0; i < signal.size(); ++i) + { + Real tmp = signal[i] - mu; + numerator += tmp*tmp; + denominator += (signal[i] - noisy_signal[i])*(signal[i] - noisy_signal[i]); + } + if (numerator == 0 && denominator == 0) + { + return std::numeric_limits::quiet_NaN(); + } + if (denominator == 0) + { + return std::numeric_limits::infinity(); + } + + return numerator/denominator; + +} + +template +auto mean_invariant_oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::tools::mean_invariant_oracle_snr(signal, noisy_signal)); +} + + +// Follows the definition of SNR given in Mallat, A Wavelet Tour of Signal Processing, equation 11.16. +template +auto oracle_snr_db(Container const & signal, Container const & noisy_signal) +{ + using std::log10; + return 10*log10(boost::math::tools::oracle_snr(signal, noisy_signal)); +} + +// A good reference on the M2M4 estimator: +// D. R. Pauluzzi and N. C. Beaulieu, "A comparison of SNR estimation techniques for the AWGN channel," IEEE Trans. Communications, Vol. 48, No. 10, pp. 1681-1691, 2000. +// A nice python implementation: +// https://github.com/gnuradio/gnuradio/blob/master/gr-digital/examples/snr_estimators.py +template +auto m2m4_snr_estimator(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + BOOST_MATH_ASSERT_MSG(estimated_signal_kurtosis > 0, "The estimated signal kurtosis must be positive"); + BOOST_MATH_ASSERT_MSG(estimated_noise_kurtosis > 0, "The estimated noise kurtosis must be positive."); + using Real = typename std::iterator_traits::value_type; + using std::sqrt; + if constexpr (std::is_floating_point::value || std::numeric_limits::max_exponent) + { + // If we first eliminate N, we obtain the quadratic equation: + // (ka+kw-6)S^2 + 2M2(3-kw)S + kw*M2^2 - M4 = 0 =: a*S^2 + bs*N + cs = 0 + // If we first eliminate S, we obtain the quadratic equation: + // (ka+kw-6)N^2 + 2M2(3-ka)N + ka*M2^2 - M4 = 0 =: a*N^2 + bn*N + cn = 0 + // I believe these equations are totally independent quadratics; + // if one has a complex solution it is not necessarily the case that the other must also. + // However, I can't prove that, so there is a chance that this does unnecessary work. + // Future improvements: There are algorithms which can solve quadratics much more effectively than the naive implementation found here. + // See: https://stackoverflow.com/questions/48979861/numerically-stable-method-for-solving-quadratic-equations/50065711#50065711 + auto [M1, M2, M3, M4] = boost::math::tools::first_four_moments(first, last); + if (M4 == 0) + { + // The signal is constant. There is no noise: + return std::numeric_limits::infinity(); + } + // Change to notation in Pauluzzi, equation 41: + auto kw = estimated_noise_kurtosis; + auto ka = estimated_signal_kurtosis; + // A common case, since it's the default: + Real a = (ka+kw-6); + Real bs = 2*M2*(3-kw); + Real cs = kw*M2*M2 - M4; + Real bn = 2*M2*(3-ka); + Real cn = ka*M2*M2 - M4; + auto [S0, S1] = boost::math::tools::quadratic_roots(a, bs, cs); + if (S1 > 0) + { + auto N = M2 - S1; + if (N > 0) + { + return S1/N; + } + if (S0 > 0) + { + N = M2 - S0; + if (N > 0) + { + return S0/N; + } + } + } + auto [N0, N1] = boost::math::tools::quadratic_roots(a, bn, cn); + if (N1 > 0) + { + auto S = M2 - N1; + if (S > 0) + { + return S/N1; + } + if (N0 > 0) + { + S = M2 - N0; + if (S > 0) + { + return S/N0; + } + } + } + // This happens distressingly often. It's a limitation of the method. + return std::numeric_limits::quiet_NaN(); + } + else + { + BOOST_MATH_ASSERT_MSG(false, "The M2M4 estimator has not been implemented for this type."); + return std::numeric_limits::quiet_NaN(); + } +} + +template +inline auto m2m4_snr_estimator(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + return m2m4_snr_estimator(noisy_signal.cbegin(), noisy_signal.cend(), estimated_signal_kurtosis, estimated_noise_kurtosis); +} + +template +inline auto m2m4_snr_estimator_db(ForwardIterator first, ForwardIterator last, decltype(*first) estimated_signal_kurtosis=1, decltype(*first) estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(first, last, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + + +template +inline auto m2m4_snr_estimator_db(Container const & noisy_signal, typename Container::value_type estimated_signal_kurtosis=1, typename Container::value_type estimated_noise_kurtosis=3) +{ + using std::log10; + return 10*log10(m2m4_snr_estimator(noisy_signal, estimated_signal_kurtosis, estimated_noise_kurtosis)); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/simple_continued_fraction.hpp b/libcxx/src/third-party/boost/math/tools/simple_continued_fraction.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/simple_continued_fraction.hpp @@ -0,0 +1,169 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_SIMPLE_CONTINUED_FRACTION_HPP +#define BOOST_MATH_TOOLS_SIMPLE_CONTINUED_FRACTION_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +namespace boost::math::tools { + +template +class simple_continued_fraction { +public: + simple_continued_fraction(Real x) : x_{x} { + using std::floor; + using std::abs; + using std::sqrt; + using std::isfinite; + if (!isfinite(x)) { + throw std::domain_error("Cannot convert non-finites into continued fractions."); + } + b_.reserve(50); + Real bj = floor(x); + b_.push_back(static_cast(bj)); + if (bj == x) { + b_.shrink_to_fit(); + return; + } + x = 1/(x-bj); + Real f = bj; + if (bj == 0) { + f = 16*(std::numeric_limits::min)(); + } + Real C = f; + Real D = 0; + int i = 0; + // the "1 + i++" lets the error bound grow slowly with the number of convergents. + // I have not worked out the error propagation of the Modified Lentz's method to see if it does indeed grow at this rate. + // Numerical Recipes claims that no one has worked out the error analysis of the modified Lentz's method. + while (abs(f - x_) >= (1 + i++)*std::numeric_limits::epsilon()*abs(x_)) + { + bj = floor(x); + b_.push_back(static_cast(bj)); + x = 1/(x-bj); + D += bj; + if (D == 0) { + D = 16*(std::numeric_limits::min)(); + } + C = bj + 1/C; + if (C==0) { + C = 16*(std::numeric_limits::min)(); + } + D = 1/D; + f *= (C*D); + } + // Deal with non-uniqueness of continued fractions: [a0; a1, ..., an, 1] = a0; a1, ..., an + 1]. + // The shorter representation is considered the canonical representation, + // so if we compute a non-canonical representation, change it to canonical: + if (b_.size() > 2 && b_.back() == 1) { + b_[b_.size() - 2] += 1; + b_.resize(b_.size() - 1); + } + b_.shrink_to_fit(); + + for (size_t i = 1; i < b_.size(); ++i) { + if (b_[i] <= 0) { + std::ostringstream oss; + oss << "Found a negative partial denominator: b[" << i << "] = " << b_[i] << "." + #ifndef BOOST_MATH_STANDALONE + << " This means the integer type '" << boost::core::demangle(typeid(Z).name()) + #else + << " This means the integer type '" << typeid(Z).name() + #endif + << "' has overflowed and you need to use a wider type," + << " or there is a bug."; + throw std::overflow_error(oss.str()); + } + } + } + + Real khinchin_geometric_mean() const { + if (b_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + using std::log; + using std::exp; + // Precompute the most probable logarithms. See the Gauss-Kuzmin distribution for details. + // Example: b_i = 1 has probability -log_2(3/4) ~ .415: + // A random partial denominator has ~80% chance of being in this table: + const std::array logs{std::numeric_limits::quiet_NaN(), Real(0), log(static_cast(2)), log(static_cast(3)), log(static_cast(4)), log(static_cast(5)), log(static_cast(6))}; + Real log_prod = 0; + for (size_t i = 1; i < b_.size(); ++i) { + if (b_[i] < static_cast(logs.size())) { + log_prod += logs[b_[i]]; + } + else + { + log_prod += log(static_cast(b_[i])); + } + } + log_prod /= (b_.size()-1); + return exp(log_prod); + } + + Real khinchin_harmonic_mean() const { + if (b_.size() == 1) { + return std::numeric_limits::quiet_NaN(); + } + Real n = b_.size() - 1; + Real denom = 0; + for (size_t i = 1; i < b_.size(); ++i) { + denom += 1/static_cast(b_[i]); + } + return n/denom; + } + + const std::vector& partial_denominators() const { + return b_; + } + + template + friend std::ostream& operator<<(std::ostream& out, simple_continued_fraction& scf); + +private: + const Real x_; + std::vector b_; +}; + + +template +std::ostream& operator<<(std::ostream& out, simple_continued_fraction& scf) { + constexpr const int p = std::numeric_limits::max_digits10; + if constexpr (p == 2147483647) { + out << std::setprecision(scf.x_.backend().precision()); + } else { + out << std::setprecision(p); + } + + out << "[" << scf.b_.front(); + if (scf.b_.size() > 1) + { + out << "; "; + for (size_t i = 1; i < scf.b_.size() -1; ++i) + { + out << scf.b_[i] << ", "; + } + out << scf.b_.back(); + } + out << "]"; + return out; +} + + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/stats.hpp b/libcxx/src/third-party/boost/math/tools/stats.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/stats.hpp @@ -0,0 +1,87 @@ +// (C) Copyright John Maddock 2005-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_TOOLS_STATS_INCLUDED +#define BOOST_MATH_TOOLS_STATS_INCLUDED + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include + +namespace boost{ namespace math{ namespace tools{ + +template +class stats +{ +public: + stats() + : m_min(tools::max_value()), + m_max(-tools::max_value()), + m_total(0), + m_squared_total(0) + {} + void add(const T& val) + { + if(val < m_min) + m_min = val; + if(val > m_max) + m_max = val; + m_total += val; + ++m_count; + m_squared_total += val*val; + } + T min BOOST_PREVENT_MACRO_SUBSTITUTION()const{ return m_min; } + T max BOOST_PREVENT_MACRO_SUBSTITUTION()const{ return m_max; } + T total()const{ return m_total; } + T mean()const{ return m_total / static_cast(m_count); } + std::uintmax_t count()const{ return m_count; } + T variance()const + { + BOOST_MATH_STD_USING + + T t = m_squared_total - m_total * m_total / m_count; + t /= m_count; + return t; + } + T variance1()const + { + BOOST_MATH_STD_USING + + T t = m_squared_total - m_total * m_total / m_count; + t /= (m_count-1); + return t; + } + T rms()const + { + BOOST_MATH_STD_USING + + return sqrt(m_squared_total / static_cast(m_count)); + } + stats& operator+=(const stats& s) + { + if(s.m_min < m_min) + m_min = s.m_min; + if(s.m_max > m_max) + m_max = s.m_max; + m_total += s.m_total; + m_squared_total += s.m_squared_total; + m_count += s.m_count; + return *this; + } +private: + T m_min, m_max, m_total, m_squared_total; + std::uintmax_t m_count{0}; +}; + +} // namespace tools +} // namespace math +} // namespace boost + +#endif + diff --git a/libcxx/src/third-party/boost/math/tools/test_value.hpp b/libcxx/src/third-party/boost/math/tools/test_value.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/test_value.hpp @@ -0,0 +1,143 @@ +// Copyright Paul A. Bristow 2017. +// Copyright John Maddock 2017. + +// 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) + +// test_value.hpp + +#ifndef TEST_VALUE_HPP +#define TEST_VALUE_HPP + +// BOOST_MATH_TEST_VALUE is used to create a test value of suitable type from a decimal digit string. +// Two parameters, both a floating-point literal double like 1.23 (not long double so no suffix L) +// and a decimal digit string const char* like "1.23" must be provided. +// The decimal value represented must be the same of course, with at least enough precision for long double. +// Note there are two gotchas to this approach: +// * You need all values to be real floating-point values +// * and *MUST* include a decimal point (to avoid confusion with an integer literal). +// * It's slow to compile compared to a simple literal. + +// Speed is not an issue for a few test values, +// but it's not generally usable in large tables +// where you really need everything to be statically initialized. + +// Macro BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE provides a global diagnostic value for create_type. + +#include // For float_64_t, float128_t. Must be first include! +#ifndef BOOST_MATH_STANDALONE +#include +#endif +#include +#include + +#ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE +// global int create_type(0); must be defined before including this file. +#endif + +#ifdef BOOST_HAS_FLOAT128 +typedef __float128 largest_float; +#define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##Q +#define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS 113 +#else +typedef long double largest_float; +#define BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) x##L +#define BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS std::numeric_limits::digits +#endif + +template +inline T create_test_value(largest_float val, const char*, const std::true_type&, const T2&) +{ // Construct from long double or quad parameter val (ignoring string/const char* str). + // (This is case for MPL parameters = true_ and T2 == false_, + // and MPL parameters = true_ and T2 == true_ cpp_bin_float) + // All built-in/fundamental floating-point types, + // and other User-Defined Types that can be constructed without loss of precision + // from long double suffix L (or quad suffix Q), + // + // Choose this method, even if can be constructed from a string, + // because it will be faster, and more likely to be the closest representation. + // (This is case for MPL parameters = true_type and T2 == true_type). + #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 1; + #endif + return static_cast(val); +} + +template +inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::true_type&) +{ // Construct from decimal digit string const char* @c str (ignoring long double parameter). + // For example, extended precision or other User-Defined types which ARE constructible from a string + // (but not from double, or long double without loss of precision). + // (This is case for MPL parameters = false_type and T2 == true_type). + #ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 2; + #endif + return T(str); +} + +template +inline T create_test_value(largest_float, const char* str, const std::false_type&, const std::false_type&) +{ // Create test value using from lexical cast of decimal digit string const char* str. + // For example, extended precision or other User-Defined types which are NOT constructible from a string + // (NOR constructible from a long double). + // (This is case T1 = false_type and T2 == false_type). +#ifdef BOOST_MATH_INSTRUMENT_CREATE_TEST_VALUE + create_type = 3; +#endif +#if defined(BOOST_MATH_STANDALONE) + static_assert(sizeof(T) == 0, "Can not create a test value using lexical cast of string in standalone mode"); + return T(); +#else + return boost::lexical_cast(str); +#endif +} + +// T real type, x a decimal digits representation of a floating-point, for example: 12.34. +// It must include a decimal point (or it would be interpreted as an integer). + +// x is converted to a long double by appending the letter L (to suit long double fundamental type), 12.34L. +// x is also passed as a const char* or string representation "12.34" +// (to suit most other types that cannot be constructed from long double without possible loss). + +// BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) makes a long double or quad version, with +// suffix a letter L (or Q) to suit long double (or quad) fundamental type, 12.34L or 12.34Q. +// #x makes a decimal digit string version to suit multiprecision and fixed_point constructors, "12.34". +// (Constructing from double or long double (or quad) could lose precision for multiprecision or fixed-point). + +// The matching create_test_value function above is chosen depending on the T1 and T2 mpl bool truths. +// The string version from #x is used if the precision of T is greater than long double. + +// Example: long double test_value = BOOST_MATH_TEST_VALUE(double, 1.23456789); + +#define BOOST_MATH_TEST_VALUE(T, x) create_test_value(\ + BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x),\ + #x,\ + std::integral_constant::is_specialized &&\ + (std::numeric_limits::radix == 2)\ + && (std::numeric_limits::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ + && std::is_convertible::value>(),\ + std::integral_constant::value>()\ +) + +#if LDBL_MAX_10_EXP > DBL_MAX_10_EXP +#define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) BOOST_MATH_TEST_LARGEST_FLOAT_SUFFIX(x) +#else +#define BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x) 0.0 +#endif + +#define BOOST_MATH_HUGE_TEST_VALUE(T, x) create_test_value(\ + BOOST_MATH_TEST_HUGE_FLOAT_SUFFIX(x),\ + #x,\ + std::integral_constant::is_specialized &&\ + (std::numeric_limits::radix == 2)\ + && (std::numeric_limits::digits <= BOOST_MATH_TEST_LARGEST_FLOAT_DIGITS)\ + && std::is_convertible::value>(),\ + std::integral_constant::value>()\ +) +#endif // TEST_VALUE_HPP diff --git a/libcxx/src/third-party/boost/math/tools/throw_exception.hpp b/libcxx/src/third-party/boost/math/tools/throw_exception.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/throw_exception.hpp @@ -0,0 +1,22 @@ +// (C) Copyright Matt Borland 2021. +// 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_TOOLS_THROW_EXCEPTION_HPP +#define BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP + +#include + +#ifndef BOOST_MATH_STANDALONE + +#include +#define BOOST_MATH_THROW_EXCEPTION(expr) boost::throw_exception(expr); + +#else // Standalone mode - use standard library facilities + +#define BOOST_MATH_THROW_EXCEPTION(expr) throw expr; + +#endif // BOOST_MATH_STANDALONE + +#endif // BOOST_MATH_TOOLS_THROW_EXCEPTION_HPP diff --git a/libcxx/src/third-party/boost/math/tools/toms748_solve.hpp b/libcxx/src/third-party/boost/math/tools/toms748_solve.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/toms748_solve.hpp @@ -0,0 +1,622 @@ +// (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_TOOLS_SOLVE_ROOT_HPP +#define BOOST_MATH_TOOLS_SOLVE_ROOT_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_MATH_LOG_ROOT_ITERATIONS +# define BOOST_MATH_LOGGER_INCLUDE +# include BOOST_MATH_LOGGER_INCLUDE +# undef BOOST_MATH_LOGGER_INCLUDE +#else +# define BOOST_MATH_LOG_COUNT(count) +#endif + +namespace boost{ namespace math{ namespace tools{ + +template +class eps_tolerance +{ +public: + eps_tolerance() : eps(4 * tools::epsilon()) + { + + } + eps_tolerance(unsigned bits) + { + BOOST_MATH_STD_USING + eps = (std::max)(T(ldexp(1.0F, 1-bits)), T(4 * tools::epsilon())); + } + bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return fabs(a - b) <= (eps * (std::min)(fabs(a), fabs(b))); + } +private: + T eps; +}; + +struct equal_floor +{ + equal_floor()= default; + template + bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return floor(a) == floor(b); + } +}; + +struct equal_ceil +{ + equal_ceil()= default; + template + bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return ceil(a) == ceil(b); + } +}; + +struct equal_nearest_integer +{ + equal_nearest_integer()= default; + template + bool operator()(const T& a, const T& b) + { + BOOST_MATH_STD_USING + return floor(a + 0.5f) == floor(b + 0.5f); + } +}; + +namespace detail{ + +template +void bracket(F f, T& a, T& b, T c, T& fa, T& fb, T& d, T& fd) +{ + // + // Given a point c inside the existing enclosing interval + // [a, b] sets a = c if f(c) == 0, otherwise finds the new + // enclosing interval: either [a, c] or [c, b] and sets + // d and fd to the point that has just been removed from + // the interval. In other words d is the third best guess + // to the root. + // + BOOST_MATH_STD_USING // For ADL of std math functions + T tol = tools::epsilon() * 2; + // + // If the interval [a,b] is very small, or if c is too close + // to one end of the interval then we need to adjust the + // location of c accordingly: + // + if((b - a) < 2 * tol * a) + { + c = a + (b - a) / 2; + } + else if(c <= a + fabs(a) * tol) + { + c = a + fabs(a) * tol; + } + else if(c >= b - fabs(b) * tol) + { + c = b - fabs(b) * tol; + } + // + // OK, lets invoke f(c): + // + T fc = f(c); + // + // if we have a zero then we have an exact solution to the root: + // + if(fc == 0) + { + a = c; + fa = 0; + d = 0; + fd = 0; + return; + } + // + // Non-zero fc, update the interval: + // + if(boost::math::sign(fa) * boost::math::sign(fc) < 0) + { + d = b; + fd = fb; + b = c; + fb = fc; + } + else + { + d = a; + fd = fa; + a = c; + fa= fc; + } +} + +template +inline T safe_div(T num, T denom, T r) +{ + // + // return num / denom without overflow, + // return r if overflow would occur. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + if(fabs(denom) < 1) + { + if(fabs(denom * tools::max_value()) <= fabs(num)) + return r; + } + return num / denom; +} + +template +inline T secant_interpolate(const T& a, const T& b, const T& fa, const T& fb) +{ + // + // Performs standard secant interpolation of [a,b] given + // function evaluations f(a) and f(b). Performs a bisection + // if secant interpolation would leave us very close to either + // a or b. Rationale: we only call this function when at least + // one other form of interpolation has already failed, so we know + // that the function is unlikely to be smooth with a root very + // close to a or b. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + T tol = tools::epsilon() * 5; + T c = a - (fa / (fb - fa)) * (b - a); + if((c <= a + fabs(a) * tol) || (c >= b - fabs(b) * tol)) + return (a + b) / 2; + return c; +} + +template +T quadratic_interpolate(const T& a, const T& b, T const& d, + const T& fa, const T& fb, T const& fd, + unsigned count) +{ + // + // Performs quadratic interpolation to determine the next point, + // takes count Newton steps to find the location of the + // quadratic polynomial. + // + // Point d must lie outside of the interval [a,b], it is the third + // best approximation to the root, after a and b. + // + // Note: this does not guarantee to find a root + // inside [a, b], so we fall back to a secant step should + // the result be out of range. + // + // Start by obtaining the coefficients of the quadratic polynomial: + // + T B = safe_div(T(fb - fa), T(b - a), tools::max_value()); + T A = safe_div(T(fd - fb), T(d - b), tools::max_value()); + A = safe_div(T(A - B), T(d - a), T(0)); + + if(A == 0) + { + // failure to determine coefficients, try a secant step: + return secant_interpolate(a, b, fa, fb); + } + // + // Determine the starting point of the Newton steps: + // + T c; + if(boost::math::sign(A) * boost::math::sign(fa) > 0) + { + c = a; + } + else + { + c = b; + } + // + // Take the Newton steps: + // + for(unsigned i = 1; i <= count; ++i) + { + //c -= safe_div(B * c, (B + A * (2 * c - a - b)), 1 + c - a); + c -= safe_div(T(fa+(B+A*(c-b))*(c-a)), T(B + A * (2 * c - a - b)), T(1 + c - a)); + } + if((c <= a) || (c >= b)) + { + // Oops, failure, try a secant step: + c = secant_interpolate(a, b, fa, fb); + } + return c; +} + +template +T cubic_interpolate(const T& a, const T& b, const T& d, + const T& e, const T& fa, const T& fb, + const T& fd, const T& fe) +{ + // + // Uses inverse cubic interpolation of f(x) at points + // [a,b,d,e] to obtain an approximate root of f(x). + // Points d and e lie outside the interval [a,b] + // and are the third and forth best approximations + // to the root that we have found so far. + // + // Note: this does not guarantee to find a root + // inside [a, b], so we fall back to quadratic + // interpolation in case of an erroneous result. + // + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b + << " d = " << d << " e = " << e << " fa = " << fa << " fb = " << fb + << " fd = " << fd << " fe = " << fe); + T q11 = (d - e) * fd / (fe - fd); + T q21 = (b - d) * fb / (fd - fb); + T q31 = (a - b) * fa / (fb - fa); + T d21 = (b - d) * fd / (fd - fb); + T d31 = (a - b) * fb / (fb - fa); + BOOST_MATH_INSTRUMENT_CODE( + "q11 = " << q11 << " q21 = " << q21 << " q31 = " << q31 + << " d21 = " << d21 << " d31 = " << d31); + T q22 = (d21 - q11) * fb / (fe - fb); + T q32 = (d31 - q21) * fa / (fd - fa); + T d32 = (d31 - q21) * fd / (fd - fa); + T q33 = (d32 - q22) * fa / (fe - fa); + T c = q31 + q32 + q33 + a; + BOOST_MATH_INSTRUMENT_CODE( + "q22 = " << q22 << " q32 = " << q32 << " d32 = " << d32 + << " q33 = " << q33 << " c = " << c); + + if((c <= a) || (c >= b)) + { + // Out of bounds step, fall back to quadratic interpolation: + c = quadratic_interpolate(a, b, d, fa, fb, fd, 3); + BOOST_MATH_INSTRUMENT_CODE( + "Out of bounds interpolation, falling back to quadratic interpolation. c = " << c); + } + + return c; +} + +} // namespace detail + +template +std::pair toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, std::uintmax_t& max_iter, const Policy& pol) +{ + // + // Main entry point and logic for Toms Algorithm 748 + // root finder. + // + BOOST_MATH_STD_USING // For ADL of std math functions + + static const char* function = "boost::math::tools::toms748_solve<%1%>"; + + // + // Sanity check - are we allowed to iterate at all? + // + if (max_iter == 0) + return std::make_pair(ax, bx); + + std::uintmax_t count = max_iter; + T a, b, fa, fb, c, u, fu, a0, b0, d, fd, e, fe; + static const T mu = 0.5f; + + // initialise a, b and fa, fb: + a = ax; + b = bx; + if(a >= b) + return boost::math::detail::pair_from_single(policies::raise_domain_error( + function, + "Parameters a and b out of order: a=%1%", a, pol)); + fa = fax; + fb = fbx; + + if(tol(a, b) || (fa == 0) || (fb == 0)) + { + max_iter = 0; + if(fa == 0) + b = a; + else if(fb == 0) + a = b; + return std::make_pair(a, b); + } + + if(boost::math::sign(fa) * boost::math::sign(fb) > 0) + return boost::math::detail::pair_from_single(policies::raise_domain_error( + function, + "Parameters a and b do not bracket the root: a=%1%", a, pol)); + // dummy value for fd, e and fe: + fe = e = fd = 1e5F; + + if(fa != 0) + { + // + // On the first step we take a secant step: + // + c = detail::secant_interpolate(a, b, fa, fb); + detail::bracket(f, a, b, c, fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + + if(count && (fa != 0) && !tol(a, b)) + { + // + // On the second step we take a quadratic interpolation: + // + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2); + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + } + } + + while(count && (fa != 0) && !tol(a, b)) + { + // save our brackets: + a0 = a; + b0 = b; + // + // Starting with the third step taken + // we can use either quadratic or cubic interpolation. + // Cubic interpolation requires that all four function values + // fa, fb, fd, and fe are distinct, should that not be the case + // then variable prof will get set to true, and we'll end up + // taking a quadratic step instead. + // + T min_diff = tools::min_value() * 32; + bool prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff); + if(prof) + { + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 2); + BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!"); + } + else + { + c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe); + } + // + // re-bracket, and check for termination: + // + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + // + // Now another interpolated step: + // + prof = (fabs(fa - fb) < min_diff) || (fabs(fa - fd) < min_diff) || (fabs(fa - fe) < min_diff) || (fabs(fb - fd) < min_diff) || (fabs(fb - fe) < min_diff) || (fabs(fd - fe) < min_diff); + if(prof) + { + c = detail::quadratic_interpolate(a, b, d, fa, fb, fd, 3); + BOOST_MATH_INSTRUMENT_CODE("Can't take cubic step!!!!"); + } + else + { + c = detail::cubic_interpolate(a, b, d, e, fa, fb, fd, fe); + } + // + // Bracket again, and check termination condition, update e: + // + detail::bracket(f, a, b, c, fa, fb, d, fd); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + // + // Now we take a double-length secant step: + // + if(fabs(fa) < fabs(fb)) + { + u = a; + fu = fa; + } + else + { + u = b; + fu = fb; + } + c = u - 2 * (fu / (fb - fa)) * (b - a); + if(fabs(c - u) > (b - a) / 2) + { + c = a + (b - a) / 2; + } + // + // Bracket again, and check termination condition: + // + e = d; + fe = fd; + detail::bracket(f, a, b, c, fa, fb, d, fd); + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + BOOST_MATH_INSTRUMENT_CODE(" tol = " << T((fabs(a) - fabs(b)) / fabs(a))); + if((0 == --count) || (fa == 0) || tol(a, b)) + break; + // + // And finally... check to see if an additional bisection step is + // to be taken, we do this if we're not converging fast enough: + // + if((b - a) < mu * (b0 - a0)) + continue; + // + // bracket again on a bisection: + // + e = d; + fe = fd; + detail::bracket(f, a, b, T(a + (b - a) / 2), fa, fb, d, fd); + --count; + BOOST_MATH_INSTRUMENT_CODE("Not converging: Taking a bisection!!!!"); + BOOST_MATH_INSTRUMENT_CODE(" a = " << a << " b = " << b); + } // while loop + + max_iter -= count; + if(fa == 0) + { + b = a; + } + else if(fb == 0) + { + a = b; + } + BOOST_MATH_LOG_COUNT(max_iter) + return std::make_pair(a, b); +} + +template +inline std::pair toms748_solve(F f, const T& ax, const T& bx, const T& fax, const T& fbx, Tol tol, std::uintmax_t& max_iter) +{ + return toms748_solve(f, ax, bx, fax, fbx, tol, max_iter, policies::policy<>()); +} + +template +inline std::pair toms748_solve(F f, const T& ax, const T& bx, Tol tol, std::uintmax_t& max_iter, const Policy& pol) +{ + if (max_iter <= 2) + return std::make_pair(ax, bx); + max_iter -= 2; + std::pair r = toms748_solve(f, ax, bx, f(ax), f(bx), tol, max_iter, pol); + max_iter += 2; + return r; +} + +template +inline std::pair toms748_solve(F f, const T& ax, const T& bx, Tol tol, std::uintmax_t& max_iter) +{ + return toms748_solve(f, ax, bx, tol, max_iter, policies::policy<>()); +} + +template +std::pair bracket_and_solve_root(F f, const T& guess, T factor, bool rising, Tol tol, std::uintmax_t& max_iter, const Policy& pol) +{ + BOOST_MATH_STD_USING + static const char* function = "boost::math::tools::bracket_and_solve_root<%1%>"; + // + // Set up initial brackets: + // + T a = guess; + T b = a; + T fa = f(a); + T fb = fa; + // + // Set up invocation count: + // + std::uintmax_t count = max_iter - 1; + + int step = 32; + + if((fa < 0) == (guess < 0 ? !rising : rising)) + { + // + // Zero is to the right of b, so walk upwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(count == 0) + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", b, pol)); + // + // Heuristic: normally it's best not to increase the step sizes as we'll just end up + // with a really wide range to search for the root. However, if the initial guess was *really* + // bad then we need to speed up the search otherwise we'll take forever if we're orders of + // magnitude out. This happens most often if the guess is a small value (say 1) and the result + // we're looking for is close to std::numeric_limits::min(). + // + if((max_iter - count) % step == 0) + { + factor *= 2; + if(step > 1) step /= 2; + } + // + // Now go ahead and move our guess by "factor": + // + a = b; + fa = fb; + b *= factor; + fb = f(b); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + else + { + // + // Zero is to the left of a, so walk downwards + // until we find it: + // + while((boost::math::sign)(fb) == (boost::math::sign)(fa)) + { + if(fabs(a) < tools::min_value()) + { + // Escape route just in case the answer is zero! + max_iter -= count; + max_iter += 1; + return a > 0 ? std::make_pair(T(0), T(a)) : std::make_pair(T(a), T(0)); + } + if(count == 0) + return boost::math::detail::pair_from_single(policies::raise_evaluation_error(function, "Unable to bracket root, last nearest value was %1%", a, pol)); + // + // Heuristic: normally it's best not to increase the step sizes as we'll just end up + // with a really wide range to search for the root. However, if the initial guess was *really* + // bad then we need to speed up the search otherwise we'll take forever if we're orders of + // magnitude out. This happens most often if the guess is a small value (say 1) and the result + // we're looking for is close to std::numeric_limits::min(). + // + if((max_iter - count) % step == 0) + { + factor *= 2; + if(step > 1) step /= 2; + } + // + // Now go ahead and move are guess by "factor": + // + b = a; + fb = fa; + a /= factor; + fa = f(a); + --count; + BOOST_MATH_INSTRUMENT_CODE("a = " << a << " b = " << b << " fa = " << fa << " fb = " << fb << " count = " << count); + } + } + max_iter -= count; + max_iter += 1; + std::pair r = toms748_solve( + f, + (a < 0 ? b : a), + (a < 0 ? a : b), + (a < 0 ? fb : fa), + (a < 0 ? fa : fb), + tol, + count, + pol); + max_iter += count; + BOOST_MATH_INSTRUMENT_CODE("max_iter = " << max_iter << " count = " << count); + BOOST_MATH_LOG_COUNT(max_iter) + return r; +} + +template +inline std::pair bracket_and_solve_root(F f, const T& guess, const T& factor, bool rising, Tol tol, std::uintmax_t& max_iter) +{ + return bracket_and_solve_root(f, guess, factor, rising, tol, max_iter, policies::policy<>()); +} + +} // namespace tools +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_TOOLS_SOLVE_ROOT_HPP + diff --git a/libcxx/src/third-party/boost/math/tools/traits.hpp b/libcxx/src/third-party/boost/math/tools/traits.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/traits.hpp @@ -0,0 +1,140 @@ +// Copyright John Maddock 2007. +// Copyright Matt Borland 2021. +// 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) + +/* +This header defines two traits classes, both in namespace boost::math::tools. + +is_distribution::value is true iff D has overloaded "cdf" and +"quantile" functions, plus member typedefs value_type and policy_type. +It's not much of a definitive test frankly, +but if it looks like a distribution and quacks like a distribution +then it must be a distribution. + +is_scaled_distribution::value is true iff D is a distribution +as defined above, and has member functions "scale" and "location". + +*/ + +#ifndef BOOST_STATS_IS_DISTRIBUTION_HPP +#define BOOST_STATS_IS_DISTRIBUTION_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +namespace boost{ namespace math{ namespace tools{ + +namespace detail{ + +#define BOOST_MATH_HAS_NAMED_TRAIT(trait, name) \ +template \ +class trait \ +{ \ +private: \ + using yes = char; \ + struct no { char x[2]; }; \ + \ + template \ + static yes test(typename U::name* = nullptr); \ + \ + template \ + static no test(...); \ + \ +public: \ + static constexpr bool value = (sizeof(test(0)) == sizeof(char)); \ +}; + +BOOST_MATH_HAS_NAMED_TRAIT(has_value_type, value_type) +BOOST_MATH_HAS_NAMED_TRAIT(has_policy_type, policy_type) +BOOST_MATH_HAS_NAMED_TRAIT(has_backend_type, backend_type) + +// C++17-esque helpers +#if defined(__cpp_variable_templates) && __cpp_variable_templates >= 201304L +template +constexpr bool has_value_type_v = has_value_type::value; + +template +constexpr bool has_policy_type_v = has_policy_type::value; + +template +constexpr bool has_backend_type_v = has_backend_type::value; +#endif + +template +char cdf(const D& ...); +template +char quantile(const D& ...); + +template +struct has_cdf +{ + static D d; + static constexpr bool value = sizeof(cdf(d, 0.0f)) != 1; +}; + +template +struct has_quantile +{ + static D d; + static constexpr bool value = sizeof(quantile(d, 0.0f)) != 1; +}; + +template +struct is_distribution_imp +{ + static constexpr bool value = + has_quantile::value + && has_cdf::value + && has_value_type::value + && has_policy_type::value; +}; + +template +struct result_tag{}; + +template +double test_has_location(const volatile result_tag*); +template +char test_has_location(...); + +template +double test_has_scale(const volatile result_tag*); +template +char test_has_scale(...); + +template +struct is_scaled_distribution_helper +{ + static constexpr bool value = false; +}; + +template +struct is_scaled_distribution_helper +{ + static constexpr bool value = + (sizeof(test_has_location(0)) != 1) + && + (sizeof(test_has_scale(0)) != 1); +}; + +template +struct is_scaled_distribution_imp +{ + static constexpr bool value = (::boost::math::tools::detail::is_scaled_distribution_helper::value>::value); +}; + +} // namespace detail + +template struct is_distribution : public std::integral_constant::value> {}; +template struct is_scaled_distribution : public std::integral_constant::value> {}; + +}}} + +#endif + + diff --git a/libcxx/src/third-party/boost/math/tools/tuple.hpp b/libcxx/src/third-party/boost/math/tools/tuple.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/tuple.hpp @@ -0,0 +1,27 @@ +// (C) Copyright John Maddock 2010. +// 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_TUPLE_HPP_INCLUDED +#define BOOST_MATH_TUPLE_HPP_INCLUDED + +#include +#include + +namespace boost{ namespace math{ + +using ::std::tuple; + +// [6.1.3.2] Tuple creation functions +using ::std::ignore; +using ::std::make_tuple; +using ::std::tie; +using ::std::get; + +// [6.1.3.3] Tuple helper classes +using ::std::tuple_size; +using ::std::tuple_element; + +}} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/ulps_plot.hpp b/libcxx/src/third-party/boost/math/tools/ulps_plot.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/ulps_plot.hpp @@ -0,0 +1,598 @@ +// (C) Copyright Nick Thompson 2020. +// 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_TOOLS_ULP_PLOT_HPP +#define BOOST_MATH_TOOLS_ULP_PLOT_HPP +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef BOOST_MATH_STANDALONE +#include +#endif + +// Design of this function comes from: +// https://blogs.mathworks.com/cleve/2017/01/23/ulps-plots-reveal-math-function-accurary/ + +// The envelope is the maximum of 1/2 and half the condition number of function evaluation. + +namespace boost::math::tools { + +namespace detail { +template +void write_gridlines(std::ostream& fs, int horizontal_lines, int vertical_lines, + F1 x_scale, F2 y_scale, CoarseReal min_x, CoarseReal max_x, PreciseReal min_y, PreciseReal max_y, + int graph_width, int graph_height, int margin_left, std::string const & font_color) +{ + // Make a grid: + for (int i = 1; i <= horizontal_lines; ++i) { + PreciseReal y_cord_dataspace = min_y + ((max_y - min_y)*i)/horizontal_lines; + auto y = y_scale(y_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << y_cord_dataspace << "\n"; + } + + for (int i = 1; i <= vertical_lines; ++i) { + CoarseReal x_cord_dataspace = min_x + ((max_x - min_x)*i)/vertical_lines; + CoarseReal x = x_scale(x_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << x_cord_dataspace << "\n"; + } +} +} + +template +class ulps_plot { +public: + ulps_plot(F hi_acc_impl, CoarseReal a, CoarseReal b, + size_t samples = 1000, bool perturb_abscissas = false, int random_seed = -1); + + ulps_plot& clip(PreciseReal clip); + + ulps_plot& width(int width); + + ulps_plot& envelope_color(std::string const & color); + + ulps_plot& title(std::string const & title); + + ulps_plot& background_color(std::string const & background_color); + + ulps_plot& font_color(std::string const & font_color); + + ulps_plot& crop_color(std::string const & color); + + ulps_plot& nan_color(std::string const & color); + + ulps_plot& ulp_envelope(bool write_ulp); + + template + ulps_plot& add_fn(G g, std::string const & color = "steelblue"); + + ulps_plot& horizontal_lines(int horizontal_lines); + + ulps_plot& vertical_lines(int vertical_lines); + + void write(std::string const & filename) const; + + friend std::ostream& operator<<(std::ostream& fs, ulps_plot const & plot) + { + using std::abs; + using std::floor; + using std::isnan; + if (plot.ulp_list_.size() == 0) + { + throw std::domain_error("No functions added for comparison."); + } + if (plot.width_ <= 1) + { + throw std::domain_error("Width = " + std::to_string(plot.width_) + ", which is too small."); + } + + PreciseReal worst_ulp_distance = 0; + PreciseReal min_y = (std::numeric_limits::max)(); + PreciseReal max_y = std::numeric_limits::lowest(); + for (auto const & ulp_vec : plot.ulp_list_) + { + for (auto const & ulp : ulp_vec) + { + if (static_cast(abs(ulp)) > worst_ulp_distance) + { + worst_ulp_distance = static_cast(abs(ulp)); + } + if (static_cast(ulp) < min_y) + { + min_y = static_cast(ulp); + } + if (static_cast(ulp) > max_y) + { + max_y = static_cast(ulp); + } + } + } + + // half-ulp accuracy is the best that can be expected; sometimes we can get less, but barely less. + // then the axes don't show up; painful! + if (max_y < 0.5) { + max_y = 0.5; + } + if (min_y > -0.5) { + min_y = -0.5; + } + + if (plot.clip_ > 0) + { + if (max_y > plot.clip_) + { + max_y = plot.clip_; + } + if (min_y < -plot.clip_) + { + min_y = -plot.clip_; + } + } + + int height = static_cast(floor(static_cast(plot.width_)/1.61803)); + int margin_top = 40; + int margin_left = 25; + if (plot.title_.size() == 0) + { + margin_top = 10; + margin_left = 15; + } + int margin_bottom = 20; + int margin_right = 20; + int graph_height = height - margin_bottom - margin_top; + int graph_width = plot.width_ - margin_left - margin_right; + + // Maps [a,b] to [0, graph_width] + auto x_scale = [&](CoarseReal x)->CoarseReal + { + return ((x-plot.a_)/(plot.b_ - plot.a_))*static_cast(graph_width); + }; + + auto y_scale = [&](PreciseReal y)->PreciseReal + { + return ((max_y - y)/(max_y - min_y) )*static_cast(graph_height); + }; + + fs << "\n" + << "\n" + << "\n"; + if (plot.title_.size() > 0) + { + fs << "" + << plot.title_ + << "\n"; + } + + // Construct SVG group to simplify the calculations slightly: + fs << "\n"; + // y-axis: + fs << "\n"; + PreciseReal x_axis_loc = y_scale(static_cast(0)); + fs << "\n"; + + if (worst_ulp_distance > 3) + { + detail::write_gridlines(fs, plot.horizontal_lines_, plot.vertical_lines_, x_scale, y_scale, plot.a_, plot.b_, + min_y, max_y, graph_width, graph_height, margin_left, plot.font_color_); + } + else + { + std::vector ys{-3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0}; + for (double & i : ys) + { + if (min_y <= i && i <= max_y) + { + PreciseReal y_cord_dataspace = i; + PreciseReal y = y_scale(y_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << y_cord_dataspace << "\n"; + } + } + for (int i = 1; i <= plot.vertical_lines_; ++i) + { + CoarseReal x_cord_dataspace = plot.a_ + ((plot.b_ - plot.a_)*i)/plot.vertical_lines_; + CoarseReal x = x_scale(x_cord_dataspace); + fs << "\n"; + + fs << "" + << std::setprecision(4) << x_cord_dataspace << "\n"; + } + } + + int color_idx = 0; + for (auto const & ulp : plot.ulp_list_) + { + std::string color = plot.colors_[color_idx++]; + for (size_t j = 0; j < ulp.size(); ++j) + { + if (isnan(ulp[j])) + { + if(plot.nan_color_ == "") + continue; + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(plot.clip_)); + fs << "\n"; + y = y_scale(static_cast(-plot.clip_)); + fs << "\n"; + } + if (plot.clip_ > 0 && static_cast(abs(ulp[j])) > plot.clip_) + { + if (plot.crop_color_ == "") + continue; + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(ulp[j] < 0 ? -plot.clip_ : plot.clip_)); + fs << "\n"; + } + else + { + CoarseReal x = x_scale(plot.coarse_abscissas_[j]); + PreciseReal y = y_scale(static_cast(ulp[j])); + fs << "\n"; + } + } + } + + if (plot.ulp_envelope_) + { + std::string close_path = "' stroke='" + plot.envelope_color_ + "' stroke-width='1' fill='none'>\n"; + size_t jstart = 0; + while (plot.cond_[jstart] > max_y) + { + ++jstart; + if (jstart >= plot.cond_.size()) + { + goto done; + } + } + + size_t jmin = jstart; + new_top_path: + if (jmin >= plot.cond_.size()) + { + goto start_bottom_paths; + } + fs << "\n" + << "\n"; + return fs; + } + +private: + std::vector precise_abscissas_; + std::vector coarse_abscissas_; + std::vector precise_ordinates_; + std::vector cond_; + std::list> ulp_list_; + std::vector colors_; + CoarseReal a_; + CoarseReal b_; + PreciseReal clip_; + int width_; + std::string envelope_color_; + bool ulp_envelope_; + int horizontal_lines_; + int vertical_lines_; + std::string title_; + std::string background_color_; + std::string font_color_; + std::string crop_color_; + std::string nan_color_; +}; + +template +ulps_plot& ulps_plot::envelope_color(std::string const & color) +{ + envelope_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::clip(PreciseReal clip) +{ + clip_ = clip; + return *this; +} + +template +ulps_plot& ulps_plot::width(int width) +{ + width_ = width; + return *this; +} + +template +ulps_plot& ulps_plot::horizontal_lines(int horizontal_lines) +{ + horizontal_lines_ = horizontal_lines; + return *this; +} + +template +ulps_plot& ulps_plot::vertical_lines(int vertical_lines) +{ + vertical_lines_ = vertical_lines; + return *this; +} + +template +ulps_plot& ulps_plot::title(std::string const & title) +{ + title_ = title; + return *this; +} + +template +ulps_plot& ulps_plot::background_color(std::string const & background_color) +{ + background_color_ = background_color; + return *this; +} + +template +ulps_plot& ulps_plot::font_color(std::string const & font_color) +{ + font_color_ = font_color; + return *this; +} + +template +ulps_plot& ulps_plot::crop_color(std::string const & color) +{ + crop_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::nan_color(std::string const & color) +{ + nan_color_ = color; + return *this; +} + +template +ulps_plot& ulps_plot::ulp_envelope(bool write_ulp_envelope) +{ + ulp_envelope_ = write_ulp_envelope; + return *this; +} + +namespace detail{ +bool ends_with(std::string const& filename, std::string const& suffix) +{ + if(filename.size() < suffix.size()) + { + return false; + } + + return std::equal(std::begin(suffix), std::end(suffix), std::end(filename) - suffix.size()); +} +} + +template +void ulps_plot::write(std::string const & filename) const +{ + if(!boost::math::tools::detail::ends_with(filename, ".svg")) + { + throw std::logic_error("Only svg files are supported at this time."); + } + std::ofstream fs(filename); + fs << *this; + fs.close(); +} + + +template +ulps_plot::ulps_plot(F hi_acc_impl, CoarseReal a, CoarseReal b, + size_t samples, bool perturb_abscissas, int random_seed) : crop_color_("red") +{ + // Use digits10 for this comparison in case the two types have differeing radixes: + static_assert(std::numeric_limits::digits10 >= std::numeric_limits::digits10, "PreciseReal must have higher precision that CoarseReal"); + if (samples < 10) + { + throw std::domain_error("Must have at least 10 samples, samples = " + std::to_string(samples)); + } + if (b <= a) + { + throw std::domain_error("On interval [a,b], b > a is required."); + } + a_ = a; + b_ = b; + + std::mt19937_64 gen; + if (random_seed == -1) + { + std::random_device rd; + gen.seed(rd()); + } + + // Boost's uniform_real_distribution can generate quad and multiprecision random numbers; std's cannot: + #ifndef BOOST_MATH_STANDALONE + boost::random::uniform_real_distribution dis(static_cast(a), static_cast(b)); + #else + // Use std::random in standalone mode if it is a type that the standard library can support (float, double, or long double) + static_assert(std::numeric_limits::digits10 <= std::numeric_limits::digits10, "Standalone mode does not support types with precision that exceeds long double"); + std::uniform_real_distribution dis(static_cast(a), static_cast(b)); + #endif + + precise_abscissas_.resize(samples); + coarse_abscissas_.resize(samples); + + if (perturb_abscissas) + { + for(size_t i = 0; i < samples; ++i) + { + precise_abscissas_[i] = dis(gen); + } + std::sort(precise_abscissas_.begin(), precise_abscissas_.end()); + for (size_t i = 0; i < samples; ++i) + { + coarse_abscissas_[i] = static_cast(precise_abscissas_[i]); + } + } + else + { + for(size_t i = 0; i < samples; ++i) + { + coarse_abscissas_[i] = static_cast(dis(gen)); + } + std::sort(coarse_abscissas_.begin(), coarse_abscissas_.end()); + for (size_t i = 0; i < samples; ++i) + { + precise_abscissas_[i] = static_cast(coarse_abscissas_[i]); + } + } + + precise_ordinates_.resize(samples); + for (size_t i = 0; i < samples; ++i) + { + precise_ordinates_[i] = hi_acc_impl(precise_abscissas_[i]); + } + + cond_.resize(samples, std::numeric_limits::quiet_NaN()); + for (size_t i = 0 ; i < samples; ++i) + { + PreciseReal y = precise_ordinates_[i]; + if (y != 0) + { + // Maybe cond_ is badly names; should it be half_cond_? + cond_[i] = boost::math::tools::evaluation_condition_number(hi_acc_impl, precise_abscissas_[i])/2; + // Half-ULP accuracy is the correctly rounded result, so make sure the envelop doesn't go below this: + if (cond_[i] < 0.5) + { + cond_[i] = 0.5; + } + } + // else leave it as nan. + } + clip_ = -1; + width_ = 1100; + envelope_color_ = "chartreuse"; + ulp_envelope_ = true; + horizontal_lines_ = 8; + vertical_lines_ = 10; + title_ = ""; + background_color_ = "black"; + font_color_ = "white"; +} + +template +template +ulps_plot& ulps_plot::add_fn(G g, std::string const & color) +{ + using std::abs; + size_t samples = precise_abscissas_.size(); + std::vector ulps(samples); + for (size_t i = 0; i < samples; ++i) + { + PreciseReal y_hi_acc = precise_ordinates_[i]; + PreciseReal y_lo_acc = static_cast(g(coarse_abscissas_[i])); + PreciseReal absy = abs(y_hi_acc); + PreciseReal dist = static_cast(nextafter(static_cast(absy), (std::numeric_limits::max)()) - static_cast(absy)); + ulps[i] = static_cast((y_lo_acc - y_hi_acc)/dist); + } + ulp_list_.emplace_back(ulps); + colors_.emplace_back(color); + return *this; +} + + + + +} // namespace boost::math::tools +#endif diff --git a/libcxx/src/third-party/boost/math/tools/univariate_statistics.hpp b/libcxx/src/third-party/boost/math/tools/univariate_statistics.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/univariate_statistics.hpp @@ -0,0 +1,429 @@ +// (C) Copyright Nick Thompson 2018. +// 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_TOOLS_UNIVARIATE_STATISTICS_HPP +#define BOOST_MATH_TOOLS_UNIVARIATE_STATISTICS_HPP + +#include +#include +#include +#include +#include + +BOOST_MATH_HEADER_DEPRECATED(""); + +namespace boost::math::tools { + +template +auto mean(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the mean."); + if constexpr (std::is_integral::value) + { + double mu = 0; + double i = 1; + for(auto it = first; it != last; ++it) { + mu = mu + (*it - mu)/i; + i += 1; + } + return mu; + } + else if constexpr (std::is_same_v::iterator_category, std::random_access_iterator_tag>) + { + size_t elements = std::distance(first, last); + Real mu0 = 0; + Real mu1 = 0; + Real mu2 = 0; + Real mu3 = 0; + Real i = 1; + auto end = last - (elements % 4); + for(auto it = first; it != end; it += 4) { + Real inv = Real(1)/i; + Real tmp0 = (*it - mu0); + Real tmp1 = (*(it+1) - mu1); + Real tmp2 = (*(it+2) - mu2); + Real tmp3 = (*(it+3) - mu3); + // please generate a vectorized fma here + mu0 += tmp0*inv; + mu1 += tmp1*inv; + mu2 += tmp2*inv; + mu3 += tmp3*inv; + i += 1; + } + Real num1 = Real(elements - (elements %4))/Real(4); + Real num2 = num1 + Real(elements % 4); + + for (auto it = end; it != last; ++it) + { + mu3 += (*it-mu3)/i; + i += 1; + } + + return (num1*(mu0+mu1+mu2) + num2*mu3)/Real(elements); + } + else + { + auto it = first; + Real mu = *it; + Real i = 2; + while(++it != last) + { + mu += (*it - mu)/i; + i += 1; + } + return mu; + } +} + +template +inline auto mean(Container const & v) +{ + return mean(v.cbegin(), v.cend()); +} + +template +auto variance(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute mean and variance."); + // Higham, Accuracy and Stability, equation 1.6a and 1.6b: + if constexpr (std::is_integral::value) + { + double M = *first; + double Q = 0; + double k = 2; + for (auto it = std::next(first); it != last; ++it) + { + double tmp = *it - M; + Q = Q + ((k-1)*tmp*tmp)/k; + M = M + tmp/k; + k += 1; + } + return Q/(k-1); + } + else + { + Real M = *first; + Real Q = 0; + Real k = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real tmp = (*it - M)/k; + Q += k*(k-1)*tmp*tmp; + M += tmp; + k += 1; + } + return Q/(k-1); + } +} + +template +inline auto variance(Container const & v) +{ + return variance(v.cbegin(), v.cend()); +} + +template +auto sample_variance(ForwardIterator first, ForwardIterator last) +{ + size_t n = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(n > 1, "At least two samples are required to compute the sample variance."); + return n*variance(first, last)/(n-1); +} + +template +inline auto sample_variance(Container const & v) +{ + return sample_variance(v.cbegin(), v.cend()); +} + + +// Follows equation 1.5 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto skewness(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute skewness."); + if constexpr (std::is_integral::value) + { + double M1 = *first; + double M2 = 0; + double M3 = 0; + double n = 2; + for (auto it = std::next(first); it != last; ++it) + { + double delta21 = *it - M1; + double tmp = delta21/n; + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + double var = M2/(n-1); + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return static_cast(0); + } + double skew = M3/(M2*sqrt(var)); + return skew; + } + else + { + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M3 += tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 += tmp*(n-1)*delta21; + M1 += tmp; + n += 1; + } + + Real var = M2/(n-1); + if (var == 0) + { + // The limit is technically undefined, but the interpretation here is clear: + // A constant dataset has no skewness. + return Real(0); + } + Real skew = M3/(M2*sqrt(var)); + return skew; + } +} + +template +inline auto skewness(Container const & v) +{ + return skewness(v.cbegin(), v.cend()); +} + +// Follows equation 1.5/1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto first_four_moments(ForwardIterator first, ForwardIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last, "At least one sample is required to compute the first four moments."); + if constexpr (std::is_integral::value) + { + double M1 = *first; + double M2 = 0; + double M3 = 0; + double M4 = 0; + double n = 2; + for (auto it = std::next(first); it != last; ++it) + { + double delta21 = *it - M1; + double tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2/(n-1), M3/(n-1), M4/(n-1)); + } + else + { + Real M1 = *first; + Real M2 = 0; + Real M3 = 0; + Real M4 = 0; + Real n = 2; + for (auto it = std::next(first); it != last; ++it) + { + Real delta21 = *it - M1; + Real tmp = delta21/n; + M4 = M4 + tmp*(tmp*tmp*delta21*((n-1)*(n*n-3*n+3)) + 6*tmp*M2 - 4*M3); + M3 = M3 + tmp*((n-1)*(n-2)*delta21*tmp - 3*M2); + M2 = M2 + tmp*(n-1)*delta21; + M1 = M1 + tmp; + n += 1; + } + + return std::make_tuple(M1, M2/(n-1), M3/(n-1), M4/(n-1)); + } +} + +template +inline auto first_four_moments(Container const & v) +{ + return first_four_moments(v.cbegin(), v.cend()); +} + + +// Follows equation 1.6 of: +// https://prod.sandia.gov/techlib-noauth/access-control.cgi/2008/086212.pdf +template +auto kurtosis(ForwardIterator first, ForwardIterator last) +{ + auto [M1, M2, M3, M4] = first_four_moments(first, last); + if (M2 == 0) + { + return M2; + } + return M4/(M2*M2); +} + +template +inline auto kurtosis(Container const & v) +{ + return kurtosis(v.cbegin(), v.cend()); +} + +template +auto excess_kurtosis(ForwardIterator first, ForwardIterator last) +{ + return kurtosis(first, last) - 3; +} + +template +inline auto excess_kurtosis(Container const & v) +{ + return excess_kurtosis(v.cbegin(), v.cend()); +} + + +template +auto median(RandomAccessIterator first, RandomAccessIterator last) +{ + size_t num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero length vector is undefined."); + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last); + return *middle; + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last); + std::nth_element(middle, middle+1, last); + return (*middle + *(middle+1))/2; + } +} + + +template +inline auto median(RandomAccessContainer & v) +{ + return median(v.begin(), v.end()); +} + +template +auto gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + using Real = typename std::iterator_traits::value_type; + BOOST_MATH_ASSERT_MSG(first != last && std::next(first) != last, "Computation of the Gini coefficient requires at least two samples."); + + std::sort(first, last); + if constexpr (std::is_integral::value) + { + double i = 1; + double num = 0; + double denom = 0; + for (auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + return static_cast(0); + } + + return ((2*num)/denom - i)/(i-1); + } + else + { + Real i = 1; + Real num = 0; + Real denom = 0; + for (auto it = first; it != last; ++it) + { + num += *it*i; + denom += *it; + ++i; + } + + // If the l1 norm is zero, all elements are zero, so every element is the same. + if (denom == 0) + { + return Real(0); + } + + return ((2*num)/denom - i)/(i-1); + } +} + +template +inline auto gini_coefficient(RandomAccessContainer & v) +{ + return gini_coefficient(v.begin(), v.end()); +} + +template +inline auto sample_gini_coefficient(RandomAccessIterator first, RandomAccessIterator last) +{ + size_t n = std::distance(first, last); + return n*gini_coefficient(first, last)/(n-1); +} + +template +inline auto sample_gini_coefficient(RandomAccessContainer & v) +{ + return sample_gini_coefficient(v.begin(), v.end()); +} + +template +auto median_absolute_deviation(RandomAccessIterator first, RandomAccessIterator last, typename std::iterator_traits::value_type center=std::numeric_limits::value_type>::quiet_NaN()) +{ + using std::abs; + using Real = typename std::iterator_traits::value_type; + using std::isnan; + if (isnan(center)) + { + center = boost::math::tools::median(first, last); + } + size_t num_elems = std::distance(first, last); + BOOST_MATH_ASSERT_MSG(num_elems > 0, "The median of a zero-length vector is undefined."); + auto comparator = [¢er](Real a, Real b) { return abs(a-center) < abs(b-center);}; + if (num_elems & 1) + { + auto middle = first + (num_elems - 1)/2; + std::nth_element(first, middle, last, comparator); + return abs(*middle); + } + else + { + auto middle = first + num_elems/2 - 1; + std::nth_element(first, middle, last, comparator); + std::nth_element(middle, middle+1, last, comparator); + return (abs(*middle) + abs(*(middle+1)))/abs(static_cast(2)); + } +} + +template +inline auto median_absolute_deviation(RandomAccessContainer & v, typename RandomAccessContainer::value_type center=std::numeric_limits::quiet_NaN()) +{ + return median_absolute_deviation(v.begin(), v.end(), center); +} + +} +#endif diff --git a/libcxx/src/third-party/boost/math/tools/user.hpp b/libcxx/src/third-party/boost/math/tools/user.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/user.hpp @@ -0,0 +1,105 @@ +// Copyright John Maddock 2007. +// Copyright Paul A. Bristow 2007. + +// 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_TOOLS_USER_HPP +#define BOOST_MATH_TOOLS_USER_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +// This file can be modified by the user to change the default policies. +// See "Changing the Policy Defaults" in documentation. + +// define this if the platform has no long double functions, +// or if the long double versions have only double precision: +// +// #define BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS +// +// Performance tuning options: +// +// #define BOOST_MATH_POLY_METHOD 3 +// #define BOOST_MATH_RATIONAL_METHOD 3 +// +// The maximum order of polynomial that will be evaluated +// via an unrolled specialisation: +// +// #define BOOST_MATH_MAX_POLY_ORDER 17 +// +// decide whether to store constants as integers or reals: +// +// #define BOOST_MATH_INT_TABLE_TYPE(RT, IT) IT + +// +// Default policies follow: +// +// Domain errors: +// +// #define BOOST_MATH_DOMAIN_ERROR_POLICY throw_on_error +// +// Pole errors: +// +// #define BOOST_MATH_POLE_ERROR_POLICY throw_on_error +// +// Overflow Errors: +// +// #define BOOST_MATH_OVERFLOW_ERROR_POLICY throw_on_error +// +// Internal Evaluation Errors: +// +// #define BOOST_MATH_EVALUATION_ERROR_POLICY throw_on_error +// +// Underflow: +// +// #define BOOST_MATH_UNDERFLOW_ERROR_POLICY ignore_error +// +// Denorms: +// +// #define BOOST_MATH_DENORM_ERROR_POLICY ignore_error +// +// Max digits to use for internal calculations: +// +// #define BOOST_MATH_DIGITS10_POLICY 0 +// +// Promote floats to doubles internally? +// +// #define BOOST_MATH_PROMOTE_FLOAT_POLICY true +// +// Promote doubles to long double internally: +// +// #define BOOST_MATH_PROMOTE_DOUBLE_POLICY true +// +// What do discrete quantiles return? +// +// #define BOOST_MATH_DISCRETE_QUANTILE_POLICY integer_round_outwards +// +// If a function is mathematically undefined +// (for example the Cauchy distribution has no mean), +// then do we stop the code from compiling? +// +// #define BOOST_MATH_ASSERT_UNDEFINED_POLICY true +// +// Maximum series iterations permitted: +// +// #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 1000000 +// +// Maximum root finding steps permitted: +// +// define BOOST_MATH_MAX_ROOT_ITERATION_POLICY 200 +// +// Enable use of __float128 in numeric constants: +// +// #define BOOST_MATH_USE_FLOAT128 +// +// Disable use of __float128 in numeric_constants even if the compiler looks to support it: +// +// #define BOOST_MATH_DISABLE_FLOAT128 + +#endif // BOOST_MATH_TOOLS_USER_HPP + + diff --git a/libcxx/src/third-party/boost/math/tools/workaround.hpp b/libcxx/src/third-party/boost/math/tools/workaround.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tools/workaround.hpp @@ -0,0 +1,38 @@ +// Copyright (c) 2006-7 John Maddock +// 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_TOOLS_WORHAROUND_HPP +#define BOOST_MATH_TOOLS_WORHAROUND_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include + +namespace boost{ namespace math{ namespace tools{ +// +// We call this short forwarding function so that we can work around a bug +// on Darwin that causes std::fmod to return a NaN. The test case is: +// std::fmod(1185.0L, 1.5L); +// +template +inline T fmod_workaround(T a, T b) BOOST_MATH_NOEXCEPT(T) +{ + BOOST_MATH_STD_USING + return fmod(a, b); +} +#if (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && ((LDBL_MANT_DIG == 106) || (__LDBL_MANT_DIG__ == 106)) +template <> +inline long double fmod_workaround(long double a, long double b) noexcept +{ + return ::fmodl(a, b); +} +#endif + +}}} // namespaces + +#endif // BOOST_MATH_TOOLS_WORHAROUND_HPP + diff --git a/libcxx/src/third-party/boost/math/tr1.hpp b/libcxx/src/third-party/boost/math/tr1.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tr1.hpp @@ -0,0 +1,1121 @@ +// Copyright John Maddock 2008. +// 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_TR1_HPP +#define BOOST_MATH_TR1_HPP + +#ifdef _MSC_VER +#pragma once +#endif + +#include // So we can check which std C lib we're using + +#ifdef __cplusplus + +#include +#include + +namespace boost{ namespace math{ namespace tr1{ extern "C"{ + +#endif // __cplusplus + +#ifndef BOOST_PREVENT_MACRO_SUBSTITUTION +#define BOOST_PREVENT_MACRO_SUBSTITUTION /**/ +#endif + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_MATH_TR1_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_MATH_TR1_DYN_LINK) +// export if this is our own source, otherwise import: +#ifdef BOOST_MATH_TR1_SOURCE +# define BOOST_MATH_TR1_DECL BOOST_SYMBOL_EXPORT +#else +# define BOOST_MATH_TR1_DECL BOOST_SYMBOL_IMPORT +#endif // BOOST_MATH_TR1_SOURCE +#else +# define BOOST_MATH_TR1_DECL +#endif // DYN_LINK +// +// Set any throw specifications on the C99 extern "C" functions - these have to be +// the same as used in the std lib if any. +// +#if defined(__GLIBC__) && defined(__THROW) +# define BOOST_MATH_C99_THROW_SPEC __THROW +#else +# define BOOST_MATH_C99_THROW_SPEC +#endif + +// +// Now set up the libraries to link against: +// Not compatible with standalone mode +// +#ifndef BOOST_MATH_STANDALONE +#include +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_c99 +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_c99f +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_LIB_NAME boost_math_c99l +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_tr1 +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) +# define BOOST_LIB_NAME boost_math_tr1f +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#if !defined(BOOST_MATH_TR1_NO_LIB) && !defined(BOOST_MATH_TR1_SOURCE) \ + && !defined(BOOST_ALL_NO_LIB) && defined(__cplusplus) \ + && !defined(BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS) +# define BOOST_LIB_NAME boost_math_tr1l +# if defined(BOOST_MATH_TR1_DYN_LINK) || defined(BOOST_ALL_DYN_LINK) +# define BOOST_DYN_LINK +# endif +# include +#endif +#else // Standalone mode +# if defined(_MSC_VER) && !defined(BOOST_ALL_NO_LIB) +# pragma message("Auto linking of TR1 is not supported in standalone mode") +# endif +#endif // BOOST_MATH_STANDALONE + +#if !(defined(__INTEL_COMPILER) && defined(__APPLE__)) && !(defined(__FLT_EVAL_METHOD__) && !defined(__cplusplus)) +#if !defined(FLT_EVAL_METHOD) +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == -1 +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == 0 +typedef float float_t; +typedef double double_t; +#elif FLT_EVAL_METHOD == 1 +typedef double float_t; +typedef double double_t; +#else +typedef long double float_t; +typedef long double double_t; +#endif +#endif + +// C99 Functions: +double BOOST_MATH_TR1_DECL boost_acosh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_acoshf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_acoshl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_asinh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_asinhf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_asinhl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_atanh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_atanhf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_atanhl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cbrtf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cbrtl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_copysign BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_copysignf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_copysignl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_erf BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_erff BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_erfl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_erfc BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_erfcf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_erfcl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_exp2 BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_exp2f BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_exp2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_expm1f BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_expm1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_fdim BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fdimf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fdiml BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_fma BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y, double z) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fmaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y, float z) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fmal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, long double z) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_fmax BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fmaxf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fmaxl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_fmin BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_fminf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_fminl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_hypot BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_hypotf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_hypotl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +#if 0 +int BOOST_MATH_TR1_DECL boost_ilogb BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +int BOOST_MATH_TR1_DECL boost_ilogbf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +int BOOST_MATH_TR1_DECL boost_ilogbl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_lgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_lgammal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +long long BOOST_MATH_TR1_DECL boost_llround BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long long BOOST_MATH_TR1_DECL boost_llroundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long long BOOST_MATH_TR1_DECL boost_llroundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_log1p BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_log1pf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_log1pl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL log2 BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL log2f BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL log2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL logb BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL logbf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL logbl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrint BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL lrintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +long BOOST_MATH_TR1_DECL boost_lround BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL boost_lroundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long BOOST_MATH_TR1_DECL boost_lroundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL nan BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL nanf BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL nanl BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL nearbyintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL nearbyintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_nextafterf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_nextafterl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(double x, long double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_nexttowardf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, long double y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_nexttowardl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_remainder BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_remainderf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_remainderl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_remquo BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_remquof BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_remquol BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, int *pquo) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_rint BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_rintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_rintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_round BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_roundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_roundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; +#if 0 +double BOOST_MATH_TR1_DECL boost_scalbln BOOST_PREVENT_MACRO_SUBSTITUTION(double x, long ex) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_scalblnf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, long ex) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_scalblnl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long ex) BOOST_MATH_C99_THROW_SPEC; +double BOOST_MATH_TR1_DECL boost_scalbn BOOST_PREVENT_MACRO_SUBSTITUTION(double x, int ex) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_scalbnf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, int ex) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_scalbnl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, int ex) BOOST_MATH_C99_THROW_SPEC; +#endif +double BOOST_MATH_TR1_DECL boost_tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_tgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_tgammal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +double BOOST_MATH_TR1_DECL boost_trunc BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_truncf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_truncl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.1] associated Laguerre polynomials: +double BOOST_MATH_TR1_DECL boost_assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_assoc_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_assoc_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.2] associated Legendre functions: +double BOOST_MATH_TR1_DECL boost_assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_assoc_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_assoc_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.3] beta function: +double BOOST_MATH_TR1_DECL boost_beta BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_betaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_betal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.4] (complete) elliptic integral of the first kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(double k) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(float k) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.5] (complete) elliptic integral of the second kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(double k) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_2f BOOST_PREVENT_MACRO_SUBSTITUTION(float k) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.6] (complete) elliptic integral of the third kind: +double BOOST_MATH_TR1_DECL boost_comp_ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double nu) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_comp_ellint_3f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float nu) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_comp_ellint_3l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu) BOOST_MATH_C99_THROW_SPEC; +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +double BOOST_MATH_TR1_DECL conf_hyperg BOOST_PREVENT_MACRO_SUBSTITUTION(double a, double c, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL conf_hypergf BOOST_PREVENT_MACRO_SUBSTITUTION(float a, float c, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL conf_hypergl BOOST_PREVENT_MACRO_SUBSTITUTION(long double a, long double c, long double x) BOOST_MATH_C99_THROW_SPEC; +#endif +// [5.2.1.8] regular modified cylindrical Bessel functions: +double BOOST_MATH_TR1_DECL boost_cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_if BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_il BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +double BOOST_MATH_TR1_DECL boost_cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_jf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_jl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +double BOOST_MATH_TR1_DECL boost_cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_bessel_kf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_bessel_kl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.11] cylindrical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// cylindrical Bessel functions (of the second kind): +double BOOST_MATH_TR1_DECL boost_cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_cyl_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_cyl_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +double BOOST_MATH_TR1_DECL boost_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +double BOOST_MATH_TR1_DECL boost_ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_2f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +double BOOST_MATH_TR1_DECL boost_ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double nu, double phi) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_ellint_3f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_ellint_3l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.15] exponential integral: +double BOOST_MATH_TR1_DECL boost_expint BOOST_PREVENT_MACRO_SUBSTITUTION(double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_expintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_expintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.16] Hermite polynomials: +double BOOST_MATH_TR1_DECL boost_hermite BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_hermitef BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_hermitel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +#if 0 +// [5.2.1.17] hypergeometric functions: +double BOOST_MATH_TR1_DECL hyperg BOOST_PREVENT_MACRO_SUBSTITUTION(double a, double b, double c, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL hypergf BOOST_PREVENT_MACRO_SUBSTITUTION(float a, float b, float c, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL hypergl BOOST_PREVENT_MACRO_SUBSTITUTION(long double a, long double b, long double c, +long double x) BOOST_MATH_C99_THROW_SPEC; +#endif + +// [5.2.1.18] Laguerre polynomials: +double BOOST_MATH_TR1_DECL boost_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.19] Legendre polynomials: +double BOOST_MATH_TR1_DECL boost_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.20] Riemann zeta function: +double BOOST_MATH_TR1_DECL boost_riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(double) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_riemann_zetaf BOOST_PREVENT_MACRO_SUBSTITUTION(float) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_riemann_zetal BOOST_PREVENT_MACRO_SUBSTITUTION(long double) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.21] spherical Bessel functions (of the first kind): +double BOOST_MATH_TR1_DECL boost_sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_besself BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_bessell BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.22] spherical associated Legendre functions: +double BOOST_MATH_TR1_DECL boost_sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double theta) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) BOOST_MATH_C99_THROW_SPEC; + +// [5.2.1.23] spherical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// spherical Bessel functions (of the second kind): +double BOOST_MATH_TR1_DECL boost_sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) BOOST_MATH_C99_THROW_SPEC; +float BOOST_MATH_TR1_DECL boost_sph_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) BOOST_MATH_C99_THROW_SPEC; +long double BOOST_MATH_TR1_DECL boost_sph_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) BOOST_MATH_C99_THROW_SPEC; + +#ifdef __cplusplus + +}}}} // namespaces + +#include + +namespace boost{ namespace math{ namespace tr1{ +// +// Declare overload of the functions which forward to the +// C interfaces: +// +// C99 Functions: +inline double acosh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_acosh BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float acoshf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_acoshf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double acoshl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_acoshl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float acosh BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::acoshf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double acosh BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::acoshl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type acosh BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::acosh BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double asinh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_asinh BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float asinhf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_asinhf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double asinhl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_asinhl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float asinh BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::asinhf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double asinh BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::asinhl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type asinh BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::asinh BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double atanh BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_atanh BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float atanhf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_atanhf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double atanhl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_atanhl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float atanh BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::atanhf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double atanh BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::atanhl(x); } +template +inline typename tools::promote_args::type atanh BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::atanh BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float cbrtf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_cbrtf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double cbrtl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_cbrtl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::cbrtf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::cbrtl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double copysign BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_copysign BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float copysignf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_copysignf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double copysignl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_copysignl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float copysign BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::copysignf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double copysign BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::copysignl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type copysign BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::copysign BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline double erf BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_erf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erff BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_erff BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_erfl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::erff BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erf BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::erfl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type erf BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::erf BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline double erfc BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_erfc BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erfcf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_erfcf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfcl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_erfcl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float erfc BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::erfcf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double erfc BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::erfcl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type erfc BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::erfc BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#if 0 +double exp2 BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +float exp2f BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long double exp2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline float expm1f BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_expm1f BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expm1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_expm1l BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::expm1f BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::expm1l BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#if 0 +double fdim BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y); +float fdimf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y); +long double fdiml BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y); +double fma BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y, double z); +float fmaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y, float z); +long double fmal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, long double z); +#endif +inline double fmax BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_fmax BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmaxf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_fmaxf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmaxl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_fmaxl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmax BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::fmaxf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmax BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::fmaxl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type fmax BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::fmax BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline double fmin BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_fmin BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fminf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_fminf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fminl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_fminl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float fmin BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::fminf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double fmin BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::fminl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type fmin BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::fmin BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline float hypotf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_hypotf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double hypot BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_hypot BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double hypotl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_hypotl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float hypot BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::hypotf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double hypot BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::hypotl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type hypot BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::hypot BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +#if 0 +int ilogb BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +int ilogbf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +int ilogbl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline float lgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_lgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double lgammal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_lgammal BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::lgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::lgammal BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +#ifdef BOOST_HAS_LONG_LONG +#if 0 +long long llrint BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +long long llrintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long long llrintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif + +inline long long llroundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_llroundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_llround BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llroundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_llroundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::llroundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long long llround BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::llroundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline long long llround BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return llround BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast(x)); } +#endif + +inline float log1pf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_log1pf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double log1p BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_log1p BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double log1pl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_log1pl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float log1p BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::log1pf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double log1p BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::log1pl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type log1p BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::log1p BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } +#if 0 +double log2 BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +float log2f BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long double log2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); + +double logb BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +float logbf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long double logbl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +long lrint BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +long lrintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long lrintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline long lroundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_lroundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_lround BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lroundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_lroundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::lroundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long lround BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::lroundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +long lround BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::lround BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast(x)); } +#if 0 +double nan BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str); +float nanf BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str); +long double nanl BOOST_PREVENT_MACRO_SUBSTITUTION(const char *str); +double nearbyint BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +float nearbyintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long double nearbyintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline float nextafterf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_nextafterf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nextafterl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_nextafterl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::nextafterf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::nextafterl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return boost::math::tr1::nextafter BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +inline float nexttowardf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_nexttowardf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nexttowardl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_nexttowardl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::nexttowardf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::nexttowardl BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(T1 x, T2 y) +{ return static_cast::type>(boost::math::tr1::nexttoward BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast(y))); } +#if 0 +double remainder BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y); +float remainderf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y); +long double remainderl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y); +double remquo BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y, int *pquo); +float remquof BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y, int *pquo); +long double remquol BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y, int *pquo); +double rint BOOST_PREVENT_MACRO_SUBSTITUTION(double x); +float rintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x); +long double rintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x); +#endif +inline float roundf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_roundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double round BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_round BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double roundl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_roundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float round BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::roundf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double round BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::roundl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type round BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::round BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } +#if 0 +double scalbln BOOST_PREVENT_MACRO_SUBSTITUTION(double x, long ex); +float scalblnf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, long ex); +long double scalblnl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long ex); +double scalbn BOOST_PREVENT_MACRO_SUBSTITUTION(double x, int ex); +float scalbnf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, int ex); +long double scalbnl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, int ex); +#endif +inline float tgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_tgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double tgammal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_tgammal BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::tgammaf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::tgammal BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +inline float truncf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_truncf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double trunc BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_trunc BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double truncl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_truncl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float trunc BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::truncf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double trunc BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::truncl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type trunc BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::trunc BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +# define NO_MACRO_EXPAND /**/ +// C99 macros defined as C++ templates +template bool signbit NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL signbit NO_MACRO_EXPAND(long double x); + +template int fpclassify NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(float x); +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(double x); +template<> int BOOST_MATH_TR1_DECL fpclassify NO_MACRO_EXPAND(long double x); + +template bool isfinite NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isfinite NO_MACRO_EXPAND(long double x); + +template bool isinf NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isinf NO_MACRO_EXPAND(long double x); + +template bool isnan NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isnan NO_MACRO_EXPAND(long double x); + +template bool isnormal NO_MACRO_EXPAND(T) +{ static_assert(sizeof(T) == 0, "Undefined behavior; this template should never be instantiated"); return false; } // must not be instantiated +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(float x); +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(double x); +template<> bool BOOST_MATH_TR1_DECL isnormal NO_MACRO_EXPAND(long double x); + +#undef NO_MACRO_EXPAND + +// [5.2.1.1] associated Laguerre polynomials: +inline float assoc_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) +{ return boost::math::tr1::boost_assoc_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline double assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, double x) +{ return boost::math::tr1::boost_assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline long double assoc_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) +{ return boost::math::tr1::boost_assoc_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline float assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, float x) +{ return boost::math::tr1::assoc_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +inline long double assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, long double x) +{ return boost::math::tr1::assoc_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, x); } +template +inline typename tools::promote_args::type assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, unsigned m, T x) +{ return boost::math::tr1::assoc_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(n, m, static_cast::type>(x)); } + +// [5.2.1.2] associated Legendre functions: +inline float assoc_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) +{ return boost::math::tr1::boost_assoc_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline double assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double x) +{ return boost::math::tr1::boost_assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline long double assoc_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) +{ return boost::math::tr1::boost_assoc_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline float assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float x) +{ return boost::math::tr1::assoc_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +inline long double assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double x) +{ return boost::math::tr1::assoc_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, x); } +template +inline typename tools::promote_args::type assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, T x) +{ return boost::math::tr1::assoc_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, static_cast::type>(x)); } + +// [5.2.1.3] beta function: +inline float betaf BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::boost_betaf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline double beta BOOST_PREVENT_MACRO_SUBSTITUTION(double x, double y) +{ return boost::math::tr1::boost_beta BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double betal BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::boost_betal BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline float beta BOOST_PREVENT_MACRO_SUBSTITUTION(float x, float y) +{ return boost::math::tr1::betaf BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +inline long double beta BOOST_PREVENT_MACRO_SUBSTITUTION(long double x, long double y) +{ return boost::math::tr1::betal BOOST_PREVENT_MACRO_SUBSTITUTION(x, y); } +template +inline typename tools::promote_args::type beta BOOST_PREVENT_MACRO_SUBSTITUTION(T2 x, T1 y) +{ return boost::math::tr1::beta BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x), static_cast::type>(y)); } + +// [5.2.1.4] (complete) elliptic integral of the first kind: +inline float comp_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(float k) +{ return boost::math::tr1::boost_comp_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(k); } +inline double comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(double k) +{ return boost::math::tr1::boost_comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(k); } +inline long double comp_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k) +{ return boost::math::tr1::boost_comp_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(k); } +inline float comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(float k) +{ return boost::math::tr1::comp_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(k); } +inline long double comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(long double k) +{ return boost::math::tr1::comp_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(k); } +template +inline typename tools::promote_args::type comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(T k) +{ return boost::math::tr1::comp_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k)); } + +// [5.2.1.5] (complete) elliptic integral of the second kind: +inline float comp_ellint_2f(float k) +{ return boost::math::tr1::boost_comp_ellint_2f(k); } +inline double comp_ellint_2(double k) +{ return boost::math::tr1::boost_comp_ellint_2(k); } +inline long double comp_ellint_2l(long double k) +{ return boost::math::tr1::boost_comp_ellint_2l(k); } +inline float comp_ellint_2(float k) +{ return boost::math::tr1::comp_ellint_2f(k); } +inline long double comp_ellint_2(long double k) +{ return boost::math::tr1::comp_ellint_2l(k); } +template +inline typename tools::promote_args::type comp_ellint_2(T k) +{ return boost::math::tr1::comp_ellint_2(static_cast::type> BOOST_PREVENT_MACRO_SUBSTITUTION(k)); } + +// [5.2.1.6] (complete) elliptic integral of the third kind: +inline float comp_ellint_3f(float k, float nu) +{ return boost::math::tr1::boost_comp_ellint_3f(k, nu); } +inline double comp_ellint_3(double k, double nu) +{ return boost::math::tr1::boost_comp_ellint_3(k, nu); } +inline long double comp_ellint_3l(long double k, long double nu) +{ return boost::math::tr1::boost_comp_ellint_3l(k, nu); } +inline float comp_ellint_3(float k, float nu) +{ return boost::math::tr1::comp_ellint_3f(k, nu); } +inline long double comp_ellint_3(long double k, long double nu) +{ return boost::math::tr1::comp_ellint_3l(k, nu); } +template +inline typename tools::promote_args::type comp_ellint_3(T1 k, T2 nu) +{ return boost::math::tr1::comp_ellint_3(static_cast::type> BOOST_PREVENT_MACRO_SUBSTITUTION(k), static_cast::type> BOOST_PREVENT_MACRO_SUBSTITUTION(nu)); } + +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +double conf_hyperg BOOST_PREVENT_MACRO_SUBSTITUTION(double a, double c, double x); +float conf_hypergf BOOST_PREVENT_MACRO_SUBSTITUTION(float a, float c, float x); +long double conf_hypergl BOOST_PREVENT_MACRO_SUBSTITUTION(long double a, long double c, long double x); +#endif + +// [5.2.1.8] regular modified cylindrical Bessel functions: +inline float cyl_bessel_if BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_if BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_il BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_il BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_if BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_il BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_i BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +inline float cyl_bessel_jf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_jf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_jl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_jl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_jf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_jl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_j BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +inline float cyl_bessel_kf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_bessel_kf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_kl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_bessel_kl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_bessel_kf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_bessel_kl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_bessel_k BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type> BOOST_PREVENT_MACRO_SUBSTITUTION(nu), static_cast::type>(x)); } + +// [5.2.1.11] cylindrical Neumann functions; +// cylindrical Bessel functions (of the second kind): +inline float cyl_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::boost_cyl_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline double cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(double nu, double x) +{ return boost::math::tr1::boost_cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::boost_cyl_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline float cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(float nu, float x) +{ return boost::math::tr1::cyl_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +inline long double cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(long double nu, long double x) +{ return boost::math::tr1::cyl_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(nu, x); } +template +inline typename tools::promote_args::type cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(T1 nu, T2 x) +{ return boost::math::tr1::cyl_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(nu), static_cast::type>(x)); } + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +inline float ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::boost_ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline double ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double phi) +{ return boost::math::tr1::boost_ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::boost_ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline float ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::ellint_1f BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::ellint_1l BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +template +inline typename tools::promote_args::type ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 phi) +{ return boost::math::tr1::ellint_1 BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(phi)); } + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +inline float ellint_2f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::boost_ellint_2f BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline double ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double phi) +{ return boost::math::tr1::boost_ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_2l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::boost_ellint_2l BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline float ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float phi) +{ return boost::math::tr1::ellint_2f BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +inline long double ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double phi) +{ return boost::math::tr1::ellint_2l BOOST_PREVENT_MACRO_SUBSTITUTION(k, phi); } +template +inline typename tools::promote_args::type ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 phi) +{ return boost::math::tr1::ellint_2 BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(phi)); } + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +inline float ellint_3f BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) +{ return boost::math::tr1::boost_ellint_3f BOOST_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline double ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(double k, double nu, double phi) +{ return boost::math::tr1::boost_ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline long double ellint_3l BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) +{ return boost::math::tr1::boost_ellint_3l BOOST_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline float ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(float k, float nu, float phi) +{ return boost::math::tr1::ellint_3f BOOST_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +inline long double ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(long double k, long double nu, long double phi) +{ return boost::math::tr1::ellint_3l BOOST_PREVENT_MACRO_SUBSTITUTION(k, nu, phi); } +template +inline typename tools::promote_args::type ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(T1 k, T2 nu, T3 phi) +{ return boost::math::tr1::ellint_3 BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(k), static_cast::type>(nu), static_cast::type>(phi)); } + +// [5.2.1.15] exponential integral: +inline float expintf BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::boost_expintf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline double expint BOOST_PREVENT_MACRO_SUBSTITUTION(double x) +{ return boost::math::tr1::boost_expint BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expintl BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::boost_expintl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline float expint BOOST_PREVENT_MACRO_SUBSTITUTION(float x) +{ return boost::math::tr1::expintf BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +inline long double expint BOOST_PREVENT_MACRO_SUBSTITUTION(long double x) +{ return boost::math::tr1::expintl BOOST_PREVENT_MACRO_SUBSTITUTION(x); } +template +inline typename tools::promote_args::type expint BOOST_PREVENT_MACRO_SUBSTITUTION(T x) +{ return boost::math::tr1::expint BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(x)); } + +// [5.2.1.16] Hermite polynomials: +inline float hermitef BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_hermitef BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double hermite BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_hermite BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double hermitel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_hermitel BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float hermite BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::hermitef BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double hermite BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::hermitel BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type hermite BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::hermite BOOST_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +#if 0 +// [5.2.1.17] hypergeometric functions: +double hyperg BOOST_PREVENT_MACRO_SUBSTITUTION(double a, double b, double c, double x); +float hypergf BOOST_PREVENT_MACRO_SUBSTITUTION(float a, float b, float c, float x); +long double hypergl BOOST_PREVENT_MACRO_SUBSTITUTION(long double a, long double b, long double c, +long double x); +#endif + +// [5.2.1.18] Laguerre polynomials: +inline float laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::laguerref BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::laguerrel BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::laguerre BOOST_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +// [5.2.1.19] Legendre polynomials: +inline float legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) +{ return boost::math::tr1::boost_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline double legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, double x) +{ return boost::math::tr1::boost_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline long double legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) +{ return boost::math::tr1::boost_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline float legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, float x) +{ return boost::math::tr1::legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, x); } +inline long double legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, long double x) +{ return boost::math::tr1::legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, x); } +template +inline typename tools::promote_args::type legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, T x) +{ return boost::math::tr1::legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, static_cast::type>(x)); } + +// [5.2.1.20] Riemann zeta function: +inline float riemann_zetaf BOOST_PREVENT_MACRO_SUBSTITUTION(float z) +{ return boost::math::tr1::boost_riemann_zetaf BOOST_PREVENT_MACRO_SUBSTITUTION(z); } +inline double riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(double z) +{ return boost::math::tr1::boost_riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(z); } +inline long double riemann_zetal BOOST_PREVENT_MACRO_SUBSTITUTION(long double z) +{ return boost::math::tr1::boost_riemann_zetal BOOST_PREVENT_MACRO_SUBSTITUTION(z); } +inline float riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(float z) +{ return boost::math::tr1::riemann_zetaf BOOST_PREVENT_MACRO_SUBSTITUTION(z); } +inline long double riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(long double z) +{ return boost::math::tr1::riemann_zetal BOOST_PREVENT_MACRO_SUBSTITUTION(z); } +template +inline typename tools::promote_args::type riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(T z) +{ return boost::math::tr1::riemann_zeta BOOST_PREVENT_MACRO_SUBSTITUTION(static_cast::type>(z)); } + +// [5.2.1.21] spherical Bessel functions (of the first kind): +inline float sph_besself BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_sph_besself BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_bessell BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_sph_bessell BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::sph_besself BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::sph_bessell BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::sph_bessel BOOST_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +// [5.2.1.22] spherical associated Legendre functions: +inline float sph_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) +{ return boost::math::tr1::boost_sph_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline double sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, double theta) +{ return boost::math::tr1::boost_sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline long double sph_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) +{ return boost::math::tr1::boost_sph_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline float sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, float theta) +{ return boost::math::tr1::sph_legendref BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +inline long double sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, long double theta) +{ return boost::math::tr1::sph_legendrel BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, theta); } +template +inline typename tools::promote_args::type sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned l, unsigned m, T theta) +{ return boost::math::tr1::sph_legendre BOOST_PREVENT_MACRO_SUBSTITUTION(l, m, static_cast::type>(theta)); } + +// [5.2.1.23] spherical Neumann functions; +// spherical Bessel functions (of the second kind): +inline float sph_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::boost_sph_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline double sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, double x) +{ return boost::math::tr1::boost_sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::boost_sph_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline float sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, float x) +{ return boost::math::tr1::sph_neumannf BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +inline long double sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, long double x) +{ return boost::math::tr1::sph_neumannl BOOST_PREVENT_MACRO_SUBSTITUTION(n, x); } +template +inline typename tools::promote_args::type sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(unsigned n, T x) +{ return boost::math::tr1::sph_neumann BOOST_PREVENT_MACRO_SUBSTITUTION(n, static_cast::type>(x)); } + +}}} // namespaces + +#else // __cplusplus + +#include + +#endif // __cplusplus + +#endif // BOOST_MATH_TR1_HPP + diff --git a/libcxx/src/third-party/boost/math/tr1_c_macros.ipp b/libcxx/src/third-party/boost/math/tr1_c_macros.ipp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math/tr1_c_macros.ipp @@ -0,0 +1,810 @@ +// Copyright John Maddock 2008-11. +// 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_C_MACROS_IPP +#define BOOST_MATH_C_MACROS_IPP + +// C99 Functions: +#ifdef acosh +#undef acosh +#endif +#define acosh boost_acosh +#ifdef acoshf +#undef acoshf +#endif +#define acoshf boost_acoshf +#ifdef acoshl +#undef acoshl +#endif +#define acoshl boost_acoshl + +#ifdef asinh +#undef asinh +#endif +#define asinh boost_asinh +#ifdef asinhf +#undef asinhf +#endif +#define asinhf boost_asinhf +#ifdef asinhl +#undef asinhl +#endif +#define asinhl boost_asinhl + +#ifdef atanh +#undef atanh +#endif +#define atanh boost_atanh +#ifdef atanhf +#undef atanhf +#endif +#define atanhf boost_atanhf +#ifdef atanhl +#undef atanhl +#endif +#define atanhl boost_atanhl + +#ifdef cbrt +#undef cbrt +#endif +#define cbrt boost_cbrt +#ifdef cbrtf +#undef cbrtf +#endif +#define cbrtf boost_cbrtf +#ifdef cbrtl +#undef cbrtl +#endif +#define cbrtl boost_cbrtl + +#ifdef copysign +#undef copysign +#endif +#define copysign boost_copysign +#ifdef copysignf +#undef copysignf +#endif +#define copysignf boost_copysignf +#ifdef copysignl +#undef copysignl +#endif +#define copysignl boost_copysignl + +#ifdef erf +#undef erf +#endif +#define erf boost_erf +#ifdef erff +#undef erff +#endif +#define erff boost_erff +#ifdef erfl +#undef erfl +#endif +#define erfl boost_erfl + +#ifdef erfc +#undef erfc +#endif +#define erfc boost_erfc +#ifdef erfcf +#undef erfcf +#endif +#define erfcf boost_erfcf +#ifdef erfcl +#undef erfcl +#endif +#define erfcl boost_erfcl + +#if 0 +#ifdef exp2 +#undef exp2 +#endif +#define exp2 boost_exp2 +#ifdef exp2f +#undef exp2f +#endif +#define exp2f boost_exp2f +#ifdef exp2l +#undef exp2l +#endif +#define exp2l boost_exp2l +#endif + +#ifdef expm1 +#undef expm1 +#endif +#define expm1 boost_expm1 +#ifdef expm1f +#undef expm1f +#endif +#define expm1f boost_expm1f +#ifdef expm1l +#undef expm1l +#endif +#define expm1l boost_expm1l + +#if 0 +#ifdef fdim +#undef fdim +#endif +#define fdim boost_fdim +#ifdef fdimf +#undef fdimf +#endif +#define fdimf boost_fdimf +#ifdef fdiml +#undef fdiml +#endif +#define fdiml boost_fdiml +#ifdef acosh +#undef acosh +#endif +#define fma boost_fma +#ifdef fmaf +#undef fmaf +#endif +#define fmaf boost_fmaf +#ifdef fmal +#undef fmal +#endif +#define fmal boost_fmal +#endif + +#ifdef fmax +#undef fmax +#endif +#define fmax boost_fmax +#ifdef fmaxf +#undef fmaxf +#endif +#define fmaxf boost_fmaxf +#ifdef fmaxl +#undef fmaxl +#endif +#define fmaxl boost_fmaxl + +#ifdef fmin +#undef fmin +#endif +#define fmin boost_fmin +#ifdef fminf +#undef fminf +#endif +#define fminf boost_fminf +#ifdef fminl +#undef fminl +#endif +#define fminl boost_fminl + +#ifdef hypot +#undef hypot +#endif +#define hypot boost_hypot +#ifdef hypotf +#undef hypotf +#endif +#define hypotf boost_hypotf +#ifdef hypotl +#undef hypotl +#endif +#define hypotl boost_hypotl + +#if 0 +#ifdef ilogb +#undef ilogb +#endif +#define ilogb boost_ilogb +#ifdef ilogbf +#undef ilogbf +#endif +#define ilogbf boost_ilogbf +#ifdef ilogbl +#undef ilogbl +#endif +#define ilogbl boost_ilogbl +#endif + +#ifdef lgamma +#undef lgamma +#endif +#define lgamma boost_lgamma +#ifdef lgammaf +#undef lgammaf +#endif +#define lgammaf boost_lgammaf +#ifdef lgammal +#undef lgammal +#endif +#define lgammal boost_lgammal + +#ifdef BOOST_HAS_LONG_LONG +#if 0 +#ifdef llrint +#undef llrint +#endif +#define llrint boost_llrint +#ifdef llrintf +#undef llrintf +#endif +#define llrintf boost_llrintf +#ifdef llrintl +#undef llrintl +#endif +#define llrintl boost_llrintl +#endif +#ifdef llround +#undef llround +#endif +#define llround boost_llround +#ifdef llroundf +#undef llroundf +#endif +#define llroundf boost_llroundf +#ifdef llroundl +#undef llroundl +#endif +#define llroundl boost_llroundl +#endif + +#ifdef log1p +#undef log1p +#endif +#define log1p boost_log1p +#ifdef log1pf +#undef log1pf +#endif +#define log1pf boost_log1pf +#ifdef log1pl +#undef log1pl +#endif +#define log1pl boost_log1pl + +#if 0 +#ifdef log2 +#undef log2 +#endif +#define log2 boost_log2 +#ifdef log2f +#undef log2f +#endif +#define log2f boost_log2f +#ifdef log2l +#undef log2l +#endif +#define log2l boost_log2l + +#ifdef logb +#undef logb +#endif +#define logb boost_logb +#ifdef logbf +#undef logbf +#endif +#define logbf boost_logbf +#ifdef logbl +#undef logbl +#endif +#define logbl boost_logbl + +#ifdef lrint +#undef lrint +#endif +#define lrint boost_lrint +#ifdef lrintf +#undef lrintf +#endif +#define lrintf boost_lrintf +#ifdef lrintl +#undef lrintl +#endif +#define lrintl boost_lrintl +#endif + +#ifdef lround +#undef lround +#endif +#define lround boost_lround +#ifdef lroundf +#undef lroundf +#endif +#define lroundf boost_lroundf +#ifdef lroundl +#undef lroundl +#endif +#define lroundl boost_lroundl + +#if 0 +#ifdef nan +#undef nan +#endif +#define nan boost_nan +#ifdef nanf +#undef nanf +#endif +#define nanf boost_nanf +#ifdef nanl +#undef nanl +#endif +#define nanl boost_nanl + +#ifdef nearbyint +#undef nearbyint +#endif +#define nearbyint boost_nearbyint +#ifdef nearbyintf +#undef nearbyintf +#endif +#define nearbyintf boost_nearbyintf +#ifdef nearbyintl +#undef nearbyintl +#endif +#define nearbyintl boost_nearbyintl +#endif + +#ifdef nextafter +#undef nextafter +#endif +#define nextafter boost_nextafter +#ifdef nextafterf +#undef nextafterf +#endif +#define nextafterf boost_nextafterf +#ifdef nextafterl +#undef nextafterl +#endif +#define nextafterl boost_nextafterl + +#ifdef nexttoward +#undef nexttoward +#endif +#define nexttoward boost_nexttoward +#ifdef nexttowardf +#undef nexttowardf +#endif +#define nexttowardf boost_nexttowardf +#ifdef nexttowardl +#undef nexttowardl +#endif +#define nexttowardl boost_nexttowardl + +#if 0 +#ifdef remainder +#undef remainder +#endif +#define remainder boost_remainder +#ifdef remainderf +#undef remainderf +#endif +#define remainderf boost_remainderf +#ifdef remainderl +#undef remainderl +#endif +#define remainderl boost_remainderl + +#ifdef remquo +#undef remquo +#endif +#define remquo boost_remquo +#ifdef remquof +#undef remquof +#endif +#define remquof boost_remquof +#ifdef remquol +#undef remquol +#endif +#define remquol boost_remquol + +#ifdef rint +#undef rint +#endif +#define rint boost_rint +#ifdef rintf +#undef rintf +#endif +#define rintf boost_rintf +#ifdef rintl +#undef rintl +#endif +#define rintl boost_rintl +#endif + +#ifdef round +#undef round +#endif +#define round boost_round +#ifdef roundf +#undef roundf +#endif +#define roundf boost_roundf +#ifdef roundl +#undef roundl +#endif +#define roundl boost_roundl + +#if 0 +#ifdef scalbln +#undef scalbln +#endif +#define scalbln boost_scalbln +#ifdef scalblnf +#undef scalblnf +#endif +#define scalblnf boost_scalblnf +#ifdef scalblnl +#undef scalblnl +#endif +#define scalblnl boost_scalblnl + +#ifdef scalbn +#undef scalbn +#endif +#define scalbn boost_scalbn +#ifdef scalbnf +#undef scalbnf +#endif +#define scalbnf boost_scalbnf +#ifdef scalbnl +#undef scalbnl +#endif +#define scalbnl boost_scalbnl +#endif + +#ifdef tgamma +#undef tgamma +#endif +#define tgamma boost_tgamma +#ifdef tgammaf +#undef tgammaf +#endif +#define tgammaf boost_tgammaf +#ifdef tgammal +#undef tgammal +#endif +#define tgammal boost_tgammal + +#ifdef trunc +#undef trunc +#endif +#define trunc boost_trunc +#ifdef truncf +#undef truncf +#endif +#define truncf boost_truncf +#ifdef truncl +#undef truncl +#endif +#define truncl boost_truncl + +// [5.2.1.1] associated Laguerre polynomials: +#ifdef assoc_laguerre +#undef assoc_laguerre +#endif +#define assoc_laguerre boost_assoc_laguerre +#ifdef assoc_laguerref +#undef assoc_laguerref +#endif +#define assoc_laguerref boost_assoc_laguerref +#ifdef assoc_laguerrel +#undef assoc_laguerrel +#endif +#define assoc_laguerrel boost_assoc_laguerrel + +// [5.2.1.2] associated Legendre functions: +#ifdef assoc_legendre +#undef assoc_legendre +#endif +#define assoc_legendre boost_assoc_legendre +#ifdef assoc_legendref +#undef assoc_legendref +#endif +#define assoc_legendref boost_assoc_legendref +#ifdef assoc_legendrel +#undef assoc_legendrel +#endif +#define assoc_legendrel boost_assoc_legendrel + +// [5.2.1.3] beta function: +#ifdef beta +#undef beta +#endif +#define beta boost_beta +#ifdef betaf +#undef betaf +#endif +#define betaf boost_betaf +#ifdef betal +#undef betal +#endif +#define betal boost_betal + +// [5.2.1.4] (complete) elliptic integral of the first kind: +#ifdef comp_ellint_1 +#undef comp_ellint_1 +#endif +#define comp_ellint_1 boost_comp_ellint_1 +#ifdef comp_ellint_1f +#undef comp_ellint_1f +#endif +#define comp_ellint_1f boost_comp_ellint_1f +#ifdef comp_ellint_1l +#undef comp_ellint_1l +#endif +#define comp_ellint_1l boost_comp_ellint_1l + +// [5.2.1.5] (complete) elliptic integral of the second kind: +#ifdef comp_ellint_2 +#undef comp_ellint_2 +#endif +#define comp_ellint_2 boost_comp_ellint_2 +#ifdef comp_ellint_2f +#undef comp_ellint_2f +#endif +#define comp_ellint_2f boost_comp_ellint_2f +#ifdef comp_ellint_2l +#undef comp_ellint_2l +#endif +#define comp_ellint_2l boost_comp_ellint_2l + +// [5.2.1.6] (complete) elliptic integral of the third kind: +#ifdef comp_ellint_3 +#undef comp_ellint_3 +#endif +#define comp_ellint_3 boost_comp_ellint_3 +#ifdef comp_ellint_3f +#undef comp_ellint_3f +#endif +#define comp_ellint_3f boost_comp_ellint_3f +#ifdef comp_ellint_3l +#undef comp_ellint_3l +#endif +#define comp_ellint_3l boost_comp_ellint_3l + +#if 0 +// [5.2.1.7] confluent hypergeometric functions: +#ifdef conf_hyper +#undef conf_hyper +#endif +#define conf_hyper boost_conf_hyper +#ifdef conf_hyperf +#undef conf_hyperf +#endif +#define conf_hyperf boost_conf_hyperf +#ifdef conf_hyperl +#undef conf_hyperl +#endif +#define conf_hyperl boost_conf_hyperl +#endif + +// [5.2.1.8] regular modified cylindrical Bessel functions: +#ifdef cyl_bessel_i +#undef cyl_bessel_i +#endif +#define cyl_bessel_i boost_cyl_bessel_i +#ifdef cyl_bessel_if +#undef cyl_bessel_if +#endif +#define cyl_bessel_if boost_cyl_bessel_if +#ifdef cyl_bessel_il +#undef cyl_bessel_il +#endif +#define cyl_bessel_il boost_cyl_bessel_il + +// [5.2.1.9] cylindrical Bessel functions (of the first kind): +#ifdef cyl_bessel_j +#undef cyl_bessel_j +#endif +#define cyl_bessel_j boost_cyl_bessel_j +#ifdef cyl_bessel_jf +#undef cyl_bessel_jf +#endif +#define cyl_bessel_jf boost_cyl_bessel_jf +#ifdef cyl_bessel_jl +#undef cyl_bessel_jl +#endif +#define cyl_bessel_jl boost_cyl_bessel_jl + +// [5.2.1.10] irregular modified cylindrical Bessel functions: +#ifdef cyl_bessel_k +#undef cyl_bessel_k +#endif +#define cyl_bessel_k boost_cyl_bessel_k +#ifdef cyl_bessel_kf +#undef cyl_bessel_kf +#endif +#define cyl_bessel_kf boost_cyl_bessel_kf +#ifdef cyl_bessel_kl +#undef cyl_bessel_kl +#endif +#define cyl_bessel_kl boost_cyl_bessel_kl + +// [5.2.1.11] cylindrical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// cylindrical Bessel functions (of the second kind): +#ifdef cyl_neumann +#undef cyl_neumann +#endif +#define cyl_neumann boost_cyl_neumann +#ifdef cyl_neumannf +#undef cyl_neumannf +#endif +#define cyl_neumannf boost_cyl_neumannf +#ifdef cyl_neumannl +#undef cyl_neumannl +#endif +#define cyl_neumannl boost_cyl_neumannl + +// [5.2.1.12] (incomplete) elliptic integral of the first kind: +#ifdef ellint_1 +#undef ellint_1 +#endif +#define ellint_1 boost_ellint_1 +#ifdef ellint_1f +#undef ellint_1f +#endif +#define ellint_1f boost_ellint_1f +#ifdef ellint_1l +#undef ellint_1l +#endif +#define ellint_1l boost_ellint_1l + +// [5.2.1.13] (incomplete) elliptic integral of the second kind: +#ifdef ellint_2 +#undef ellint_2 +#endif +#define ellint_2 boost_ellint_2 +#ifdef ellint_2f +#undef ellint_2f +#endif +#define ellint_2f boost_ellint_2f +#ifdef ellint_2l +#undef ellint_2l +#endif +#define ellint_2l boost_ellint_2l + +// [5.2.1.14] (incomplete) elliptic integral of the third kind: +#ifdef ellint_3 +#undef ellint_3 +#endif +#define ellint_3 boost_ellint_3 +#ifdef ellint_3f +#undef ellint_3f +#endif +#define ellint_3f boost_ellint_3f +#ifdef ellint_3l +#undef ellint_3l +#endif +#define ellint_3l boost_ellint_3l + +// [5.2.1.15] exponential integral: +#ifdef expint +#undef expint +#endif +#define expint boost_expint +#ifdef expintf +#undef expintf +#endif +#define expintf boost_expintf +#ifdef expintl +#undef expintl +#endif +#define expintl boost_expintl + +// [5.2.1.16] Hermite polynomials: +#ifdef hermite +#undef hermite +#endif +#define hermite boost_hermite +#ifdef hermitef +#undef hermitef +#endif +#define hermitef boost_hermitef +#ifdef hermitel +#undef hermitel +#endif +#define hermitel boost_hermitel + +#if 0 +// [5.2.1.17] hypergeometric functions: +#ifdef hyperg +#undef hyperg +#endif +#define hyperg boost_hyperg +#ifdef hypergf +#undef hypergf +#endif +#define hypergf boost_hypergf +#ifdef hypergl +#undef hypergl +#endif +#define hypergl boost_hypergl +#endif + +// [5.2.1.18] Laguerre polynomials: +#ifdef laguerre +#undef laguerre +#endif +#define laguerre boost_laguerre +#ifdef laguerref +#undef laguerref +#endif +#define laguerref boost_laguerref +#ifdef laguerrel +#undef laguerrel +#endif +#define laguerrel boost_laguerrel + +// [5.2.1.19] Legendre polynomials: +#ifdef legendre +#undef legendre +#endif +#define legendre boost_legendre +#ifdef legendref +#undef legendref +#endif +#define legendref boost_legendref +#ifdef legendrel +#undef legendrel +#endif +#define legendrel boost_legendrel + +// [5.2.1.20] Riemann zeta function: +#ifdef riemann_zeta +#undef riemann_zeta +#endif +#define riemann_zeta boost_riemann_zeta +#ifdef riemann_zetaf +#undef riemann_zetaf +#endif +#define riemann_zetaf boost_riemann_zetaf +#ifdef riemann_zetal +#undef riemann_zetal +#endif +#define riemann_zetal boost_riemann_zetal + +// [5.2.1.21] spherical Bessel functions (of the first kind): +#ifdef sph_bessel +#undef sph_bessel +#endif +#define sph_bessel boost_sph_bessel +#ifdef sph_besself +#undef sph_besself +#endif +#define sph_besself boost_sph_besself +#ifdef sph_bessell +#undef sph_bessell +#endif +#define sph_bessell boost_sph_bessell + +// [5.2.1.22] spherical associated Legendre functions: +#ifdef sph_legendre +#undef sph_legendre +#endif +#define sph_legendre boost_sph_legendre +#ifdef sph_legendref +#undef sph_legendref +#endif +#define sph_legendref boost_sph_legendref +#ifdef sph_legendrel +#undef sph_legendrel +#endif +#define sph_legendrel boost_sph_legendrel + +// [5.2.1.23] spherical Neumann functions BOOST_MATH_C99_THROW_SPEC; +// spherical Bessel functions (of the second kind): +#ifdef sph_neumann +#undef sph_neumann +#endif +#define sph_neumann boost_sph_neumann +#ifdef sph_neumannf +#undef sph_neumannf +#endif +#define sph_neumannf boost_sph_neumannf +#ifdef sph_neumannl +#undef sph_neumannl +#endif +#define sph_neumannl boost_sph_neumannl + +#endif // BOOST_MATH_C_MACROS_IPP diff --git a/libcxx/src/third-party/boost/math_fwd.hpp b/libcxx/src/third-party/boost/math_fwd.hpp new file mode 100644 --- /dev/null +++ b/libcxx/src/third-party/boost/math_fwd.hpp @@ -0,0 +1,42 @@ +// Boost math_fwd.hpp header file ------------------------------------------// + +// (C) Copyright Hubert Holin and Daryle Walker 2001-2002. Distributed under 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) + +// See http://www.boost.org/libs/math for documentation. + +#ifndef BOOST_MATH_FWD_HPP +#define BOOST_MATH_FWD_HPP + +namespace boost +{ +namespace math +{ + + +// From ----------------------------------------// + +template < typename T > + class quaternion; + +// Also has many function templates (including operators) + + +// From ------------------------------------------// + +template < typename T > + class octonion; + +template < > + class octonion< float >; +template < > + class octonion< double >; +template < > + class octonion< long double >; + +} // namespace math +} // namespace boost + + +#endif // BOOST_MATH_FWD_HPP diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/assoc_laguerre.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/assoc_laguerre.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/assoc_laguerre.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.99), std::assoc_laguerre(0, 0, T(0.)), T(1.01))); + assert(between(0.99f, std::assoc_laguerref(0, 0, T(0.)), 1.01f)); + assert(between(0.99l, std::assoc_laguerrel(0, 0, T(0.)), 1.01l)); + + assert(between(T(0.99), std::assoc_laguerre(1, 1, T(1.)), T(1.01))); + assert(between(0.99f, std::assoc_laguerref(1, 1, T(1.)), 1.01f)); + assert(between(0.99l, std::assoc_laguerrel(1, 1, T(1.)), 1.01l)); + + assert(between(T(-0.01), std::assoc_laguerre(2, 2, T(2.)), T(0.01))); + assert(between(-0.01f, std::assoc_laguerref(2, 2, T(2.)), 0.01f)); + assert(between(-0.01l, std::assoc_laguerrel(2, 2, T(2.)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::assoc_laguerre(0, 0, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.99, std::assoc_laguerre(0, 0, T(0.)), 1.01)); + assert(between(0.99f, std::assoc_laguerref(0, 0, T(0.)), 1.01f)); + assert(between(0.99l, std::assoc_laguerrel(0, 0, T(0.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/assoc_legendre.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/assoc_legendre.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/assoc_legendre.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.99), std::assoc_legendre(0, 0, T(0.)), T(1.01))); + assert(between(0.99f, std::assoc_legendref(0, 0, T(0.)), 1.01f)); + assert(between(0.99l, std::assoc_legendrel(0, 0, T(0.)), 1.01l)); + + assert(between(T(-0.01), std::assoc_legendre(1, 1, T(1.)), T(0.01))); + assert(between(-0.01f, std::assoc_legendref(1, 1, T(1.)), 0.01f)); + assert(between(-0.01l, std::assoc_legendrel(1, 1, T(1.)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::assoc_legendre(0, 0, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.99, std::assoc_legendre(0, 0, T(0.)), 1.01)); + assert(between(0.99f, std::assoc_legendref(0, 0, T(0.)), 1.01f)); + assert(between(0.99l, std::assoc_legendrel(0, 0, T(0.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/beta.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/beta.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/beta.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(std::isnan(std::beta(T(0.), T(0.)))); + assert(std::isnan(std::betaf(T(0.), T(0.)))); + assert(std::isnan(std::betal(T(0.), T(0.)))); + + assert(between(T(0.99), std::beta(T(1.), T(1.)), T(1.01))); + assert(between(0.99f, std::betaf(T(1.), T(1.)), 1.01f)); + assert(between(0.99l, std::betal(T(1.), T(1.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::beta(0., std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::beta(std::numeric_limits::quiet_NaN(), 0.); }); + check_no_domain_error([] { + (void)std::beta(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(std::isnan(std::beta(T(0.), T(0.)))); + assert(std::isnan(std::betaf(T(0.), T(0.)))); + assert(std::isnan(std::betal(T(0.), T(0.)))); + + assert(between(0.99, std::beta(T(1.), T(1.)), 1.01)); + assert(between(0.99f, std::betaf(T(1.), T(1.)), 1.01f)); + assert(between(0.99l, std::betal(T(1.), T(1.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/common.h b/libcxx/test/std/numerics/c.math/sf.cmath/common.h new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/common.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef TEST_SF_CMATH_COMMON_H +#define TEST_SF_CMATH_COMMON_H + +#include +#include +#include + +template +bool between(std::type_identity_t lower, T value, std::type_identity_t upper) { + return lower < value && value < upper; +} + +template +void check_no_domain_error(Func f) { +#if math_errhandling & MATH_ERRNO + errno = EACCES; +#endif +#if math_errhandling & MATH_ERREXCEPT + std::feclearexcept(FE_INVALID); +#endif + f(); +#if math_errhandling & MATH_ERRNO + assert(errno == EACCES); +#endif +#if math_errhandling & MATH_ERREXCEPT + assert(!std::fetestexcept(FE_INVALID)); +#endif +} + +template +void check_domain_error(Func f) { +#if math_errhandling & MATH_ERRNO + errno = EACCES; +#endif +#if math_errhandling & MATH_ERREXCEPT + std::feclearexcept(FE_INVALID); +#endif + f(); +#if math_errhandling & MATH_ERRNO + assert(errno == EDOM); +#endif +#if math_errhandling & MATH_ERREXCEPT + assert(std::fetestexcept(FE_INVALID)); +#endif +} + +#endif // TEST_SF_CMATH_COMMON_H diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_1.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_1.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_1.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.56), std::comp_ellint_1(T(0.)), T(1.58))); + assert(between(1.56f, std::comp_ellint_1f(T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_1l(T(0.)), 1.58l)); + + assert(between(T(1.99), std::comp_ellint_1(T(0.8)), T(2.01))); + assert(between(1.99f, std::comp_ellint_1f(T(0.8)), 2.01f)); + assert(between(1.99l, std::comp_ellint_1l(T(0.8)), 2.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::comp_ellint_1(std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.56, std::comp_ellint_1(T(0.)), 1.58)); + assert(between(1.56f, std::comp_ellint_1f(T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_1l(T(0.)), 1.58l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_2.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_2.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_2.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.56), std::comp_ellint_2(T(0.)), T(1.58))); + assert(between(1.56f, std::comp_ellint_2f(T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_2l(T(0.)), 1.58l)); + + assert(between(T(1.27), std::comp_ellint_2(T(0.8)), T(1.29))); + assert(between(1.27f, std::comp_ellint_2f(T(0.8)), 1.29f)); + assert(between(1.27l, std::comp_ellint_2l(T(0.8)), 1.29l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::comp_ellint_2(std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.56, std::comp_ellint_2(T(0.)), 1.58)); + assert(between(1.56f, std::comp_ellint_2f(T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_2l(T(0.)), 1.58l)); + + assert(between(0.99, std::comp_ellint_2(T(1.)), 1.01)); + assert(between(0.99f, std::comp_ellint_2f(T(1.)), 1.01f)); + assert(between(0.99l, std::comp_ellint_2l(T(1.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_3.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_3.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/comp_ellint_3.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.56), std::comp_ellint_3(T(0.), T(0.)), T(1.58))); + assert(between(1.56f, std::comp_ellint_3f(T(0.), T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_3l(T(0.), T(0.)), 1.58l)); + + assert(between(T(1.34), std::comp_ellint_3(T(0.8), T(-1.)), T(1.36))); + assert(between(1.34f, std::comp_ellint_3f(T(0.8), T(-1.)), 1.36f)); + assert(between(1.34l, std::comp_ellint_3l(T(0.8), T(-1.)), 1.36l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::comp_ellint_3(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::comp_ellint_3(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::comp_ellint_3(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.56, std::comp_ellint_3(T(0.), T(0.)), 1.58)); + assert(between(1.56f, std::comp_ellint_3f(T(0.), T(0.)), 1.58f)); + assert(between(1.56l, std::comp_ellint_3l(T(0.), T(0.)), 1.58l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_i.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_i.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_i.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.99), std::cyl_bessel_i(T(0.), T(0.)), T(1.01))); + assert(between(0.99f, std::cyl_bessel_if(T(0.), T(0.)), 1.01f)); + assert(between(0.99l, std::cyl_bessel_il(T(0.), T(0.)), 1.01l)); + + assert(between(T(0.55), std::cyl_bessel_i(T(1.), T(1.)), T(0.57))); + assert(between(0.55f, std::cyl_bessel_if(T(1.), T(1.)), 0.57f)); + assert(between(0.55l, std::cyl_bessel_il(T(1.), T(1.)), 0.57l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::cyl_bessel_i(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::cyl_bessel_i(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::cyl_bessel_i(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.99, std::cyl_bessel_i(T(0.), T(0.)), 1.01)); + assert(between(0.99f, std::cyl_bessel_if(T(0.), T(0.)), 1.01f)); + assert(between(0.99l, std::cyl_bessel_il(T(0.), T(0.)), 1.01l)); + + assert(between(0.55, std::cyl_bessel_i(T(1.), T(1.)), 0.57)); + assert(between(0.55f, std::cyl_bessel_if(T(1.), T(1.)), 0.57f)); + assert(between(0.55l, std::cyl_bessel_il(T(1.), T(1.)), 0.57l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_j.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_j.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_j.pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.99), std::cyl_bessel_j(T(0.), T(0.)), T(1.01))); + assert(between(0.99f, std::cyl_bessel_jf(T(0.), T(0.)), 1.01f)); + assert(between(0.99l, std::cyl_bessel_jl(T(0.), T(0.)), 1.01l)); + + assert(between(T(0.44), std::cyl_bessel_j(T(1.), T(1.)), T(0.46))); + assert(between(0.44f, std::cyl_bessel_jf(T(1.), T(1.)), 0.46f)); + assert(between(0.44l, std::cyl_bessel_jl(T(1.), T(1.)), 0.46l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::cyl_bessel_j(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::cyl_bessel_j(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::cyl_bessel_j(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.99, std::cyl_bessel_j(T(0.), T(0.)), 1.01)); + assert(between(0.99f, std::cyl_bessel_jf(T(0.), T(0.)), 1.01f)); + assert(between(0.99l, std::cyl_bessel_jl(T(0.), T(0.)), 1.01l)); + + assert(between(0.44, std::cyl_bessel_j(T(1.), T(1.)), 0.46)); + assert(between(0.44f, std::cyl_bessel_jf(T(1.), T(1.)), 0.46f)); + assert(between(0.44l, std::cyl_bessel_jl(T(1.), T(1.)), 0.46l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_k.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_k.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_bessel_k.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.60), std::cyl_bessel_k(T(1.), T(1.)), T(0.62))); + assert(between(0.60f, std::cyl_bessel_kf(T(1.), T(1.)), 0.62f)); + assert(between(0.60l, std::cyl_bessel_kl(T(1.), T(1.)), 0.62l)); + + assert(between(T(1.07), std::cyl_bessel_k(T(0.5), T(0.5)), T(1.09))); + assert(between(1.07f, std::cyl_bessel_kf(T(0.5), T(0.5)), 1.09f)); + assert(between(1.07l, std::cyl_bessel_kl(T(0.5), T(0.5)), 1.09l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::cyl_bessel_k(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::cyl_bessel_k(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::cyl_bessel_k(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + check_domain_error([] { (void)std::cyl_bessel_k(T(0.), T(0.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.60, std::cyl_bessel_k(T(1.), T(1.)), 0.62)); + assert(between(0.60f, std::cyl_bessel_kf(T(1.), T(1.)), 0.62f)); + assert(between(0.60l, std::cyl_bessel_kl(T(1.), T(1.)), 0.62l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/cyl_neumann.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_neumann.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/cyl_neumann.pass.cpp @@ -0,0 +1,61 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(-0.79), std::cyl_neumann(T(1.), T(1.)), T(-0.77))); + assert(between(-0.79f, std::cyl_neumannf(T(1.), T(1.)), -0.77f)); + assert(between(-0.79l, std::cyl_neumannl(T(1.), T(1.)), -0.77l)); + + assert(between(T(-0.63), std::cyl_neumann(T(2.0), T(2.0)), T(-0.61))); + assert(between(-0.63f, std::cyl_neumannf(T(2.0), T(2.0)), -0.61f)); + assert(between(-0.63l, std::cyl_neumannl(T(2.0), T(2.0)), -0.61l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::cyl_neumann(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::cyl_neumann(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::cyl_neumann(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + check_domain_error([] { (void)std::cyl_neumann(T(0.), T(0.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-0.79, std::cyl_neumann(T(1.), T(1.)), -0.77)); + assert(between(-0.79f, std::cyl_neumannf(T(1.), T(1.)), -0.77f)); + assert(between(-0.79l, std::cyl_neumannl(T(1.), T(1.)), -0.77l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/ellint_1.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_1.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_1.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.21), std::ellint_1(T(1.), T(1.)), T(1.23))); + assert(between(1.21f, std::ellint_1f(T(1.), T(1.)), 1.23f)); + assert(between(1.21l, std::ellint_1l(T(1.), T(1.)), 1.23l)); + + assert(between(T(-0.01), std::ellint_1(T(0.0), T(0.0)), T(0.01))); + assert(between(-0.01f, std::ellint_1f(T(0.0), T(0.0)), 0.01f)); + assert(between(-0.01l, std::ellint_1l(T(0.0), T(0.0)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::ellint_1(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::ellint_1(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::ellint_1(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + check_domain_error([] { (void)std::ellint_1(T(2.), T(2.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.21, std::ellint_1(T(1.), T(1.)), 1.23)); + assert(between(1.21f, std::ellint_1f(T(1.), T(1.)), 1.23f)); + assert(between(1.21l, std::ellint_1l(T(1.), T(1.)), 1.23l)); + + assert(between(-0.01, std::ellint_1(T(0.0), T(0.0)), 0.01)); + assert(between(-0.01f, std::ellint_1f(T(0.0), T(0.0)), 0.01f)); + assert(between(-0.01l, std::ellint_1l(T(0.0), T(0.0)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/ellint_2.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_2.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_2.pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.83), std::ellint_2(T(1.), T(1.)), T(0.85))); + assert(between(0.83f, std::ellint_2f(T(1.), T(1.)), 0.85f)); + assert(between(0.83l, std::ellint_2l(T(1.), T(1.)), 0.85l)); + + assert(between(T(-0.01), std::ellint_2(T(0.0), T(0.0)), T(0.01))); + assert(between(-0.01f, std::ellint_2f(T(0.0), T(0.0)), 0.01f)); + assert(between(-0.01l, std::ellint_2l(T(0.0), T(0.0)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::ellint_2(T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { (void)std::ellint_2(std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { + (void)std::ellint_2(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + check_domain_error([] { (void)std::ellint_2(T(2.), T(2.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.83, std::ellint_2(T(1.), T(1.)), 0.85)); + assert(between(0.83f, std::ellint_2f(T(1.), T(1.)), 0.85f)); + assert(between(0.83l, std::ellint_2l(T(1.), T(1.)), 0.85l)); + + assert(between(-0.01, std::ellint_2(T(0.0), T(0.0)), 0.01)); + assert(between(-0.01f, std::ellint_2f(T(0.0), T(0.0)), 0.01f)); + assert(between(-0.01l, std::ellint_2l(T(0.0), T(0.0)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/ellint_3.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_3.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/ellint_3.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.52), std::ellint_3(T(0.5), T(0.5), T(0.5)), T(0.54))); + assert(between(0.52f, std::ellint_3f(T(0.5), T(0.5), T(0.5)), 0.54f)); + assert(between(0.52l, std::ellint_3l(T(0.5), T(0.5), T(0.5)), 0.54l)); + + assert(between(T(-0.01), std::ellint_3(T(0.0), T(0.0), T(0.0)), T(0.01))); + assert(between(-0.01f, std::ellint_3f(T(0.0), T(0.0), T(0.0)), 0.01f)); + assert(between(-0.01l, std::ellint_3l(T(0.0), T(0.0), T(0.0)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::ellint_3(std::numeric_limits::quiet_NaN(), T(0.), T(0.)); }); + check_no_domain_error([] { (void)std::ellint_3(T(0.), std::numeric_limits::quiet_NaN(), T(0.)); }); + check_no_domain_error([] { (void)std::ellint_3(T(0.), T(0.), std::numeric_limits::quiet_NaN()); }); + check_no_domain_error([] { + (void)std::ellint_3(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN(), T(0.)); + }); + check_no_domain_error([] { + (void)std::ellint_3(std::numeric_limits::quiet_NaN(), T(0.), std::numeric_limits::quiet_NaN()); + }); + check_no_domain_error([] { + (void)std::ellint_3(T(0.), std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + }); + check_no_domain_error([] { + (void)std::ellint_3(std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN(), + std::numeric_limits::quiet_NaN()); + }); + check_domain_error([] { (void)std::ellint_3(T(1.), T(1.), T(1.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-0.01, std::ellint_3(T(0.), T(0.), T(0.)), 0.01)); + assert(between(-0.01f, std::ellint_3f(T(0.), T(0.), T(0.)), 0.01f)); + assert(between(-0.01l, std::ellint_3l(T(0.), T(0.), T(0.)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/expint.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/expint.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/expint.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.88), std::expint(T(1.)), T(1.90))); + assert(between(1.88f, std::expintf(T(1.)), 1.90f)); + assert(between(1.88l, std::expintl(T(1.)), 1.90l)); + + assert(between(T(0.45), std::expint(T(0.5)), T(0.47))); + assert(between(0.45f, std::expintf(T(0.5)), 0.47f)); + assert(between(0.45l, std::expintl(T(0.5)), 0.47l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::expint(std::numeric_limits::quiet_NaN()); }); + check_domain_error([] { (void)std::expint(T(0.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.88, std::expint(T(1.)), 1.90)); + assert(between(1.88f, std::expintf(T(1.)), 1.90f)); + assert(between(1.88l, std::expintl(T(1.)), 1.90l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/hermite.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/hermite.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/hermite.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(1.99), std::hermite(1, T(1.)), T(2.01))); + assert(between(1.99f, std::hermitef(1, T(1.)), 2.01f)); + assert(between(1.99l, std::hermitel(1, T(1.)), 2.01l)); + + assert(between(T(0.99), std::hermite(1, T(0.5)), T(1.01))); + assert(between(0.99f, std::hermitef(1, T(0.5)), 1.01f)); + assert(between(0.99l, std::hermitel(1, T(0.5)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::hermite(1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(1.99, std::hermite(1, T(1.)), 2.01)); + assert(between(1.99f, std::hermitef(1, T(1.)), 2.01f)); + assert(between(1.99l, std::hermitel(1, T(1.)), 2.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/laguerre.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/laguerre.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/laguerre.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(-0.01), std::laguerre(1, T(1.)), T(0.01))); + assert(between(-0.01f, std::laguerref(1, T(1.)), 0.01f)); + assert(between(-0.01l, std::laguerrel(1, T(1.)), 0.01l)); + + assert(between(T(0.49), std::laguerre(1, T(0.5)), T(0.51))); + assert(between(0.49f, std::laguerref(1, T(0.5)), 0.51f)); + assert(between(0.49l, std::laguerrel(1, T(0.5)), 0.51l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::laguerre(1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-0.01, std::laguerre(1, T(1.)), 0.01)); + assert(between(-0.01f, std::laguerref(1, T(1.)), 0.01f)); + assert(between(-0.01l, std::laguerrel(1, T(1.)), 0.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/legendre.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/legendre.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/legendre.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.99), std::legendre(1, T(1.)), T(1.01))); + assert(between(0.99f, std::legendref(1, T(1.)), 1.01f)); + assert(between(0.99l, std::legendrel(1, T(1.)), 1.01l)); + + assert(between(T(0.49), std::legendre(1, T(0.5)), T(0.51))); + assert(between(0.49f, std::legendref(1, T(0.5)), 0.51f)); + assert(between(0.49l, std::legendrel(1, T(0.5)), 0.51l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::legendre(1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.99, std::legendre(1, T(1.)), 1.01)); + assert(between(0.99f, std::legendref(1, T(1.)), 1.01f)); + assert(between(0.99l, std::legendrel(1, T(1.)), 1.01l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/riemann_zeta.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/riemann_zeta.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/riemann_zeta.pass.cpp @@ -0,0 +1,57 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(-1.47), std::riemann_zeta(T(0.5)), T(-1.45))); + assert(between(-1.47f, std::riemann_zetaf(T(0.5)), -1.45f)); + assert(between(-1.47l, std::riemann_zetal(T(0.5)), -1.45l)); + + assert(between(T(-0.51), std::riemann_zeta(T(0.)), T(-0.49))); + assert(between(-0.51f, std::riemann_zetaf(T(0.)), -0.49f)); + assert(between(-0.51l, std::riemann_zetal(T(0.)), -0.49l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::riemann_zeta(std::numeric_limits::quiet_NaN()); }); + check_domain_error([] { (void)std::riemann_zeta(T(1.)); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-0.51, std::riemann_zeta(T(0.)), -0.49)); + assert(between(-0.51f, std::riemann_zetaf(T(0.)), -0.49f)); + assert(between(-0.51l, std::riemann_zetal(T(0.)), -0.49l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/sph_bessel.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/sph_bessel.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/sph_bessel.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(0.29), std::sph_bessel(1, T(1.)), T(0.31))); + assert(between(0.29f, std::sph_besself(1, T(1.)), 0.31f)); + assert(between(0.29l, std::sph_bessell(1, T(1.)), 0.31l)); + + assert(between(T(0.15), std::sph_bessel(1, T(0.5)), T(0.17))); + assert(between(0.15f, std::sph_besself(1, T(0.5)), 0.17f)); + assert(between(0.15l, std::sph_bessell(1, T(0.5)), 0.17l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::sph_bessel(1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(0.29, std::sph_bessel(1, T(1.)), 1.31)); + assert(between(0.29f, std::sph_besself(1, T(1.)), 1.31f)); + assert(between(0.29l, std::sph_bessell(1, T(1.)), 1.31l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/sph_legendre.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/sph_legendre.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/sph_legendre.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(-0.30), std::sph_legendre(1, 1, T(1.)), T(-0.28))); + assert(between(-0.30f, std::sph_legendref(1, 1, T(1.)), -0.28f)); + assert(between(-0.30l, std::sph_legendrel(1, 1, T(1.)), -0.28l)); + + assert(between(T(-0.17), std::sph_legendre(1, 1, T(0.5)), T(-0.15))); + assert(between(-0.17f, std::sph_legendref(1, 1, T(0.5)), -0.15f)); + assert(between(-0.17l, std::sph_legendrel(1, 1, T(0.5)), -0.15l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::sph_legendre(1, 1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-0.30, std::sph_legendre(1, 1, T(1.)), -0.28)); + assert(between(-0.30f, std::sph_legendref(1, 1, T(1.)), -0.28f)); + assert(between(-0.30l, std::sph_legendrel(1, 1, T(1.)), -0.28l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/std/numerics/c.math/sf.cmath/sph_neumann.pass.cpp b/libcxx/test/std/numerics/c.math/sf.cmath/sph_neumann.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/numerics/c.math/sf.cmath/sph_neumann.pass.cpp @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +#include +#include +#include +#include + +#include "common.h" +#include "type_algorithms.h" + +struct TestFloatingPoint { + template + void operator()() { + assert(between(T(-1.39), std::sph_neumann(1, T(1.)), T(-1.37))); + assert(between(-1.39f, std::sph_neumannf(1, T(1.)), -1.37f)); + assert(between(-1.39l, std::sph_neumannl(1, T(1.)), -1.37l)); + + assert(between(T(-4.47), std::sph_neumann(1, T(0.5)), T(4.45))); + assert(between(-4.47f, std::sph_neumannf(1, T(0.5)), 4.45f)); + assert(between(-4.47l, std::sph_neumannl(1, T(0.5)), 4.45l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + + check_no_domain_error([] { (void)std::sph_neumann(1, std::numeric_limits::quiet_NaN()); }); + } +}; + +struct TestIntegral { + template + void operator()() { + assert(between(-1.39, std::sph_neumann(1, T(1.)), -1.37)); + assert(between(-1.39f, std::sph_neumannf(1, T(1.)), -1.37f)); + assert(between(-1.39l, std::sph_neumannl(1, T(1.)), -1.37l)); + + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } +}; + +int main(int, char**) { + meta::for_each(meta::floating_point_types{}, TestFloatingPoint{}); + meta::for_each(meta::integral_types{}, TestIntegral{}); + + return 0; +} diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt --- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt +++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL) set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC) -find_package(Clang 16) +find_package(Clang 17) set(SOURCES abi_tag_on_virtual.cpp