histogram: Implement iteration of bin widths and normalized bins
This commit is contained in:
parent
c64544baa8
commit
86a411143e
@ -13,7 +13,55 @@ pub trait Merge {
|
||||
}
|
||||
|
||||
/// Get the bins and ranges from a histogram.
|
||||
pub trait Histogram {
|
||||
pub trait Histogram:
|
||||
where for<'a> &'a Self: IntoIterator<Item = ((f64, f64), u64)>
|
||||
{
|
||||
/// Return the bins of the histogram.
|
||||
fn bins(&self) -> &[u64];
|
||||
|
||||
/// Return an iterator over the bins normalized by the bin widths.
|
||||
fn normalized_bins(&self) -> IterNormalized<<&Self as IntoIterator>::IntoIter> {
|
||||
IterNormalized { histogram_iter: (&self).into_iter() }
|
||||
}
|
||||
|
||||
/// Return an iterator over the bin widths.
|
||||
fn widths(&self) -> IterWidths<<&Self as IntoIterator>::IntoIter> {
|
||||
IterWidths { histogram_iter: (&self).into_iter() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over the bins normalized by bin width.
|
||||
pub struct IterNormalized<T>
|
||||
where T: Iterator<Item = ((f64, f64), u64)>
|
||||
{
|
||||
histogram_iter: T,
|
||||
}
|
||||
|
||||
impl<T> Iterator for IterNormalized<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), count)| (count as f64) / (b - a))
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterate over the widths of the bins.
|
||||
pub struct IterWidths<T>
|
||||
where T: Iterator<Item = ((f64, f64), u64)>
|
||||
{
|
||||
histogram_iter: T,
|
||||
}
|
||||
|
||||
impl<T> Iterator for IterWidths<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), _)| b - a)
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,33 @@ fn iter() {
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn normalized_bins() {
|
||||
let inf = std::f64::INFINITY;
|
||||
let mut 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();
|
||||
for &i in &[0.05, 0.1, 0.7, 1.0, 1.5] {
|
||||
h.add(i).unwrap();
|
||||
}
|
||||
let normalized: Vec<f64> = h.normalized_bins().collect();
|
||||
let expected = [0., 10., 0., 0., 0., 0., 10., 0., 0., 0.];
|
||||
for (a, b) in normalized.iter().zip(expected.iter()) {
|
||||
assert_almost_eq!(a, b, 1e-14);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widths() {
|
||||
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 widths: Vec<f64> = h.widths().collect();
|
||||
let expected = [inf, 0.1, 0.1, 0.1, 0., 0.3, 0.1, 0.1, 0.1, inf];
|
||||
for (a, b) in widths.iter().zip(expected.iter()) {
|
||||
assert_almost_eq!(a, b, 1e-14);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_ranges_infinity() {
|
||||
let inf = std::f64::INFINITY;
|
||||
|
Loading…
x
Reference in New Issue
Block a user