File indexing completed on 2025-01-18 09:40:05
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP
0008 #define BOOST_MATH_HYPERGEOMETRIC_1F1_SCALED_SERIES_HPP
0009
0010 #include <array>
0011 #include <cstdint>
0012
0013 namespace boost{ namespace math{ namespace detail{
0014
0015 template <class T, class Policy>
0016 T hypergeometric_1F1_scaled_series(const T& a, const T& b, T z, const Policy& pol, const char* function)
0017 {
0018 BOOST_MATH_STD_USING
0019
0020
0021
0022
0023
0024
0025 T sum(0), term(1), upper_limit(sqrt(boost::math::tools::max_value<T>())), diff;
0026 unsigned n = 0;
0027 long long log_scaling_factor = 1 - lltrunc(boost::math::tools::log_max_value<T>());
0028 T scaling_factor = exp(T(log_scaling_factor));
0029 std::intmax_t current_scaling = 0;
0030
0031 do
0032 {
0033 sum += term;
0034 if (sum >= upper_limit)
0035 {
0036 sum *= scaling_factor;
0037 term *= scaling_factor;
0038 current_scaling += log_scaling_factor;
0039 }
0040 term *= (((a + n) / ((b + n) * (n + 1))) * z);
0041 if (n > boost::math::policies::get_max_series_iterations<Policy>())
0042 return boost::math::policies::raise_evaluation_error(function, "Series did not converge, best value is %1%", sum, pol);
0043 ++n;
0044 diff = fabs(term / sum);
0045 } while (diff > boost::math::policies::get_epsilon<T, Policy>());
0046
0047 z = -z - current_scaling;
0048 while (z < log_scaling_factor)
0049 {
0050 z -= log_scaling_factor;
0051 sum *= scaling_factor;
0052 }
0053 return sum * exp(z);
0054 }
0055
0056
0057
0058 } } }
0059
0060 #endif