From aa7eb193dfdadeeede6a57efe3f8bc53eaca8a5d Mon Sep 17 00:00:00 2001 From: emir-signal Date: Thu, 15 Jan 2026 15:50:09 -0500 Subject: [PATCH] Improve/fix Welford variance calculation --- src/rust/src/core/call_summary.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/rust/src/core/call_summary.rs b/src/rust/src/core/call_summary.rs index 4da4e09e..c1baa288 100644 --- a/src/rust/src/core/call_summary.rs +++ b/src/rust/src/core/call_summary.rs @@ -151,12 +151,9 @@ macro_rules! impl_sample_trait { /// Running variance and mean (Welford's method). fn variance(variance: Self, mean: Self, count: usize, sample: Self) -> (Self, Self) { let n = count as $type; - let new_mean = mean + (sample - mean) / (n + 1.0); - let new_variance = if n > 1.0 { - ((n - 1.0) / n) * variance + (sample - mean) * (sample - new_mean) / (n + 1.0) - } else { - 0.0 - }; + let new_mean = mean + (sample - mean) / n; + let new_variance = + variance + ((sample - mean) * (sample - new_mean) - variance) / n; (new_variance, new_mean) } } @@ -199,10 +196,10 @@ impl DistributionSummary { if self.max_val < sample { self.max_val = sample; } + self.count += 1; let (variance, mean) = T::variance(self.variance, self.mean, self.count, sample); self.mean = mean; self.variance = variance; - self.count += 1; } } } @@ -1268,7 +1265,7 @@ mod test { .iter() .enumerate() .fold((0.0, 0.0), |(variance, mean), (i, sample)| { - f32::variance(variance, mean, i, *sample) + f32::variance(variance, mean, i + 1, *sample) }); println!(