2 ///////////////////////////////////////////////////////////////////////////////
3 // Copyright 2014 Anton Bikineev
4 // Copyright 2014 Christopher Kormanyos
5 // Copyright 2014 John Maddock
6 // Copyright 2014 Paul Bristow
7 // Distributed under the Boost
8 // Software License, Version 1.0. (See accompanying file
9 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP
12 #define BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP
14 namespace boost { namespace math { namespace detail {
16 // primary template for term of continued fraction
17 template <class T, unsigned p, unsigned q>
18 struct hypergeometric_pFq_cf_term;
20 // partial specialization for 0F1
22 struct hypergeometric_pFq_cf_term<T, 0u, 1u>
24 typedef std::pair<T,T> result_type;
26 hypergeometric_pFq_cf_term(const T& b, const T& z):
28 term(std::make_pair(T(0), T(1)))
32 result_type operator()()
34 const result_type result = term;
36 numer = -(z / (b * n));
37 term = std::make_pair(numer, 1 - numer);
49 // partial specialization for 1F0
51 struct hypergeometric_pFq_cf_term<T, 1u, 0u>
53 typedef std::pair<T,T> result_type;
55 hypergeometric_pFq_cf_term(const T& a, const T& z):
57 term(std::make_pair(T(0), T(1)))
61 result_type operator()()
63 const result_type result = term;
65 numer = -((a * z) / n);
66 term = std::make_pair(numer, 1 - numer);
78 // partial specialization for 1F1
80 struct hypergeometric_pFq_cf_term<T, 1u, 1u>
82 typedef std::pair<T,T> result_type;
84 hypergeometric_pFq_cf_term(const T& a, const T& b, const T& z):
85 n(1), a(a), b(b), z(z),
86 term(std::make_pair(T(0), T(1)))
90 result_type operator()()
92 const result_type result = term;
94 numer = -((a * z) / (b * n));
95 term = std::make_pair(numer, 1 - numer);
107 // partial specialization for 1f2
109 struct hypergeometric_pFq_cf_term<T, 1u, 2u>
111 typedef std::pair<T,T> result_type;
113 hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z):
114 n(1), a(a), b(b), c(c), z(z),
115 term(std::make_pair(T(0), T(1)))
119 result_type operator()()
121 const result_type result = term;
123 numer = -((a * z) / ((b * c) * n));
124 term = std::make_pair(numer, 1 - numer);
136 // partial specialization for 2f1
138 struct hypergeometric_pFq_cf_term<T, 2u, 1u>
140 typedef std::pair<T,T> result_type;
142 hypergeometric_pFq_cf_term(const T& a, const T& b, const T& c, const T& z):
143 n(1), a(a), b(b), c(c), z(z),
144 term(std::make_pair(T(0), T(1)))
148 result_type operator()()
150 const result_type result = term;
152 numer = -(((a * b) * z) / (c * n));
153 term = std::make_pair(numer, 1 - numer);
165 template <class T, unsigned p, unsigned q, class Policy>
166 inline T compute_cf_pFq(detail::hypergeometric_pFq_cf_term<T, p, q>& term, const Policy& pol)
169 boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
170 const T result = tools::continued_fraction_b(
172 boost::math::policies::get_epsilon<T, Policy>(),
174 boost::math::policies::check_series_iterations<T>(
175 "boost::math::hypergeometric_pFq_cf<%1%>(%1%,%1%,%1%)",
181 template <class T, class Policy>
182 inline T hypergeometric_0F1_cf(const T& b, const T& z, const Policy& pol)
184 detail::hypergeometric_pFq_cf_term<T, 0u, 1u> f(b, z);
185 T result = detail::compute_cf_pFq(f, pol);
186 result = ((z / b) / result) + 1;
190 template <class T, class Policy>
191 inline T hypergeometric_1F0_cf(const T& a, const T& z, const Policy& pol)
193 detail::hypergeometric_pFq_cf_term<T, 1u, 0u> f(a, z);
194 T result = detail::compute_cf_pFq(f, pol);
195 result = ((a * z) / result) + 1;
199 template <class T, class Policy>
200 inline T hypergeometric_1F1_cf(const T& a, const T& b, const T& z, const Policy& pol)
202 detail::hypergeometric_pFq_cf_term<T, 1u, 1u> f(a, b, z);
203 T result = detail::compute_cf_pFq(f, pol);
204 result = (((a * z) / b) / result) + 1;
208 template <class T, class Policy>
209 inline T hypergeometric_1F2_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol)
211 detail::hypergeometric_pFq_cf_term<T, 1u, 2u> f(a, b, c, z);
212 T result = detail::compute_cf_pFq(f, pol);
213 result = (((a * z) / (b * c)) / result) + 1;
217 template <class T, class Policy>
218 inline T hypergeometric_2F1_cf(const T& a, const T& b, const T& c, const T& z, const Policy& pol)
220 detail::hypergeometric_pFq_cf_term<T, 2u, 1u> f(a, b, c, z);
221 T result = detail::compute_cf_pFq(f, pol);
222 result = ((((a * b) * z) / c) / result) + 1;
228 #endif // BOOST_MATH_DETAIL_HYPERGEOMETRIC_CF_HPP