inline reduce to make minmax compatibal with serde

This commit is contained in:
Eh2406 2017-12-17 22:53:50 -05:00
parent 046f47a0c2
commit b26652f2a7
3 changed files with 10 additions and 65 deletions

View File

@ -77,7 +77,6 @@ extern crate serde;
mod moments; mod moments;
mod weighted_mean; mod weighted_mean;
mod minmax; mod minmax;
mod reduce;
mod quantile; mod quantile;
mod traits; mod traits;

View File

@ -1,6 +1,5 @@
use core; use core;
use super::reduce::Reduce;
use super::{Estimate, Merge}; use super::{Estimate, Merge};
/// Calculate the minimum of `a` and `b`. /// Calculate the minimum of `a` and `b`.
@ -27,7 +26,7 @@ fn max(a: f64, b: f64) -> f64 {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Min { pub struct Min {
r: Reduce<fn(f64, f64) -> f64>, x: f64,
} }
impl Min { impl Min {
@ -35,7 +34,7 @@ impl Min {
#[inline] #[inline]
pub fn from_value(x: f64) -> Min { pub fn from_value(x: f64) -> Min {
Min { Min {
r: Reduce::from_value_and_fn(x, min), x: x,
} }
} }
@ -48,7 +47,7 @@ impl Min {
/// Estimate the minium of the population. /// Estimate the minium of the population.
#[inline] #[inline]
pub fn min(&self) -> f64 { pub fn min(&self) -> f64 {
self.r.reduction() self.x
} }
} }
@ -63,7 +62,7 @@ impl_from_iterator!(Min);
impl Estimate for Min { impl Estimate for Min {
#[inline] #[inline]
fn add(&mut self, x: f64) { fn add(&mut self, x: f64) {
self.r.add(x); self.x = min(self.x, x);
} }
#[inline] #[inline]
@ -91,7 +90,7 @@ impl Merge for Min {
/// ``` /// ```
#[inline] #[inline]
fn merge(&mut self, other: &Min) { fn merge(&mut self, other: &Min) {
self.r.merge(&other.r); self.add(other.x);
} }
} }
@ -109,7 +108,7 @@ impl Merge for Min {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Max { pub struct Max {
r: Reduce<fn(f64, f64) -> f64>, x: f64,
} }
impl Max { impl Max {
@ -117,7 +116,7 @@ impl Max {
#[inline] #[inline]
pub fn from_value(x: f64) -> Max { pub fn from_value(x: f64) -> Max {
Max { Max {
r: Reduce::from_value_and_fn(x, max), x: x,
} }
} }
@ -130,7 +129,7 @@ impl Max {
/// Estimate the maxium of the population. /// Estimate the maxium of the population.
#[inline] #[inline]
pub fn max(&self) -> f64 { pub fn max(&self) -> f64 {
self.r.reduction() self.x
} }
} }
@ -145,7 +144,7 @@ impl_from_iterator!(Max);
impl Estimate for Max { impl Estimate for Max {
#[inline] #[inline]
fn add(&mut self, x: f64) { fn add(&mut self, x: f64) {
self.r.add(x); self.x = max(self.x, x);
} }
#[inline] #[inline]
@ -173,6 +172,6 @@ impl Merge for Max {
/// ``` /// ```
#[inline] #[inline]
fn merge(&mut self, other: &Max) { fn merge(&mut self, other: &Max) {
self.r.merge(&other.r); self.add(other.x);
} }
} }

View File

@ -1,53 +0,0 @@
use super::{Estimate, Merge};
/// Estimate the reduction of a sequence of numbers ("population").
///
/// The reduction is a given function `Fn(f64, f64) -> f64`.
///
/// Everything is calculated iteratively using constant memory, so the sequence
/// of numbers can be an iterator.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Reduce<F> {
x: f64,
reduce: F,
}
impl<F> Reduce<F> {
/// Create a new reduction estimator given an initial value and a reduction.
#[inline]
pub fn from_value_and_fn(x: f64, f: F) -> Reduce<F> {
Reduce { x: x, reduce: f }
}
/// Estimate the reduction of the population.
#[inline]
pub fn reduction(&self) -> f64 {
self.x
}
}
impl<F> Estimate for Reduce<F>
where F: Fn(f64, f64) -> f64,
{
#[inline]
fn add(&mut self, x: f64) {
self.x = (self.reduce)(self.x, x);
}
#[inline]
fn estimate(&self) -> f64 {
self.reduction()
}
}
impl<F> Merge for Reduce<F>
where F: Fn(f64, f64) -> f64,
{
/// Merge another sample into this one.
#[inline]
fn merge(&mut self, other: &Reduce<F>) {
self.add(other.x);
}
}