1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
4 #include <boost/random/gamma_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
35 template <
bool propto,
36 typename T_y,
typename T_shape,
typename T_scale,
38 typename return_type<T_y,T_shape,T_scale>::type
41 static const char*
function =
"stan::prob::inv_gamma_log(%1%)";
47 using boost::math::tools::promote_args;
60 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
76 "Random variable",
"Shape parameter",
90 for (
size_t n = 0; n <
length(y); n++) {
91 const double y_dbl =
value_of(y_vec[n]);
98 operands_and_partials(y, alpha, beta);
102 using boost::math::digamma;
110 for(
size_t n = 0; n <
length(y); n++) {
115 inv_y[n] = 1.0 /
value_of(y_vec[n]);
120 lgamma_alpha(
length(alpha));
123 digamma_alpha(
length(alpha));
124 for (
size_t n = 0; n <
length(alpha); n++) {
128 digamma_alpha[n] = digamma(
value_of(alpha_vec[n]));
135 for (
size_t n = 0; n <
length(beta); n++)
138 for (
size_t n = 0; n < N; n++) {
140 const double alpha_dbl =
value_of(alpha_vec[n]);
141 const double beta_dbl =
value_of(beta_vec[n]);
144 logp -= lgamma_alpha[n];
146 logp += alpha_dbl * log_beta[n];
148 logp -= (alpha_dbl+1.0) * log_y[n];
150 logp -= beta_dbl * inv_y[n];
154 operands_and_partials.
d_x1[n]
155 += -(alpha_dbl+1) * inv_y[n] + beta_dbl * inv_y[n] * inv_y[n];
157 operands_and_partials.
d_x2[n]
158 += -digamma_alpha[n] + log_beta[n] - log_y[n];
160 operands_and_partials.
d_x3[n] += alpha_dbl / beta_dbl - inv_y[n];
162 return operands_and_partials.
to_var(logp);
165 template <
bool propto,
166 typename T_y,
typename T_shape,
typename T_scale>
173 template <
typename T_y,
typename T_shape,
typename T_scale,
179 return inv_gamma_log<false>(y,alpha,beta,Policy());
182 template <
typename T_y,
typename T_shape,
typename T_scale>
205 template <
typename T_y,
typename T_shape,
typename T_scale,
class Policy>
215 static const char*
function =
"stan::prob::inv_gamma_cdf(%1%)";
226 using boost::math::tools::promote_args;
230 if (!
check_finite(
function, alpha,
"Shape parameter", &P, Policy()))
233 if (!
check_positive(
function, alpha,
"Shape parameter", &P, Policy()))
236 if (!
check_finite(
function, beta,
"Scale parameter", &P, Policy()))
239 if (!
check_positive(
function, beta,
"Scale parameter", &P, Policy()))
242 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
249 "Random variable",
"Shape parameter",
258 size_t N =
max_size(y, alpha, beta);
261 operands_and_partials(y, alpha, beta);
265 + operands_and_partials.
nvaris, 0.0);
272 return operands_and_partials.
to_var(0.0);
276 using boost::math::gamma_p_derivative;
277 using boost::math::gamma_q;
278 using boost::math::digamma;
284 gamma_vec(stan::length(alpha));
287 digamma_vec(stan::length(alpha));
291 const double alpha_dbl =
value_of(alpha_vec[i]);
292 gamma_vec[i] =
tgamma(alpha_dbl);
293 digamma_vec[i] = digamma(alpha_dbl);
298 for (
size_t n = 0; n < N; n++) {
301 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity())
305 const double y_dbl =
value_of(y_vec[n]);
306 const double y_inv_dbl = 1.0 / y_dbl;
307 const double alpha_dbl =
value_of(alpha_vec[n]);
308 const double beta_dbl =
value_of(beta_vec[n]);
311 const double Pn = gamma_q(alpha_dbl, beta_dbl * y_inv_dbl);
316 operands_and_partials.
d_x1[n]
317 += beta_dbl * y_inv_dbl * y_inv_dbl
318 * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl)
322 operands_and_partials.
d_x2[n]
324 * y_inv_dbl, gamma_vec[n],
325 digamma_vec[n]) / Pn;
328 operands_and_partials.
d_x3[n]
329 += - y_inv_dbl * gamma_p_derivative(alpha_dbl,
330 beta_dbl * y_inv_dbl) / Pn;
336 operands_and_partials.
d_x1[n] *= P;
340 operands_and_partials.
d_x2[n] *= P;
344 operands_and_partials.
d_x3[n] *= P;
346 return operands_and_partials.
to_var(P);
349 template <
typename T_y,
typename T_shape,
typename T_scale>
360 using boost::variate_generator;
361 using boost::random::gamma_distribution;
362 variate_generator<RNG&, gamma_distribution<> >
363 gamma_rng(rng, gamma_distribution<>(alpha, 1 / beta));