Implement Max
This commit is contained in:
parent
c1af508205
commit
0d1e1c4f12
@ -41,4 +41,4 @@ mod reduce;
|
||||
|
||||
pub use average::{Average, AverageWithError};
|
||||
pub use weighted_average::{WeightedAverage, WeightedAverageWithError};
|
||||
pub use minmax::Min;
|
||||
pub use minmax::{Min, Max};
|
||||
|
@ -7,6 +7,11 @@ fn min(a: f64, b: f64) -> f64 {
|
||||
a.min(b)
|
||||
}
|
||||
|
||||
/// Calculate the maximum of `a` and `b`.
|
||||
fn max(a: f64, b: f64) -> f64 {
|
||||
a.max(b)
|
||||
}
|
||||
|
||||
/// Estimate the minimum of a sequence of numbers ("population").
|
||||
///
|
||||
/// Everything is calculated iteratively using constant memory, so the sequence
|
||||
@ -86,3 +91,83 @@ impl core::iter::FromIterator<f64> for Min {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
/// Estimate the maximum of a sequence of numbers ("population").
|
||||
///
|
||||
/// Everything is calculated iteratively using constant memory, so the sequence
|
||||
/// of numbers can be an iterator.
|
||||
///
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// use average::Max;
|
||||
///
|
||||
/// let a: Max = (1..6).map(Into::into).collect();
|
||||
/// assert_eq!(a.max(), 5.);
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Max {
|
||||
r: Reduce<fn(f64, f64) -> f64>,
|
||||
}
|
||||
|
||||
impl Max {
|
||||
/// Create a new maxium estimator from a given value.
|
||||
#[inline]
|
||||
pub fn from_value(x: f64) -> Max {
|
||||
Max {
|
||||
r: Reduce::from_value_and_fn(x, max),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new maximum estimator.
|
||||
#[inline]
|
||||
pub fn new() -> Max {
|
||||
Max::from_value(::core::f64::NEG_INFINITY)
|
||||
}
|
||||
|
||||
/// Add an element sampled from the population.
|
||||
#[inline]
|
||||
pub fn add(&mut self, x: f64) {
|
||||
self.r.add(x);
|
||||
}
|
||||
|
||||
/// Estimate the maxium of the population.
|
||||
#[inline]
|
||||
pub fn max(&self) -> f64 {
|
||||
self.r.reduction()
|
||||
}
|
||||
|
||||
/// Merge another sample into this one.
|
||||
///
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```
|
||||
/// use average::Max;
|
||||
///
|
||||
/// let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
/// let (left, right) = sequence.split_at(3);
|
||||
/// let max_total: Max = sequence.iter().map(|x| *x).collect();
|
||||
/// let mut max_left: Max = left.iter().map(|x| *x).collect();
|
||||
/// let max_right: Max = right.iter().map(|x| *x).collect();
|
||||
/// max_left.merge(&max_right);
|
||||
/// assert_eq!(max_total.max(), max_left.max());
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn merge(&mut self, other: &Max) {
|
||||
self.r.merge(&other.r);
|
||||
}
|
||||
}
|
||||
|
||||
impl core::iter::FromIterator<f64> for Max {
|
||||
fn from_iter<T>(iter: T) -> Max
|
||||
where T: IntoIterator<Item=f64>
|
||||
{
|
||||
let mut a = Max::new();
|
||||
for i in iter {
|
||||
a.add(i);
|
||||
}
|
||||
a
|
||||
}
|
||||
}
|
||||
|
34
tests/max.rs
Normal file
34
tests/max.rs
Normal file
@ -0,0 +1,34 @@
|
||||
extern crate average;
|
||||
|
||||
extern crate core;
|
||||
|
||||
use core::iter::Iterator;
|
||||
|
||||
use average::Max;
|
||||
|
||||
#[test]
|
||||
fn trivial() {
|
||||
let mut m = Max::new();
|
||||
m.add(2.);
|
||||
m.add(1.);
|
||||
assert_eq!(m.max(), 2.);
|
||||
m.add(3.);
|
||||
m.add(1.);
|
||||
assert_eq!(m.max(), 3.)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge() {
|
||||
let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
for mid in 1..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let max_total: Max = sequence.iter().map(|x| *x).collect();
|
||||
assert_eq!(max_total.max(), 9.);
|
||||
let mut max_left: Max = left.iter().map(|x| *x).collect();
|
||||
assert_eq!(max_left.max(), sequence[mid - 1]);
|
||||
let max_right: Max = right.iter().map(|x| *x).collect();
|
||||
assert_eq!(max_right.max(), 9.);
|
||||
max_left.merge(&max_right);
|
||||
assert_eq!(max_total.max(), max_left.max());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user