cbtop/frequency_control/
variance.rs1#[derive(Debug, Clone, Default)]
5pub struct FrequencyVariance {
6 pub mean_mhz: f64,
8 pub std_dev_mhz: f64,
10 pub cv_percent: f64,
12 pub min_mhz: f64,
14 pub max_mhz: f64,
16 pub sample_count: usize,
18}
19
20impl FrequencyVariance {
21 pub fn from_samples(readings: &[f64]) -> Self {
23 if readings.is_empty() {
24 return Self::default();
25 }
26 let n = readings.len() as f64;
27 let mean = readings.iter().sum::<f64>() / n;
28 let var = readings.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (n - 1.0).max(1.0);
29 let std_dev = var.sqrt();
30 let cv = if mean > 0.0 {
31 std_dev / mean * 100.0
32 } else {
33 0.0
34 };
35 Self {
36 mean_mhz: mean,
37 std_dev_mhz: std_dev,
38 cv_percent: cv,
39 min_mhz: readings.iter().copied().fold(f64::INFINITY, f64::min),
40 max_mhz: readings.iter().copied().fold(f64::NEG_INFINITY, f64::max),
41 sample_count: readings.len(),
42 }
43 }
44
45 pub fn is_stable(&self) -> bool {
47 self.cv_percent < 3.0
48 }
49
50 pub fn range_mhz(&self) -> f64 {
52 self.max_mhz - self.min_mhz
53 }
54}