libtest: DSTify Stats

This commit is contained in:
Jorge Aparicio 2014-11-17 15:13:56 -05:00
parent 88c743def3
commit 38c17dc324

View File

@ -38,7 +38,7 @@ fn local_sort<T: Float>(v: &mut [T]) {
}
/// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
pub trait Stats <T: FloatMath + FromPrimitive>{
pub trait Stats <T: FloatMath + FromPrimitive> for Sized? {
/// Sum of the samples.
///
@ -47,24 +47,24 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates"]
/// (http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps)
/// *Discrete & Computational Geometry 18*, 3 (Oct 1997), 305-363, Shewchuk J.R.
fn sum(self) -> T;
fn sum(&self) -> T;
/// Minimum value of the samples.
fn min(self) -> T;
fn min(&self) -> T;
/// Maximum value of the samples.
fn max(self) -> T;
fn max(&self) -> T;
/// Arithmetic mean (average) of the samples: sum divided by sample-count.
///
/// See: https://en.wikipedia.org/wiki/Arithmetic_mean
fn mean(self) -> T;
fn mean(&self) -> T;
/// Median of the samples: value separating the lower half of the samples from the higher half.
/// Equal to `self.percentile(50.0)`.
///
/// See: https://en.wikipedia.org/wiki/Median
fn median(self) -> T;
fn median(&self) -> T;
/// Variance of the samples: bias-corrected mean of the squares of the differences of each
/// sample from the sample mean. Note that this calculates the _sample variance_ rather than the
@ -73,7 +73,7 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// than `n`.
///
/// See: https://en.wikipedia.org/wiki/Variance
fn var(self) -> T;
fn var(&self) -> T;
/// Standard deviation: the square root of the sample variance.
///
@ -81,13 +81,13 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// `median_abs_dev` for unknown distributions.
///
/// See: https://en.wikipedia.org/wiki/Standard_deviation
fn std_dev(self) -> T;
fn std_dev(&self) -> T;
/// Standard deviation as a percent of the mean value. See `std_dev` and `mean`.
///
/// Note: this is not a robust statistic for non-normal distributions. Prefer the
/// `median_abs_dev_pct` for unknown distributions.
fn std_dev_pct(self) -> T;
fn std_dev_pct(&self) -> T;
/// Scaled median of the absolute deviations of each sample from the sample median. This is a
/// robust (distribution-agnostic) estimator of sample variability. Use this in preference to
@ -96,10 +96,10 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// deviation.
///
/// See: http://en.wikipedia.org/wiki/Median_absolute_deviation
fn median_abs_dev(self) -> T;
fn median_abs_dev(&self) -> T;
/// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`.
fn median_abs_dev_pct(self) -> T;
fn median_abs_dev_pct(&self) -> T;
/// Percentile: the value below which `pct` percent of the values in `self` fall. For example,
/// percentile(95.0) will return the value `v` such that 95% of the samples `s` in `self`
@ -108,7 +108,7 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// Calculated by linear interpolation between closest ranks.
///
/// See: http://en.wikipedia.org/wiki/Percentile
fn percentile(self, pct: T) -> T;
fn percentile(&self, pct: T) -> T;
/// Quartiles of the sample: three values that divide the sample into four equal groups, each
/// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This
@ -116,13 +116,13 @@ pub trait Stats <T: FloatMath + FromPrimitive>{
/// is otherwise equivalent.
///
/// See also: https://en.wikipedia.org/wiki/Quartile
fn quartiles(self) -> (T,T,T);
fn quartiles(&self) -> (T,T,T);
/// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th
/// percentile (3rd quartile). See `quartiles`.
///
/// See also: https://en.wikipedia.org/wiki/Interquartile_range
fn iqr(self) -> T;
fn iqr(&self) -> T;
}
/// Extracted collection of all the summary statistics of a sample set.
@ -163,9 +163,9 @@ impl<T: FloatMath + FromPrimitive> Summary<T> {
}
}
impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
impl<T: FloatMath + FromPrimitive> Stats<T> for [T] {
// FIXME #11059 handle NaN, inf and overflow
fn sum(self) -> T {
fn sum(&self) -> T {
let mut partials = vec![];
for &mut x in self.iter() {
@ -198,26 +198,26 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
partials.iter().fold(zero, |p, q| p + *q)
}
fn min(self) -> T {
fn min(&self) -> T {
assert!(self.len() != 0);
self.iter().fold(self[0], |p, q| p.min(*q))
}
fn max(self) -> T {
fn max(&self) -> T {
assert!(self.len() != 0);
self.iter().fold(self[0], |p, q| p.max(*q))
}
fn mean(self) -> T {
fn mean(&self) -> T {
assert!(self.len() != 0);
self.sum() / FromPrimitive::from_uint(self.len()).unwrap()
}
fn median(self) -> T {
fn median(&self) -> T {
self.percentile(FromPrimitive::from_uint(50).unwrap())
}
fn var(self) -> T {
fn var(&self) -> T {
if self.len() < 2 {
Float::zero()
} else {
@ -235,16 +235,16 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
}
}
fn std_dev(self) -> T {
fn std_dev(&self) -> T {
self.var().sqrt()
}
fn std_dev_pct(self) -> T {
fn std_dev_pct(&self) -> T {
let hundred = FromPrimitive::from_uint(100).unwrap();
(self.std_dev() / self.mean()) * hundred
}
fn median_abs_dev(self) -> T {
fn median_abs_dev(&self) -> T {
let med = self.median();
let abs_devs: Vec<T> = self.iter().map(|&v| (med - v).abs()).collect();
// This constant is derived by smarter statistics brains than me, but it is
@ -253,18 +253,18 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
abs_devs.as_slice().median() * number
}
fn median_abs_dev_pct(self) -> T {
fn median_abs_dev_pct(&self) -> T {
let hundred = FromPrimitive::from_uint(100).unwrap();
(self.median_abs_dev() / self.median()) * hundred
}
fn percentile(self, pct: T) -> T {
fn percentile(&self, pct: T) -> T {
let mut tmp = self.to_vec();
local_sort(tmp.as_mut_slice());
percentile_of_sorted(tmp.as_slice(), pct)
}
fn quartiles(self) -> (T,T,T) {
fn quartiles(&self) -> (T,T,T) {
let mut tmp = self.to_vec();
local_sort(tmp.as_mut_slice());
let first = FromPrimitive::from_uint(25).unwrap();
@ -276,7 +276,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
(a,b,c)
}
fn iqr(self) -> T {
fn iqr(&self) -> T {
let (a,_,c) = self.quartiles();
c - a
}