123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804 |
- #ifndef BOOST_MATH_HYPERGEOMETRIC_1F1_HPP
- #define BOOST_MATH_HYPERGEOMETRIC_1F1_HPP
- #include <boost/math/tools/config.hpp>
- #include <boost/math/policies/policy.hpp>
- #include <boost/math/policies/error_handling.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_series.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_asym.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_rational.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_recurrence.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_by_ratios.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_pade.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_bessel.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_scaled_series.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_pFq_checked_series.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_addition_theorems_on_z.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_large_abz.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_small_a_negative_b_by_ratio.hpp>
- #include <boost/math/special_functions/detail/hypergeometric_1F1_negative_b_regions.hpp>
- namespace boost { namespace math { namespace detail {
-
- template <class T>
- inline bool check_hypergeometric_1F1_parameters(const T& a, const T& b)
- {
- BOOST_MATH_STD_USING
- if ((b <= 0) && (b == floor(b)))
- {
- if ((a >= 0) || (a < b) || (a != floor(a)))
- return false;
- }
- return true;
- }
- template <class T, class Policy>
- T hypergeometric_1F1_divergent_fallback(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling)
- {
- BOOST_MATH_STD_USING
- const char* function = "hypergeometric_1F1_divergent_fallback<%1%>(%1%,%1%,%1%)";
-
-
-
-
-
- if (b > 0)
- {
-
- #if 0
- if ((z < b) && (a > -50))
-
- return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling);
- T z_limit = fabs((2 * a - b) / (sqrt(fabs(a))));
- int k = 1 + itrunc(z - z_limit);
-
- T convergence_at_50 = (b - a + 50) * k / (z * 50);
- if ((k > 0) && (k < 50) && (fabs(convergence_at_50) < 1) && (z > z_limit))
- {
- return boost::math::detail::hypergeometric_1f1_recurrence_on_z_minus_zero(a, b, T(z - k), k, pol, log_scaling);
- }
- #endif
- if (z < b)
- return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling);
- else
- return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling);
- }
- else
- {
- if (a < 0)
- {
- if ((b < a) && (z < -b / 4))
- return hypergeometric_1F1_from_function_ratio_negative_ab(a, b, z, pol, log_scaling);
- else
- {
-
-
-
-
-
-
- bool can_use_recursion = (z - b + 100 < boost::math::policies::get_max_series_iterations<Policy>()) && (100 - a < boost::math::policies::get_max_series_iterations<Policy>());
- T sqr = 4 * a * z + b * b - 2 * b * z + z * z;
- T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a - b);
- if(can_use_recursion && ((std::max)(a, b) + iterations_to_convergence > -300))
- return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling);
-
-
-
-
-
- if((a < b) && can_use_recursion)
- return hypergeometric_1F1_backwards_recursion_on_b_for_negative_a(a, b, z, pol, function, log_scaling);
- }
- }
- else
- {
-
-
-
-
-
-
-
-
-
-
-
- int domain = hypergeometric_1F1_negative_b_recurrence_region(a, b, z);
- if ((domain < 0) && ((a > 1) || (boost::math::policies::digits<T, Policy>() <= 64)))
- return hypergeometric_1F1_from_function_ratio_negative_b(a, b, z, pol, log_scaling);
- else if (domain > 0)
- {
- if (boost::math::policies::digits<T, Policy>() <= 64)
- return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling);
- #ifndef BOOST_MATH_NO_EXCEPTIONS
- try
- #endif
- {
- return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling);
- }
- #ifndef BOOST_MATH_NO_EXCEPTIONS
- catch (const evaluation_error&)
- {
-
-
-
- return hypergeometric_1F1_from_function_ratio_negative_b_forwards(a, b, z, pol, log_scaling);
- }
- #endif
- }
-
-
-
-
-
-
- }
- }
-
-
- return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling);
- }
- template <class T>
- bool is_convergent_negative_z_series(const T& a, const T& b, const T& z, const T& b_minus_a)
- {
- BOOST_MATH_STD_USING
-
-
-
- if((b_minus_a > 0) && (b > 0))
- {
- if (a < 0)
- return false;
- }
-
-
-
- if ((fabs(z * a / b) < 2) && (fabs(z * (a + 10) / ((b + 10) * 10)) < 1))
- {
-
- if (a < 0)
- {
- T n = 300 - floor(a);
- if (fabs((a + n) * z / ((b + n) * n)) < 1)
- {
- if (b < 0)
- {
- T m = 3 - floor(b);
- if (fabs((a + m) * z / ((b + m) * m)) < 1)
- return true;
- }
- else
- return true;
- }
- }
- else if (b < 0)
- {
- T n = 3 - floor(b);
- if (fabs((a + n) * z / ((b + n) * n)) < 1)
- return true;
- }
- }
- if ((b > 0) && (a < 0))
- {
-
-
-
-
-
-
-
- T sqr = 4 * a * z + b * b - 2 * b * z + z * z;
- T iterations_to_convergence = sqr > 0 ? T(0.5f * (-sqrt(sqr) - b + z)) : T(-a + b);
- if (iterations_to_convergence < 0)
- iterations_to_convergence = 0.5f * (sqrt(sqr) - b + z);
- if (a + iterations_to_convergence < -50)
- {
-
- if (a > -1)
- return true;
- T n = 300 - floor(a);
- if(fabs((a + n) * z / ((b + n) * n)) < 1)
- return true;
- }
- }
- return false;
- }
- template <class T>
- inline T cyl_bessel_i_shrinkage_rate(const T& z)
- {
-
-
- if (z < -160)
- return 1;
- if (z < -40)
- return 0.75f;
- if (z < -20)
- return 0.5f;
- if (z < -7)
- return 0.25f;
- if (z < -2)
- return 0.1f;
- return 0.05f;
- }
- template <class T>
- inline bool hypergeometric_1F1_is_13_3_6_region(const T& a, const T& b, const T& z)
- {
- BOOST_MATH_STD_USING
- if(fabs(a) == 0.5)
- return false;
- if ((z < 0) && (fabs(10 * a / b) < 1) && (fabs(a) < 50))
- {
- T shrinkage = cyl_bessel_i_shrinkage_rate(z);
-
- if ((fabs((2 * a - 1) * (2 * a - b) / b) < 2) && (fabs(shrinkage * (2 * a + 9) * (2 * a - b + 10) / (10 * (b + 10))) < 0.75))
- return true;
- }
- return false;
- }
- template <class T>
- inline bool hypergeometric_1F1_need_kummer_reflection(const T& a, const T& b, const T& z)
- {
- BOOST_MATH_STD_USING
-
-
-
- if (z > 0)
- return false;
- if (z < -1)
- return true;
-
-
-
-
-
- if (a > 0)
- {
- if (b > 0)
- {
- return fabs((a + 10) * z / (10 * (b + 10))) < 1;
- }
- else
- {
- return true;
- }
- }
- else
- {
- if (b > 0)
- {
- return false;
- }
- else
- {
- return true;
- }
- }
- }
-
- template <class T, class Policy>
- T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol, long long& log_scaling)
- {
- BOOST_MATH_STD_USING
- static const char* const function = "boost::math::hypergeometric_1F1<%1%,%1%,%1%>(%1%,%1%,%1%)";
- if ((z == 0) || (a == 0))
- return T(1);
-
- if (!detail::check_hypergeometric_1F1_parameters(a, b))
- return policies::raise_domain_error<T>(
- function,
- "Function is indeterminate for negative integer b = %1%.",
- b,
- pol);
-
- if (a == -1)
- {
- T r = 1 - (z / b);
- if (fabs(r) < 0.5)
- r = (b - z) / b;
- return r;
- }
- const T b_minus_a = b - a;
-
- if (b_minus_a == 0)
- {
- if ((a < 0) && (floor(a) == a))
- {
-
- if ((a < -20) && (z > 0) && (z < 1))
- {
-
- return exp(z) * boost::math::gamma_q(1 - a, z, pol);
- }
-
- return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling);
- }
- long long scale = lltrunc(z, pol);
- log_scaling += scale;
- return exp(z - scale);
- }
-
- if ((b_minus_a == -1) && (fabs(a) > 0.5))
- {
-
- if ((a < 0) && (a == ceil(a)) && (a > -50))
- return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function);
- log_scaling = lltrunc(floor(z));
- T local_z = z - log_scaling;
- return (b + z) * exp(local_z) / b;
- }
- if ((a == 1) && (b == 2))
- return boost::math::expm1(z, pol) / z;
- if ((b - a == b) && (fabs(z / b) < policies::get_epsilon<T, Policy>()))
- return 1;
-
-
-
- if (z < 0)
- {
- if (hypergeometric_1F1_is_13_3_6_region(a, b, z))
- {
-
-
- T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling);
- long long scale = lltrunc(z, pol);
- log_scaling += scale;
- return r * exp(z - scale);
- }
- if ((b < 0) && (fabs(a) < 1e-2))
- {
-
-
-
- if (b - ceil(b) == a)
- {
-
-
- long long scaling = lltrunc(z);
- T r = exp(z - scaling) * detail::hypergeometric_1F1_imp<T>(b_minus_a, b, -z, pol, log_scaling);
- log_scaling += scaling;
- return r;
- }
- if ((b < -1) && (max_b_for_1F1_small_a_negative_b_by_ratio(z) < b))
- return hypergeometric_1F1_small_a_negative_b_by_ratio(a, b, z, pol, log_scaling);
- if ((b > -1) && (b < -0.5f))
- {
-
- T first = hypergeometric_1F1_imp(a, T(b + 2), z, pol);
- T second = hypergeometric_1F1_imp(a, T(b + 1), z, pol);
- return tools::apply_recurrence_relation_backward(hypergeometric_1F1_recurrence_small_b_coefficients<T>(a, b, z, 1), 1, first, second);
- }
-
-
-
- T r = boost::math::detail::hypergeometric_1F1_AS_13_3_6(b_minus_a, b, T(-z), a, pol, log_scaling);
- long long scale = lltrunc(z, pol);
- log_scaling += scale;
- return r * exp(z - scale);
- }
- }
-
-
-
-
-
- if (detail::hypergeometric_1F1_asym_region(a, b, z, pol))
- {
- long long saved_scale = log_scaling;
- #ifndef BOOST_MATH_NO_EXCEPTIONS
- try
- #endif
- {
- return hypergeometric_1F1_asym_large_z_series(a, b, z, pol, log_scaling);
- }
- #ifndef BOOST_MATH_NO_EXCEPTIONS
- catch (const evaluation_error&)
- {
- }
- #endif
-
-
-
-
- log_scaling = saved_scale;
- }
- if ((fabs(a * z / b) < 3.5) && (fabs(z * 100) < fabs(b)) && ((fabs(a) > 1e-2) || (b < -5)))
- return detail::hypergeometric_1F1_rational(a, b, z, pol);
- if (hypergeometric_1F1_need_kummer_reflection(a, b, z))
- {
- if (a == 1)
- return detail::hypergeometric_1F1_pade(b, z, pol);
- if (is_convergent_negative_z_series(a, b, z, b_minus_a))
- {
- if ((boost::math::sign(b_minus_a) == boost::math::sign(b)) && ((b > 0) || (b < -200)))
- {
-
-
-
-
-
-
-
-
-
-
-
- return hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling);
- }
- }
- if ((b < 0) && (floor(b) == b))
- {
-
-
- if(a > -50)
- return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function);
-
- return hypergeometric_1F1_imp(a, float_next(b), z, pol, log_scaling);
- }
- else
- {
-
-
-
-
-
-
- long long scaling = lltrunc(z);
- T r = exp(z - scaling) * detail::hypergeometric_1F1_imp<T>(b_minus_a, b, -z, pol, log_scaling);
- log_scaling += scaling;
- return r;
- }
- }
-
-
-
- bool series_is_divergent = (a + 1) * z / (b + 1) < -1;
- if (series_is_divergent && (a < 0) && (b < 0) && (a > -1))
- series_is_divergent = false;
-
-
-
-
-
- if (!series_is_divergent && (a < 0) && (b < 0) && (b > a))
- {
-
-
-
-
-
-
-
- T convergence_point = sqrt((a - 1) * (a - b)) - a;
- if (-b < convergence_point)
- {
- T n = -floor(b);
- series_is_divergent = (a + n) * z / ((b + n) * n) < -1;
- }
- }
- else if (!series_is_divergent && (b < 0) && (a > 0))
- {
-
- series_is_divergent = true;
- }
- if (series_is_divergent && (b < -1) && (b > -5) && (a > b))
- series_is_divergent = false;
-
-
-
-
-
- if (series_is_divergent)
- {
- if((a < 0) && (floor(a) == a) && (-a < policies::get_max_series_iterations<Policy>()))
-
- return hypergeometric_1F1_backward_recurrence_for_negative_a(a, b, z, pol, function, log_scaling);
-
-
-
-
-
-
- if (b > 0)
- {
- T z_limit = fabs((2 * a - b) / (sqrt(fabs(a))));
- if ((z < z_limit) && hypergeometric_1F1_is_tricomi_viable_positive_b(a, b, z))
- return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling);
- }
- else
- {
- if (a < 0)
- {
- T z_limit = fabs((2 * a - b) / (sqrt(fabs(a))));
-
-
-
-
-
- if (((z < z_limit) || (a > -500)) && ((b > -500) || (b - 2 * a > 0)) && (z < -a))
- {
-
-
-
- if(!(((a < b) && (z > -b)) || (z > z_limit)))
- return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling);
-
-
-
-
-
-
-
- if(b > -1)
- return detail::hypergeometric_1F1_AS_13_3_7_tricomi(a, b, z, pol, log_scaling);
- }
- }
-
-
-
-
- }
- return hypergeometric_1F1_divergent_fallback(a, b, z, pol, log_scaling);
- }
- if (hypergeometric_1F1_is_13_3_6_region(b_minus_a, b, T(-z)))
- {
-
-
- return boost::math::detail::hypergeometric_1F1_AS_13_3_6(a, b, z, b_minus_a, pol, log_scaling);
- }
- #if 0
- if ((a > 0) && (b > 0) && (a * z / b > 2))
- {
-
-
-
-
- if (is_convergent_negative_z_series(b_minus_a, b, T(-z), b_minus_a))
- {
- long long scaling = lltrunc(z);
- T r = exp(z - scaling) * detail::hypergeometric_1F1_checked_series_impl(b_minus_a, b, T(-z), pol, log_scaling);
- log_scaling += scaling;
- return r;
- }
- }
- #endif
- if ((a > 0) && (b > 0) && (a * z > 50))
- return detail::hypergeometric_1F1_large_abz(a, b, z, pol, log_scaling);
- if (b < 0)
- return detail::hypergeometric_1F1_checked_series_impl(a, b, z, pol, log_scaling);
-
- return detail::hypergeometric_1F1_generic_series(a, b, z, pol, log_scaling, function);
- }
- template <class T, class Policy>
- inline T hypergeometric_1F1_imp(const T& a, const T& b, const T& z, const Policy& pol)
- {
- BOOST_MATH_STD_USING
- long long log_scaling = 0;
- T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling);
-
-
-
- static const thread_local long long max_scaling = lltrunc(boost::math::tools::log_max_value<T>()) - 2;
- static const thread_local T max_scale_factor = exp(T(max_scaling));
- while (log_scaling > max_scaling)
- {
- result *= max_scale_factor;
- log_scaling -= max_scaling;
- }
- while (log_scaling < -max_scaling)
- {
- result /= max_scale_factor;
- log_scaling += max_scaling;
- }
- if (log_scaling)
- result *= exp(T(log_scaling));
- return result;
- }
- template <class T, class Policy>
- inline T log_hypergeometric_1F1_imp(const T& a, const T& b, const T& z, int* sign, const Policy& pol)
- {
- BOOST_MATH_STD_USING
- long long log_scaling = 0;
- T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling);
- if (sign)
- *sign = result < 0 ? -1 : 1;
- result = log(fabs(result)) + log_scaling;
- return result;
- }
- template <class T, class Policy>
- inline T hypergeometric_1F1_regularized_imp(const T& a, const T& b, const T& z, const Policy& pol)
- {
- BOOST_MATH_STD_USING
- long long log_scaling = 0;
- T result = hypergeometric_1F1_imp(a, b, z, pol, log_scaling);
-
-
-
- int result_sign = 1;
- T scale = log_scaling - boost::math::lgamma(b, &result_sign, pol);
- static const thread_local T max_scaling = boost::math::tools::log_max_value<T>() - 2;
- static const thread_local T max_scale_factor = exp(max_scaling);
- while (scale > max_scaling)
- {
- result *= max_scale_factor;
- scale -= max_scaling;
- }
- while (scale < -max_scaling)
- {
- result /= max_scale_factor;
- scale += max_scaling;
- }
- if (scale != 0)
- result *= exp(scale);
- return result * result_sign;
- }
- }
- template <class T1, class T2, class T3, class Policy>
- inline typename tools::promote_args<T1, T2, T3>::type hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& )
- {
- BOOST_FPU_EXCEPTION_GUARD
- typedef typename tools::promote_args<T1, T2, T3>::type result_type;
- typedef typename policies::evaluation<result_type, Policy>::type value_type;
- typedef typename policies::normalise<
- Policy,
- policies::promote_float<false>,
- policies::promote_double<false>,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
- return policies::checked_narrowing_cast<result_type, Policy>(
- detail::hypergeometric_1F1_imp<value_type>(
- static_cast<value_type>(a),
- static_cast<value_type>(b),
- static_cast<value_type>(z),
- forwarding_policy()),
- "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)");
- }
- template <class T1, class T2, class T3>
- inline typename tools::promote_args<T1, T2, T3>::type hypergeometric_1F1(T1 a, T2 b, T3 z)
- {
- return hypergeometric_1F1(a, b, z, policies::policy<>());
- }
- template <class T1, class T2, class T3, class Policy>
- inline typename tools::promote_args<T1, T2, T3>::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z, const Policy& )
- {
- BOOST_FPU_EXCEPTION_GUARD
- typedef typename tools::promote_args<T1, T2, T3>::type result_type;
- typedef typename policies::evaluation<result_type, Policy>::type value_type;
- typedef typename policies::normalise<
- Policy,
- policies::promote_float<false>,
- policies::promote_double<false>,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
- return policies::checked_narrowing_cast<result_type, Policy>(
- detail::hypergeometric_1F1_regularized_imp<value_type>(
- static_cast<value_type>(a),
- static_cast<value_type>(b),
- static_cast<value_type>(z),
- forwarding_policy()),
- "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)");
- }
- template <class T1, class T2, class T3>
- inline typename tools::promote_args<T1, T2, T3>::type hypergeometric_1F1_regularized(T1 a, T2 b, T3 z)
- {
- return hypergeometric_1F1_regularized(a, b, z, policies::policy<>());
- }
- template <class T1, class T2, class T3, class Policy>
- inline typename tools::promote_args<T1, T2, T3>::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, const Policy& )
- {
- BOOST_FPU_EXCEPTION_GUARD
- typedef typename tools::promote_args<T1, T2, T3>::type result_type;
- typedef typename policies::evaluation<result_type, Policy>::type value_type;
- typedef typename policies::normalise<
- Policy,
- policies::promote_float<false>,
- policies::promote_double<false>,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
- return policies::checked_narrowing_cast<result_type, Policy>(
- detail::log_hypergeometric_1F1_imp<value_type>(
- static_cast<value_type>(a),
- static_cast<value_type>(b),
- static_cast<value_type>(z),
- 0,
- forwarding_policy()),
- "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)");
- }
- template <class T1, class T2, class T3>
- inline typename tools::promote_args<T1, T2, T3>::type log_hypergeometric_1F1(T1 a, T2 b, T3 z)
- {
- return log_hypergeometric_1F1(a, b, z, policies::policy<>());
- }
- template <class T1, class T2, class T3, class Policy>
- inline typename tools::promote_args<T1, T2, T3>::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign, const Policy& )
- {
- BOOST_FPU_EXCEPTION_GUARD
- typedef typename tools::promote_args<T1, T2, T3>::type result_type;
- typedef typename policies::evaluation<result_type, Policy>::type value_type;
- typedef typename policies::normalise<
- Policy,
- policies::promote_float<false>,
- policies::promote_double<false>,
- policies::discrete_quantile<>,
- policies::assert_undefined<> >::type forwarding_policy;
- return policies::checked_narrowing_cast<result_type, Policy>(
- detail::log_hypergeometric_1F1_imp<value_type>(
- static_cast<value_type>(a),
- static_cast<value_type>(b),
- static_cast<value_type>(z),
- sign,
- forwarding_policy()),
- "boost::math::hypergeometric_1F1<%1%>(%1%,%1%,%1%)");
- }
- template <class T1, class T2, class T3>
- inline typename tools::promote_args<T1, T2, T3>::type log_hypergeometric_1F1(T1 a, T2 b, T3 z, int* sign)
- {
- return log_hypergeometric_1F1(a, b, z, sign, policies::policy<>());
- }
- } }
- #endif
|