Automatic Differentiation
 
Loading...
Searching...
No Matches
yule_simon_lccdf.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_PRIM_PROB_YULE_SIMON_LCCDF_HPP
2#define STAN_MATH_PRIM_PROB_YULE_SIMON_LCCDF_HPP
3
16
17namespace stan {
18namespace math {
19
33template <typename T_n, typename T_alpha>
35 const T_alpha& alpha) {
36 using T_partials_return = partials_return_t<T_n, T_alpha>;
37 using T_n_ref = ref_type_t<T_n>;
38 using T_alpha_ref = ref_type_t<T_alpha>;
39 static constexpr const char* function = "yule_simon_lccdf";
40
41 check_consistent_sizes(function, "Outcome variable", n, "Shape parameter",
42 alpha);
43 if (size_zero(n, alpha)) {
44 return 0.0;
45 }
46
47 T_n_ref n_ref = n;
48 T_alpha_ref alpha_ref = alpha;
49 check_positive_finite(function, "Shape parameter", alpha_ref);
50
51 scalar_seq_view<T_n> n_vec(n);
52 scalar_seq_view<T_alpha_ref> alpha_vec(alpha_ref);
53 const size_t max_size_seq_view = max_size(n_ref, alpha_ref);
54
55 // Explicit return for invalid or extreme values
56 // The gradients are technically ill-defined, but treated as zero
57 for (int i = 0; i < stan::math::size(n); i++) {
58 if (n_vec.val(i) < 1.0) {
59 return 0.0;
60 }
61 if (n_vec.val(i) == std::numeric_limits<int>::max()) {
62 return negative_infinity();
63 }
64 }
65
66 T_partials_return log_ccdf(0.0);
67 auto ops_partials = make_partials_propagator(alpha_ref);
68 for (size_t i = 0; i < max_size_seq_view; i++) {
69 auto np1 = n_vec.val(i) + 1.0;
70 auto ap1 = alpha_vec.val(i) + 1.0;
71 auto nap1 = n_vec.val(i) + ap1;
72 log_ccdf += lgamma(ap1) + lgamma(np1) - lgamma(nap1);
73
74 if constexpr (is_autodiff_v<T_alpha>) {
75 partials<0>(ops_partials)[i] += digamma(ap1) - digamma(nap1);
76 }
77 }
78
79 return ops_partials.build(log_ccdf);
80}
81
82} // namespace math
83} // namespace stan
84#endif
scalar_seq_view provides a uniform sequence-like wrapper around either a scalar or a sequence of scal...
return_type_t< T_alpha > yule_simon_lccdf(const T_n &n, const T_alpha &alpha)
Returns the log CCDF of the Yule-Simon distribution with shape parameter.
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
int64_t size(const T &m)
Returns the size (number of the elements) of a matrix_cl or var_value<matrix_cl<T>>.
Definition size.hpp:19
static constexpr double negative_infinity()
Return negative infinity.
bool size_zero(const T &x)
Returns 1 if input is of length 0, returns 0 otherwise.
Definition size_zero.hpp:19
void check_consistent_sizes(const char *)
Trivial no input case, this function is a no-op.
fvar< T > lgamma(const fvar< T > &x)
Return the natural logarithm of the gamma function applied to the specified argument.
Definition lgamma.hpp:21
int64_t max_size(const T1 &x1, const Ts &... xs)
Calculate the size of the largest input.
Definition max_size.hpp:20
auto make_partials_propagator(Ops &&... ops)
Construct an partials_propagator.
void check_positive_finite(const char *function, const char *name, const T_y &y)
Check if y is positive and finite.
fvar< T > digamma(const fvar< T > &x)
Return the derivative of the log gamma function at the specified argument.
Definition digamma.hpp:23
typename ref_type_if< true, T >::type ref_type_t
Definition ref_type.hpp:56
typename partials_return_type< Args... >::type partials_return_t
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...