1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__NEG_BINOMIAL_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__DISCRETE__NEG_BINOMIAL_HPP__
4 #include <boost/random/negative_binomial_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
7 #include <boost/math/special_functions/digamma.hpp>
23 template <
bool propto,
25 typename T_shape,
typename T_inv_scale,
27 typename return_type<T_shape, T_inv_scale>::type
30 const T_inv_scale& beta,
33 static const char*
function =
"stan::prob::neg_binomial_log(%1%)";
51 if (!
check_finite(
function, alpha,
"Shape parameter", &logp, Policy()))
53 if (!
check_positive(
function, alpha,
"Shape parameter", &logp, Policy()))
55 if (!
check_finite(
function, beta,
"Inverse scale parameter",
64 "Shape parameter",
"Inverse scale parameter",
74 using boost::math::digamma;
84 operands_and_partials(alpha,beta);
86 size_t len_ab =
max_size(alpha,beta);
90 for (
size_t i = 0; i < len_ab; ++i)
95 for (
size_t i = 0; i <
length(beta); ++i)
99 log_beta_m_log1p_beta(
length(beta));
100 for (
size_t i = 0; i <
length(beta); ++i)
101 log_beta_m_log1p_beta[i] =
log(
value_of(beta_vec[i])) - log1p_beta[i];
105 alpha_times_log_beta_over_1p_beta(len_ab);
106 for (
size_t i = 0; i < len_ab; ++i)
107 alpha_times_log_beta_over_1p_beta[i]
114 digamma_alpha(
length(alpha));
116 for (
size_t i = 0; i <
length(alpha); ++i)
117 digamma_alpha[i] = digamma(
value_of(alpha_vec[i]));
123 for (
size_t i = 0; i <
length(beta); ++i)
129 lambda_m_alpha_over_1p_beta(len_ab);
131 for (
size_t i = 0; i < len_ab; ++i)
132 lambda_m_alpha_over_1p_beta[i] =
137 for (
size_t i = 0; i <
size; i++) {
138 if (alpha_vec[i] > 1e10) {
140 logp -=
lgamma(n_vec[i] + 1.0);
145 operands_and_partials.
d_x1[i]
146 += n_vec[i] /
value_of(alpha_vec[i])
149 operands_and_partials.
d_x2[i]
150 += (lambda[i] - n_vec[i]) /
value_of(beta_vec[i]) ;
154 logp += binomial_coefficient_log<double>(n_vec[i]
160 alpha_times_log_beta_over_1p_beta[i]
161 - n_vec[i] * log1p_beta[i];
164 operands_and_partials.
d_x1[i]
165 += digamma(
value_of(alpha_vec[i]) + n_vec[i])
167 + log_beta_m_log1p_beta[i];
169 operands_and_partials.
d_x2[i]
170 += lambda_m_alpha_over_1p_beta[i]
171 - n_vec[i] / (
value_of(beta_vec[i]) + 1.0);
174 return operands_and_partials.
to_var(logp);
177 template <
bool propto,
179 typename T_shape,
typename T_inv_scale>
183 const T_shape& alpha,
184 const T_inv_scale& beta) {
185 return neg_binomial_log<propto>(n,alpha,beta,
189 template <
typename T_n,
190 typename T_shape,
typename T_inv_scale,
195 const T_shape& alpha,
196 const T_inv_scale& beta,
198 return neg_binomial_log<false>(n,alpha,beta,Policy());
201 template <
typename T_n,
202 typename T_shape,
typename T_inv_scale>
206 const T_shape& alpha,
207 const T_inv_scale& beta) {
208 return neg_binomial_log<false>(n,alpha,beta,
213 template <
bool propto,
typename T_n,
typename T_shape,
214 typename T_inv_scale,
218 const T_inv_scale& beta,
221 static const char*
function =
"stan::prob::neg_binomial_cdf(%1%)";
236 if (!
check_finite(
function, alpha,
"Shape parameter", &P, Policy()))
239 if (!
check_positive(
function, alpha,
"Shape parameter", &P, Policy()))
242 if (!
check_finite(
function, beta,
"Inverse scale parameter",
254 "Inverse scale parameter",
271 using boost::math::ibeta_derivative;
273 using boost::math::digamma;
276 operands_and_partials(alpha, beta);
280 + operands_and_partials.
nvaris,
287 return operands_and_partials.
to_var(0.0);
293 digammaN_vec(stan::length(alpha));
296 digammaAlpha_vec(stan::length(alpha));
299 digammaSum_vec(stan::length(alpha));
302 betaFunc_vec(stan::length(alpha));
307 const double n_dbl =
value_of(n_vec[i]);
308 const double alpha_dbl =
value_of(alpha_vec[i]);
310 digammaN_vec[i] = digamma(n_dbl + 1);
311 digammaAlpha_vec[i] = digamma(alpha_dbl);
312 digammaSum_vec[i] = digamma(n_dbl + alpha_dbl + 1);
313 betaFunc_vec[i] = boost::math::beta(n_dbl + 1, alpha_dbl);
317 for (
size_t i = 0; i <
size; i++) {
322 == std::numeric_limits<double>::infinity())
325 const double n_dbl =
value_of(n_vec[i]);
326 const double alpha_dbl =
value_of(alpha_vec[i]);
327 const double beta_dbl =
value_of(beta_vec[i]);
329 const double p_dbl = beta_dbl / (1.0 + beta_dbl);
330 const double d_dbl = 1.0 / ( (1.0 + beta_dbl)
331 * (1.0 + beta_dbl) );
333 const double Pi =
ibeta(alpha_dbl, n_dbl + 1.0, p_dbl);
349 operands_and_partials.
d_x1[i]
354 operands_and_partials.
d_x2[i]
355 += d_dbl * ibeta_derivative(alpha_dbl, n_dbl + 1, p_dbl)
362 operands_and_partials.
d_x1[i] *= P;
366 operands_and_partials.
d_x2[i] *= P;
368 return operands_and_partials.
to_var(P);
372 template <
bool propto,
typename T_n,
typename T_shape,
373 typename T_inv_scale>
376 const T_inv_scale& beta) {
377 return neg_binomial_cdf<propto>(n, alpha, beta,
381 template <
typename T_n,
typename T_shape,
typename T_inv_scale,
385 const T_inv_scale& beta,
const Policy&) {
386 return neg_binomial_cdf<false>(n, alpha, beta, Policy());
389 template <
typename T_n,
typename T_shape,
typename T_inv_scale>
392 const T_inv_scale& beta) {
393 return neg_binomial_cdf<false>(n, alpha, beta,
402 using boost::variate_generator;
403 using boost::random::negative_binomial_distribution;
404 variate_generator<RNG&, negative_binomial_distribution<> >
406 negative_binomial_distribution<>(alpha,