histogram: Implement iteration over bin centers

This commit is contained in:
Vinzent Steinberg 2018-03-06 18:55:21 +01:00
parent 3f22412aa3
commit d1ab9630af
2 changed files with 35 additions and 0 deletions

View File

@ -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<T> Iterator for IterWidths<T>
self.histogram_iter.next().map(|((a, b), _)| b - a)
}
}
/// Iterate over the bin centers.
pub struct IterBinCenters<T>
where T: Iterator<Item = ((f64, f64), u64)>
{
histogram_iter: T,
}
impl<T> Iterator for IterBinCenters<T>
where T: Iterator<Item = ((f64, f64), u64)>
{
type Item = f64;
#[inline]
fn next(&mut self) -> Option<f64> {
self.histogram_iter.next().map(|((a, b), _)| 0.5 * (a + b))
}
}

View File

@ -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<f64> = 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;