From eeb94886adccb3f13003f92f117115d17846ce1f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 17 Apr 2015 15:32:42 -0700 Subject: std: Remove deprecated/unstable num functionality This commit removes all the old casting/generic traits from `std::num` that are no longer in use by the standard library. This additionally removes the old `strconv` module which has not seen much use in quite a long time. All generic functionality has been supplanted with traits in the `num` crate and the `strconv` module is supplanted with the [rust-strconv crate][rust-strconv]. [rust-strconv]: https://github.com/lifthrasiir/rust-strconv This is a breaking change due to the removal of these deprecated crates, and the alternative crates are listed above. [breaking-change] --- src/libtest/lib.rs | 5 +- src/libtest/stats.rs | 147 +++++++++++++++++++++++++-------------------------- 2 files changed, 75 insertions(+), 77 deletions(-) (limited to 'src/libtest') diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 5c967747104..4532f5d65d8 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -75,7 +75,6 @@ use std::fs::File; use std::io::prelude::*; use std::io; use std::iter::repeat; -use std::num::{Float, Int}; use std::path::PathBuf; use std::sync::mpsc::{channel, Sender}; use std::sync::{Arc, Mutex}; @@ -413,7 +412,7 @@ pub fn parse_opts(args: &[String]) -> Option { #[derive(Clone, PartialEq)] pub struct BenchSamples { - ns_iter_summ: stats::Summary, + ns_iter_summ: stats::Summary, mb_s: usize, } @@ -1066,7 +1065,7 @@ impl Bencher { } // This is a more statistics-driven benchmark algorithm - pub fn auto_bench(&mut self, mut f: F) -> stats::Summary where F: FnMut(&mut Bencher) { + pub fn auto_bench(&mut self, mut f: F) -> stats::Summary where F: FnMut(&mut Bencher) { // Initial bench run to get ballpark figure. let mut n = 1; self.bench_n(n, |x| f(x)); diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 06e0de76eaf..341be762601 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -13,9 +13,8 @@ use std::cmp::Ordering::{self, Less, Greater, Equal}; use std::mem; -use std::num::{Float, FromPrimitive}; -fn local_cmp(x: T, y: T) -> Ordering { +fn local_cmp(x: f64, y: f64) -> Ordering { // arbitrarily decide that NaNs are larger than everything. if y.is_nan() { Less @@ -30,12 +29,12 @@ fn local_cmp(x: T, y: T) -> Ordering { } } -fn local_sort(v: &mut [T]) { - v.sort_by(|x: &T, y: &T| local_cmp(*x, *y)); +fn local_sort(v: &mut [f64]) { + v.sort_by(|x: &f64, y: &f64| local_cmp(*x, *y)); } /// Trait that provides simple descriptive statistics on a univariate set of numeric samples. -pub trait Stats { +pub trait Stats { /// Sum of the samples. /// @@ -43,24 +42,24 @@ pub trait Stats { /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at: /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates"] /// (http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps) - fn sum(&self) -> T; + fn sum(&self) -> f64; /// Minimum value of the samples. - fn min(&self) -> T; + fn min(&self) -> f64; /// Maximum value of the samples. - fn max(&self) -> T; + fn max(&self) -> f64; /// 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) -> f64; /// 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) -> f64; /// 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 @@ -69,7 +68,7 @@ pub trait Stats { /// than `n`. /// /// See: https://en.wikipedia.org/wiki/Variance - fn var(&self) -> T; + fn var(&self) -> f64; /// Standard deviation: the square root of the sample variance. /// @@ -77,13 +76,13 @@ pub trait Stats { /// `median_abs_dev` for unknown distributions. /// /// See: https://en.wikipedia.org/wiki/Standard_deviation - fn std_dev(&self) -> T; + fn std_dev(&self) -> f64; /// 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) -> f64; /// 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 @@ -92,10 +91,10 @@ pub trait Stats { /// deviation. /// /// See: http://en.wikipedia.org/wiki/Median_absolute_deviation - fn median_abs_dev(&self) -> T; + fn median_abs_dev(&self) -> f64; /// 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) -> f64; /// 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` @@ -104,7 +103,7 @@ pub trait Stats { /// Calculated by linear interpolation between closest ranks. /// /// See: http://en.wikipedia.org/wiki/Percentile - fn percentile(&self, pct: T) -> T; + fn percentile(&self, pct: f64) -> f64; /// 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 @@ -112,36 +111,36 @@ pub trait Stats { /// is otherwise equivalent. /// /// See also: https://en.wikipedia.org/wiki/Quartile - fn quartiles(&self) -> (T,T,T); + fn quartiles(&self) -> (f64,f64,f64); /// 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) -> f64; } /// Extracted collection of all the summary statistics of a sample set. #[derive(Clone, PartialEq)] #[allow(missing_docs)] -pub struct Summary { - pub sum: T, - pub min: T, - pub max: T, - pub mean: T, - pub median: T, - pub var: T, - pub std_dev: T, - pub std_dev_pct: T, - pub median_abs_dev: T, - pub median_abs_dev_pct: T, - pub quartiles: (T,T,T), - pub iqr: T, +pub struct Summary { + pub sum: f64, + pub min: f64, + pub max: f64, + pub mean: f64, + pub median: f64, + pub var: f64, + pub std_dev: f64, + pub std_dev_pct: f64, + pub median_abs_dev: f64, + pub median_abs_dev_pct: f64, + pub quartiles: (f64,f64,f64), + pub iqr: f64, } -impl Summary { +impl Summary { /// Construct a new summary of a sample set. - pub fn new(samples: &[T]) -> Summary { + pub fn new(samples: &[f64]) -> Summary { Summary { sum: samples.sum(), min: samples.min(), @@ -159,9 +158,9 @@ impl Summary { } } -impl Stats for [T] { +impl Stats for [f64] { // FIXME #11059 handle NaN, inf and overflow - fn sum(&self) -> T { + fn sum(&self) -> f64 { let mut partials = vec![]; for &x in self { @@ -170,7 +169,7 @@ impl Stats for [T] { // This inner loop applies `hi`/`lo` summation to each // partial so that the list of partial sums remains exact. for i in 0..partials.len() { - let mut y: T = partials[i]; + let mut y: f64 = partials[i]; if x.abs() < y.abs() { mem::swap(&mut x, &mut y); } @@ -178,7 +177,7 @@ impl Stats for [T] { // `lo`. Together `hi+lo` are exactly equal to `x+y`. let hi = x + y; let lo = y - (hi - x); - if lo != Float::zero() { + if lo != 0.0 { partials[j] = lo; j += 1; } @@ -191,35 +190,35 @@ impl Stats for [T] { partials.truncate(j+1); } } - let zero: T = Float::zero(); + let zero: f64 = 0.0; partials.iter().fold(zero, |p, q| p + *q) } - fn min(&self) -> T { + fn min(&self) -> f64 { assert!(!self.is_empty()); self.iter().fold(self[0], |p, q| p.min(*q)) } - fn max(&self) -> T { + fn max(&self) -> f64 { assert!(!self.is_empty()); self.iter().fold(self[0], |p, q| p.max(*q)) } - fn mean(&self) -> T { + fn mean(&self) -> f64 { assert!(!self.is_empty()); - self.sum() / FromPrimitive::from_usize(self.len()).unwrap() + self.sum() / (self.len() as f64) } - fn median(&self) -> T { - self.percentile(FromPrimitive::from_usize(50).unwrap()) + fn median(&self) -> f64 { + self.percentile(50 as f64) } - fn var(&self) -> T { + fn var(&self) -> f64 { if self.len() < 2 { - Float::zero() + 0.0 } else { let mean = self.mean(); - let mut v: T = Float::zero(); + let mut v: f64 = 0.0; for s in self { let x = *s - mean; v = v + x*x; @@ -227,53 +226,53 @@ impl Stats for [T] { // NB: this is _supposed to be_ len-1, not len. If you // change it back to len, you will be calculating a // population variance, not a sample variance. - let denom = FromPrimitive::from_usize(self.len()-1).unwrap(); + let denom = (self.len() - 1) as f64; v/denom } } - fn std_dev(&self) -> T { + fn std_dev(&self) -> f64 { self.var().sqrt() } - fn std_dev_pct(&self) -> T { - let hundred = FromPrimitive::from_usize(100).unwrap(); + fn std_dev_pct(&self) -> f64 { + let hundred = 100 as f64; (self.std_dev() / self.mean()) * hundred } - fn median_abs_dev(&self) -> T { + fn median_abs_dev(&self) -> f64 { let med = self.median(); - let abs_devs: Vec = self.iter().map(|&v| (med - v).abs()).collect(); + let abs_devs: Vec = self.iter().map(|&v| (med - v).abs()).collect(); // This constant is derived by smarter statistics brains than me, but it is // consistent with how R and other packages treat the MAD. - let number = FromPrimitive::from_f64(1.4826).unwrap(); + let number = 1.4826; abs_devs.median() * number } - fn median_abs_dev_pct(&self) -> T { - let hundred = FromPrimitive::from_usize(100).unwrap(); + fn median_abs_dev_pct(&self) -> f64 { + let hundred = 100 as f64; (self.median_abs_dev() / self.median()) * hundred } - fn percentile(&self, pct: T) -> T { + fn percentile(&self, pct: f64) -> f64 { let mut tmp = self.to_vec(); local_sort(&mut tmp); percentile_of_sorted(&tmp, pct) } - fn quartiles(&self) -> (T,T,T) { + fn quartiles(&self) -> (f64,f64,f64) { let mut tmp = self.to_vec(); local_sort(&mut tmp); - let first = FromPrimitive::from_usize(25).unwrap(); + let first = 25f64; let a = percentile_of_sorted(&tmp, first); - let secound = FromPrimitive::from_usize(50).unwrap(); + let secound = 50f64; let b = percentile_of_sorted(&tmp, secound); - let third = FromPrimitive::from_usize(75).unwrap(); + let third = 75f64; let c = percentile_of_sorted(&tmp, third); (a,b,c) } - fn iqr(&self) -> T { + fn iqr(&self) -> f64 { let (a,_,c) = self.quartiles(); c - a } @@ -282,41 +281,41 @@ impl Stats for [T] { // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using // linear interpolation. If samples are not sorted, return nonsensical value. -fn percentile_of_sorted(sorted_samples: &[T], - pct: T) -> T { +fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 { assert!(!sorted_samples.is_empty()); if sorted_samples.len() == 1 { return sorted_samples[0]; } - let zero: T = Float::zero(); + let zero: f64 = 0.0; assert!(zero <= pct); - let hundred = FromPrimitive::from_usize(100).unwrap(); + let hundred = 100f64; assert!(pct <= hundred); if pct == hundred { return sorted_samples[sorted_samples.len() - 1]; } - let length = FromPrimitive::from_usize(sorted_samples.len() - 1).unwrap(); + let length = (sorted_samples.len() - 1) as f64; let rank = (pct / hundred) * length; let lrank = rank.floor(); let d = rank - lrank; - let n = lrank.to_usize().unwrap(); + let n = lrank as usize; let lo = sorted_samples[n]; let hi = sorted_samples[n+1]; lo + (hi - lo) * d } -/// Winsorize a set of samples, replacing values above the `100-pct` percentile and below the `pct` -/// percentile with those percentiles themselves. This is a way of minimizing the effect of -/// outliers, at the cost of biasing the sample. It differs from trimming in that it does not -/// change the number of samples, just changes the values of those that are outliers. +/// Winsorize a set of samples, replacing values above the `100-pct` percentile +/// and below the `pct` percentile with those percentiles themselves. This is a +/// way of minimizing the effect of outliers, at the cost of biasing the sample. +/// It differs from trimming in that it does not change the number of samples, +/// just changes the values of those that are outliers. /// /// See: http://en.wikipedia.org/wiki/Winsorising -pub fn winsorize(samples: &mut [T], pct: T) { +pub fn winsorize(samples: &mut [f64], pct: f64) { let mut tmp = samples.to_vec(); local_sort(&mut tmp); let lo = percentile_of_sorted(&tmp, pct); - let hundred: T = FromPrimitive::from_usize(100).unwrap(); + let hundred = 100 as f64; let hi = percentile_of_sorted(&tmp, hundred-pct); for samp in samples { if *samp > hi { -- cgit 1.4.1-3-g733a5