use crate::betainc;
pub fn betacdf(x: f64, a: f64, b: f64, upper: bool) -> f64 {
match (0.0 < a && a < f64::INFINITY) && (0.0 < b && b < f64::INFINITY) {
true => (),
false => return f64::NAN,
}
match upper {
true => {
if x <= 0.0 { return 1.0; }
if x >= 1.0 { return 0.0; }
},
false => {
if x < 0.0 { return 0.0;}
if x > 1.0 { return 1.0;}
},
}
let p = betainc(x, a, b, !upper);
return p;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_betacdf_uniform() {
assert_eq!(betacdf(0.1, 1.0, 1.0, false), 0.1);
assert_eq!(betacdf(0.5, 1.0, 1.0, false), 0.5);
assert_eq!(betacdf(0.9, 1.0, 1.0, false), 0.9);
}
#[test]
fn test_betacdf_known_values() {
let tol = 1e-14;
assert!((betacdf(0.2, 1.0, 3.0, false) - 0.488).abs() < tol);
assert_eq!(betacdf(0.5, 2.0, 2.0, false), 0.5);
}
#[test]
fn test_betacdf_tail_consistency() {
let x = 0.3;
let a = 2.5;
let b = 1.5;
let p = betacdf(x, a, b, false);
let q = betacdf(x, a, b, true);
assert!((p + q - 1.0).abs() < 1e-15);
}
#[test]
fn test_betacdf_symmetry() {
let x = 0.4;
let a = 3.0;
let b = 2.0;
assert!((betacdf(x, a, b, false) - betacdf(1.0 - x, b, a, true)).abs() < 1e-15);
}
#[test]
fn test_betacdf_boundaries() {
assert_eq!(betacdf(-0.1, 2.0, 2.0, false), 0.0);
assert_eq!(betacdf(1.1, 2.0, 2.0, false), 1.0);
assert_eq!(betacdf(-0.1, 2.0, 2.0, true), 1.0);
assert_eq!(betacdf(1.1, 2.0, 2.0, true), 0.0);
}
#[test]
fn test_betacdf_invalid_params() {
assert!(betacdf(0.5, 0.0, 1.0, false).is_nan());
assert!(betacdf(0.5, 1.0, -1.0, false).is_nan());
assert!(betacdf(0.5, f64::INFINITY, 1.0, false).is_nan());
}
}