#![doc=include_str!("../README.md")]
#![deny(warnings, missing_docs, unsafe_code)]
pub mod argsort;
pub mod fill_nan;
pub mod mean;
pub mod median;
pub mod normalize;
pub mod range;
pub mod rank;
pub mod stddev;
pub mod sum_of_squares;
pub mod variance;
mod welford_online;
pub mod zscore;
use argsort::{ArgSort, ArgSortIter};
pub use fill_nan::FillNan;
use fill_nan::FillNanIter;
pub use mean::Mean;
pub use median::Median;
pub use normalize::Normalize;
use normalize::NormalizeIter;
use range::Range;
use rank::{Rank, RankIter};
pub use stddev::StdDev;
pub use sum_of_squares::SumOfSquares;
pub use variance::Variance;
pub use zscore::ZScore;
use zscore::ZScoreIter;
pub trait Iterstats<A>: Iterator {
fn mean(self) -> <A as Mean>::Output
where
Self: Sized + Iterator<Item = A> + Clone,
A: Mean,
{
A::mean(self)
}
fn variance(self) -> <A as Variance>::Output
where
Self: Sized + Iterator<Item = A>,
A: Variance,
{
A::variance(self)
}
fn stddev(self) -> <A as StdDev>::Output
where
Self: Sized + Iterator<Item = A>,
A: StdDev,
{
A::stddev(self)
}
fn zscore(self) -> ZScoreIter<<A as ZScore>::Output>
where
Self: Sized + Iterator<Item = A> + Clone,
A: ZScore,
{
A::zscore(self)
}
fn normalize(
self,
min: <A as Normalize>::Output,
max: <A as Normalize>::Output,
) -> NormalizeIter<<A as Normalize>::Output>
where
Self: Sized + Iterator<Item = A> + Clone,
A: Normalize,
{
A::normalize(self, min, max)
}
fn sum_of_squares(self) -> <A as SumOfSquares>::Output
where
Self: Sized + Iterator<Item = A>,
A: SumOfSquares,
{
A::sum_of_squares(self)
}
fn median(self) -> <A as Median>::Output
where
Self: Sized + Iterator<Item = A>,
A: Median,
{
A::median(self)
}
fn range(self) -> Option<(<A as Range>::Output, <A as Range>::Output)>
where
Self: Sized + Iterator<Item = A>,
A: Range,
{
A::range(self)
}
fn fill_nan(
self,
repl: <A as FillNan>::Output,
) -> FillNanIter<impl Iterator<Item = <A as FillNan>::Output>, <A as FillNan>::Output>
where
Self: Sized + Iterator<Item = A>,
A: FillNan,
{
A::fill_nan(self, repl)
}
fn argsort(self) -> ArgSortIter<<A as ArgSort>::Output>
where
Self: Sized + Iterator<Item = A>,
A: ArgSort,
{
A::argsort(self)
}
fn rank(self) -> RankIter
where
Self: Sized + Iterator<Item = A>,
A: Rank,
{
A::rank(self)
}
}
impl<I, A> Iterstats<A> for I where I: Iterator + ?Sized {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mean() {
let data = [1., 2., 3., 4.];
let exp = 2.5;
assert_eq!(data.iter().mean(), exp);
assert_eq!(data.into_iter().mean(), exp);
}
#[test]
fn variance() {
let data = [1., 2., 3., 4.];
let exp = 1.25;
assert_eq!(data.iter().variance(), exp);
assert_eq!(data.into_iter().variance(), exp);
}
#[test]
fn stddev() {
let data = [1., 2., 3., 4.];
let exp = 1.25f64.sqrt();
assert_eq!(data.iter().stddev(), exp);
assert_eq!(data.into_iter().stddev(), exp);
}
#[test]
fn zscore() {
let data = [1., 2., 3., 4.];
let exp = vec![
-1.3416407864998738,
-0.4472135954999579,
0.4472135954999579,
1.3416407864998738,
];
assert_eq!(data.iter().zscore().collect::<Vec<_>>(), exp);
assert_eq!(data.into_iter().zscore().collect::<Vec<_>>(), exp);
}
#[test]
fn normalize() {
let data = [1., 2., 3., 5.];
let normmin = 0.;
let normmax = 1.;
let exp = vec![0., 0.25, 0.5, 1.];
assert_eq!(
data.iter().normalize(normmin, normmax).collect::<Vec<_>>(),
exp
);
assert_eq!(
data.into_iter()
.normalize(normmin, normmax)
.collect::<Vec<_>>(),
exp
);
}
#[test]
fn sum_of_squares() {
let data = [1., 2., 3., 5.];
let exp = 8.75;
assert_eq!(data.iter().sum_of_squares(), exp);
assert_eq!(data.into_iter().sum_of_squares(), exp);
}
#[test]
fn median() {
let data = [2, 7, 198, 2, 2, 7];
let exp = 4;
assert_eq!(data.iter().median(), exp);
assert_eq!(data.into_iter().median(), exp);
}
#[test]
fn range() {
let data = [2, 7, -198, 2, 7];
let exprange = (-198, 7);
assert_eq!(data.iter().range().unwrap(), exprange);
assert_eq!(data.into_iter().range().unwrap(), exprange);
}
#[test]
fn fillnan() {
let data = [1., 100., 2., f32::NAN, 3., 5.];
let fill = 100.;
let exp = vec![1., 100., 2., 100., 3., 5.];
assert_eq!(data.iter().fill_nan(fill).collect::<Vec<_>>(), exp);
assert_eq!(data.into_iter().fill_nan(fill).collect::<Vec<_>>(), exp);
}
#[test]
fn argsort() {
let data = [
f64::NAN,
4.2,
0.0,
f64::NEG_INFINITY,
-0.0,
f64::INFINITY,
-f64::NAN,
];
let exp = vec![6, 3, 4, 2, 1, 5, 0];
assert_eq!(data.iter().argsort().collect::<Vec<_>>(), exp);
assert_eq!(data.into_iter().argsort().collect::<Vec<_>>(), exp);
}
#[test]
fn rank() {
let data = [
f64::NAN,
4.2,
0.0,
f64::NEG_INFINITY,
-0.0,
f64::INFINITY,
-f64::NAN,
];
let exp = vec![6, 4, 3, 1, 2, 5, 0];
assert_eq!(data.iter().rank().collect::<Vec<_>>(), exp);
assert_eq!(data.into_iter().rank().collect::<Vec<_>>(), exp);
}
}