From dc87b77f7c6b4cfb77fa45ffda6d1f9c67a650ae Mon Sep 17 00:00:00 2001 From: Ben Goodrich Date: Tue, 12 Dec 2023 19:28:47 -0500 Subject: [PATCH] check_nonnegative -> check_positive StanHeaders::stanFunction("poisson_lcdf", n = 10L, lambda = c(0, 0)) crashes for 2.32 unless we throw an error before it evaluates stuff --- StanHeaders/inst/include/stan | 1 - .../stan/math/prim/prob/poisson_lcdf.hpp | 69 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) delete mode 120000 StanHeaders/inst/include/stan create mode 100644 StanHeaders/inst/include/stan/math/prim/prob/poisson_lcdf.hpp diff --git a/StanHeaders/inst/include/stan b/StanHeaders/inst/include/stan deleted file mode 120000 index 5364ea3d5..000000000 --- a/StanHeaders/inst/include/stan +++ /dev/null @@ -1 +0,0 @@ -upstream/lib/stan_math/stan/ \ No newline at end of file diff --git a/StanHeaders/inst/include/stan/math/prim/prob/poisson_lcdf.hpp b/StanHeaders/inst/include/stan/math/prim/prob/poisson_lcdf.hpp new file mode 100644 index 000000000..adea7a33f --- /dev/null +++ b/StanHeaders/inst/include/stan/math/prim/prob/poisson_lcdf.hpp @@ -0,0 +1,69 @@ +#ifndef STAN_MATH_PRIM_PROB_POISSON_LCDF_HPP +#define STAN_MATH_PRIM_PROB_POISSON_LCDF_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace stan { +namespace math { + +template +return_type_t poisson_lcdf(const T_n& n, const T_rate& lambda) { + using T_partials_return = partials_return_t; + using T_n_ref = ref_type_if_t::value, T_n>; + using T_lambda_ref = ref_type_if_t::value, T_rate>; + static const char* function = "poisson_lcdf"; + check_consistent_sizes(function, "Random variable", n, "Rate parameter", + lambda); + + T_n_ref n_ref = n; + T_lambda_ref lambda_ref = lambda; + + decltype(auto) n_val = to_ref(as_value_column_array_or_scalar(n_ref)); + decltype(auto) lambda_val + = to_ref(as_value_column_array_or_scalar(lambda_ref)); + + check_positive(function, "Rate parameter", lambda_val); + + if (size_zero(n, lambda)) { + return 0; + } + + auto ops_partials = make_partials_propagator(lambda_ref); + + if (sum(promote_scalar(n_val < 0))) { + return ops_partials.build(negative_infinity()); + } + + const auto& log_Pi = to_ref_if::value>( + log(gamma_q(n_val + 1.0, lambda_val))); + T_partials_return P = sum(log_Pi); + + if (!is_constant_all::value) { + partials<0>(ops_partials) = -exp(n_val * log(lambda_val) - lambda_val + - lgamma(n_val + 1.0) - log_Pi); + } + + return ops_partials.build(P); +} + +} // namespace math +} // namespace stan +#endif