Skip to main content

lawkit_core/common/
statistics.rs

1/// Calculate chi-square statistic
2pub fn calculate_chi_square(observed: &[f64], expected: &[f64]) -> f64 {
3    observed
4        .iter()
5        .zip(expected.iter())
6        .map(|(&obs, &exp)| {
7            if exp > 0.0 {
8                let diff = obs - exp;
9                (diff * diff) / exp
10            } else {
11                0.0
12            }
13        })
14        .sum()
15}
16
17/// Calculate p-value from chi-square statistic and degrees of freedom
18/// This is a simplified approximation - in production, use a proper statistics library
19pub fn calculate_p_value(chi_square: f64, degrees_of_freedom: i32) -> f64 {
20    // Simplified p-value calculation using normal approximation
21    // For more accuracy, use a proper chi-square distribution function
22
23    if chi_square <= 0.0 {
24        return 1.0;
25    }
26
27    // Simple approximation based on common critical values
28    match degrees_of_freedom {
29        8 => {
30            if chi_square >= 20.09 {
31                0.01
32            }
33            // p <= 0.01
34            else if chi_square >= 15.51 {
35                0.05
36            }
37            // p <= 0.05
38            else if chi_square >= 13.36 {
39                0.1
40            }
41            // p <= 0.1
42            else {
43                0.5
44            } // p > 0.1 (approximate)
45        }
46        _ => {
47            // Fallback approximation
48            if chi_square >= 20.0 {
49                0.01
50            } else if chi_square >= 15.0 {
51                0.05
52            } else if chi_square >= 12.0 {
53                0.1
54            } else {
55                0.5
56            }
57        }
58    }
59}
60
61/// Calculate Mean Absolute Deviation (MAD)
62pub fn calculate_mad(observed: &[f64], expected: &[f64]) -> f64 {
63    let sum: f64 = observed
64        .iter()
65        .zip(expected.iter())
66        .map(|(&obs, &exp)| (obs - exp).abs())
67        .sum();
68
69    sum / observed.len() as f64
70}