1 #ifndef __STAN__PROB__DIST__UNI__CONTINUOUS__INV_CHI_SQUARE_HPP__
2 #define __STAN__PROB__DIST__UNI__CONTINUOUS__INV_CHI_SQUARE_HPP__
4 #include <boost/random/chi_squared_distribution.hpp>
5 #include <boost/random/variate_generator.hpp>
38 template <
bool propto,
39 typename T_y,
typename T_dof,
41 typename return_type<T_y,T_dof>::type
44 static const char*
function =
"stan::prob::inv_chi_square_log(%1%)";
58 if (!
check_finite(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
60 if (!
check_positive(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
62 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
67 "Random variable",
"Degrees of freedom parameter",
77 for (
size_t n = 0; n <
length(y); n++)
81 using boost::math::digamma;
87 for (
size_t i = 0; i <
length(y); i++)
93 for (
size_t i = 0; i <
length(y); i++)
101 for (
size_t i = 0; i <
length(nu); i++) {
102 double half_nu = 0.5 *
value_of(nu_vec[i]);
104 lgamma_half_nu[i] =
lgamma(half_nu);
106 digamma_half_nu_over_two[i] = digamma(half_nu) * 0.5;
110 for (
size_t n = 0; n < N; n++) {
111 const double nu_dbl =
value_of(nu_vec[n]);
112 const double half_nu = 0.5 * nu_dbl;
115 logp += nu_dbl * NEG_LOG_TWO_OVER_TWO - lgamma_half_nu[n];
117 logp -= (half_nu+1.0) * log_y[n];
119 logp -= 0.5 * inv_y[n];
122 operands_and_partials.
d_x1[n]
123 += -(half_nu+1.0) * inv_y[n] + 0.5 * inv_y[n] * inv_y[n];
126 operands_and_partials.
d_x2[n]
127 += NEG_LOG_TWO_OVER_TWO - digamma_half_nu_over_two[n] - 0.5*log_y[n];
130 return operands_and_partials.
to_var(logp);
133 template <
bool propto,
134 typename T_y,
typename T_dof>
141 template <
typename T_y,
typename T_dof,
147 return inv_chi_square_log<false>(y,nu,Policy());
151 template <
typename T_y,
typename T_dof>
158 template <
typename T_y,
typename T_dof,
class Policy>
166 static const char*
function =
"stan::prob::inv_chi_square_cdf(%1%)";
174 using boost::math::tools::promote_args;
179 if (!
check_finite(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
182 if (!
check_positive(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
185 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
192 "Random variable",
"Degrees of freedom parameter",
211 return operands_and_partials.
to_var(0.0);
214 using boost::math::gamma_p_derivative;
215 using boost::math::gamma_q;
217 using boost::math::digamma;
228 const double nu_dbl =
value_of(nu_vec[i]);
229 gamma_vec[i] =
tgamma(0.5 * nu_dbl);
230 digamma_vec[i] = digamma(0.5 * nu_dbl);
236 for (
size_t n = 0; n < N; n++) {
240 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
245 const double y_dbl =
value_of(y_vec[n]);
246 const double y_inv_dbl = 1.0 / y_dbl;
247 const double nu_dbl =
value_of(nu_vec[n]);
250 const double Pn = gamma_q(0.5 * nu_dbl, 0.5 * y_inv_dbl);
255 operands_and_partials.
d_x1[n]
256 += 0.5 * y_inv_dbl * y_inv_dbl
257 * gamma_p_derivative(0.5 * nu_dbl, 0.5 * y_inv_dbl) / Pn;
260 operands_and_partials.
d_x2[n]
264 digamma_vec[n]) / Pn;
270 operands_and_partials.
d_x1[n] *= P;
274 operands_and_partials.
d_x2[n] *= P;
276 return operands_and_partials.
to_var(P);
279 template <
typename T_y,
typename T_dof>
289 using boost::variate_generator;
290 using boost::random::chi_squared_distribution;
291 variate_generator<RNG&, chi_squared_distribution<> >