hypergeometric_pade.hpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2014 Anton Bikineev
  3. // Copyright 2014 Christopher Kormanyos
  4. // Copyright 2014 John Maddock
  5. // Copyright 2014 Paul Bristow
  6. // Distributed under the Boost
  7. // Software License, Version 1.0. (See accompanying file
  8. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_MATH_HYPERGEOMETRIC_PADE_HPP
  11. #define BOOST_MATH_HYPERGEOMETRIC_PADE_HPP
  12. namespace boost{ namespace math{ namespace detail{
  13. // Luke: C ---------- SUBROUTINE R1F1P(CP, Z, A, B, N) ----------
  14. // Luke: C ----- PADE APPROXIMATION OF 1F1( 1 ; CP ; -Z ) -------
  15. template <class T, class Policy>
  16. inline T hypergeometric_1F1_pade(const T& cp, const T& zp, const Policy& )
  17. {
  18. BOOST_MATH_STD_USING
  19. static const T one = T(1);
  20. // Luke: C ------------- INITIALIZATION -------------
  21. const T z = -zp;
  22. const T zz = z * z;
  23. T b0 = one;
  24. T a0 = one;
  25. T xi1 = one;
  26. T ct1 = cp + one;
  27. T cp1 = cp - one;
  28. T b1 = one + (z / ct1);
  29. T a1 = b1 - (z / cp);
  30. const unsigned max_iterations = boost::math::policies::get_max_series_iterations<Policy>();
  31. T b2 = T(0), a2 = T(0);
  32. T result = T(0), prev_result;
  33. for (unsigned k = 1; k < max_iterations; ++k)
  34. {
  35. // Luke: C ----- CALCULATION OF THE MULTIPLIERS -----
  36. // Luke: C ----------- FOR THE RECURSION ------------
  37. const T ct2 = ct1 * ct1;
  38. const T g1 = one + ((cp1 / (ct2 + ct1 + ct1)) * z);
  39. const T g2 = ((xi1 / (ct2 - one)) * ((xi1 + cp1) / ct2)) * zz;
  40. // Luke: C ------- THE RECURRENCE RELATIONS ---------
  41. // Luke: C ------------ ARE AS FOLLOWS --------------
  42. b2 = (g1 * b1) + (g2 * b0);
  43. a2 = (g1 * a1) + (g2 * a0);
  44. prev_result = result;
  45. result = a2 / b2;
  46. // condition for interruption
  47. if ((fabs(result) * boost::math::tools::epsilon<T>()) > fabs(result - prev_result))
  48. break;
  49. b0 = b1; b1 = b2;
  50. a0 = a1; a1 = a2;
  51. ct1 += 2;
  52. xi1 += 1;
  53. }
  54. return a2 / b2;
  55. }
  56. // Luke: C -------- SUBROUTINE R2F1P(BP, CP, Z, A, B, N) --------
  57. // Luke: C ---- PADE APPROXIMATION OF 2F1( 1 , BP; CP ; -Z ) ----
  58. template <class T, class Policy>
  59. inline T hypergeometric_2F1_pade(const T& bp, const T& cp, const T& zp, const Policy& pol)
  60. {
  61. BOOST_MATH_STD_USING
  62. static const T one = T(1);
  63. // Luke: C ---------- INITIALIZATION -----------
  64. const T z = -zp;
  65. const T zz = z * z;
  66. T b0 = one;
  67. T a0 = one;
  68. T xi1 = one;
  69. T ct1 = cp;
  70. const T b1c1 = (cp - one) * (bp - one);
  71. T b1 = one + ((z / (cp + one)) * (bp + one));
  72. T a1 = b1 - ((bp / cp) * z);
  73. const unsigned max_iterations = boost::math::policies::get_max_series_iterations<Policy>();
  74. T b2 = T(0), a2 = T(0);
  75. T result = T(0), prev_result = a1 / b1;
  76. for (unsigned k = 1; k < max_iterations; ++k)
  77. {
  78. // Luke: C ----- CALCULATION OF THE MULTIPLIERS -----
  79. // Luke: C ----------- FOR THE RECURSION ------------
  80. const T ct2 = ct1 + xi1;
  81. const T ct3 = ct2 * ct2;
  82. const T g2 = (((((ct1 / ct3) * (bp - ct1)) / (ct3 - one)) * xi1) * (bp + xi1)) * zz;
  83. ++xi1;
  84. const T g1 = one + (((((xi1 + xi1) * ct1) + b1c1) / (ct3 + ct2 + ct2)) * z);
  85. // Luke: C ------- THE RECURRENCE RELATIONS ---------
  86. // Luke: C ------------ ARE AS FOLLOWS --------------
  87. b2 = (g1 * b1) + (g2 * b0);
  88. a2 = (g1 * a1) + (g2 * a0);
  89. prev_result = result;
  90. result = a2 / b2;
  91. // condition for interruption
  92. if ((fabs(result) * boost::math::tools::epsilon<T>()) > fabs(result - prev_result))
  93. break;
  94. b0 = b1; b1 = b2;
  95. a0 = a1; a1 = a2;
  96. ++ct1;
  97. }
  98. return a2 / b2;
  99. }
  100. } } } // namespaces
  101. #endif // BOOST_MATH_HYPERGEOMETRIC_PADE_HPP