Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / math / special_functions / detail / hypergeometric_separated_series.hpp
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_SEPARATED_SERIES_HPP
11 #define BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP
12
13   namespace boost { namespace math { namespace detail {
14
15   template <class T, class Policy>
16   inline T hypergeometric_1F1_separated_series(const T& a, const T& b, const T& z, const Policy& pol)
17   {
18     BOOST_MATH_STD_USING
19
20     boost::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
21     const T factor = policies::get_epsilon<T, Policy>();
22
23     T denom = 1, numer = 1;
24     T intermediate_result = 1, result = 1;
25     T a_pochhammer = a, z_pow = z;
26     unsigned N = 0;
27     while (--max_iter)
28     {
29       ++N;
30       const T mult = (((b + N) - 1) * N);
31       denom *= mult; numer *= mult;
32       numer += a_pochhammer * z_pow;
33
34       result = numer / denom;
35
36       if (fabs(factor * result) > fabs(result - intermediate_result))
37         break;
38
39       intermediate_result = result;
40
41       a_pochhammer *= (a + N);
42       z_pow *= z;
43     }
44
45     return result;
46   }
47
48   } } } // namespaces
49
50 #endif // BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP