diff --git a/src/statistics/mean.rs b/src/statistics/mean.rs index 9f07aca..f7ff0a1 100644 --- a/src/statistics/mean.rs +++ b/src/statistics/mean.rs @@ -1,23 +1,36 @@ /// Arithmetic mean -pub trait Mean { - /// Result type - type Result; - /// Compute the arithmetic mean - fn mean(self) -> Self::Result; +/// Provide the Mean trait for Iterators +pub trait MeanExt: Iterator { + /// Compute the arithmetic mean of this iterator + fn mean(self) -> f32 + where + Self: Sized, + f32: Mean, + { + f32::mean(self) + } } -impl Mean for I -where - I: Iterator, -{ - type Result = f32; +impl MeanExt for I {} + +/// Types for which a mean can be calculated +pub trait Mean { + /// Compute the arithmetic mean of the given iterator + fn mean(iter: I) -> Self + where + I: Iterator; +} - fn mean(self) -> f32 { +impl Mean for f32 { + fn mean(iter: I) -> Self + where + I: Iterator, + { let mut num_items = 0; let mut sum = 0.0; - for item in self { + for item in iter { num_items += 1; sum += item; } @@ -26,12 +39,23 @@ where } } +impl<'a> Mean<&'a f32> for f32 { + fn mean(iter: I) -> Self + where + I: Iterator, + { + iter.copied().mean() + } +} + #[cfg(test)] mod tests { - use super::Mean; + use super::MeanExt; #[test] fn mean_test() { - assert_eq!([1.0, 3.0, 5.0].iter().cloned().mean(), 3.0); + assert_eq!([1.0, 3.0, 5.0].iter().mean(), 3.0); + + assert_eq!(IntoIterator::into_iter([1.0, 3.0, 5.0]).mean(), 3.0); } } diff --git a/src/statistics/trim.rs b/src/statistics/trim.rs index 7d1762f..266626a 100644 --- a/src/statistics/trim.rs +++ b/src/statistics/trim.rs @@ -1,6 +1,6 @@ //! Iterate over input slices after culling statistical outliers. -use super::mean::Mean; +use super::mean::MeanExt; #[allow(unused_imports)] use crate::F32Ext; use core::{iter, slice}; diff --git a/src/statistics/variance.rs b/src/statistics/variance.rs index 6c0b98b..4ae5ce8 100644 --- a/src/statistics/variance.rs +++ b/src/statistics/variance.rs @@ -1,4 +1,4 @@ -use super::mean::Mean; +use super::mean::MeanExt; /// Statistical variance pub trait Variance {