1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__NEG_BINOMIAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__NEG_BINOMIAL_HPP__
4 #include <boost/math/special_functions/digamma.hpp>
18 template <
bool propto,
20 typename T_shape,
typename T_inv_scale,
22 typename return_type<T_shape, T_inv_scale>::type
25 const T_inv_scale& beta,
28 static const char*
function =
"stan::prob::neg_binomial_log(%1%)";
46 if (!
check_finite(
function, alpha,
"Shape parameter", &logp, Policy()))
48 if (!
check_positive(
function, alpha,
"Shape parameter", &logp, Policy()))
50 if (!
check_finite(
function, beta,
"Inverse scale parameter",
59 "Shape parameter",
"Inverse scale parameter",
69 using boost::math::digamma;
75 size_t size =
max_size(n, alpha, beta);
79 size_t len_ab =
max_size(alpha,beta);
82 for (
size_t i = 0; i < len_ab; ++i)
87 for (
size_t i = 0; i <
length(beta); ++i)
91 log_beta_m_log1p_beta(
length(beta));
92 for (
size_t i = 0; i <
length(beta); ++i)
93 log_beta_m_log1p_beta[i] =
log(
value_of(beta_vec[i])) - log1p_beta[i];
96 alpha_times_log_beta_over_1p_beta(len_ab);
97 for (
size_t i = 0; i < len_ab; ++i)
98 alpha_times_log_beta_over_1p_beta[i]
104 digamma_alpha(
length(alpha));
106 for (
size_t i = 0; i <
length(alpha); ++i)
107 digamma_alpha[i] = digamma(
value_of(alpha_vec[i]));
112 for (
size_t i = 0; i <
length(beta); ++i)
117 lambda_m_alpha_over_1p_beta(len_ab);
119 for (
size_t i = 0; i < len_ab; ++i)
120 lambda_m_alpha_over_1p_beta[i] =
125 for (
size_t i = 0; i < size; i++) {
126 if (alpha_vec[i] > 1e10) {
128 logp -=
lgamma(n_vec[i] + 1.0);
133 operands_and_partials.
d_x1[i]
134 += n_vec[i] /
value_of(alpha_vec[i])
137 operands_and_partials.
d_x2[i]
138 += (lambda[i] - n_vec[i]) /
value_of(beta_vec[i]) ;
142 logp += binomial_coefficient_log<double>(n_vec[i]
147 alpha_times_log_beta_over_1p_beta[i]
148 - n_vec[i] * log1p_beta[i];
151 operands_and_partials.
d_x1[i]
152 += digamma(
value_of(alpha_vec[i]) + n_vec[i])
154 + log_beta_m_log1p_beta[i];
156 operands_and_partials.
d_x2[i]
157 += lambda_m_alpha_over_1p_beta[i]
158 - n_vec[i] / (
value_of(beta_vec[i]) + 1.0);
161 return operands_and_partials.
to_var(logp);
164 template <
bool propto,
166 typename T_shape,
typename T_inv_scale>
170 const T_shape& alpha,
171 const T_inv_scale& beta) {
172 return neg_binomial_log<propto>(n,alpha,beta,
176 template <
typename T_n,
177 typename T_shape,
typename T_inv_scale,
182 const T_shape& alpha,
183 const T_inv_scale& beta,
185 return neg_binomial_log<false>(n,alpha,beta,Policy());
188 template <
typename T_n,
189 typename T_shape,
typename T_inv_scale>
193 const T_shape& alpha,
194 const T_inv_scale& beta) {
195 return neg_binomial_log<false>(n,alpha,beta,
200 template <
bool propto,
typename T_n,
typename T_shape,
typename T_inv_scale,
206 static const char*
function =
"stan::prob::neg_binomial_cdf(%1%)";
224 if (!
check_finite(
function, alpha,
"Shape parameter", &P, Policy()))
227 if (!
check_positive(
function, alpha,
"Shape parameter", &P, Policy()))
230 if (!
check_finite(
function, beta,
"Inverse scale parameter",
241 "Shape parameter",
"Inverse scale parameter",
253 size_t size =
max_size(n, alpha, beta);
257 using boost::math::ibetac;
258 using boost::math::ibeta_derivative;
260 using boost::math::digamma;
274 const double n_dbl =
value_of(n_vec[i]);
275 const double alpha_dbl =
value_of(alpha_vec[i]);
277 digammaN_vec[i] = digamma(n_dbl);
278 digammaAlpha_vec[i] = digamma(alpha_dbl + 1);
279 digammaSum_vec[i] = digamma(n_dbl + alpha_dbl + 1);
280 betaFunc_vec[i] = boost::math::beta(n_dbl, alpha_dbl + 1);
285 operands_and_partials(alpha, beta);
291 for (
size_t i = 0; i < size; i++) {
292 const double n_dbl =
value_of(n_vec[i]);
293 const double alpha_dbl =
value_of(alpha_vec[i]);
294 const double beta_dbl =
value_of(beta_vec[i]);
296 const double p_dbl = beta_dbl / (1.0 + beta_dbl);
297 const double d_dbl = 1.0 / ( (1.0 + beta_dbl) * (1.0 + beta_dbl) );
299 const double Pi = ibetac(alpha_dbl + 1, n_dbl, p_dbl);
308 digammaAlpha_vec[i], digammaN_vec[i],
309 digammaSum_vec[i], betaFunc_vec[i]);
311 operands_and_partials.
d_x1[n]
316 operands_and_partials.
d_x2[i]
317 += - d_dbl * ibeta_derivative(alpha_dbl + 1, n_dbl, p_dbl) / Pi;
321 for (
size_t i = 0; i < size; i++) {
323 operands_and_partials.
d_x1[i] *= P;
325 operands_and_partials.
d_x2[i] *= P;
331 template <
bool propto,
typename T_n,
typename T_shape,
typename T_inv_scale>
337 template <
typename T_n,
typename T_shape,
typename T_inv_scale,
class Policy>
341 return neg_binomial_cdf<false>(n, alpha, beta, Policy());
344 template <
typename T_n,
typename T_shape,
typename T_inv_scale>