pub(crate) fn regularized_gamma_p(a: f64, x: f64) -> f64 {
crate::distributions::reg_gamma_p(a, x)
}
pub(crate) fn chi2_cdf(x: f64, k: usize) -> f64 {
crate::distributions::chi2_cdf(x, k)
}
pub(crate) fn chi2_quantile(p: f64, k: usize) -> f64 {
crate::distributions::chi2_quantile(p, k)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::distributions::ln_gamma;
use std::f64::consts::PI;
#[test]
fn test_ln_gamma_known_values() {
assert!((ln_gamma(1.0)).abs() < 1e-10);
assert!((ln_gamma(2.0)).abs() < 1e-10);
assert!((ln_gamma(5.0) - 24.0_f64.ln()).abs() < 1e-6);
assert!((ln_gamma(0.5) - 0.5 * PI.ln()).abs() < 1e-6);
}
#[test]
fn test_chi2_cdf_zero() {
assert_eq!(chi2_cdf(0.0, 1), 0.0);
assert_eq!(chi2_cdf(0.0, 5), 0.0);
assert_eq!(chi2_cdf(-1.0, 3), 0.0);
}
#[test]
fn test_chi2_cdf_known_values() {
let val = chi2_cdf(1.3862943611198906, 2);
assert!(
(val - 0.5).abs() < 1e-4,
"chi2_cdf(1.386, 2) should be ~0.5, got {val}"
);
let val = chi2_cdf(5.991464547107979, 2);
assert!(
(val - 0.95).abs() < 1e-3,
"chi2_cdf(5.991, 2) should be ~0.95, got {val}"
);
}
#[test]
fn test_chi2_quantile_median() {
let q = chi2_quantile(0.5, 2);
assert!(
(q - 1.3862943611198906).abs() < 0.01,
"chi2_quantile(0.5, 2) should be ~1.3863, got {q}"
);
}
#[test]
fn test_chi2_quantile_95th() {
let q = chi2_quantile(0.95, 2);
assert!(
(q - 5.991464547107979).abs() < 0.01,
"chi2_quantile(0.95, 2) should be ~5.991, got {q}"
);
}
#[test]
fn test_chi2_roundtrip() {
for k in &[1, 2, 5, 10, 20] {
for &x in &[0.5, 1.0, 3.0, 5.0, 10.0, 20.0] {
let p = chi2_cdf(x, *k);
if p > 0.001 && p < 0.999 {
let x_back = chi2_quantile(p, *k);
assert!(
(x_back - x).abs() < 0.05,
"Round-trip failed for k={k}, x={x}: got p={p}, x_back={x_back}"
);
}
}
}
}
#[test]
fn test_chi2_quantile_boundary() {
assert_eq!(chi2_quantile(0.0, 5), 0.0);
assert!(chi2_quantile(1.0, 5).is_infinite());
}
#[test]
fn test_regularized_gamma_boundary() {
assert_eq!(regularized_gamma_p(1.0, 0.0), 0.0);
assert_eq!(regularized_gamma_p(5.0, 0.0), 0.0);
}
}