impl FromIterator<&f64> and FromIterator<&(f64, f64)>
This allows to write let k: Kurtosis = a.iter().collect(); instead of let k: Kurtosis = a.iter().map(|x| *x).collect(); but breaks type inference for code like let m: Min = (1..6).map(Into::into).collect(); where let m: Min = (1..6).map(f64::from).collect(); has to be used instead. Fixes #8.
This commit is contained in:
parent
68a4fa64cb
commit
e4345f5046
@ -29,7 +29,7 @@
|
||||
//! ```
|
||||
//! use average::{MeanWithError, Estimate};
|
||||
//!
|
||||
//! let mut a: MeanWithError = (1..6).map(Into::into).collect();
|
||||
//! let mut a: MeanWithError = (1..6).map(f64::from).collect();
|
||||
//! a.add(42.);
|
||||
//! println!("The mean is {} ± {}.", a.mean(), a.error());
|
||||
//! ```
|
||||
|
@ -44,7 +44,7 @@ macro_rules! assert_almost_eq {
|
||||
///
|
||||
/// concatenate!(MinMax, [Min, min], [Max, max]);
|
||||
///
|
||||
/// let s: MinMax = (1..6).map(Into::into).collect();
|
||||
/// let s: MinMax = (1..6).map(f64::from).collect();
|
||||
///
|
||||
/// assert_eq!(s.min(), 1.0);
|
||||
/// assert_eq!(s.max(), 5.0);
|
||||
@ -157,5 +157,17 @@ macro_rules! impl_from_iterator {
|
||||
e
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ::core::iter::FromIterator<&'a f64> for $name {
|
||||
fn from_iter<T>(iter: T) -> $name
|
||||
where T: IntoIterator<Item=&'a f64>
|
||||
{
|
||||
let mut e = $name::new();
|
||||
for &i in iter {
|
||||
e.add(i);
|
||||
}
|
||||
e
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ fn max(a: f64, b: f64) -> f64 {
|
||||
/// ```
|
||||
/// use average::Min;
|
||||
///
|
||||
/// let a: Min = (1..6).map(Into::into).collect();
|
||||
/// let a: Min = (1..6).map(f64::from).collect();
|
||||
/// println!("The minimum is {}.", a.min());
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
@ -82,9 +82,9 @@ impl Merge for Min {
|
||||
///
|
||||
/// let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
/// let (left, right) = sequence.split_at(3);
|
||||
/// let min_total: Min = sequence.iter().map(|x| *x).collect();
|
||||
/// let mut min_left: Min = left.iter().map(|x| *x).collect();
|
||||
/// let min_right: Min = right.iter().map(|x| *x).collect();
|
||||
/// let min_total: Min = sequence.iter().collect();
|
||||
/// let mut min_left: Min = left.iter().collect();
|
||||
/// let min_right: Min = right.iter().collect();
|
||||
/// min_left.merge(&min_right);
|
||||
/// assert_eq!(min_total.min(), min_left.min());
|
||||
/// ```
|
||||
@ -102,7 +102,7 @@ impl Merge for Min {
|
||||
/// ```
|
||||
/// use average::Max;
|
||||
///
|
||||
/// let a: Max = (1..6).map(Into::into).collect();
|
||||
/// let a: Max = (1..6).map(f64::from).collect();
|
||||
/// assert_eq!(a.max(), 5.);
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
@ -164,9 +164,9 @@ impl Merge for 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();
|
||||
/// let max_total: Max = sequence.iter().collect();
|
||||
/// let mut max_left: Max = left.iter().collect();
|
||||
/// let max_right: Max = right.iter().collect();
|
||||
/// max_left.merge(&max_right);
|
||||
/// assert_eq!(max_total.max(), max_left.max());
|
||||
/// ```
|
||||
|
@ -6,7 +6,7 @@
|
||||
/// ```
|
||||
/// use average::Mean;
|
||||
///
|
||||
/// let a: Mean = (1..6).map(Into::into).collect();
|
||||
/// let a: Mean = (1..6).map(f64::from).collect();
|
||||
/// println!("The mean is {}.", a.mean());
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
@ -100,9 +100,9 @@ impl Merge for Mean {
|
||||
///
|
||||
/// let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
/// let (left, right) = sequence.split_at(3);
|
||||
/// let avg_total: Mean = sequence.iter().map(|x| *x).collect();
|
||||
/// let mut avg_left: Mean = left.iter().map(|x| *x).collect();
|
||||
/// let avg_right: Mean = right.iter().map(|x| *x).collect();
|
||||
/// let avg_total: Mean = sequence.iter().collect();
|
||||
/// let mut avg_left: Mean = left.iter().collect();
|
||||
/// let avg_right: Mean = right.iter().collect();
|
||||
/// avg_left.merge(&avg_right);
|
||||
/// assert_eq!(avg_total.mean(), avg_left.mean());
|
||||
/// ```
|
||||
|
@ -9,7 +9,7 @@
|
||||
/// ```
|
||||
/// use average::Variance;
|
||||
///
|
||||
/// let a: Variance = (1..6).map(Into::into).collect();
|
||||
/// let a: Variance = (1..6).map(f64::from).collect();
|
||||
/// println!("The mean is {} ± {}.", a.mean(), a.error());
|
||||
/// ```
|
||||
#[derive(Debug, Clone)]
|
||||
@ -139,9 +139,9 @@ impl Merge for Variance {
|
||||
///
|
||||
/// let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
/// let (left, right) = sequence.split_at(3);
|
||||
/// let avg_total: Variance = sequence.iter().map(|x| *x).collect();
|
||||
/// let mut avg_left: Variance = left.iter().map(|x| *x).collect();
|
||||
/// let avg_right: Variance = right.iter().map(|x| *x).collect();
|
||||
/// let avg_total: Variance = sequence.iter().collect();
|
||||
/// let mut avg_left: Variance = left.iter().collect();
|
||||
/// let avg_right: Variance = right.iter().collect();
|
||||
/// avg_left.merge(&avg_right);
|
||||
/// assert_eq!(avg_total.mean(), avg_left.mean());
|
||||
/// assert_eq!(avg_total.sample_variance(), avg_left.sample_variance());
|
||||
|
@ -91,6 +91,18 @@ impl core::iter::FromIterator<(f64, f64)> for WeightedMean {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> core::iter::FromIterator<&'a (f64, f64)> for WeightedMean {
|
||||
fn from_iter<T>(iter: T) -> WeightedMean
|
||||
where T: IntoIterator<Item=&'a (f64, f64)>
|
||||
{
|
||||
let mut a = WeightedMean::new();
|
||||
for &(i, w) in iter {
|
||||
a.add(i, w);
|
||||
}
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
impl Merge for WeightedMean {
|
||||
/// Merge another sample into this one.
|
||||
///
|
||||
@ -104,9 +116,9 @@ impl Merge for WeightedMean {
|
||||
/// (1., 0.1), (2., 0.2), (3., 0.3), (4., 0.4), (5., 0.5),
|
||||
/// (6., 0.6), (7., 0.7), (8., 0.8), (9., 0.9)];
|
||||
/// let (left, right) = weighted_sequence.split_at(3);
|
||||
/// let avg_total: WeightedMean = weighted_sequence.iter().map(|&x| x).collect();
|
||||
/// let mut avg_left: WeightedMean = left.iter().map(|&x| x).collect();
|
||||
/// let avg_right: WeightedMean = right.iter().map(|&x| x).collect();
|
||||
/// let avg_total: WeightedMean = weighted_sequence.iter().collect();
|
||||
/// let mut avg_left: WeightedMean = left.iter().collect();
|
||||
/// let avg_right: WeightedMean = right.iter().collect();
|
||||
/// avg_left.merge(&avg_right);
|
||||
/// assert!((avg_total.mean() - avg_left.mean()).abs() < 1e-15);
|
||||
/// ```
|
||||
@ -276,9 +288,9 @@ impl Merge for WeightedMeanWithError {
|
||||
/// (1., 0.1), (2., 0.2), (3., 0.3), (4., 0.4), (5., 0.5),
|
||||
/// (6., 0.6), (7., 0.7), (8., 0.8), (9., 0.9)];
|
||||
/// let (left, right) = weighted_sequence.split_at(3);
|
||||
/// let avg_total: WeightedMeanWithError = weighted_sequence.iter().map(|&x| x).collect();
|
||||
/// let mut avg_left: WeightedMeanWithError = left.iter().map(|&x| x).collect();
|
||||
/// let avg_right: WeightedMeanWithError = right.iter().map(|&x| x).collect();
|
||||
/// let avg_total: WeightedMeanWithError = weighted_sequence.iter().collect();
|
||||
/// let mut avg_left: WeightedMeanWithError = left.iter().collect();
|
||||
/// let avg_right: WeightedMeanWithError = right.iter().collect();
|
||||
/// avg_left.merge(&avg_right);
|
||||
/// assert!((avg_total.weighted_mean() - avg_left.weighted_mean()).abs() < 1e-15);
|
||||
/// assert!((avg_total.error() - avg_left.error()).abs() < 1e-15);
|
||||
@ -308,3 +320,15 @@ impl core::iter::FromIterator<(f64, f64)> for WeightedMeanWithError {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> core::iter::FromIterator<&'a (f64, f64)> for WeightedMeanWithError {
|
||||
fn from_iter<T>(iter: T) -> WeightedMeanWithError
|
||||
where T: IntoIterator<Item=&'a (f64, f64)>
|
||||
{
|
||||
let mut a = WeightedMeanWithError::new();
|
||||
for &(i, w) in iter {
|
||||
a.add(i, w);
|
||||
}
|
||||
a
|
||||
}
|
||||
}
|
||||
|
@ -65,9 +65,9 @@ fn merge() {
|
||||
let sequence: &[f64] = &[1., 2., 3., -4., 5.1, 6.3, 7.3, -8., 9., 1.];
|
||||
for mid in 0..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let avg_total: Kurtosis = sequence.iter().map(|x| *x).collect();
|
||||
let mut avg_left: Kurtosis = left.iter().map(|x| *x).collect();
|
||||
let avg_right: Kurtosis = right.iter().map(|x| *x).collect();
|
||||
let avg_total: Kurtosis = sequence.iter().collect();
|
||||
let mut avg_left: Kurtosis = left.iter().collect();
|
||||
let avg_right: Kurtosis = right.iter().collect();
|
||||
avg_left.merge(&avg_right);
|
||||
assert_eq!(avg_total.len(), avg_left.len());
|
||||
assert_almost_eq!(avg_total.mean(), avg_left.mean(), 1e-14);
|
||||
|
@ -33,7 +33,7 @@ fn concatenate_simple() {
|
||||
}
|
||||
|
||||
{
|
||||
let s: MinMax = (1..6).map(Into::into).collect();
|
||||
let s: MinMax = (1..6).map(f64::from).collect();
|
||||
|
||||
assert_eq!(s.min(), 1.0);
|
||||
assert_eq!(s.max(), 5.0);
|
||||
@ -48,7 +48,7 @@ fn concatenate_moments() {
|
||||
[Variance, variance, mean, sample_variance],
|
||||
[Quantile, quantile, quantile]);
|
||||
|
||||
let e: Estimator = (1..6).map(Into::into).collect();
|
||||
let e: Estimator = (1..6).map(f64::from).collect();
|
||||
|
||||
assert_eq!(e.mean(), 3.0);
|
||||
assert_eq!(e.sample_variance(), 2.5);
|
||||
|
@ -40,11 +40,11 @@ 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();
|
||||
let max_total: Max = sequence.iter().collect();
|
||||
assert_eq!(max_total.max(), 9.);
|
||||
let mut max_left: Max = left.iter().map(|x| *x).collect();
|
||||
let mut max_left: Max = left.iter().collect();
|
||||
assert_eq!(max_left.max(), sequence[mid - 1]);
|
||||
let max_right: Max = right.iter().map(|x| *x).collect();
|
||||
let max_right: Max = right.iter().collect();
|
||||
assert_eq!(max_right.max(), 9.);
|
||||
max_left.merge(&max_right);
|
||||
assert_eq!(max_total.max(), max_left.max());
|
||||
|
@ -55,7 +55,7 @@ fn numerically_unstable() {
|
||||
// The naive algorithm fails for this example due to cancelation.
|
||||
let big = 1e9;
|
||||
let sample = &[big + 4., big + 7., big + 13., big + 16.];
|
||||
let a: MeanWithError = sample.iter().map(|x| *x).collect();
|
||||
let a: MeanWithError = sample.iter().collect();
|
||||
assert_eq!(a.sample_variance(), 30.);
|
||||
}
|
||||
|
||||
@ -64,9 +64,9 @@ fn merge() {
|
||||
let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.];
|
||||
for mid in 0..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let avg_total: MeanWithError = sequence.iter().map(|x| *x).collect();
|
||||
let mut avg_left: MeanWithError = left.iter().map(|x| *x).collect();
|
||||
let avg_right: MeanWithError = right.iter().map(|x| *x).collect();
|
||||
let avg_total: MeanWithError = sequence.iter().collect();
|
||||
let mut avg_left: MeanWithError = left.iter().collect();
|
||||
let avg_right: MeanWithError = right.iter().collect();
|
||||
avg_left.merge(&avg_right);
|
||||
assert_eq!(avg_total.len(), avg_left.len());
|
||||
assert_eq!(avg_total.mean(), avg_left.mean());
|
||||
|
@ -40,11 +40,11 @@ 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 min_total: Min = sequence.iter().map(|x| *x).collect();
|
||||
let min_total: Min = sequence.iter().collect();
|
||||
assert_eq!(min_total.min(), 1.);
|
||||
let mut min_left: Min = left.iter().map(|x| *x).collect();
|
||||
let mut min_left: Min = left.iter().collect();
|
||||
assert_eq!(min_left.min(), 1.);
|
||||
let min_right: Min = right.iter().map(|x| *x).collect();
|
||||
let min_right: Min = right.iter().collect();
|
||||
assert_eq!(min_right.min(), sequence[mid]);
|
||||
min_left.merge(&min_right);
|
||||
assert_eq!(min_total.min(), min_left.min());
|
||||
|
@ -81,9 +81,9 @@ fn merge() {
|
||||
let sequence: &[f64] = &[1., 2., 3., -4., 5.1, 6.3, 7.3, -8., 9., 1.];
|
||||
for mid in 0..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let avg_total: Moments = sequence.iter().map(|x| *x).collect();
|
||||
let mut avg_left: Moments = left.iter().map(|x| *x).collect();
|
||||
let avg_right: Moments = right.iter().map(|x| *x).collect();
|
||||
let avg_total: Moments = sequence.iter().collect();
|
||||
let mut avg_left: Moments = left.iter().collect();
|
||||
let avg_right: Moments = right.iter().collect();
|
||||
avg_left.merge(&avg_right);
|
||||
assert_eq!(avg_total.len(), avg_left.len());
|
||||
assert_almost_eq!(avg_total.mean(), avg_left.mean(), 1e-14);
|
||||
|
@ -63,9 +63,9 @@ fn merge() {
|
||||
let sequence: &[f64] = &[1., 2., 3., -4., 5., 6., 7., 8., 9., 1.];
|
||||
for mid in 0..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let avg_total: Skewness = sequence.iter().map(|x| *x).collect();
|
||||
let mut avg_left: Skewness = left.iter().map(|x| *x).collect();
|
||||
let avg_right: Skewness = right.iter().map(|x| *x).collect();
|
||||
let avg_total: Skewness = sequence.iter().collect();
|
||||
let mut avg_left: Skewness = left.iter().collect();
|
||||
let avg_right: Skewness = right.iter().collect();
|
||||
avg_left.merge(&avg_right);
|
||||
assert_eq!(avg_total.len(), avg_left.len());
|
||||
assert_almost_eq!(avg_total.mean(), avg_left.mean(), 1e-14);
|
||||
|
@ -21,7 +21,7 @@ fn initialize_vec(size: usize) -> Vec<f64> {
|
||||
#[test]
|
||||
fn average_vs_streaming_stats_small() {
|
||||
let values = initialize_vec(100);
|
||||
let a: average::MeanWithError = values.iter().map(|x| *x).collect();
|
||||
let a: average::MeanWithError = values.iter().collect();
|
||||
let b: stats::OnlineStats = values.iter().map(|x| *x).collect();
|
||||
assert_almost_eq!(a.mean(), b.mean(), 1e-16);
|
||||
assert_almost_eq!(a.population_variance(), b.variance(), 1e-14);
|
||||
@ -30,7 +30,7 @@ fn average_vs_streaming_stats_small() {
|
||||
#[test]
|
||||
fn average_vs_streaming_stats_large() {
|
||||
let values = initialize_vec(1_000_000);
|
||||
let a: average::MeanWithError = values.iter().map(|x| *x).collect();
|
||||
let a: average::MeanWithError = values.iter().collect();
|
||||
let b: stats::OnlineStats = values.iter().map(|x| *x).collect();
|
||||
assert_almost_eq!(a.mean(), b.mean(), 1e-16);
|
||||
assert_almost_eq!(a.population_variance(), b.variance(), 1e-13);
|
||||
|
@ -111,9 +111,9 @@ fn merge_weighted() {
|
||||
(6., 0.6), (7., 0.7), (8., 0.8), (9., 0.)];
|
||||
for mid in 0..sequence.len() {
|
||||
let (left, right) = sequence.split_at(mid);
|
||||
let avg_total: WeightedMeanWithError = sequence.iter().map(|&(x, w)| (x, w)).collect();
|
||||
let mut avg_left: WeightedMeanWithError = left.iter().map(|&(x, w)| (x, w)).collect();
|
||||
let avg_right: WeightedMeanWithError = right.iter().map(|&(x, w)| (x, w)).collect();
|
||||
let avg_total: WeightedMeanWithError = sequence.iter().collect();
|
||||
let mut avg_left: WeightedMeanWithError = left.iter().collect();
|
||||
let avg_right: WeightedMeanWithError = right.iter().collect();
|
||||
avg_left.merge(&avg_right);
|
||||
assert_eq!(avg_total.len(), avg_left.len());
|
||||
assert_almost_eq!(avg_total.sum_weights(), avg_left.sum_weights(), 1e-15);
|
||||
|
Loading…
Reference in New Issue
Block a user