hypergeometric_separated_series.hpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  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. namespace boost { namespace math { namespace detail {
  13. template <class T, class Policy>
  14. inline T hypergeometric_1F1_separated_series(const T& a, const T& b, const T& z, const Policy& pol)
  15. {
  16. BOOST_MATH_STD_USING
  17. std::uintmax_t max_iter = policies::get_max_series_iterations<Policy>();
  18. const T factor = policies::get_epsilon<T, Policy>();
  19. T denom = 1, numer = 1;
  20. T intermediate_result = 1, result = 1;
  21. T a_pochhammer = a, z_pow = z;
  22. unsigned N = 0;
  23. while (--max_iter)
  24. {
  25. ++N;
  26. const T mult = (((b + N) - 1) * N);
  27. denom *= mult; numer *= mult;
  28. numer += a_pochhammer * z_pow;
  29. result = numer / denom;
  30. if (fabs(factor * result) > fabs(result - intermediate_result))
  31. break;
  32. intermediate_result = result;
  33. a_pochhammer *= (a + N);
  34. z_pow *= z;
  35. }
  36. return result;
  37. }
  38. } } } // namespaces
  39. #endif // BOOST_MATH_HYPERGEOMETRIC_SEPARATED_SERIES_HPP