bessel_i0.hpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. // Copyright (c) 2006 Xiaogang Zhang
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_BESSEL_I0_HPP
  6. #define BOOST_MATH_BESSEL_I0_HPP
  7. #ifdef _MSC_VER
  8. #pragma once
  9. #endif
  10. #include <boost/math/tools/rational.hpp>
  11. #include <boost/math/tools/big_constant.hpp>
  12. #include <boost/assert.hpp>
  13. // Modified Bessel function of the first kind of order zero
  14. // minimax rational approximations on intervals, see
  15. // Blair and Edwards, Chalk River Report AECL-4928, 1974
  16. namespace boost { namespace math { namespace detail{
  17. template <typename T>
  18. T bessel_i0(T x);
  19. template <class T>
  20. struct bessel_i0_initializer
  21. {
  22. struct init
  23. {
  24. init()
  25. {
  26. do_init();
  27. }
  28. static void do_init()
  29. {
  30. bessel_i0(T(1));
  31. }
  32. void force_instantiate()const{}
  33. };
  34. static const init initializer;
  35. static void force_instantiate()
  36. {
  37. initializer.force_instantiate();
  38. }
  39. };
  40. template <class T>
  41. const typename bessel_i0_initializer<T>::init bessel_i0_initializer<T>::initializer;
  42. template <typename T>
  43. T bessel_i0(T x)
  44. {
  45. bessel_i0_initializer<T>::force_instantiate();
  46. static const T P1[] = {
  47. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2335582639474375249e+15)),
  48. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -5.5050369673018427753e+14)),
  49. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -3.2940087627407749166e+13)),
  50. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -8.4925101247114157499e+11)),
  51. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1912746104985237192e+10)),
  52. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.0313066708737980747e+08)),
  53. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -5.9545626019847898221e+05)),
  54. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.4125195876041896775e+03)),
  55. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -7.0935347449210549190e+00)),
  56. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5453977791786851041e-02)),
  57. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.5172644670688975051e-05)),
  58. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -3.0517226450451067446e-08)),
  59. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.6843448573468483278e-11)),
  60. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.5982226675653184646e-14)),
  61. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -5.2487866627945699800e-18)),
  62. };
  63. static const T Q1[] = {
  64. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2335582639474375245e+15)),
  65. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 7.8858692566751002988e+12)),
  66. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.2207067397808979846e+10)),
  67. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0377081058062166144e+07)),
  68. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -4.8527560179962773045e+03)),
  69. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)),
  70. };
  71. static const T P2[] = {
  72. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.2210262233306573296e-04)),
  73. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3067392038106924055e-02)),
  74. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -4.4700805721174453923e-01)),
  75. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 5.5674518371240761397e+00)),
  76. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -2.3517945679239481621e+01)),
  77. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 3.1611322818701131207e+01)),
  78. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -9.6090021968656180000e+00)),
  79. };
  80. static const T Q2[] = {
  81. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -5.5194330231005480228e-04)),
  82. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 3.2547697594819615062e-02)),
  83. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -1.1151759188741312645e+00)),
  84. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.3982595353892851542e+01)),
  85. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -6.0228002066743340583e+01)),
  86. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 8.5539563258012929600e+01)),
  87. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, -3.1446690275135491500e+01)),
  88. static_cast<T>(BOOST_MATH_BIG_CONSTANT(T, 64, 1.0)),
  89. };
  90. T value, factor, r;
  91. BOOST_MATH_STD_USING
  92. using namespace boost::math::tools;
  93. if (x < 0)
  94. {
  95. x = -x; // even function
  96. }
  97. if (x == 0)
  98. {
  99. return static_cast<T>(1);
  100. }
  101. if (x <= 15) // x in (0, 15]
  102. {
  103. T y = x * x;
  104. value = evaluate_polynomial(P1, y) / evaluate_polynomial(Q1, y);
  105. }
  106. else // x in (15, \infty)
  107. {
  108. T y = 1 / x - T(1) / 15;
  109. r = evaluate_polynomial(P2, y) / evaluate_polynomial(Q2, y);
  110. factor = exp(x) / sqrt(x);
  111. value = factor * r;
  112. }
  113. return value;
  114. }
  115. }}} // namespaces
  116. #endif // BOOST_MATH_BESSEL_I0_HPP