gam_math/
serial_dependence.rs1pub fn autocorr_ess(x: &[f64]) -> f64 {
14 let n = x.len();
15 if n <= 1 {
16 return n as f64;
17 }
18 let mean = x.iter().sum::<f64>() / n as f64;
19 let var = x.iter().map(|v| (v - mean) * (v - mean)).sum::<f64>() / n as f64;
20 if var <= 0.0 {
21 return n as f64;
22 }
23 let lag_cap = (n as f64).sqrt() as usize;
24 let mut rho_sum = 0.0;
25 for lag in 1..=lag_cap.max(1).min(n - 1) {
26 let mut cov = 0.0;
27 for i in lag..n {
28 cov += (x[i] - mean) * (x[i - lag] - mean);
29 }
30 cov /= (n - lag) as f64;
31 let rho = cov / var;
32 if rho <= 0.0 || !rho.is_finite() {
33 break;
34 }
35 rho_sum += rho;
36 }
37 (n as f64 / (1.0 + 2.0 * rho_sum)).max(1.0)
38}
39
40pub fn newey_west_se(x: &[f64]) -> f64 {
44 let n = x.len();
45 if n <= 1 {
46 return f64::INFINITY;
47 }
48 let mean = x.iter().sum::<f64>() / n as f64;
49 let lag_cap = (n as f64).sqrt() as usize;
50 let mut gamma0 = 0.0;
51 for v in x {
52 gamma0 += (v - mean) * (v - mean);
53 }
54 gamma0 /= n as f64;
55 let mut var = gamma0;
56 for lag in 1..=lag_cap.max(1).min(n - 1) {
57 let mut gamma = 0.0;
58 for i in lag..n {
59 gamma += (x[i] - mean) * (x[i - lag] - mean);
60 }
61 gamma /= n as f64;
62 let w = 1.0 - lag as f64 / (lag_cap as f64 + 1.0);
63 var += 2.0 * w * gamma;
64 }
65 (var.max(0.0) / n as f64).sqrt()
66}