bessel_k1.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. // Copyright (c) 2006 Xiaogang Zhang
  2. // Copyright (c) 2017 John Maddock
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_MATH_BESSEL_K1_HPP
  7. #define BOOST_MATH_BESSEL_K1_HPP
  8. #ifdef _MSC_VER
  9. #pragma once
  10. #pragma warning(push)
  11. #pragma warning(disable:4702) // Unreachable code (release mode only warning)
  12. #endif
  13. #include <boost/math/tools/config.hpp>
  14. #include <boost/math/tools/type_traits.hpp>
  15. #include <boost/math/tools/numeric_limits.hpp>
  16. #include <boost/math/tools/precision.hpp>
  17. #include <boost/math/tools/rational.hpp>
  18. #include <boost/math/tools/big_constant.hpp>
  19. #include <boost/math/policies/error_handling.hpp>
  20. #include <boost/math/tools/assert.hpp>
  21. #if defined(__GNUC__) && defined(BOOST_MATH_USE_FLOAT128)
  22. //
  23. // This is the only way we can avoid
  24. // warning: non-standard suffix on floating constant [-Wpedantic]
  25. // when building with -Wall -pedantic. Neither __extension__
  26. // nor #pragma diagnostic ignored work :(
  27. //
  28. #pragma GCC system_header
  29. #endif
  30. // Modified Bessel function of the second kind of order zero
  31. // minimax rational approximations on intervals, see
  32. // Russon and Blair, Chalk River Report AECL-3461, 1969,
  33. // as revised by Pavel Holoborodko in "Rational Approximations
  34. // for the Modified Bessel Function of the Second Kind - K0(x)
  35. // for Computations with Double Precision", see
  36. // http://www.advanpix.com/2016/01/05/rational-approximations-for-the-modified-bessel-function-of-the-second-kind-k1-for-computations-with-double-precision/
  37. //
  38. // The actual coefficients used are our own derivation (by JM)
  39. // since we extend to both greater and lesser precision than the
  40. // references above. We can also improve performance WRT to
  41. // Holoborodko without loss of precision.
  42. namespace boost { namespace math { namespace detail{
  43. template <typename T, int N>
  44. BOOST_MATH_GPU_ENABLED inline T bessel_k1_imp(const T&, const boost::math::integral_constant<int, N>&)
  45. {
  46. BOOST_MATH_ASSERT(0);
  47. return 0;
  48. }
  49. template <typename T>
  50. BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant<int, 24>&)
  51. {
  52. BOOST_MATH_STD_USING
  53. if(x <= 1)
  54. {
  55. // Maximum Deviation Found: 3.090e-12
  56. // Expected Error Term : -3.053e-12
  57. // Maximum Relative Change in Control Points : 4.927e-02
  58. // Max Error found at float precision = Poly : 7.918347e-10
  59. BOOST_MATH_STATIC const T Y = 8.695471287e-02f;
  60. BOOST_MATH_STATIC const T P[] =
  61. {
  62. -3.621379531e-03f,
  63. 7.131781976e-03f,
  64. -1.535278300e-05f
  65. };
  66. BOOST_MATH_STATIC const T Q[] =
  67. {
  68. 1.000000000e+00f,
  69. -5.173102701e-02f,
  70. 9.203530671e-04f
  71. };
  72. T a = x * x / 4;
  73. a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2;
  74. // Maximum Deviation Found: 3.556e-08
  75. // Expected Error Term : -3.541e-08
  76. // Maximum Relative Change in Control Points : 8.203e-02
  77. BOOST_MATH_STATIC const T P2[] =
  78. {
  79. -3.079657469e-01f,
  80. -8.537108913e-02f,
  81. -4.640275408e-03f,
  82. -1.156442414e-04f
  83. };
  84. return tools::evaluate_polynomial(P2, T(x * x)) * x + 1 / x + log(x) * a;
  85. }
  86. else
  87. {
  88. // Maximum Deviation Found: 3.369e-08
  89. // Expected Error Term : -3.227e-08
  90. // Maximum Relative Change in Control Points : 9.917e-02
  91. // Max Error found at float precision = Poly : 6.084411e-08
  92. BOOST_MATH_STATIC const T Y = 1.450342178f;
  93. BOOST_MATH_STATIC const T P[] =
  94. {
  95. -1.970280088e-01f,
  96. 2.188747807e-02f,
  97. 7.270394756e-01f,
  98. 2.490678196e-01f
  99. };
  100. BOOST_MATH_STATIC const T Q[] =
  101. {
  102. 1.000000000e+00f,
  103. 2.274292882e+00f,
  104. 9.904984851e-01f,
  105. 4.585534549e-02f
  106. };
  107. if(x < tools::log_max_value<T>())
  108. return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
  109. else
  110. {
  111. T ex = exp(-x / 2);
  112. return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
  113. }
  114. }
  115. }
  116. template <typename T>
  117. BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant<int, 53>&)
  118. {
  119. BOOST_MATH_STD_USING
  120. if(x <= 1)
  121. {
  122. // Maximum Deviation Found: 1.922e-17
  123. // Expected Error Term : 1.921e-17
  124. // Maximum Relative Change in Control Points : 5.287e-03
  125. // Max Error found at double precision = Poly : 2.004747e-17
  126. BOOST_MATH_STATIC const T Y = 8.69547128677368164e-02f;
  127. BOOST_MATH_STATIC const T P[] =
  128. {
  129. -3.62137953440350228e-03,
  130. 7.11842087490330300e-03,
  131. 1.00302560256614306e-05,
  132. 1.77231085381040811e-06
  133. };
  134. BOOST_MATH_STATIC const T Q[] =
  135. {
  136. 1.00000000000000000e+00,
  137. -4.80414794429043831e-02,
  138. 9.85972641934416525e-04,
  139. -8.91196859397070326e-06
  140. };
  141. T a = x * x / 4;
  142. a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2;
  143. // Maximum Deviation Found: 4.053e-17
  144. // Expected Error Term : -4.053e-17
  145. // Maximum Relative Change in Control Points : 3.103e-04
  146. // Max Error found at double precision = Poly : 1.246698e-16
  147. BOOST_MATH_STATIC const T P2[] =
  148. {
  149. -3.07965757829206184e-01,
  150. -7.80929703673074907e-02,
  151. -2.70619343754051620e-03,
  152. -2.49549522229072008e-05
  153. };
  154. BOOST_MATH_STATIC const T Q2[] =
  155. {
  156. 1.00000000000000000e+00,
  157. -2.36316836412163098e-02,
  158. 2.64524577525962719e-04,
  159. -1.49749618004162787e-06
  160. };
  161. return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a;
  162. }
  163. else
  164. {
  165. // Maximum Deviation Found: 8.883e-17
  166. // Expected Error Term : -1.641e-17
  167. // Maximum Relative Change in Control Points : 2.786e-01
  168. // Max Error found at double precision = Poly : 1.258798e-16
  169. BOOST_MATH_STATIC const T Y = 1.45034217834472656f;
  170. BOOST_MATH_STATIC const T P[] =
  171. {
  172. -1.97028041029226295e-01,
  173. -2.32408961548087617e+00,
  174. -7.98269784507699938e+00,
  175. -2.39968410774221632e+00,
  176. 3.28314043780858713e+01,
  177. 5.67713761158496058e+01,
  178. 3.30907788466509823e+01,
  179. 6.62582288933739787e+00,
  180. 3.08851840645286691e-01
  181. };
  182. BOOST_MATH_STATIC const T Q[] =
  183. {
  184. 1.00000000000000000e+00,
  185. 1.41811409298826118e+01,
  186. 7.35979466317556420e+01,
  187. 1.77821793937080859e+02,
  188. 2.11014501598705982e+02,
  189. 1.19425262951064454e+02,
  190. 2.88448064302447607e+01,
  191. 2.27912927104139732e+00,
  192. 2.50358186953478678e-02
  193. };
  194. if(x < tools::log_max_value<T>())
  195. return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
  196. else
  197. {
  198. T ex = exp(-x / 2);
  199. return ((tools::evaluate_rational(P, Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
  200. }
  201. }
  202. }
  203. template <typename T>
  204. BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant<int, 64>&)
  205. {
  206. BOOST_MATH_STD_USING
  207. if(x <= 1)
  208. {
  209. // Maximum Deviation Found: 5.549e-23
  210. // Expected Error Term : -5.548e-23
  211. // Maximum Relative Change in Control Points : 2.002e-03
  212. // Max Error found at float80 precision = Poly : 9.352785e-22
  213. BOOST_MATH_STATIC const T Y = 8.695471286773681640625e-02f;
  214. BOOST_MATH_STATIC const T P[] =
  215. {
  216. BOOST_MATH_BIG_CONSTANT(T, 64, -3.621379534403483072861e-03),
  217. BOOST_MATH_BIG_CONSTANT(T, 64, 7.102135866103952705932e-03),
  218. BOOST_MATH_BIG_CONSTANT(T, 64, 4.167545240236717601167e-05),
  219. BOOST_MATH_BIG_CONSTANT(T, 64, 2.537484002571894870830e-06),
  220. BOOST_MATH_BIG_CONSTANT(T, 64, 6.603228256820000135990e-09)
  221. };
  222. BOOST_MATH_STATIC const T Q[] =
  223. {
  224. BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
  225. BOOST_MATH_BIG_CONSTANT(T, 64, -4.354457194045068370363e-02),
  226. BOOST_MATH_BIG_CONSTANT(T, 64, 8.709137201220209072820e-04),
  227. BOOST_MATH_BIG_CONSTANT(T, 64, -9.676151796359590545143e-06),
  228. BOOST_MATH_BIG_CONSTANT(T, 64, 5.162715192766245311659e-08)
  229. };
  230. T a = x * x / 4;
  231. a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2;
  232. // Maximum Deviation Found: 1.995e-23
  233. // Expected Error Term : 1.995e-23
  234. // Maximum Relative Change in Control Points : 8.174e-04
  235. // Max Error found at float80 precision = Poly : 4.137325e-20
  236. BOOST_MATH_STATIC const T P2[] =
  237. {
  238. BOOST_MATH_BIG_CONSTANT(T, 64, -3.079657578292062244054e-01),
  239. BOOST_MATH_BIG_CONSTANT(T, 64, -7.963049154965966503231e-02),
  240. BOOST_MATH_BIG_CONSTANT(T, 64, -3.103277523735639924895e-03),
  241. BOOST_MATH_BIG_CONSTANT(T, 64, -4.023052834702215699504e-05),
  242. BOOST_MATH_BIG_CONSTANT(T, 64, -1.719459155018493821839e-07)
  243. };
  244. BOOST_MATH_STATIC const T Q2[] =
  245. {
  246. BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
  247. BOOST_MATH_BIG_CONSTANT(T, 64, -1.863917670410152669768e-02),
  248. BOOST_MATH_BIG_CONSTANT(T, 64, 1.699367098849735298090e-04),
  249. BOOST_MATH_BIG_CONSTANT(T, 64, -9.309358790546076298429e-07),
  250. BOOST_MATH_BIG_CONSTANT(T, 64, 2.708893480271612711933e-09)
  251. };
  252. return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a;
  253. }
  254. else
  255. {
  256. // Maximum Deviation Found: 9.785e-20
  257. // Expected Error Term : -3.302e-21
  258. // Maximum Relative Change in Control Points : 3.432e-01
  259. // Max Error found at float80 precision = Poly : 1.083755e-19
  260. BOOST_MATH_STATIC const T Y = 1.450342178344726562500e+00f;
  261. BOOST_MATH_STATIC const T P[] =
  262. {
  263. BOOST_MATH_BIG_CONSTANT(T, 64, -1.970280410292263112917e-01),
  264. BOOST_MATH_BIG_CONSTANT(T, 64, -4.058564803062959169322e+00),
  265. BOOST_MATH_BIG_CONSTANT(T, 64, -3.036658174194917777473e+01),
  266. BOOST_MATH_BIG_CONSTANT(T, 64, -9.576825392332820142173e+01),
  267. BOOST_MATH_BIG_CONSTANT(T, 64, -6.706969489248020941949e+01),
  268. BOOST_MATH_BIG_CONSTANT(T, 64, 3.264572499406168221382e+02),
  269. BOOST_MATH_BIG_CONSTANT(T, 64, 8.584972047303151034100e+02),
  270. BOOST_MATH_BIG_CONSTANT(T, 64, 8.422082733280017909550e+02),
  271. BOOST_MATH_BIG_CONSTANT(T, 64, 3.738005441471368178383e+02),
  272. BOOST_MATH_BIG_CONSTANT(T, 64, 7.016938390144121276609e+01),
  273. BOOST_MATH_BIG_CONSTANT(T, 64, 4.319614662598089438939e+00),
  274. BOOST_MATH_BIG_CONSTANT(T, 64, 3.710715864316521856193e-02)
  275. };
  276. BOOST_MATH_STATIC const T Q[] =
  277. {
  278. BOOST_MATH_BIG_CONSTANT(T, 64, 1.000000000000000000000e+00),
  279. BOOST_MATH_BIG_CONSTANT(T, 64, 2.298433045824439052398e+01),
  280. BOOST_MATH_BIG_CONSTANT(T, 64, 2.082047745067709230037e+02),
  281. BOOST_MATH_BIG_CONSTANT(T, 64, 9.662367854250262046592e+02),
  282. BOOST_MATH_BIG_CONSTANT(T, 64, 2.504148628460454004686e+03),
  283. BOOST_MATH_BIG_CONSTANT(T, 64, 3.712730364911389908905e+03),
  284. BOOST_MATH_BIG_CONSTANT(T, 64, 3.108002081150068641112e+03),
  285. BOOST_MATH_BIG_CONSTANT(T, 64, 1.400149940532448553143e+03),
  286. BOOST_MATH_BIG_CONSTANT(T, 64, 3.083303048095846226299e+02),
  287. BOOST_MATH_BIG_CONSTANT(T, 64, 2.748706060530351833346e+01),
  288. BOOST_MATH_BIG_CONSTANT(T, 64, 6.321900849331506946977e-01),
  289. };
  290. if(x < tools::log_max_value<T>())
  291. return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
  292. else
  293. {
  294. T ex = exp(-x / 2);
  295. return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
  296. }
  297. }
  298. }
  299. template <typename T>
  300. BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant<int, 113>&)
  301. {
  302. BOOST_MATH_STD_USING
  303. if(x <= 1)
  304. {
  305. // Maximum Deviation Found: 7.120e-35
  306. // Expected Error Term : -7.119e-35
  307. // Maximum Relative Change in Control Points : 1.207e-03
  308. // Max Error found at float128 precision = Poly : 7.143688e-35
  309. BOOST_MATH_STATIC const T Y = 8.695471286773681640625000000000000000e-02f;
  310. BOOST_MATH_STATIC const T P[] =
  311. {
  312. BOOST_MATH_BIG_CONSTANT(T, 113, -3.621379534403483072916666666666595475e-03),
  313. BOOST_MATH_BIG_CONSTANT(T, 113, 7.074117676930975433219826471336547627e-03),
  314. BOOST_MATH_BIG_CONSTANT(T, 113, 9.631337631362776369069668419033041661e-05),
  315. BOOST_MATH_BIG_CONSTANT(T, 113, 3.468935967870048731821071646104412775e-06),
  316. BOOST_MATH_BIG_CONSTANT(T, 113, 2.956705020559599861444492614737168261e-08),
  317. BOOST_MATH_BIG_CONSTANT(T, 113, 2.347140307321161346703214099534250263e-10),
  318. BOOST_MATH_BIG_CONSTANT(T, 113, 5.569608494081482873946791086435679661e-13)
  319. };
  320. BOOST_MATH_STATIC const T Q[] =
  321. {
  322. BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
  323. BOOST_MATH_BIG_CONSTANT(T, 113, -3.580768910152105375615558920428350204e-02),
  324. BOOST_MATH_BIG_CONSTANT(T, 113, 6.197467671701485365363068445534557369e-04),
  325. BOOST_MATH_BIG_CONSTANT(T, 113, -6.707466533308630411966030561446666237e-06),
  326. BOOST_MATH_BIG_CONSTANT(T, 113, 4.846687802282250112624373388491123527e-08),
  327. BOOST_MATH_BIG_CONSTANT(T, 113, -2.248493131151981569517383040323900343e-10),
  328. BOOST_MATH_BIG_CONSTANT(T, 113, 5.319279786372775264555728921709381080e-13)
  329. };
  330. T a = x * x / 4;
  331. a = ((tools::evaluate_rational(P, Q, a) + Y) * a * a + a / 2 + 1) * x / 2;
  332. // Maximum Deviation Found: 4.473e-37
  333. // Expected Error Term : 4.473e-37
  334. // Maximum Relative Change in Control Points : 8.550e-04
  335. // Max Error found at float128 precision = Poly : 8.167701e-35
  336. BOOST_MATH_STATIC const T P2[] =
  337. {
  338. BOOST_MATH_BIG_CONSTANT(T, 113, -3.079657578292062244053600156878870690e-01),
  339. BOOST_MATH_BIG_CONSTANT(T, 113, -8.133183745732467770755578848987414875e-02),
  340. BOOST_MATH_BIG_CONSTANT(T, 113, -3.548968792764174773125420229299431951e-03),
  341. BOOST_MATH_BIG_CONSTANT(T, 113, -5.886125468718182876076972186152445490e-05),
  342. BOOST_MATH_BIG_CONSTANT(T, 113, -4.506712111733707245745396404449639865e-07),
  343. BOOST_MATH_BIG_CONSTANT(T, 113, -1.632502325880313239698965376754406011e-09),
  344. BOOST_MATH_BIG_CONSTANT(T, 113, -2.311973065898784812266544485665624227e-12)
  345. };
  346. BOOST_MATH_STATIC const T Q2[] =
  347. {
  348. BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
  349. BOOST_MATH_BIG_CONSTANT(T, 113, -1.311471216733781016657962995723287450e-02),
  350. BOOST_MATH_BIG_CONSTANT(T, 113, 8.571876054797365417068164018709472969e-05),
  351. BOOST_MATH_BIG_CONSTANT(T, 113, -3.630181215268238731442496851497901293e-07),
  352. BOOST_MATH_BIG_CONSTANT(T, 113, 1.070176111227805048604885986867484807e-09),
  353. BOOST_MATH_BIG_CONSTANT(T, 113, -2.129046580769872602793220056461084761e-12),
  354. BOOST_MATH_BIG_CONSTANT(T, 113, 2.294906469421390890762001971790074432e-15)
  355. };
  356. return tools::evaluate_rational(P2, Q2, T(x * x)) * x + 1 / x + log(x) * a;
  357. }
  358. else if(x < 4)
  359. {
  360. // Max error in interpolated form: 5.307e-37
  361. // Max Error found at float128 precision = Poly: 7.087862e-35
  362. BOOST_MATH_STATIC const T Y = 1.5023040771484375f;
  363. BOOST_MATH_STATIC const T P[] =
  364. {
  365. BOOST_MATH_BIG_CONSTANT(T, 113, -2.489899398329369710528254347931380044e-01),
  366. BOOST_MATH_BIG_CONSTANT(T, 113, -6.819080211203854781858815596508456873e+00),
  367. BOOST_MATH_BIG_CONSTANT(T, 113, -7.599915699069767382647695624952723034e+01),
  368. BOOST_MATH_BIG_CONSTANT(T, 113, -4.450211910821295507926582231071300718e+02),
  369. BOOST_MATH_BIG_CONSTANT(T, 113, -1.451374687870925175794150513723956533e+03),
  370. BOOST_MATH_BIG_CONSTANT(T, 113, -2.405805746895098802803503988539098226e+03),
  371. BOOST_MATH_BIG_CONSTANT(T, 113, -5.638808326778389656403861103277220518e+02),
  372. BOOST_MATH_BIG_CONSTANT(T, 113, 5.513958744081268456191778822780865708e+03),
  373. BOOST_MATH_BIG_CONSTANT(T, 113, 1.121301640926540743072258116122834804e+04),
  374. BOOST_MATH_BIG_CONSTANT(T, 113, 1.080094900175649541266613109971296190e+04),
  375. BOOST_MATH_BIG_CONSTANT(T, 113, 5.896531083639613332407534434915552429e+03),
  376. BOOST_MATH_BIG_CONSTANT(T, 113, 1.856602122319645694042555107114028437e+03),
  377. BOOST_MATH_BIG_CONSTANT(T, 113, 3.237121918853145421414003823957537419e+02),
  378. BOOST_MATH_BIG_CONSTANT(T, 113, 2.842072954561323076230238664623893504e+01),
  379. BOOST_MATH_BIG_CONSTANT(T, 113, 1.039705646510167437971862966128055524e+00),
  380. BOOST_MATH_BIG_CONSTANT(T, 113, 1.008418100718254816100425022904039530e-02)
  381. };
  382. BOOST_MATH_STATIC const T Q[] =
  383. {
  384. BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
  385. BOOST_MATH_BIG_CONSTANT(T, 113, 2.927456835239137986889227412815459529e+01),
  386. BOOST_MATH_BIG_CONSTANT(T, 113, 3.598985593265577043711382994516531273e+02),
  387. BOOST_MATH_BIG_CONSTANT(T, 113, 2.449897377085510281395819892689690579e+03),
  388. BOOST_MATH_BIG_CONSTANT(T, 113, 1.025555887684561913263090023158085327e+04),
  389. BOOST_MATH_BIG_CONSTANT(T, 113, 2.774140447181062463181892531100679195e+04),
  390. BOOST_MATH_BIG_CONSTANT(T, 113, 4.962055507843204417243602332246120418e+04),
  391. BOOST_MATH_BIG_CONSTANT(T, 113, 5.908269326976180183216954452196772931e+04),
  392. BOOST_MATH_BIG_CONSTANT(T, 113, 4.655160454422016855911700790722577942e+04),
  393. BOOST_MATH_BIG_CONSTANT(T, 113, 2.383586885019548163464418964577684608e+04),
  394. BOOST_MATH_BIG_CONSTANT(T, 113, 7.679920375586960324298491662159976419e+03),
  395. BOOST_MATH_BIG_CONSTANT(T, 113, 1.478586421028842906987799049804565008e+03),
  396. BOOST_MATH_BIG_CONSTANT(T, 113, 1.565384974896746094224942654383537090e+02),
  397. BOOST_MATH_BIG_CONSTANT(T, 113, 7.902617937084010911005732488607114511e+00),
  398. BOOST_MATH_BIG_CONSTANT(T, 113, 1.429293010387921526110949911029094926e-01),
  399. BOOST_MATH_BIG_CONSTANT(T, 113, 3.880342607911083143560111853491047663e-04)
  400. };
  401. return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
  402. }
  403. else
  404. {
  405. // Maximum Deviation Found: 4.359e-37
  406. // Expected Error Term : -6.565e-40
  407. // Maximum Relative Change in Control Points : 1.880e-01
  408. // Max Error found at float128 precision = Poly : 2.943572e-35
  409. BOOST_MATH_STATIC const T Y = 1.308816909790039062500000000000000000f;
  410. BOOST_MATH_STATIC const T P[] =
  411. {
  412. BOOST_MATH_BIG_CONSTANT(T, 113, -5.550277247453881129211735759447737350e-02),
  413. BOOST_MATH_BIG_CONSTANT(T, 113, -3.485883080219574328217554864956175929e+00),
  414. BOOST_MATH_BIG_CONSTANT(T, 113, -8.903760658131484239300875153154881958e+01),
  415. BOOST_MATH_BIG_CONSTANT(T, 113, -1.144813672213626237418235110712293337e+03),
  416. BOOST_MATH_BIG_CONSTANT(T, 113, -6.498400501156131446691826557494158173e+03),
  417. BOOST_MATH_BIG_CONSTANT(T, 113, 1.573531831870363502604119835922166116e+04),
  418. BOOST_MATH_BIG_CONSTANT(T, 113, 5.417416550054632009958262596048841154e+05),
  419. BOOST_MATH_BIG_CONSTANT(T, 113, 4.271266450613557412825896604269130661e+06),
  420. BOOST_MATH_BIG_CONSTANT(T, 113, 1.898386013314389952534433455681107783e+07),
  421. BOOST_MATH_BIG_CONSTANT(T, 113, 5.353798784656436259250791761023512750e+07),
  422. BOOST_MATH_BIG_CONSTANT(T, 113, 9.839619195427352438957774052763490067e+07),
  423. BOOST_MATH_BIG_CONSTANT(T, 113, 1.169246368651532232388152442538005637e+08),
  424. BOOST_MATH_BIG_CONSTANT(T, 113, 8.696368884166831199967845883371116431e+07),
  425. BOOST_MATH_BIG_CONSTANT(T, 113, 3.810226630422736458064005843327500169e+07),
  426. BOOST_MATH_BIG_CONSTANT(T, 113, 8.854996610560406127438950635716757614e+06),
  427. BOOST_MATH_BIG_CONSTANT(T, 113, 8.981057433937398731355768088809437625e+05),
  428. BOOST_MATH_BIG_CONSTANT(T, 113, 2.519440069856232098711793483639792952e+04)
  429. };
  430. BOOST_MATH_STATIC const T Q[] =
  431. {
  432. BOOST_MATH_BIG_CONSTANT(T, 113, 1.000000000000000000000000000000000000e+00),
  433. BOOST_MATH_BIG_CONSTANT(T, 113, 7.127348248283623146544565916604103560e+01),
  434. BOOST_MATH_BIG_CONSTANT(T, 113, 2.205092684176906740104488180754982065e+03),
  435. BOOST_MATH_BIG_CONSTANT(T, 113, 3.911249195069050636298346469740075758e+04),
  436. BOOST_MATH_BIG_CONSTANT(T, 113, 4.426103406579046249654548481377792614e+05),
  437. BOOST_MATH_BIG_CONSTANT(T, 113, 3.365861555422488771286500241966208541e+06),
  438. BOOST_MATH_BIG_CONSTANT(T, 113, 1.765377714160383676864913709252529840e+07),
  439. BOOST_MATH_BIG_CONSTANT(T, 113, 6.453822726931857253365138260720815246e+07),
  440. BOOST_MATH_BIG_CONSTANT(T, 113, 1.643207885048369990391975749439783892e+08),
  441. BOOST_MATH_BIG_CONSTANT(T, 113, 2.882540678243694621895816336640877878e+08),
  442. BOOST_MATH_BIG_CONSTANT(T, 113, 3.410120808992380266174106812005338148e+08),
  443. BOOST_MATH_BIG_CONSTANT(T, 113, 2.628138016559335882019310900426773027e+08),
  444. BOOST_MATH_BIG_CONSTANT(T, 113, 1.250794693811010646965360198541047961e+08),
  445. BOOST_MATH_BIG_CONSTANT(T, 113, 3.378723408195485594610593014072950078e+07),
  446. BOOST_MATH_BIG_CONSTANT(T, 113, 4.488253856312453816451380319061865560e+06),
  447. BOOST_MATH_BIG_CONSTANT(T, 113, 2.202167197882689873967723350537104582e+05),
  448. BOOST_MATH_BIG_CONSTANT(T, 113, 1.673233230356966539460728211412989843e+03)
  449. };
  450. if(x < tools::log_max_value<T>())
  451. return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * exp(-x) / sqrt(x));
  452. else
  453. {
  454. T ex = exp(-x / 2);
  455. return ((tools::evaluate_polynomial(P, T(1 / x)) / tools::evaluate_polynomial(Q, T(1 / x)) + Y) * ex / sqrt(x)) * ex;
  456. }
  457. }
  458. }
  459. template <typename T>
  460. BOOST_MATH_GPU_ENABLED T bessel_k1_imp(const T& x, const boost::math::integral_constant<int, 0>&)
  461. {
  462. if(boost::math::tools::digits<T>() <= 24)
  463. return bessel_k1_imp(x, boost::math::integral_constant<int, 24>());
  464. else if(boost::math::tools::digits<T>() <= 53)
  465. return bessel_k1_imp(x, boost::math::integral_constant<int, 53>());
  466. else if(boost::math::tools::digits<T>() <= 64)
  467. return bessel_k1_imp(x, boost::math::integral_constant<int, 64>());
  468. else if(boost::math::tools::digits<T>() <= 113)
  469. return bessel_k1_imp(x, boost::math::integral_constant<int, 113>());
  470. BOOST_MATH_ASSERT(0);
  471. return 0;
  472. }
  473. template <typename T>
  474. BOOST_MATH_GPU_ENABLED inline T bessel_k1(const T& x)
  475. {
  476. typedef boost::math::integral_constant<int,
  477. ((boost::math::numeric_limits<T>::digits == 0) || (boost::math::numeric_limits<T>::radix != 2)) ?
  478. 0 :
  479. boost::math::numeric_limits<T>::digits <= 24 ?
  480. 24 :
  481. boost::math::numeric_limits<T>::digits <= 53 ?
  482. 53 :
  483. boost::math::numeric_limits<T>::digits <= 64 ?
  484. 64 :
  485. boost::math::numeric_limits<T>::digits <= 113 ?
  486. 113 : -1
  487. > tag_type;
  488. return bessel_k1_imp(x, tag_type());
  489. }
  490. }}} // namespaces
  491. #ifdef _MSC_VER
  492. #pragma warning(pop)
  493. #endif
  494. #endif // BOOST_MATH_BESSEL_K1_HPP