inline RealType quantile(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& p) { using boost::math::gamma_q_inv; RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); static const char* function = "boost::math::quantile(const inverse_chi_squared_distribution<%1%>&, %1%)"; // Error check: RealType error_result; if(false == detail::check_df( function, df, &error_result, Policy()) && detail::check_probability( function, p, &error_result, Policy())) { return error_result; } if(false == detail::check_probability( function, p, &error_result, Policy())) { return error_result; } // RealType shape = df /2; // inv_gamma shape, // RealType scale = df * scale/2; // inv_gamma scale, // result = scale / gamma_q_inv(shape, p, Policy()); RealType result = gamma_q_inv(df /2, p, Policy()); if(result == 0) return policies::raise_overflow_error<RealType, Policy>(function, "Random variable is infinite.", Policy()); result = df * (scale / 2) / result; return result; } // quantile
inline RealType cdf(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& x) { static const char* function = "boost::math::cdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); RealType error_result; if(false == detail::check_inverse_chi_squared(function, df, scale, &error_result, Policy()) ) { // Bad distribution. return error_result; } if((x < 0) || !(boost::math::isfinite)(x)) { // Bad x. return policies::raise_domain_error<RealType>( function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); } if (x == 0) { // Treat zero as a special case. return 0; } // RealType shape = df /2; // inv_gamma shape, // RealType scale = df * scale/2; // inv_gamma scale, // result = boost::math::gamma_q(shape, scale / x, Policy()); // inverse_gamma code. return boost::math::gamma_q(df / 2, (df * (scale / 2)) / x, Policy()); } // cdf
inline RealType mean(const inverse_chi_squared_distribution<RealType, Policy>& dist) { // Mean of inverse Chi-Squared distribution. RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); static const char* function = "boost::math::mean(const inverse_chi_squared_distribution<%1%>&)"; if(df <= 2) return policies::raise_domain_error<RealType>( function, "inverse Chi-Squared distribution only has a mode for degrees of freedom > 2, but got degrees of freedom = %1%.", df, Policy()); return (df * scale) / (df - 2); } // mean
inline RealType variance(const inverse_chi_squared_distribution<RealType, Policy>& dist) { // Variance of inverse Chi-Squared distribution. RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); static const char* function = "boost::math::variance(const inverse_chi_squared_distribution<%1%>&)"; if(df <= 4) { return policies::raise_domain_error<RealType>( function, "inverse Chi-Squared distribution only has a variance for degrees of freedom > 4, but got degrees of freedom = %1%.", df, Policy()); } return 2 * df * df * scale * scale / ((df - 2)*(df - 2) * (df - 4)); } // variance
inline RealType mode(const inverse_chi_squared_distribution<RealType, Policy>& dist) { // mode is not defined in Mathematica. // See Discussion section http://en.wikipedia.org/wiki/Talk:Scaled-inverse-chi-square_distribution // for origin of the formula used below. RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); static const char* function = "boost::math::mode(const inverse_chi_squared_distribution<%1%>&)"; if(df < 0) return policies::raise_domain_error<RealType>( function, "inverse Chi-Squared distribution only has a mode for degrees of freedom >= 0, but got degrees of freedom = %1%.", df, Policy()); return (df * scale) / (df + 2); }
RealType pdf(const inverse_chi_squared_distribution<RealType, Policy>& dist, const RealType& x) { BOOST_MATH_STD_USING // for ADL of std functions. RealType df = dist.degrees_of_freedom(); RealType scale = dist.scale(); RealType error_result; static const char* function = "boost::math::pdf(const inverse_chi_squared_distribution<%1%>&, %1%)"; if(false == detail::check_inverse_chi_squared (function, df, scale, &error_result, Policy()) ) { // Bad distribution. return error_result; } if((x < 0) || !(boost::math::isfinite)(x)) { // Bad x. return policies::raise_domain_error<RealType>( function, "inverse Chi Square parameter was %1%, but must be >= 0 !", x, Policy()); } if(x == 0) { // Treat as special case. return 0; } // Wikipedia scaled inverse chi sq (df, scale) related to inv gamma (df/2, df * scale /2) // so use inverse gamma pdf with shape = df/2, scale df * scale /2 // RealType shape = df /2; // inv_gamma shape // RealType scale = df * scale/2; // inv_gamma scale // RealType result = gamma_p_derivative(shape, scale / x, Policy()) * scale / (x * x); RealType result = df * scale/2 / x; if(result < tools::min_value<RealType>()) return 0; // Random variable is near enough infinite. result = gamma_p_derivative(df/2, result, Policy()) * df * scale/2; if(result != 0) // prevent 0 / 0, gamma_p_derivative -> 0 faster than x^2 result /= (x * x); return result; } // pdf