Implement iteration of histograms

This commit is contained in:
Vinzent Steinberg 2018-03-06 17:04:39 +01:00
parent ba93bb4e65
commit c64544baa8
2 changed files with 53 additions and 0 deletions

View File

@ -105,6 +105,44 @@ macro_rules! define_histogram {
pub fn ranges(&self) -> &[f64] {
&self.range as &[f64]
}
/// Return an iterator over the bins and corresponding ranges:
/// `((lower, upper), count)`
#[inline]
pub fn iter(&self) -> IterHistogram {
self.into_iter()
}
}
/// Iterate over all `(range, count)` pairs in the histogram.
pub struct IterHistogram<'a> {
remaining_bin: &'a [u64],
remaining_range: &'a [f64],
}
impl<'a> ::core::iter::Iterator for IterHistogram<'a> {
type Item = ((f64, f64), u64);
fn next(&mut self) -> Option<((f64, f64), u64)> {
if let Some((&bin, rest)) = self.remaining_bin.split_first() {
let left = self.remaining_range[0];
let right = self.remaining_range[1];
self.remaining_bin = rest;
self.remaining_range = &self.remaining_range[1..];
return Some(((left, right), bin));
}
None
}
}
impl<'a> ::core::iter::IntoIterator for &'a $name {
type Item = ((f64, f64), u64);
type IntoIter = IterHistogram<'a>;
fn into_iter(self) -> IterHistogram<'a> {
IterHistogram {
remaining_bin: self.bins(),
remaining_range: self.ranges(),
}
}
}
impl $crate::Histogram for $name {

View File

@ -27,6 +27,21 @@ fn from_ranges() {
assert_eq!(h.bins(), &[1, 0, 0, 0, 0, 0, 1, 0, 0, 2]);
}
#[test]
fn iter() {
let mut h = Histogram10::from_ranges(
[0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 0.8, 0.9, 1.0, 2.0].iter().cloned()).unwrap();
for &i in &[0.05, 0.7, 1.0, 1.5] {
h.add(i).unwrap();
}
let iterated: Vec<((f64, f64), u64)> = h.iter().collect();
assert_eq!(&iterated, &[
((0., 0.1), 1), ((0.1, 0.2), 0), ((0.2, 0.3), 0), ((0.3, 0.4), 0),
((0.4, 0.5), 0), ((0.5, 0.7), 0), ((0.7, 0.8), 1), ((0.8, 0.9), 0),
((0.9, 1.0), 0), ((1.0, 2.0), 2)
]);
}
#[test]
fn from_ranges_infinity() {
let inf = std::f64::INFINITY;