chore: lift some restrictions on confidence interval function

- if a value is computed it will be correct
- if the value is not finite (NaN or infinity) we panic with a message to
the user indicating what course of action they can take
- ideally we would want to use a scientific crate written in rust, xsf-rust
seemed promising but the dependency on clang + libclang is proving more
annoying than not, given we would need a single function from xsf (and it's
hard to translate all the required pieces) we keep a sort of status quo
- statrs issue : https://github.com/statrs-dev/statrs/issues/361
This commit is contained in:
Arthur Meyre
2025-11-06 13:55:39 +01:00
committed by IceTDrinker
parent 54c8c5e020
commit 7197b85ec9

View File

@@ -164,6 +164,7 @@ pub mod test_tools {
/// Samples must come from a gaussian distribution, returns the estimated confidence interval
/// for a variance measurement of a gaussian distribution.
#[track_caller]
pub fn gaussian_variance_confidence_interval(
sample_count: f64,
measured_variance: Variance,
@@ -172,19 +173,23 @@ pub mod test_tools {
assert!(probability_to_be_in_the_interval >= 0.0);
assert!(probability_to_be_in_the_interval <= 1.0);
// We have f64 arithmetic errors sightly farther away, so to protect ourselves, limit to
// 125000
assert!(
sample_count <= 125000.,
"variance_confidence_interval cannot handle sample count > 125000",
);
let alpha = 1.0 - probability_to_be_in_the_interval;
let degrees_of_freedom = sample_count - 1.0;
let chi2 = ChiSquared::new(degrees_of_freedom).unwrap();
let chi2_lower = chi2.inverse_cdf(alpha / 2.0);
let chi2_upper = chi2.inverse_cdf(1.0 - alpha / 2.0);
let result_ok = chi2_lower.is_finite() && chi2_upper.is_finite();
assert!(
result_ok,
"Got an invalid value as a result of Chi2 inverse CDF with: \n\
sample_count={sample_count} \n\
probability_to_be_in_the_interval={probability_to_be_in_the_interval} \n\
this is a known issue with statrs, \
try to change your number of samples to get a computable value."
);
// Lower bound is divided by Chi_right^2 so by chi2_upper, upper bound divided by Chi_left^2
// so chi2_lower
let lower_bound = Variance(degrees_of_freedom * measured_variance.0 / chi2_upper);