bessel_iterators.hpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2018 John Maddock
  3. // Distributed under the Boost
  4. // 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_ITERATORS_HPP
  7. #define BOOST_MATH_BESSEL_ITERATORS_HPP
  8. #include <boost/math/tools/recurrence.hpp>
  9. #include <boost/math/special_functions/bessel.hpp>
  10. namespace boost {
  11. namespace math {
  12. namespace detail {
  13. template <class T>
  14. struct bessel_jy_recurrence
  15. {
  16. bessel_jy_recurrence(T v, T z) : v(v), z(z) {}
  17. boost::math::tuple<T, T, T> operator()(int k)
  18. {
  19. return boost::math::tuple<T, T, T>(1, -2 * (v + k) / z, 1);
  20. }
  21. T v, z;
  22. };
  23. template <class T>
  24. struct bessel_ik_recurrence
  25. {
  26. bessel_ik_recurrence(T v, T z) : v(v), z(z) {}
  27. boost::math::tuple<T, T, T> operator()(int k)
  28. {
  29. return boost::math::tuple<T, T, T>(1, -2 * (v + k) / z, -1);
  30. }
  31. T v, z;
  32. };
  33. } // namespace detail
  34. template <class T, class Policy = boost::math::policies::policy<> >
  35. struct bessel_j_backwards_iterator
  36. {
  37. typedef std::ptrdiff_t difference_type;
  38. typedef T value_type;
  39. typedef T* pointer;
  40. typedef T& reference;
  41. typedef std::input_iterator_tag iterator_category;
  42. bessel_j_backwards_iterator(const T& v, const T& x)
  43. : it(detail::bessel_jy_recurrence<T>(v, x), boost::math::cyl_bessel_j(v, x, Policy()))
  44. {
  45. if(v < 0)
  46. boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  47. }
  48. bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v)
  49. : it(detail::bessel_jy_recurrence<T>(v, x), J_v)
  50. {
  51. if(v < 0)
  52. boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  53. }
  54. bessel_j_backwards_iterator(const T& v, const T& x, const T& J_v_plus_1, const T& J_v)
  55. : it(detail::bessel_jy_recurrence<T>(v, x), J_v_plus_1, J_v)
  56. {
  57. if (v < -1)
  58. boost::math::policies::raise_domain_error("bessel_j_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  59. }
  60. bessel_j_backwards_iterator& operator++()
  61. {
  62. ++it;
  63. return *this;
  64. }
  65. bessel_j_backwards_iterator operator++(int)
  66. {
  67. bessel_j_backwards_iterator t(*this);
  68. ++(*this);
  69. return t;
  70. }
  71. T operator*() { return *it; }
  72. private:
  73. boost::math::tools::backward_recurrence_iterator< detail::bessel_jy_recurrence<T> > it;
  74. };
  75. template <class T, class Policy = boost::math::policies::policy<> >
  76. struct bessel_i_backwards_iterator
  77. {
  78. typedef std::ptrdiff_t difference_type;
  79. typedef T value_type;
  80. typedef T* pointer;
  81. typedef T& reference;
  82. typedef std::input_iterator_tag iterator_category;
  83. bessel_i_backwards_iterator(const T& v, const T& x)
  84. : it(detail::bessel_ik_recurrence<T>(v, x), boost::math::cyl_bessel_i(v, x, Policy()))
  85. {
  86. if(v < -1)
  87. boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  88. }
  89. bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v)
  90. : it(detail::bessel_ik_recurrence<T>(v, x), I_v)
  91. {
  92. if(v < -1)
  93. boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  94. }
  95. bessel_i_backwards_iterator(const T& v, const T& x, const T& I_v_plus_1, const T& I_v)
  96. : it(detail::bessel_ik_recurrence<T>(v, x), I_v_plus_1, I_v)
  97. {
  98. if(v < -1)
  99. boost::math::policies::raise_domain_error("bessel_i_backwards_iterator<%1%>", "Order must be > 0 stable backwards recurrence but got %1%", v, Policy());
  100. }
  101. bessel_i_backwards_iterator& operator++()
  102. {
  103. ++it;
  104. return *this;
  105. }
  106. bessel_i_backwards_iterator operator++(int)
  107. {
  108. bessel_i_backwards_iterator t(*this);
  109. ++(*this);
  110. return t;
  111. }
  112. T operator*() { return *it; }
  113. private:
  114. boost::math::tools::backward_recurrence_iterator< detail::bessel_ik_recurrence<T> > it;
  115. };
  116. template <class T, class Policy = boost::math::policies::policy<> >
  117. struct bessel_i_forwards_iterator
  118. {
  119. typedef std::ptrdiff_t difference_type;
  120. typedef T value_type;
  121. typedef T* pointer;
  122. typedef T& reference;
  123. typedef std::input_iterator_tag iterator_category;
  124. bessel_i_forwards_iterator(const T& v, const T& x)
  125. : it(detail::bessel_ik_recurrence<T>(v, x), boost::math::cyl_bessel_i(v, x, Policy()))
  126. {
  127. if(v > 1)
  128. boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy());
  129. }
  130. bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v)
  131. : it(detail::bessel_ik_recurrence<T>(v, x), I_v)
  132. {
  133. if (v > 1)
  134. boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy());
  135. }
  136. bessel_i_forwards_iterator(const T& v, const T& x, const T& I_v_minus_1, const T& I_v)
  137. : it(detail::bessel_ik_recurrence<T>(v, x), I_v_minus_1, I_v)
  138. {
  139. if (v > 1)
  140. boost::math::policies::raise_domain_error("bessel_i_forwards_iterator<%1%>", "Order must be < 0 stable forwards recurrence but got %1%", v, Policy());
  141. }
  142. bessel_i_forwards_iterator& operator++()
  143. {
  144. ++it;
  145. return *this;
  146. }
  147. bessel_i_forwards_iterator operator++(int)
  148. {
  149. bessel_i_forwards_iterator t(*this);
  150. ++(*this);
  151. return t;
  152. }
  153. T operator*() { return *it; }
  154. private:
  155. boost::math::tools::forward_recurrence_iterator< detail::bessel_ik_recurrence<T> > it;
  156. };
  157. }
  158. } // namespaces
  159. #endif // BOOST_MATH_BESSEL_ITERATORS_HPP