diff --git a/src/traits.rs b/src/traits.rs index 4867f5c..df4a8ca 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -28,6 +28,11 @@ pub trait Histogram: fn widths(&self) -> IterWidths<<&Self as IntoIterator>::IntoIter> { IterWidths { histogram_iter: self.into_iter() } } + + /// Return an iterator over the bin centers. + fn centers(&self) -> IterBinCenters<<&Self as IntoIterator>::IntoIter> { + IterBinCenters { histogram_iter: self.into_iter() } + } } /// Iterate over the bins normalized by bin width. @@ -65,3 +70,21 @@ impl Iterator for IterWidths self.histogram_iter.next().map(|((a, b), _)| b - a) } } + +/// Iterate over the bin centers. +pub struct IterBinCenters + where T: Iterator +{ + histogram_iter: T, +} + +impl Iterator for IterBinCenters + where T: Iterator +{ + type Item = f64; + + #[inline] + fn next(&mut self) -> Option { + self.histogram_iter.next().map(|((a, b), _)| 0.5 * (a + b)) + } +} diff --git a/tests/histogram.rs b/tests/histogram.rs index 1c4ac20..6f3de26 100644 --- a/tests/histogram.rs +++ b/tests/histogram.rs @@ -69,6 +69,18 @@ fn widths() { } } +#[test] +fn centers() { + let inf = std::f64::INFINITY; + let h = Histogram10::from_ranges( + [-inf, 0.1, 0.2, 0.3, 0.4, 0.4, 0.7, 0.8, 0.9, 1.0, inf].iter().cloned()).unwrap(); + let centers: Vec = h.centers().collect(); + let expected = [-inf, 0.15, 0.25, 0.35, 0.4, 0.55, 0.75, 0.85, 0.95, inf]; + for (a, b) in centers.iter().zip(expected.iter()) { + assert_almost_eq!(a, b, 1e-14); + } +} + #[test] fn from_ranges_infinity() { let inf = std::f64::INFINITY;