pub fn okamoto_bound(confidence: f64, precision: f64) -> f64 {
(2f64 / (1f64 - confidence)).ln() * 0.5f64 / precision.powi(2)
}
pub fn adaptive_bound(avg: f64, confidence: f64, precision: f64) -> f64 {
okamoto_bound(confidence, precision)
* precision
.mul_add(-2f64 / 3f64, (avg - 0.5f64).abs())
.powi(2)
.mul_add(-4f64, 1f64)
}
pub fn derive_precision(s: u32, f: u32, confidence: f64) -> f64 {
let n = s + f;
let avg = s as f64 / n as f64;
let k = 2f64 * (2f64 / (1f64 - confidence)).ln();
let a = k.mul_add(4f64 / 9f64, n as f64);
let b = -(4f64 / 3f64) * k * (avg - 0.5f64).abs();
let c = k * (avg.powi(2) - avg);
(a.mul_add(-4f64 * c, b.powi(2)).sqrt() - b) / (2f64 * a)
}