Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:40:00

0001 //  Copyright (c) 2006 Xiaogang Zhang
0002 //  Copyright (c) 2017 John Maddock
0003 //  Use, modification and distribution are subject to the
0004 //  Boost Software License, Version 1.0. (See accompanying file
0005 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_MATH_BESSEL_K0_HPP
0008 #define BOOST_MATH_BESSEL_K0_HPP
0009 
0010 #ifdef _MSC_VER
0011 #pragma once
0012 #pragma warning(push)
0013 #pragma warning(disable:4702) // Unreachable code (release mode only warning)
0014 #endif
0015 
0016 #include <boost/math/tools/rational.hpp>
0017 #include <boost/math/tools/big_constant.hpp>
0018 #include <boost/math/policies/error_handling.hpp>
0019 #include <boost/math/tools/assert.hpp>
0020 
0021 #if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
0022 //
0023 // This is the only way we can avoid
0024 // warning: non-standard suffix on floating constant [-Wpedantic]
0025 // when building with -Wall -pedantic.  Neither __extension__
0026 // nor #pragma diagnostic ignored work :(
0027 //
0028 #pragma GCC system_header
0029 #endif
0030 
0031 // Modified Bessel function of the second kind of order zero
0032 // minimax rational approximations on intervals, see
0033 // Russon and Blair, Chalk River Report AECL-3461, 1969,
0034 // as revised by Pavel Holoborodko in "Rational Approximations 
0035 // for the Modified Bessel Function of the Second Kind - K0(x) 
0036 // for Computations with Double Precision", see 
0037 // http://www.advanpix.com/2015/11/25/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k0-for-computations-with-double-precision/
0038 //
0039 // The actual coefficients used are our own derivation (by JM)
0040 // since we extend to both greater and lesser precision than the
0041 // references above.  We can also improve performance WRT to
0042 // Holoborodko without loss of precision.
0043 
0044 namespace boost { namespace math { namespace detail{
0045 
0046 template <typename T>
0047 T bessel_k0(const T& x);
0048 
0049 template <class T, class tag>
0050 struct bessel_k0_initializer
0051 {
0052    struct init
0053    {
0054       init()
0055       {
0056          do_init(tag());
0057       }
0058       static void do_init(const std::integral_constant<int, 113>&)
0059       {
0060          bessel_k0(T(0.5));
0061          bessel_k0(T(1.5));
0062       }
0063       static void do_init(const std::integral_constant<int, 64>&)
0064       {
0065          bessel_k0(T(0.5));
0066          bessel_k0(T(1.5));
0067       }
0068       template <class U>
0069       static void do_init(const U&){}
0070       void force_instantiate()const{}
0071    };
0072    static const init initializer;
0073    static void force_instantiate()
0074    {
0075       initializer.force_instantiate();
0076    }
0077 };
0078 
0079 template <class T, class tag>
0080 const typename bessel_k0_initializer<T, tag>::init bessel_k0_initializer<T, tag>::initializer;
0081 
0082 
0083 template <typename T, int N>
0084 T bessel_k0_imp(const T&, const std::integral_constant<int, N>&)
0085 {
0086    BOOST_MATH_ASSERT(0);
0087    return 0;
0088 }
0089 
0090 template <typename T>
0091 T bessel_k0_imp(const T& x, const std::integral_constant<int, 24>&)
0092 {
0093    BOOST_MATH_STD_USING
0094    if(x <= 1)
0095    {
0096       // Maximum Deviation Found : 2.358e-09
0097       // Expected Error Term : -2.358e-09
0098       // Maximum Relative Change in Control Points : 9.552e-02
0099       // Max Error found at float precision = Poly : 4.448220e-08
0100       static const T Y = 1.137250900268554688f;
0101       static const T P[] = 
0102       {
0103          -1.372508979104259711e-01f,
0104          2.622545986273687617e-01f,
0105          5.047103728247919836e-03f
0106       };
0107       static const T Q[] = 
0108       {
0109          1.000000000000000000e+00f,
0110          -8.928694018000029415e-02f,
0111          2.985980684180969241e-03f
0112       };
0113       T a = x * x / 4;
0114       a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1;
0115 
0116       // Maximum Deviation Found:                     1.346e-09
0117       // Expected Error Term : -1.343e-09
0118       // Maximum Relative Change in Control Points : 2.405e-02
0119       // Max Error found at float precision = Poly : 1.354814e-07
0120       static const T P2[] = {
0121          1.159315158e-01f,
0122          2.789828686e-01f,
0123          2.524902861e-02f,
0124          8.457241514e-04f,
0125          1.530051997e-05f
0126       };
0127       return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a;
0128    }
0129    else
0130    {
0131       // Maximum Deviation Found:                     1.587e-08
0132       // Expected Error Term : 1.531e-08
0133       // Maximum Relative Change in Control Points : 9.064e-02
0134       // Max Error found at float precision = Poly : 5.065020e-08
0135 
0136       static const T P[] =
0137       {
0138          2.533141220e-01f,
0139          5.221502603e-01f,
0140          6.380180669e-02f,
0141          -5.934976547e-02f
0142       };
0143       static const T Q[] =
0144       {
0145          1.000000000e+00f,
0146          2.679722431e+00f,
0147          1.561635813e+00f,
0148          1.573660661e-01f
0149       };
0150       if(x < tools::log_max_value<T>())
0151          return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * exp(-x) / sqrt(x));
0152       else
0153       {
0154          T ex = exp(-x / 2);
0155          return ((tools::evaluate_rational(P, Q, T(1 / x)) + 1) * ex / sqrt(x)) * ex;
0156       }
0157    }
0158 }
0159 
0160 template <typename T>
0161 T bessel_k0_imp(const T& x, const std::integral_constant<int, 53>&)
0162 {
0163    BOOST_MATH_STD_USING
0164    if(x <= 1)
0165    {
0166       // Maximum Deviation Found:                     6.077e-17
0167       // Expected Error Term : -6.077e-17
0168       // Maximum Relative Change in Control Points : 7.797e-02
0169       // Max Error found at double precision = Poly : 1.003156e-16
0170       static const T Y = 1.137250900268554688;
0171       static const T P[] =
0172       {
0173          -1.372509002685546267e-01,
0174          2.574916117833312855e-01,
0175          1.395474602146869316e-02,
0176          5.445476986653926759e-04,
0177          7.125159422136622118e-06
0178       };
0179       static const T Q[] =
0180       {
0181          1.000000000000000000e+00,
0182          -5.458333438017788530e-02,
0183          1.291052816975251298e-03,
0184          -1.367653946978586591e-05
0185       };
0186 
0187       T a = x * x / 4;
0188       a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1;
0189 
0190       // Maximum Deviation Found:                     3.429e-18
0191       // Expected Error Term : 3.392e-18
0192       // Maximum Relative Change in Control Points : 2.041e-02
0193       // Max Error found at double precision = Poly : 2.513112e-16
0194       static const T P2[] =
0195       {
0196          1.159315156584124484e-01,
0197          2.789828789146031732e-01,
0198          2.524892993216121934e-02,
0199          8.460350907213637784e-04,
0200          1.491471924309617534e-05,
0201          1.627106892422088488e-07,
0202          1.208266102392756055e-09,
0203          6.611686391749704310e-12
0204       };
0205 
0206       return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a;
0207    }
0208    else
0209    {
0210       // Maximum Deviation Found:                     4.316e-17
0211       // Expected Error Term : 9.570e-18
0212       // Maximum Relative Change in Control Points : 2.757e-01
0213       // Max Error found at double precision = Poly : 1.001560e-16
0214 
0215       static const T Y = 1;
0216       static const T P[] =
0217       {
0218          2.533141373155002416e-01,
0219          3.628342133984595192e+00,
0220          1.868441889406606057e+01,
0221          4.306243981063412784e+01,
0222          4.424116209627428189e+01,
0223          1.562095339356220468e+01,
0224          -1.810138978229410898e+00,
0225          -1.414237994269995877e+00,
0226          -9.369168119754924625e-02
0227       };
0228       static const T Q[] =
0229       {
0230          1.000000000000000000e+00,
0231          1.494194694879908328e+01,
0232          8.265296455388554217e+01,
0233          2.162779506621866970e+02,
0234          2.845145155184222157e+02,
0235          1.851714491916334995e+02,
0236          5.486540717439723515e+01,
0237          6.118075837628957015e+00,
0238          1.586261269326235053e-01
0239       };
0240       if(x < tools::log_max_value<T>())
0241          return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
0242       else
0243       {
0244          T ex = exp(-x / 2);
0245          return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
0246       }
0247    }
0248 }
0249 
0250 template <typename T>
0251 T bessel_k0_imp(const T& x, const std::integral_constant<int, 64>&)
0252 {
0253    BOOST_MATH_STD_USING
0254       if(x <= 1)
0255       {
0256          // Maximum Deviation Found:                     2.180e-22
0257          // Expected Error Term : 2.180e-22
0258          // Maximum Relative Change in Control Points : 2.943e-01
0259          // Max Error found at float80 precision = Poly : 3.923207e-20
0260          static const T Y = 1.137250900268554687500e+00;
0261          static const T P[] =
0262          {
0263             BOOST_MATH_BIG_CONSTANT(T, 64, -1.372509002685546875002e-01),
0264             BOOST_MATH_BIG_CONSTANT(T, 64, 2.566481981037407600436e-01),
0265             BOOST_MATH_BIG_CONSTANT(T, 64, 1.551881122448948854873e-02),
0266             BOOST_MATH_BIG_CONSTANT(T, 64, 6.646112454323276529650e-04),
0267             BOOST_MATH_BIG_CONSTANT(T, 64, 1.213747930378196492543e-05),
0268             BOOST_MATH_BIG_CONSTANT(T, 64, 9.423709328020389560844e-08)
0269          };
0270          static const T Q[] =
0271          {
0272             BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
0273             BOOST_MATH_BIG_CONSTANT(T, 64, -4.843828412587773008342e-02),
0274             BOOST_MATH_BIG_CONSTANT(T, 64, 1.088484822515098936140e-03),
0275             BOOST_MATH_BIG_CONSTANT(T, 64, -1.374724008530702784829e-05),
0276             BOOST_MATH_BIG_CONSTANT(T, 64, 8.452665455952581680339e-08)
0277          };
0278 
0279 
0280          T a = x * x / 4;
0281          a = (tools::evaluate_polynomial(P, a) / tools::evaluate_polynomial(Q, a) + Y) * a + 1;
0282 
0283          // Maximum Deviation Found:                     2.440e-21
0284          // Expected Error Term : -2.434e-21
0285          // Maximum Relative Change in Control Points : 2.459e-02
0286          // Max Error found at float80 precision = Poly : 1.482487e-19
0287          static const T P2[] =
0288          {
0289             BOOST_MATH_BIG_CONSTANT(T, 64, 1.159315156584124488110e-01),
0290             BOOST_MATH_BIG_CONSTANT(T, 64, 2.764832791416047889734e-01),
0291             BOOST_MATH_BIG_CONSTANT(T, 64, 1.926062887220923354112e-02),
0292             BOOST_MATH_BIG_CONSTANT(T, 64, 3.660777862036966089410e-04),
0293             BOOST_MATH_BIG_CONSTANT(T, 64, 2.094942446930673386849e-06)
0294          };
0295          static const T Q2[] =
0296          {
0297             BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
0298             BOOST_MATH_BIG_CONSTANT(T, 64, -2.156100313881251616320e-02),
0299             BOOST_MATH_BIG_CONSTANT(T, 64, 2.315993873344905957033e-04),
0300             BOOST_MATH_BIG_CONSTANT(T, 64, -1.529444499350703363451e-06),
0301             BOOST_MATH_BIG_CONSTANT(T, 64, 5.524988589917857531177e-09)
0302          };
0303          return tools::evaluate_rational(P2, Q2, T(x * x)) - log(x) * a;
0304       }
0305       else
0306       {
0307          // Maximum Deviation Found:                     4.291e-20
0308          // Expected Error Term : 2.236e-21
0309          // Maximum Relative Change in Control Points : 3.021e-01
0310          //Max Error found at float80 precision = Poly : 8.727378e-20
0311          static const T Y = 1;
0312          static const T P[] =
0313          {
0314             BOOST_MATH_BIG_CONSTANT(T, 64, 2.533141373155002512056e-01),
0315             BOOST_MATH_BIG_CONSTANT(T, 64, 5.417942070721928652715e+00),
0316             BOOST_MATH_BIG_CONSTANT(T, 64, 4.477464607463971754433e+01),
0317             BOOST_MATH_BIG_CONSTANT(T, 64, 1.838745728725943889876e+02),
0318             BOOST_MATH_BIG_CONSTANT(T, 64, 4.009736314927811202517e+02),
0319             BOOST_MATH_BIG_CONSTANT(T, 64, 4.557411293123609803452e+02),
0320             BOOST_MATH_BIG_CONSTANT(T, 64, 2.360222564015361268955e+02),
0321             BOOST_MATH_BIG_CONSTANT(T, 64, 2.385435333168505701022e+01),
0322             BOOST_MATH_BIG_CONSTANT(T, 64, -1.750195760942181592050e+01),
0323             BOOST_MATH_BIG_CONSTANT(T, 64, -4.059789241612946683713e+00),
0324             BOOST_MATH_BIG_CONSTANT(T, 64, -1.612783121537333908889e-01)
0325          };
0326          static const T Q[] =
0327          {
0328             BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
0329             BOOST_MATH_BIG_CONSTANT(T, 64, 2.200669254769325861404e+01),
0330             BOOST_MATH_BIG_CONSTANT(T, 64, 1.900177593527144126549e+02),
0331             BOOST_MATH_BIG_CONSTANT(T, 64, 8.361003989965786932682e+02),
0332             BOOST_MATH_BIG_CONSTANT(T, 64, 2.041319870804843395893e+03),
0333             BOOST_MATH_BIG_CONSTANT(T, 64, 2.828491555113790345068e+03),
0334             BOOST_MATH_BIG_CONSTANT(T, 64, 2.190342229261529076624e+03),
0335             BOOST_MATH_BIG_CONSTANT(T, 64, 9.003330795963812219852e+02),
0336             BOOST_MATH_BIG_CONSTANT(T, 64, 1.773371397243777891569e+02),
0337             BOOST_MATH_BIG_CONSTANT(T, 64, 1.368634935531158398439e+01),
0338             BOOST_MATH_BIG_CONSTANT(T, 64, 2.543310879400359967327e-01)
0339          };
0340          if(x < tools::log_max_value<T>())
0341             return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
0342          else
0343          {
0344             T ex = exp(-x / 2);
0345             return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
0346          }
0347       }
0348 }
0349 
0350 template <typename T>
0351 T bessel_k0_imp(const T& x, const std::integral_constant<int, 113>&)
0352 {
0353    BOOST_MATH_STD_USING
0354       if(x <= 1)
0355       {
0356          // Maximum Deviation Found:                     5.682e-37
0357          // Expected Error Term : 5.682e-37
0358          // Maximum Relative Change in Control Points : 6.094e-04
0359          // Max Error found at float128 precision = Poly : 5.338213e-35
0360          static const T Y = 1.137250900268554687500000000000000000e+00f;
0361          static const T P[] =
0362          {
0363             BOOST_MATH_BIG_CONSTANT(T, 113, -1.372509002685546875000000000000000006e-01),
0364             BOOST_MATH_BIG_CONSTANT(T, 113, 2.556212905071072782462974351698081303e-01),
0365             BOOST_MATH_BIG_CONSTANT(T, 113, 1.742459135264203478530904179889103929e-02),
0366             BOOST_MATH_BIG_CONSTANT(T, 113, 8.077860530453688571555479526961318918e-04),
0367             BOOST_MATH_BIG_CONSTANT(T, 113, 1.868173911669241091399374307788635148e-05),
0368             BOOST_MATH_BIG_CONSTANT(T, 113, 2.496405768838992243478709145123306602e-07),
0369             BOOST_MATH_BIG_CONSTANT(T, 113, 1.752489221949580551692915881999762125e-09),
0370             BOOST_MATH_BIG_CONSTANT(T, 113, 5.243010555737173524710512824955368526e-12)
0371          };
0372          static const T Q[] =
0373          {
0374             BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
0375             BOOST_MATH_BIG_CONSTANT(T, 113, -4.095631064064621099785696980653193721e-02),
0376             BOOST_MATH_BIG_CONSTANT(T, 113, 8.313880983725212151967078809725835532e-04),
0377             BOOST_MATH_BIG_CONSTANT(T, 113, -1.095229912293480063501285562382835142e-05),
0378             BOOST_MATH_BIG_CONSTANT(T, 113, 1.022828799511943141130509410251996277e-07),
0379             BOOST_MATH_BIG_CONSTANT(T, 113, -6.860874007419812445494782795829046836e-10),
0380             BOOST_MATH_BIG_CONSTANT(T, 113, 3.107297802344970725756092082686799037e-12),
0381             BOOST_MATH_BIG_CONSTANT(T, 113, -7.460529579244623559164763757787600944e-15)
0382          };
0383          T a = x * x / 4;
0384          a = (tools::evaluate_rational(P, Q, a) + Y) * a + 1;
0385 
0386          // Maximum Deviation Found:                     5.173e-38
0387          // Expected Error Term : 5.105e-38
0388          // Maximum Relative Change in Control Points : 9.734e-03
0389          // Max Error found at float128 precision = Poly : 1.688806e-34
0390          static const T P2[] =
0391          {
0392             BOOST_MATH_BIG_CONSTANT(T, 113, 1.159315156584124488107200313757741370e-01),
0393             BOOST_MATH_BIG_CONSTANT(T, 113, 2.789828789146031122026800078439435369e-01),
0394             BOOST_MATH_BIG_CONSTANT(T, 113, 2.524892993216269451266750049024628432e-02),
0395             BOOST_MATH_BIG_CONSTANT(T, 113, 8.460350907082229957222453839935101823e-04),
0396             BOOST_MATH_BIG_CONSTANT(T, 113, 1.491471929926042875260452849503857976e-05),
0397             BOOST_MATH_BIG_CONSTANT(T, 113, 1.627105610481598430816014719558896866e-07),
0398             BOOST_MATH_BIG_CONSTANT(T, 113, 1.208426165007797264194914898538250281e-09),
0399             BOOST_MATH_BIG_CONSTANT(T, 113, 6.508697838747354949164182457073784117e-12),
0400             BOOST_MATH_BIG_CONSTANT(T, 113, 2.659784680639805301101014383907273109e-14),
0401             BOOST_MATH_BIG_CONSTANT(T, 113, 8.531090131964391104248859415958109654e-17),
0402             BOOST_MATH_BIG_CONSTANT(T, 113, 2.205195117066478034260323124669936314e-19),
0403             BOOST_MATH_BIG_CONSTANT(T, 113, 4.692219280289030165761119775783115426e-22),
0404             BOOST_MATH_BIG_CONSTANT(T, 113, 8.362350161092532344171965861545860747e-25),
0405             BOOST_MATH_BIG_CONSTANT(T, 113, 1.277990623924628999539014980773738258e-27)
0406          };
0407 
0408          return tools::evaluate_polynomial(P2, T(x * x)) - log(x) * a;
0409       }
0410       else
0411       {
0412          // Maximum Deviation Found:                     1.462e-34
0413          // Expected Error Term : 4.917e-40
0414          // Maximum Relative Change in Control Points : 3.385e-01
0415          // Max Error found at float128 precision = Poly : 1.567573e-34
0416          static const T Y = 1;
0417          static const T P[] =
0418          {
0419             BOOST_MATH_BIG_CONSTANT(T, 113, 2.533141373155002512078826424055226265e-01),
0420             BOOST_MATH_BIG_CONSTANT(T, 113, 2.001949740768235770078339977110749204e+01),
0421             BOOST_MATH_BIG_CONSTANT(T, 113, 6.991516715983883248363351472378349986e+02),
0422             BOOST_MATH_BIG_CONSTANT(T, 113, 1.429587951594593159075690819360687720e+04),
0423             BOOST_MATH_BIG_CONSTANT(T, 113, 1.911933815201948768044660065771258450e+05),
0424             BOOST_MATH_BIG_CONSTANT(T, 113, 1.769943016204926614862175317962439875e+06),
0425             BOOST_MATH_BIG_CONSTANT(T, 113, 1.170866154649560750500954150401105606e+07),
0426             BOOST_MATH_BIG_CONSTANT(T, 113, 5.634687099724383996792011977705727661e+07),
0427             BOOST_MATH_BIG_CONSTANT(T, 113, 1.989524036456492581597607246664394014e+08),
0428             BOOST_MATH_BIG_CONSTANT(T, 113, 5.160394785715328062088529400178080360e+08),
0429             BOOST_MATH_BIG_CONSTANT(T, 113, 9.778173054417826368076483100902201433e+08),
0430             BOOST_MATH_BIG_CONSTANT(T, 113, 1.335667778588806892764139643950439733e+09),
0431             BOOST_MATH_BIG_CONSTANT(T, 113, 1.283635100080306980206494425043706838e+09),
0432             BOOST_MATH_BIG_CONSTANT(T, 113, 8.300616188213640626577036321085025855e+08),
0433             BOOST_MATH_BIG_CONSTANT(T, 113, 3.277591957076162984986406540894621482e+08),
0434             BOOST_MATH_BIG_CONSTANT(T, 113, 5.564360536834214058158565361486115932e+07),
0435             BOOST_MATH_BIG_CONSTANT(T, 113, -1.043505161612403359098596828115690596e+07),
0436             BOOST_MATH_BIG_CONSTANT(T, 113, -7.217035248223503605127967970903027314e+06),
0437             BOOST_MATH_BIG_CONSTANT(T, 113, -1.422938158797326748375799596769964430e+06),
0438             BOOST_MATH_BIG_CONSTANT(T, 113, -1.229125746200586805278634786674745210e+05),
0439             BOOST_MATH_BIG_CONSTANT(T, 113, -4.201632288615609937883545928660649813e+03),
0440             BOOST_MATH_BIG_CONSTANT(T, 113, -3.690820607338480548346746717311811406e+01)
0441          };
0442          static const T Q[] =
0443          {
0444             BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
0445             BOOST_MATH_BIG_CONSTANT(T, 113, 7.964877874035741452203497983642653107e+01),
0446             BOOST_MATH_BIG_CONSTANT(T, 113, 2.808929943826193766839360018583294769e+03),
0447             BOOST_MATH_BIG_CONSTANT(T, 113, 5.814524004679994110944366890912384139e+04),
0448             BOOST_MATH_BIG_CONSTANT(T, 113, 7.897794522506725610540209610337355118e+05),
0449             BOOST_MATH_BIG_CONSTANT(T, 113, 7.456339470955813675629523617440433672e+06),
0450             BOOST_MATH_BIG_CONSTANT(T, 113, 5.057818717813969772198911392875127212e+07),
0451             BOOST_MATH_BIG_CONSTANT(T, 113, 2.513821619536852436424913886081133209e+08),
0452             BOOST_MATH_BIG_CONSTANT(T, 113, 9.255938846873380596038513316919990776e+08),
0453             BOOST_MATH_BIG_CONSTANT(T, 113, 2.537077551699028079347581816919572141e+09),
0454             BOOST_MATH_BIG_CONSTANT(T, 113, 5.176769339768120752974843214652367321e+09),
0455             BOOST_MATH_BIG_CONSTANT(T, 113, 7.828722317390455845253191337207432060e+09),
0456             BOOST_MATH_BIG_CONSTANT(T, 113, 8.698864296569996402006511705803675890e+09),
0457             BOOST_MATH_BIG_CONSTANT(T, 113, 7.007803261356636409943826918468544629e+09),
0458             BOOST_MATH_BIG_CONSTANT(T, 113, 4.016564631288740308993071395104715469e+09),
0459             BOOST_MATH_BIG_CONSTANT(T, 113, 1.595893010619754750655947035567624730e+09),
0460             BOOST_MATH_BIG_CONSTANT(T, 113, 4.241241839120481076862742189989406856e+08),
0461             BOOST_MATH_BIG_CONSTANT(T, 113, 7.168778094393076220871007550235840858e+07),
0462             BOOST_MATH_BIG_CONSTANT(T, 113, 7.156200301360388147635052029404211109e+06),
0463             BOOST_MATH_BIG_CONSTANT(T, 113, 3.752130382550379886741949463587008794e+05),
0464             BOOST_MATH_BIG_CONSTANT(T, 113, 8.370574966987293592457152146806662562e+03),
0465             BOOST_MATH_BIG_CONSTANT(T, 113, 4.871254714311063594080644835895740323e+01)
0466          };
0467          if(x < tools::log_max_value<T>())
0468             return  ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
0469          else
0470          {
0471             T ex = exp(-x / 2);
0472             return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
0473          }
0474       }
0475 }
0476 
0477 template <typename T>
0478 T bessel_k0_imp(const T& x, const std::integral_constant<int, 0>&)
0479 {
0480    if(boost::math::tools::digits<T>() <= 24)
0481       return bessel_k0_imp(x, std::integral_constant<int, 24>());
0482    else if(boost::math::tools::digits<T>() <= 53)
0483       return bessel_k0_imp(x, std::integral_constant<int, 53>());
0484    else if(boost::math::tools::digits<T>() <= 64)
0485       return bessel_k0_imp(x, std::integral_constant<int, 64>());
0486    else if(boost::math::tools::digits<T>() <= 113)
0487       return bessel_k0_imp(x, std::integral_constant<int, 113>());
0488    BOOST_MATH_ASSERT(0);
0489    return 0;
0490 }
0491 
0492 template <typename T>
0493 inline T bessel_k0(const T& x)
0494 {
0495    typedef std::integral_constant<int,
0496       ((std::numeric_limits<T>::digits == 0) || (std::numeric_limits<T>::radix != 2)) ?
0497       0 :
0498       std::numeric_limits<T>::digits <= 24 ?
0499       24 :
0500       std::numeric_limits<T>::digits <= 53 ?
0501       53 :
0502       std::numeric_limits<T>::digits <= 64 ?
0503       64 :
0504       std::numeric_limits<T>::digits <= 113 ?
0505       113 : -1
0506    > tag_type;
0507 
0508    bessel_k0_initializer<T, tag_type>::force_instantiate();
0509    return bessel_k0_imp(x, tag_type());
0510 }
0511 
0512 }}} // namespaces
0513 
0514 #ifdef _MSC_VER
0515 #pragma warning(pop)
0516 #endif
0517 
0518 #endif // BOOST_MATH_BESSEL_K0_HPP
0519