Refactor histograms to use common trait

This commit is contained in:
Vinzent Steinberg 2018-03-06 16:26:02 +01:00
parent dcb006e6e0
commit ba93bb4e65
4 changed files with 30 additions and 19 deletions

View File

@ -4,8 +4,10 @@
/// # extern crate core;
/// # #[macro_use] extern crate average;
/// # fn main() {
/// define_histogram!(Histogram, 10);
/// let mut h = Histogram::with_const_width(0., 100.);
/// use average::Histogram;
///
/// define_histogram!(Histogram10, 10);
/// let mut h = Histogram10::with_const_width(0., 100.);
/// for i in 0..100 {
/// h.add(i as f64).unwrap();
/// }
@ -98,17 +100,18 @@ macro_rules! define_histogram {
Ok(())
}
/// Return the bins of the histogram.
#[inline]
pub fn bins(&self) -> &[u64] {
&self.bin as &[u64]
}
/// Return the ranges of the histogram.
#[inline]
pub fn ranges(&self) -> &[f64] {
&self.range as &[f64]
}
}
impl $crate::Histogram for $name {
#[inline]
fn bins(&self) -> &[u64] {
&self.bin as &[u64]
}
}
);
}

View File

@ -95,4 +95,4 @@ pub use moments::{Mean, Variance, Skewness, Kurtosis, MeanWithError, Moments};
pub use weighted_mean::{WeightedMean, WeightedMeanWithError};
pub use minmax::{Min, Max};
pub use quantile::Quantile;
pub use traits::{Estimate, Merge};
pub use traits::{Estimate, Merge, Histogram};

View File

@ -11,3 +11,9 @@ pub trait Estimate {
pub trait Merge {
fn merge(&mut self, other: &Self);
}
/// Get the bins and ranges from a histogram.
pub trait Histogram {
/// Return the bins of the histogram.
fn bins(&self) -> &[u64];
}

View File

@ -4,11 +4,13 @@ extern crate core;
use core::iter::Iterator;
define_histogram!(Histogram, 10);
use average::Histogram;
define_histogram!(Histogram10, 10);
#[test]
fn with_const_width() {
let mut h = Histogram::with_const_width(0., 100.);
let mut h = Histogram10::with_const_width(0., 100.);
for i in 0..100 {
h.add(i as f64).unwrap();
}
@ -17,7 +19,7 @@ fn with_const_width() {
#[test]
fn from_ranges() {
let mut h = Histogram::from_ranges(
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();
@ -28,7 +30,7 @@ fn from_ranges() {
#[test]
fn from_ranges_infinity() {
let inf = std::f64::INFINITY;
let mut h = Histogram::from_ranges(
let mut h = Histogram10::from_ranges(
[-inf, -0.4, -0.3, -0.2, -0.1, 0.0, 0.1, 0.2, 0.3, 0.4, inf].iter().cloned()).unwrap();
for &i in &[-100., -0.45, 0., 0.25, 0.4, 100.] {
h.add(i).unwrap();
@ -38,15 +40,15 @@ fn from_ranges_infinity() {
#[test]
fn from_ranges_invalid() {
assert!(Histogram::from_ranges([].iter().cloned()).is_err());
assert!(Histogram10::from_ranges([].iter().cloned()).is_err());
let valid = vec![0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.7, 0.8, 0.9, 1.0, 2.0];
assert!(Histogram::from_ranges(valid.iter().cloned()).is_ok());
assert!(Histogram10::from_ranges(valid.iter().cloned()).is_ok());
let mut invalid_nan = valid.clone();
invalid_nan[3] = std::f64::NAN;
assert!(Histogram::from_ranges(invalid_nan.iter().cloned()).is_err());
assert!(Histogram10::from_ranges(invalid_nan.iter().cloned()).is_err());
let mut invalid_order = valid.clone();
invalid_order[10] = 0.9;
assert!(Histogram::from_ranges(invalid_order.iter().cloned()).is_err());
assert!(Histogram10::from_ranges(invalid_order.iter().cloned()).is_err());
let mut valid_empty_ranges = valid.clone();
valid_empty_ranges[1] = 0.;
valid_empty_ranges[10] = 1.;
@ -54,7 +56,7 @@ fn from_ranges_invalid() {
#[test]
fn from_ranges_empty() {
let mut h = Histogram::from_ranges(
let mut h = Histogram10::from_ranges(
[0., 0., 0.2, 0.3, 0.4, 0.5, 0.5, 0.8, 0.9, 2.0, 2.0].iter().cloned()).unwrap();
for &i in &[0.05, 0.7, 1.0, 1.5] {
h.add(i).unwrap();
@ -64,7 +66,7 @@ fn from_ranges_empty() {
#[test]
fn out_of_range() {
let mut h = Histogram::with_const_width(0., 100.);
let mut h = Histogram10::with_const_width(0., 100.);
assert_eq!(h.add(-0.1), Err(()));
assert_eq!(h.add(0.0), Ok(()));
assert_eq!(h.add(1.0), Ok(()));