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}