1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__INV_GAMMA_HPP__
32 template <
bool propto,
33 typename T_y,
typename T_shape,
typename T_scale,
35 typename return_type<T_y,T_shape,T_scale>::type
38 static const char*
function =
"stan::prob::inv_gamma_log(%1%)";
44 using boost::math::tools::promote_args;
57 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
73 "Random variable",
"Shape parameter",
"Scale parameter",
86 for (
size_t n = 0; n <
length(y); n++) {
87 const double y_dbl =
value_of(y_vec[n]);
97 using boost::math::digamma;
103 for(
size_t n = 0; n <
length(y); n++) {
108 inv_y[n] = 1.0 /
value_of(y_vec[n]);
112 lgamma_alpha(
length(alpha));
114 digamma_alpha(
length(alpha));
115 for (
size_t n = 0; n <
length(alpha); n++) {
119 digamma_alpha[n] = digamma(
value_of(alpha_vec[n]));
125 for (
size_t n = 0; n <
length(beta); n++)
128 for (
size_t n = 0; n < N; n++) {
130 const double alpha_dbl =
value_of(alpha_vec[n]);
131 const double beta_dbl =
value_of(beta_vec[n]);
134 logp -= lgamma_alpha[n];
136 logp += alpha_dbl * log_beta[n];
138 logp -= (alpha_dbl+1.0) * log_y[n];
140 logp -= beta_dbl * inv_y[n];
144 operands_and_partials.
d_x1[n] += -(alpha_dbl+1) * inv_y[n] + beta_dbl * inv_y[n] * inv_y[n];
146 operands_and_partials.
d_x2[n] += -digamma_alpha[n] + log_beta[n] - log_y[n];
148 operands_and_partials.
d_x3[n] += alpha_dbl / beta_dbl - inv_y[n];
150 return operands_and_partials.
to_var(logp);
153 template <
bool propto,
154 typename T_y,
typename T_shape,
typename T_scale>
161 template <
typename T_y,
typename T_shape,
typename T_scale,
167 return inv_gamma_log<false>(y,alpha,beta,Policy());
170 template <
typename T_y,
typename T_shape,
typename T_scale>
192 template <
typename T_y,
typename T_shape,
typename T_scale,
class Policy>
194 inv_gamma_cdf(
const T_y& y,
const T_shape& alpha,
const T_scale& beta,
const Policy&) {
200 static const char*
function =
"stan::prob::inv_gamma_cdf(%1%)";
209 using boost::math::tools::promote_args;
213 if (!
check_finite(
function, alpha,
"Shape parameter", &P, Policy()))
216 if (!
check_positive(
function, alpha,
"Shape parameter", &P, Policy()))
219 if (!
check_finite(
function, beta,
"Scale parameter", &P, Policy()))
222 if (!
check_positive(
function, beta,
"Scale parameter", &P, Policy()))
225 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
228 if (!
check_positive(
function, y,
"Random variable", &P, Policy()))
232 "Random variable",
"Shape parameter",
"Scale Parameter",
240 size_t N =
max_size(y, alpha, beta);
249 using boost::math::gamma_p_derivative;
250 using boost::math::gamma_q;
251 using boost::math::digamma;
261 const double alpha_dbl =
value_of(alpha_vec[i]);
262 gamma_vec[i] =
tgamma(alpha_dbl);
263 digamma_vec[i] = digamma(alpha_dbl);
269 for (
size_t n = 0; n < N; n++) {
272 const double y_dbl =
value_of(y_vec[n]);
273 const double y_inv_dbl = 1.0 / y_dbl;
274 const double alpha_dbl =
value_of(alpha_vec[n]);
275 const double beta_dbl =
value_of(beta_vec[n]);
278 const double Pn = gamma_q(alpha_dbl, beta_dbl * y_inv_dbl);
283 operands_and_partials.
d_x1[n]
284 += beta_dbl * y_inv_dbl * y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;
287 operands_and_partials.
d_x2[n]
291 operands_and_partials.
d_x3[n]
292 += - y_inv_dbl * gamma_p_derivative(alpha_dbl, beta_dbl * y_inv_dbl) / Pn;
296 for (
size_t n = 0; n < N; n++) {
299 operands_and_partials.
d_x1[n] *= P;
302 operands_and_partials.
d_x2[n] *= P;
305 operands_and_partials.
d_x3[n] *= P;
309 return operands_and_partials.
to_var(P);
313 template <
typename T_y,
typename T_shape,
typename T_scale>