use statrs::distribution::{ChiSquared, ContinuousCDF};
pub fn chi2_sample_size_gof(expected_counts: &[usize], alpha: f64) -> f64 {
let total_expected: f64 = expected_counts.iter().map(|&count| count as f64).sum();
let expected_proportions: Vec<f64> = expected_counts
.iter()
.map(|&count| count as f64 / total_expected)
.collect();
let chi_squared_dist = ChiSquared::new(expected_counts.len() as f64 - 1.0)
.expect("Failed to create Chi-squared distribution");
let chi_alpha = chi_squared_dist.inverse_cdf(1.0 - alpha);
let n = expected_proportions
.iter()
.map(|&prop| (chi_alpha / prop).powi(2))
.fold(0.0, |sum, x| sum + x)
/ expected_counts.len() as f64;
n.ceil() }
pub fn chi2_sample_size_ind(expected_counts: &[usize], alpha: f64) -> f64 {
let total_expected: f64 = expected_counts.iter().map(|&count| count as f64).sum();
let expected_proportions: Vec<f64> = expected_counts
.iter()
.map(|&count| count as f64 / total_expected)
.collect();
let chi_squared_dist = ChiSquared::new(expected_counts.len() as f64 - 1.0)
.expect("Failed to create Chi-squared distribution");
let chi_alpha = chi_squared_dist.inverse_cdf(1.0 - alpha);
let n = expected_proportions
.iter()
.map(|&prop| (chi_alpha / prop).powi(2))
.fold(0.0, |sum, x| sum + x)
/ expected_counts.len() as f64;
n.ceil() }
pub fn chi2_sample_size_variance(effect_size: f64, alpha: f64, power: f64, variance: f64) -> f64 {
let chi_squared_dist = ChiSquared::new(1.0).expect("Failed to create Chi-squared distribution");
let chi_alpha = chi_squared_dist.inverse_cdf(1.0 - alpha);
let chi_beta = chi_squared_dist.inverse_cdf(power);
let n = ((chi_alpha + chi_beta) * variance / effect_size).powi(2);
n.ceil() }