1 #ifndef __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__SCALED_INV_CHI_SQUARE_HPP__
2 #define __STAN__PROB__DISTRIBUTIONS__UNIVARIATE__CONTINUOUS__SCALED_INV_CHI_SQUARE_HPP__
35 template <
bool propto,
36 typename T_y,
typename T_dof,
typename T_scale,
38 typename return_type<T_y,T_dof,T_scale>::type
41 static const char*
function
42 =
"stan::prob::scaled_inv_chi_square_log(%1%)";
57 if (!
check_not_nan(
function, y,
"Random variable", &logp, Policy()))
59 if (!
check_finite(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
61 if (!
check_positive(
function, nu,
"Degrees of freedom parameter", &logp, Policy()))
63 if (!
check_finite(
function, s,
"Scale parameter", &logp, Policy()))
65 if (!
check_positive(
function, s,
"Scale parameter", &logp, Policy()))
69 "Random variable",
"Degrees of freedom parameter",
"Scale parameter",
82 for (
size_t n = 0; n < N; n++) {
90 for (
size_t n = 0; n < N; n++) {
96 logp += nu_vec[n] *
log(s_vec[n]);
100 logp -= nu_vec[n] * 0.5 *
square(s_vec[n]) / y_vec[n];
105 template <
bool propto,
106 typename T_y,
typename T_dof,
typename T_scale>
110 return scaled_inv_chi_square_log<propto>(y,nu,s,
114 template <
typename T_y,
typename T_dof,
typename T_scale,
120 return scaled_inv_chi_square_log<false>(y,nu,s,Policy());
123 template <
typename T_y,
typename T_dof,
typename T_scale>
127 return scaled_inv_chi_square_log<false>(y,nu,s,
145 template <
typename T_y,
typename T_dof,
typename T_scale,
class Policy>
149 static const char*
function =
"stan::prob::scaled_inv_chi_square_log(%1%)";
156 using boost::math::tools::promote_args;
160 if (!
check_not_nan(
function, y,
"Random variable", &P, Policy()))
163 if (!
check_positive(
function, y,
"Random variable", &P, Policy()))
166 if (!
check_finite(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
169 if (!
check_positive(
function, nu,
"Degrees of freedom parameter", &P, Policy()))
172 if (!
check_finite(
function, s,
"Scale parameter", &P, Policy()))
175 if (!
check_positive(
function, s,
"Scale parameter", &P, Policy()))
179 "Random variable",
"Degrees of freedom parameter",
"Scale parameter",
196 using boost::math::gamma_p_derivative;
197 using boost::math::gamma_q;
198 using boost::math::digamma;
208 const double half_nu_dbl = 0.5 *
value_of(nu_vec[i]);
209 gamma_vec[i] =
tgamma(half_nu_dbl);
210 digamma_vec[i] = digamma(half_nu_dbl);
216 for (
size_t n = 0; n < N; n++) {
219 const double y_dbl =
value_of(y_vec[n]);
220 const double y_inv_dbl = 1.0 / y_dbl;
221 const double half_nu_dbl = 0.5 *
value_of(nu_vec[n]);
222 const double s_dbl =
value_of(s_vec[n]);
223 const double half_s2_overx_dbl = 0.5 * s_dbl * s_dbl * y_inv_dbl;
224 const double half_nu_s2_overx_dbl = 2.0 * half_nu_dbl * half_s2_overx_dbl;
227 const double Pn = gamma_q(half_nu_dbl, half_nu_s2_overx_dbl);
232 operands_and_partials.
d_x1[n]
233 += half_nu_s2_overx_dbl * y_inv_dbl * gamma_p_derivative(half_nu_dbl, half_nu_s2_overx_dbl) / Pn;
236 operands_and_partials.
d_x2[n]
238 - half_s2_overx_dbl * gamma_p_derivative(half_nu_dbl, half_nu_s2_overx_dbl) ) / Pn;
241 operands_and_partials.
d_x3[n]
242 += - 2.0 * half_nu_dbl * s_dbl * y_inv_dbl * gamma_p_derivative(half_nu_dbl, half_nu_s2_overx_dbl) / Pn;
246 for (
size_t n = 0; n < N; n++) {
249 operands_and_partials.
d_x1[n] *= P;
252 operands_and_partials.
d_x2[n] *= P;
255 operands_and_partials.
d_x3[n] *= P;
259 return operands_and_partials.
to_var(P);
264 template <
typename T_y,
typename T_dof,
typename T_scale>