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>
40 template <
bool propto,
41 typename T_y,
typename T_dof>
42 typename return_type<T_y,T_dof>::type
44 static const char*
function =
"stan::prob::inv_chi_square_log(%1%)";
62 "Random variable",
"Degrees of freedom parameter",
71 for (
size_t n = 0; n <
length(y); n++)
81 for (
size_t i = 0; i <
length(y); i++)
87 for (
size_t i = 0; i <
length(y); i++)
95 for (
size_t i = 0; i <
length(nu); i++) {
96 double half_nu = 0.5 *
value_of(nu_vec[i]);
98 lgamma_half_nu[i] =
lgamma(half_nu);
100 digamma_half_nu_over_two[i] =
digamma(half_nu) * 0.5;
104 for (
size_t n = 0; n < N; n++) {
105 const double nu_dbl =
value_of(nu_vec[n]);
106 const double half_nu = 0.5 * nu_dbl;
109 logp += nu_dbl * NEG_LOG_TWO_OVER_TWO - lgamma_half_nu[n];
111 logp -= (half_nu+1.0) * log_y[n];
113 logp -= 0.5 * inv_y[n];
116 operands_and_partials.
d_x1[n]
117 += -(half_nu+1.0) * inv_y[n] + 0.5 * inv_y[n] * inv_y[n];
120 operands_and_partials.
d_x2[n]
121 += NEG_LOG_TWO_OVER_TWO - digamma_half_nu_over_two[n]
125 return operands_and_partials.
to_var(logp);
128 template <
typename T_y,
typename T_dof>
132 return inv_chi_square_log<false>(y,nu);
135 template <
typename T_y,
typename T_dof>
143 static const char*
function =
"stan::prob::inv_chi_square_cdf(%1%)";
149 using boost::math::tools::promote_args;
159 "Degrees of freedom parameter",
174 return operands_and_partials.
to_var(0.0);
177 using boost::math::gamma_p_derivative;
190 const double nu_dbl =
value_of(nu_vec[i]);
191 gamma_vec[i] =
tgamma(0.5 * nu_dbl);
192 digamma_vec[i] =
digamma(0.5 * nu_dbl);
197 for (
size_t n = 0; n < N; n++) {
201 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
206 const double y_dbl =
value_of(y_vec[n]);
207 const double y_inv_dbl = 1.0 / y_dbl;
208 const double nu_dbl =
value_of(nu_vec[n]);
211 const double Pn =
gamma_q(0.5 * nu_dbl, 0.5 * y_inv_dbl);
216 operands_and_partials.
d_x1[n]
217 += 0.5 * y_inv_dbl * y_inv_dbl
218 * gamma_p_derivative(0.5 * nu_dbl, 0.5 * y_inv_dbl) / Pn;
220 operands_and_partials.
d_x2[n]
224 digamma_vec[n]) / Pn;
229 operands_and_partials.
d_x1[n] *= P;
232 operands_and_partials.
d_x2[n] *= P;
234 return operands_and_partials.
to_var(P);
237 template <
typename T_y,
typename T_dof>
245 static const char*
function =
"stan::prob::inv_chi_square_cdf_log(%1%)";
251 using boost::math::tools::promote_args;
261 "Degrees of freedom parameter", &P);
278 using boost::math::gamma_p_derivative;
291 const double nu_dbl =
value_of(nu_vec[i]);
292 gamma_vec[i] =
tgamma(0.5 * nu_dbl);
293 digamma_vec[i] =
digamma(0.5 * nu_dbl);
298 for (
size_t n = 0; n < N; n++) {
302 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
307 const double y_dbl =
value_of(y_vec[n]);
308 const double y_inv_dbl = 1.0 / y_dbl;
309 const double nu_dbl =
value_of(nu_vec[n]);
312 const double Pn =
gamma_q(0.5 * nu_dbl, 0.5 * y_inv_dbl);
317 operands_and_partials.
d_x1[n] += 0.5 * y_inv_dbl * y_inv_dbl
318 * gamma_p_derivative(0.5 * nu_dbl, 0.5 * y_inv_dbl) / Pn;
320 operands_and_partials.
d_x2[n]
324 digamma_vec[n]) / Pn;
327 return operands_and_partials.
to_var(P);
330 template <
typename T_y,
typename T_dof>
338 static const char*
function =
"stan::prob::inv_chi_square_ccdf_log(%1%)";
344 using boost::math::tools::promote_args;
354 "Degrees of freedom parameter", &P);
368 return operands_and_partials.
to_var(0.0);
371 using boost::math::gamma_p_derivative;
384 const double nu_dbl =
value_of(nu_vec[i]);
385 gamma_vec[i] =
tgamma(0.5 * nu_dbl);
386 digamma_vec[i] =
digamma(0.5 * nu_dbl);
391 for (
size_t n = 0; n < N; n++) {
395 if (
value_of(y_vec[n]) == std::numeric_limits<double>::infinity()) {
400 const double y_dbl =
value_of(y_vec[n]);
401 const double y_inv_dbl = 1.0 / y_dbl;
402 const double nu_dbl =
value_of(nu_vec[n]);
405 const double Pn = 1.0 -
gamma_q(0.5 * nu_dbl, 0.5 * y_inv_dbl);
410 operands_and_partials.
d_x1[n] -= 0.5 * y_inv_dbl * y_inv_dbl
411 * gamma_p_derivative(0.5 * nu_dbl, 0.5 * y_inv_dbl) / Pn;
413 operands_and_partials.
d_x2[n]
417 digamma_vec[n]) / Pn;
420 return operands_and_partials.
to_var(P);
427 using boost::variate_generator;
428 using boost::random::chi_squared_distribution;
430 static const char*
function =
"stan::prob::inv_chi_square_rng(%1%)";
437 variate_generator<RNG&, chi_squared_distribution<> >
fvar< T > tgamma(const fvar< T > &x)
T_return_type to_var(double logp)
bool check_positive_finite(const char *function, const T_y &y, const char *name, T_result *result)
return_type< T_y, T_dof >::type inv_chi_square_cdf(const T_y &y, const T_dof &nu)
boost::math::tools::promote_args< T_a, T_b >::type multiply_log(const T_a a, const T_b b)
Calculated the value of the first argument times log of the second argument while behaving properly w...
DoubleVectorView allocates double values to be used as intermediate values.
return_type< T_y, T_dof >::type inv_chi_square_log(const T_y &y, const T_dof &nu)
The log of an inverse chi-squared density for y with the specified degrees of freedom parameter...
T value_of(const fvar< T > &v)
Return the value of the specified variable.
fvar< T > lgamma(const fvar< T > &x)
A variable implementation that stores operands and derivatives with respect to the variable...
boost::math::tools::promote_args< typename scalar_type< T1 >::type, typename scalar_type< T2 >::type, typename scalar_type< T3 >::type, typename scalar_type< T4 >::type, typename scalar_type< T5 >::type, typename scalar_type< T6 >::type >::type type
Metaprogram to determine if a type has a base scalar type that can be assigned to type double...
double value_of(const T x)
Return the value of the specified scalar argument converted to a double value.
Template metaprogram to calculate whether a summand needs to be included in a proportional (log) prob...
fvar< T > gamma_q(const fvar< T > &x1, const fvar< T > &x2)
VectorView< double *, is_vector< T2 >::value, is_constant_struct< T2 >::value > d_x2
double gradRegIncGamma(double a, double z, double g, double dig, double precision=1e-6)
bool check_nonnegative(const char *function, const T_y &y, const char *name, T_result *result)
bool check_consistent_sizes(const char *function, const T1 &x1, const T2 &x2, const char *name1, const char *name2, T_result *result)
size_t max_size(const T1 &x1, const T2 &x2)
return_type< T_y, T_dof >::type inv_chi_square_ccdf_log(const T_y &y, const T_dof &nu)
bool check_not_nan(const char *function, const T_y &y, const char *name, T_result *result)
Checks if the variable y is nan.
fvar< T > digamma(const fvar< T > &x)
VectorView< double *, is_vector< T1 >::value, is_constant_struct< T1 >::value > d_x1
double inv_chi_square_rng(const double nu, RNG &rng)
fvar< T > log(const fvar< T > &x)
VectorView is a template metaprogram that takes its argument and allows it to be used like a vector...
double negative_infinity()
Return negative infinity.
return_type< T_y, T_dof >::type inv_chi_square_cdf_log(const T_y &y, const T_dof &nu)
double chi_square_rng(const double nu, RNG &rng)