Implement iteration of histograms
This commit is contained in:
parent
ba93bb4e65
commit
c64544baa8
@ -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 {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user