From 2896f60b4a41ea5a05f65cedc21ab73062e010c7 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 22 Mar 2025 19:15:53 +0800 Subject: [PATCH 1/4] Update hypergeometric_pFq to delegate to specialisations where relevant --- stan/math/prim/fun.hpp | 1 + stan/math/prim/fun/hypergeometric_2F1.hpp | 7 ++-- stan/math/prim/fun/hypergeometric_3F2.hpp | 4 +-- stan/math/prim/fun/hypergeometric_pFq.hpp | 20 +++++++++--- .../prim/fun/hypergeometric_pFq_helper.hpp | 32 +++++++++++++++++++ 5 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 stan/math/prim/fun/hypergeometric_pFq_helper.hpp diff --git a/stan/math/prim/fun.hpp b/stan/math/prim/fun.hpp index bb88f8eddf1..e024ed045bc 100644 --- a/stan/math/prim/fun.hpp +++ b/stan/math/prim/fun.hpp @@ -126,6 +126,7 @@ #include #include #include +#include #include #include #include diff --git a/stan/math/prim/fun/hypergeometric_2F1.hpp b/stan/math/prim/fun/hypergeometric_2F1.hpp index ae327e033f1..4c30a90f83d 100644 --- a/stan/math/prim/fun/hypergeometric_2F1.hpp +++ b/stan/math/prim/fun/hypergeometric_2F1.hpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include namespace stan { @@ -187,7 +187,7 @@ inline return_type_t hypergeometric_2F1(const Ta1& a1, a_args << a1, a2; b_args << b; - return hypergeometric_pFq(a_args, b_args, z); + return internal::hypergeometric_pFq_helper(a_args, b_args, z); } catch (const std::exception& e) { // Apply Euler's hypergeometric transformation if function // will not converge with current arguments @@ -200,7 +200,8 @@ inline return_type_t hypergeometric_2F1(const Ta1& a1, a_args << a1_t, a2_t; b_args << b_t; - return hypergeometric_pFq(a_args, b_args, z_t) / pow(1 - z, a2); + return internal::hypergeometric_pFq_helper(a_args, b_args, z_t) + / pow(1 - z, a2); } } } // namespace math diff --git a/stan/math/prim/fun/hypergeometric_3F2.hpp b/stan/math/prim/fun/hypergeometric_3F2.hpp index 0cff50e8daa..9bea03eb194 100644 --- a/stan/math/prim/fun/hypergeometric_3F2.hpp +++ b/stan/math/prim/fun/hypergeometric_3F2.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -127,7 +127,7 @@ inline auto hypergeometric_3F2(const Ta& a, const Tb& b, const Tz& z) { if (z == 1.0 && (sum(b_ref) - sum(a_ref)) < 0.0) { return internal::hypergeometric_3F2_infsum(a_ref, b_ref, z); } - return hypergeometric_pFq(a_ref, b_ref, z); + return internal::hypergeometric_pFq_helper(a_ref, b_ref, z); } /** diff --git a/stan/math/prim/fun/hypergeometric_pFq.hpp b/stan/math/prim/fun/hypergeometric_pFq.hpp index c2b30610314..824711da56f 100644 --- a/stan/math/prim/fun/hypergeometric_pFq.hpp +++ b/stan/math/prim/fun/hypergeometric_pFq.hpp @@ -4,12 +4,15 @@ #include #include #include +#include #include -#include +#include +#include +#include +#include namespace stan { namespace math { - /** * Returns the generalized hypergeometric function applied to the * input arguments: @@ -29,6 +32,15 @@ return_type_t hypergeometric_pFq(const Ta& a, const Tb& b, const Tz& z) { plain_type_t a_ref = a; plain_type_t b_ref = b; + + if (a_ref.size() == 1 && b_ref.size() == 0) { + return hypergeometric_1F0(a_ref[0], z); + } else if (a_ref.size() == 2 && b_ref.size() == 1) { + return hypergeometric_2F1(a_ref[0], a_ref[1], b_ref[0], z); + } else if (a_ref.size() == 3 && b_ref.size() == 2) { + return hypergeometric_3F2(a_ref, b_ref, z); + } + check_finite("hypergeometric_pFq", "a", a_ref); check_finite("hypergeometric_pFq", "b", b_ref); check_finite("hypergeometric_pFq", "z", z); @@ -50,9 +62,7 @@ return_type_t hypergeometric_pFq(const Ta& a, const Tb& b, throw std::domain_error(msg.str()); } - return boost::math::hypergeometric_pFq( - std::vector(a_ref.data(), a_ref.data() + a_ref.size()), - std::vector(b_ref.data(), b_ref.data() + b_ref.size()), z); + return internal::hypergeometric_pFq_helper(a_ref, b_ref, z); } } // namespace math } // namespace stan diff --git a/stan/math/prim/fun/hypergeometric_pFq_helper.hpp b/stan/math/prim/fun/hypergeometric_pFq_helper.hpp new file mode 100644 index 00000000000..071f122659e --- /dev/null +++ b/stan/math/prim/fun/hypergeometric_pFq_helper.hpp @@ -0,0 +1,32 @@ +#ifndef STAN_MATH_PRIM_FUN_HYPERGEOMETRIC_PFQ_HELPER_HPP +#define STAN_MATH_PRIM_FUN_HYPERGEOMETRIC_PFQ_HELPER_HPP + +#include +#include +#include + +namespace stan { +namespace math { +namespace internal { +/** + * Implementation for calculating the generalized hypergeometric function + * \f$_pF_q(a_1,...,a_p;b_1,...,b_q;z)\f$. + * + * This is declared separatel to avoid circular dependencies between the + * various hypergeometric functions. + * + * @param[in] a Vector of 'a' arguments to function + * @param[in] b Vector of 'b' arguments to function + * @param[in] z Scalar z argument + * @return Generalized hypergeometric function + */ +template * = nullptr, + require_arithmetic_t* = nullptr> +inline double hypergeometric_pFq_helper(const Ta& a, const Tb& b, const Tz& z) { + return boost::math::hypergeometric_pFq(to_array_1d(a), to_array_1d(b), z); +} +} +} // namespace math +} // namespace stan +#endif From d61f51581d6c24be5fcda74206ae234ac3b43b4c Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Sat, 22 Mar 2025 07:20:09 -0400 Subject: [PATCH 2/4] [Jenkins] auto-formatting by clang-format version 10.0.0-4ubuntu1 --- stan/math/prim/fun/hypergeometric_2F1.hpp | 2 +- stan/math/prim/fun/hypergeometric_pFq_helper.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/stan/math/prim/fun/hypergeometric_2F1.hpp b/stan/math/prim/fun/hypergeometric_2F1.hpp index 4c30a90f83d..730be40fc45 100644 --- a/stan/math/prim/fun/hypergeometric_2F1.hpp +++ b/stan/math/prim/fun/hypergeometric_2F1.hpp @@ -201,7 +201,7 @@ inline return_type_t hypergeometric_2F1(const Ta1& a1, a_args << a1_t, a2_t; b_args << b_t; return internal::hypergeometric_pFq_helper(a_args, b_args, z_t) - / pow(1 - z, a2); + / pow(1 - z, a2); } } } // namespace math diff --git a/stan/math/prim/fun/hypergeometric_pFq_helper.hpp b/stan/math/prim/fun/hypergeometric_pFq_helper.hpp index 071f122659e..8867f316c3c 100644 --- a/stan/math/prim/fun/hypergeometric_pFq_helper.hpp +++ b/stan/math/prim/fun/hypergeometric_pFq_helper.hpp @@ -11,7 +11,7 @@ namespace internal { /** * Implementation for calculating the generalized hypergeometric function * \f$_pF_q(a_1,...,a_p;b_1,...,b_q;z)\f$. - * + * * This is declared separatel to avoid circular dependencies between the * various hypergeometric functions. * @@ -26,7 +26,7 @@ template Date: Sat, 22 Mar 2025 19:50:19 +0800 Subject: [PATCH 3/4] Not 3F2 for now --- stan/math/prim/fun/hypergeometric_3F2.hpp | 4 ++-- stan/math/prim/fun/hypergeometric_pFq.hpp | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/stan/math/prim/fun/hypergeometric_3F2.hpp b/stan/math/prim/fun/hypergeometric_3F2.hpp index 9bea03eb194..0cff50e8daa 100644 --- a/stan/math/prim/fun/hypergeometric_3F2.hpp +++ b/stan/math/prim/fun/hypergeometric_3F2.hpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include @@ -127,7 +127,7 @@ inline auto hypergeometric_3F2(const Ta& a, const Tb& b, const Tz& z) { if (z == 1.0 && (sum(b_ref) - sum(a_ref)) < 0.0) { return internal::hypergeometric_3F2_infsum(a_ref, b_ref, z); } - return internal::hypergeometric_pFq_helper(a_ref, b_ref, z); + return hypergeometric_pFq(a_ref, b_ref, z); } /** diff --git a/stan/math/prim/fun/hypergeometric_pFq.hpp b/stan/math/prim/fun/hypergeometric_pFq.hpp index 824711da56f..65b387b3f3c 100644 --- a/stan/math/prim/fun/hypergeometric_pFq.hpp +++ b/stan/math/prim/fun/hypergeometric_pFq.hpp @@ -8,7 +8,6 @@ #include #include #include -#include #include namespace stan { @@ -37,8 +36,6 @@ return_type_t hypergeometric_pFq(const Ta& a, const Tb& b, return hypergeometric_1F0(a_ref[0], z); } else if (a_ref.size() == 2 && b_ref.size() == 1) { return hypergeometric_2F1(a_ref[0], a_ref[1], b_ref[0], z); - } else if (a_ref.size() == 3 && b_ref.size() == 2) { - return hypergeometric_3F2(a_ref, b_ref, z); } check_finite("hypergeometric_pFq", "a", a_ref); From 66cfe21c8a3a1c7e7fdf4d36afefb7e4bca8e44b Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sun, 23 Mar 2025 13:30:12 +0800 Subject: [PATCH 4/4] Remove from central include --- stan/math/prim/fun.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/stan/math/prim/fun.hpp b/stan/math/prim/fun.hpp index e024ed045bc..bb88f8eddf1 100644 --- a/stan/math/prim/fun.hpp +++ b/stan/math/prim/fun.hpp @@ -126,7 +126,6 @@ #include #include #include -#include #include #include #include