]> git.lizzy.rs Git - rust.git/blob - src/libtest/stats.rs
Fix test
[rust.git] / src / libtest / stats.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(missing_docs)]
12 #![allow(deprecated)] // Float
13
14 use std::cmp::Ordering::{self, Equal, Greater, Less};
15 use std::mem;
16
17 fn local_cmp(x: f64, y: f64) -> Ordering {
18     // arbitrarily decide that NaNs are larger than everything.
19     if y.is_nan() {
20         Less
21     } else if x.is_nan() {
22         Greater
23     } else if x < y {
24         Less
25     } else if x == y {
26         Equal
27     } else {
28         Greater
29     }
30 }
31
32 fn local_sort(v: &mut [f64]) {
33     v.sort_by(|x: &f64, y: &f64| local_cmp(*x, *y));
34 }
35
36 /// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
37 pub trait Stats {
38     /// Sum of the samples.
39     ///
40     /// Note: this method sacrifices performance at the altar of accuracy
41     /// Depends on IEEE-754 arithmetic guarantees. See proof of correctness at:
42     /// ["Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric
43     /// Predicates"][paper]
44     ///
45     /// [paper]: http://www.cs.cmu.edu/~quake-papers/robust-arithmetic.ps
46     fn sum(&self) -> f64;
47
48     /// Minimum value of the samples.
49     fn min(&self) -> f64;
50
51     /// Maximum value of the samples.
52     fn max(&self) -> f64;
53
54     /// Arithmetic mean (average) of the samples: sum divided by sample-count.
55     ///
56     /// See: <https://en.wikipedia.org/wiki/Arithmetic_mean>
57     fn mean(&self) -> f64;
58
59     /// Median of the samples: value separating the lower half of the samples from the higher half.
60     /// Equal to `self.percentile(50.0)`.
61     ///
62     /// See: <https://en.wikipedia.org/wiki/Median>
63     fn median(&self) -> f64;
64
65     /// Variance of the samples: bias-corrected mean of the squares of the differences of each
66     /// sample from the sample mean. Note that this calculates the _sample variance_ rather than the
67     /// population variance, which is assumed to be unknown. It therefore corrects the `(n-1)/n`
68     /// bias that would appear if we calculated a population variance, by dividing by `(n-1)` rather
69     /// than `n`.
70     ///
71     /// See: <https://en.wikipedia.org/wiki/Variance>
72     fn var(&self) -> f64;
73
74     /// Standard deviation: the square root of the sample variance.
75     ///
76     /// Note: this is not a robust statistic for non-normal distributions. Prefer the
77     /// `median_abs_dev` for unknown distributions.
78     ///
79     /// See: <https://en.wikipedia.org/wiki/Standard_deviation>
80     fn std_dev(&self) -> f64;
81
82     /// Standard deviation as a percent of the mean value. See `std_dev` and `mean`.
83     ///
84     /// Note: this is not a robust statistic for non-normal distributions. Prefer the
85     /// `median_abs_dev_pct` for unknown distributions.
86     fn std_dev_pct(&self) -> f64;
87
88     /// Scaled median of the absolute deviations of each sample from the sample median. This is a
89     /// robust (distribution-agnostic) estimator of sample variability. Use this in preference to
90     /// `std_dev` if you cannot assume your sample is normally distributed. Note that this is scaled
91     /// by the constant `1.4826` to allow its use as a consistent estimator for the standard
92     /// deviation.
93     ///
94     /// See: <http://en.wikipedia.org/wiki/Median_absolute_deviation>
95     fn median_abs_dev(&self) -> f64;
96
97     /// Median absolute deviation as a percent of the median. See `median_abs_dev` and `median`.
98     fn median_abs_dev_pct(&self) -> f64;
99
100     /// Percentile: the value below which `pct` percent of the values in `self` fall. For example,
101     /// percentile(95.0) will return the value `v` such that 95% of the samples `s` in `self`
102     /// satisfy `s <= v`.
103     ///
104     /// Calculated by linear interpolation between closest ranks.
105     ///
106     /// See: <http://en.wikipedia.org/wiki/Percentile>
107     fn percentile(&self, pct: f64) -> f64;
108
109     /// Quartiles of the sample: three values that divide the sample into four equal groups, each
110     /// with 1/4 of the data. The middle value is the median. See `median` and `percentile`. This
111     /// function may calculate the 3 quartiles more efficiently than 3 calls to `percentile`, but
112     /// is otherwise equivalent.
113     ///
114     /// See also: <https://en.wikipedia.org/wiki/Quartile>
115     fn quartiles(&self) -> (f64, f64, f64);
116
117     /// Inter-quartile range: the difference between the 25th percentile (1st quartile) and the 75th
118     /// percentile (3rd quartile). See `quartiles`.
119     ///
120     /// See also: <https://en.wikipedia.org/wiki/Interquartile_range>
121     fn iqr(&self) -> f64;
122 }
123
124 /// Extracted collection of all the summary statistics of a sample set.
125 #[derive(Clone, PartialEq, Copy)]
126 #[allow(missing_docs)]
127 pub struct Summary {
128     pub sum: f64,
129     pub min: f64,
130     pub max: f64,
131     pub mean: f64,
132     pub median: f64,
133     pub var: f64,
134     pub std_dev: f64,
135     pub std_dev_pct: f64,
136     pub median_abs_dev: f64,
137     pub median_abs_dev_pct: f64,
138     pub quartiles: (f64, f64, f64),
139     pub iqr: f64,
140 }
141
142 impl Summary {
143     /// Construct a new summary of a sample set.
144     pub fn new(samples: &[f64]) -> Summary {
145         Summary {
146             sum: samples.sum(),
147             min: samples.min(),
148             max: samples.max(),
149             mean: samples.mean(),
150             median: samples.median(),
151             var: samples.var(),
152             std_dev: samples.std_dev(),
153             std_dev_pct: samples.std_dev_pct(),
154             median_abs_dev: samples.median_abs_dev(),
155             median_abs_dev_pct: samples.median_abs_dev_pct(),
156             quartiles: samples.quartiles(),
157             iqr: samples.iqr(),
158         }
159     }
160 }
161
162 impl Stats for [f64] {
163     // FIXME #11059 handle NaN, inf and overflow
164     fn sum(&self) -> f64 {
165         let mut partials = vec![];
166
167         for &x in self {
168             let mut x = x;
169             let mut j = 0;
170             // This inner loop applies `hi`/`lo` summation to each
171             // partial so that the list of partial sums remains exact.
172             for i in 0..partials.len() {
173                 let mut y: f64 = partials[i];
174                 if x.abs() < y.abs() {
175                     mem::swap(&mut x, &mut y);
176                 }
177                 // Rounded `x+y` is stored in `hi` with round-off stored in
178                 // `lo`. Together `hi+lo` are exactly equal to `x+y`.
179                 let hi = x + y;
180                 let lo = y - (hi - x);
181                 if lo != 0.0 {
182                     partials[j] = lo;
183                     j += 1;
184                 }
185                 x = hi;
186             }
187             if j >= partials.len() {
188                 partials.push(x);
189             } else {
190                 partials[j] = x;
191                 partials.truncate(j + 1);
192             }
193         }
194         let zero: f64 = 0.0;
195         partials.iter().fold(zero, |p, q| p + *q)
196     }
197
198     fn min(&self) -> f64 {
199         assert!(!self.is_empty());
200         self.iter().fold(self[0], |p, q| p.min(*q))
201     }
202
203     fn max(&self) -> f64 {
204         assert!(!self.is_empty());
205         self.iter().fold(self[0], |p, q| p.max(*q))
206     }
207
208     fn mean(&self) -> f64 {
209         assert!(!self.is_empty());
210         self.sum() / (self.len() as f64)
211     }
212
213     fn median(&self) -> f64 {
214         self.percentile(50 as f64)
215     }
216
217     fn var(&self) -> f64 {
218         if self.len() < 2 {
219             0.0
220         } else {
221             let mean = self.mean();
222             let mut v: f64 = 0.0;
223             for s in self {
224                 let x = *s - mean;
225                 v = v + x * x;
226             }
227             // NB: this is _supposed to be_ len-1, not len. If you
228             // change it back to len, you will be calculating a
229             // population variance, not a sample variance.
230             let denom = (self.len() - 1) as f64;
231             v / denom
232         }
233     }
234
235     fn std_dev(&self) -> f64 {
236         self.var().sqrt()
237     }
238
239     fn std_dev_pct(&self) -> f64 {
240         let hundred = 100 as f64;
241         (self.std_dev() / self.mean()) * hundred
242     }
243
244     fn median_abs_dev(&self) -> f64 {
245         let med = self.median();
246         let abs_devs: Vec<f64> = self.iter().map(|&v| (med - v).abs()).collect();
247         // This constant is derived by smarter statistics brains than me, but it is
248         // consistent with how R and other packages treat the MAD.
249         let number = 1.4826;
250         abs_devs.median() * number
251     }
252
253     fn median_abs_dev_pct(&self) -> f64 {
254         let hundred = 100 as f64;
255         (self.median_abs_dev() / self.median()) * hundred
256     }
257
258     fn percentile(&self, pct: f64) -> f64 {
259         let mut tmp = self.to_vec();
260         local_sort(&mut tmp);
261         percentile_of_sorted(&tmp, pct)
262     }
263
264     fn quartiles(&self) -> (f64, f64, f64) {
265         let mut tmp = self.to_vec();
266         local_sort(&mut tmp);
267         let first = 25f64;
268         let a = percentile_of_sorted(&tmp, first);
269         let second = 50f64;
270         let b = percentile_of_sorted(&tmp, second);
271         let third = 75f64;
272         let c = percentile_of_sorted(&tmp, third);
273         (a, b, c)
274     }
275
276     fn iqr(&self) -> f64 {
277         let (a, _, c) = self.quartiles();
278         c - a
279     }
280 }
281
282
283 // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using
284 // linear interpolation. If samples are not sorted, return nonsensical value.
285 fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
286     assert!(!sorted_samples.is_empty());
287     if sorted_samples.len() == 1 {
288         return sorted_samples[0];
289     }
290     let zero: f64 = 0.0;
291     assert!(zero <= pct);
292     let hundred = 100f64;
293     assert!(pct <= hundred);
294     if pct == hundred {
295         return sorted_samples[sorted_samples.len() - 1];
296     }
297     let length = (sorted_samples.len() - 1) as f64;
298     let rank = (pct / hundred) * length;
299     let lrank = rank.floor();
300     let d = rank - lrank;
301     let n = lrank as usize;
302     let lo = sorted_samples[n];
303     let hi = sorted_samples[n + 1];
304     lo + (hi - lo) * d
305 }
306
307
308 /// Winsorize a set of samples, replacing values above the `100-pct` percentile
309 /// and below the `pct` percentile with those percentiles themselves. This is a
310 /// way of minimizing the effect of outliers, at the cost of biasing the sample.
311 /// It differs from trimming in that it does not change the number of samples,
312 /// just changes the values of those that are outliers.
313 ///
314 /// See: <http://en.wikipedia.org/wiki/Winsorising>
315 pub fn winsorize(samples: &mut [f64], pct: f64) {
316     let mut tmp = samples.to_vec();
317     local_sort(&mut tmp);
318     let lo = percentile_of_sorted(&tmp, pct);
319     let hundred = 100 as f64;
320     let hi = percentile_of_sorted(&tmp, hundred - pct);
321     for samp in samples {
322         if *samp > hi {
323             *samp = hi
324         } else if *samp < lo {
325             *samp = lo
326         }
327     }
328 }
329
330 // Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
331
332 #[cfg(test)]
333 mod tests {
334     use stats::Stats;
335     use stats::Summary;
336     use std::f64;
337     use std::io::prelude::*;
338     use std::io;
339
340     macro_rules! assert_approx_eq {
341         ($a:expr, $b:expr) => ({
342             let (a, b) = (&$a, &$b);
343             assert!((*a - *b).abs() < 1.0e-6,
344                     "{} is not approximately equal to {}", *a, *b);
345         })
346     }
347
348     fn check(samples: &[f64], summ: &Summary) {
349
350         let summ2 = Summary::new(samples);
351
352         let mut w = io::sink();
353         let w = &mut w;
354         (write!(w, "\n")).unwrap();
355
356         assert_eq!(summ.sum, summ2.sum);
357         assert_eq!(summ.min, summ2.min);
358         assert_eq!(summ.max, summ2.max);
359         assert_eq!(summ.mean, summ2.mean);
360         assert_eq!(summ.median, summ2.median);
361
362         // We needed a few more digits to get exact equality on these
363         // but they're within float epsilon, which is 1.0e-6.
364         assert_approx_eq!(summ.var, summ2.var);
365         assert_approx_eq!(summ.std_dev, summ2.std_dev);
366         assert_approx_eq!(summ.std_dev_pct, summ2.std_dev_pct);
367         assert_approx_eq!(summ.median_abs_dev, summ2.median_abs_dev);
368         assert_approx_eq!(summ.median_abs_dev_pct, summ2.median_abs_dev_pct);
369
370         assert_eq!(summ.quartiles, summ2.quartiles);
371         assert_eq!(summ.iqr, summ2.iqr);
372     }
373
374     #[test]
375     fn test_min_max_nan() {
376         let xs = &[1.0, 2.0, f64::NAN, 3.0, 4.0];
377         let summary = Summary::new(xs);
378         assert_eq!(summary.min, 1.0);
379         assert_eq!(summary.max, 4.0);
380     }
381
382     #[test]
383     fn test_norm2() {
384         let val = &[958.0000000000, 924.0000000000];
385         let summ = &Summary {
386             sum: 1882.0000000000,
387             min: 924.0000000000,
388             max: 958.0000000000,
389             mean: 941.0000000000,
390             median: 941.0000000000,
391             var: 578.0000000000,
392             std_dev: 24.0416305603,
393             std_dev_pct: 2.5549022912,
394             median_abs_dev: 25.2042000000,
395             median_abs_dev_pct: 2.6784484591,
396             quartiles: (932.5000000000, 941.0000000000, 949.5000000000),
397             iqr: 17.0000000000,
398         };
399         check(val, summ);
400     }
401     #[test]
402     fn test_norm10narrow() {
403         let val = &[
404             966.0000000000,
405             985.0000000000,
406             1110.0000000000,
407             848.0000000000,
408             821.0000000000,
409             975.0000000000,
410             962.0000000000,
411             1157.0000000000,
412             1217.0000000000,
413             955.0000000000,
414         ];
415         let summ = &Summary {
416             sum: 9996.0000000000,
417             min: 821.0000000000,
418             max: 1217.0000000000,
419             mean: 999.6000000000,
420             median: 970.5000000000,
421             var: 16050.7111111111,
422             std_dev: 126.6914010938,
423             std_dev_pct: 12.6742097933,
424             median_abs_dev: 102.2994000000,
425             median_abs_dev_pct: 10.5408964451,
426             quartiles: (956.7500000000, 970.5000000000, 1078.7500000000),
427             iqr: 122.0000000000,
428         };
429         check(val, summ);
430     }
431     #[test]
432     fn test_norm10medium() {
433         let val = &[
434             954.0000000000,
435             1064.0000000000,
436             855.0000000000,
437             1000.0000000000,
438             743.0000000000,
439             1084.0000000000,
440             704.0000000000,
441             1023.0000000000,
442             357.0000000000,
443             869.0000000000,
444         ];
445         let summ = &Summary {
446             sum: 8653.0000000000,
447             min: 357.0000000000,
448             max: 1084.0000000000,
449             mean: 865.3000000000,
450             median: 911.5000000000,
451             var: 48628.4555555556,
452             std_dev: 220.5186059170,
453             std_dev_pct: 25.4846418487,
454             median_abs_dev: 195.7032000000,
455             median_abs_dev_pct: 21.4704552935,
456             quartiles: (771.0000000000, 911.5000000000, 1017.2500000000),
457             iqr: 246.2500000000,
458         };
459         check(val, summ);
460     }
461     #[test]
462     fn test_norm10wide() {
463         let val = &[
464             505.0000000000,
465             497.0000000000,
466             1591.0000000000,
467             887.0000000000,
468             1026.0000000000,
469             136.0000000000,
470             1580.0000000000,
471             940.0000000000,
472             754.0000000000,
473             1433.0000000000,
474         ];
475         let summ = &Summary {
476             sum: 9349.0000000000,
477             min: 136.0000000000,
478             max: 1591.0000000000,
479             mean: 934.9000000000,
480             median: 913.5000000000,
481             var: 239208.9888888889,
482             std_dev: 489.0899599142,
483             std_dev_pct: 52.3146817750,
484             median_abs_dev: 611.5725000000,
485             median_abs_dev_pct: 66.9482758621,
486             quartiles: (567.2500000000, 913.5000000000, 1331.2500000000),
487             iqr: 764.0000000000,
488         };
489         check(val, summ);
490     }
491     #[test]
492     fn test_norm25verynarrow() {
493         let val = &[
494             991.0000000000,
495             1018.0000000000,
496             998.0000000000,
497             1013.0000000000,
498             974.0000000000,
499             1007.0000000000,
500             1014.0000000000,
501             999.0000000000,
502             1011.0000000000,
503             978.0000000000,
504             985.0000000000,
505             999.0000000000,
506             983.0000000000,
507             982.0000000000,
508             1015.0000000000,
509             1002.0000000000,
510             977.0000000000,
511             948.0000000000,
512             1040.0000000000,
513             974.0000000000,
514             996.0000000000,
515             989.0000000000,
516             1015.0000000000,
517             994.0000000000,
518             1024.0000000000,
519         ];
520         let summ = &Summary {
521             sum: 24926.0000000000,
522             min: 948.0000000000,
523             max: 1040.0000000000,
524             mean: 997.0400000000,
525             median: 998.0000000000,
526             var: 393.2066666667,
527             std_dev: 19.8294393937,
528             std_dev_pct: 1.9888308788,
529             median_abs_dev: 22.2390000000,
530             median_abs_dev_pct: 2.2283567134,
531             quartiles: (983.0000000000, 998.0000000000, 1013.0000000000),
532             iqr: 30.0000000000,
533         };
534         check(val, summ);
535     }
536     #[test]
537     fn test_exp10a() {
538         let val = &[
539             23.0000000000,
540             11.0000000000,
541             2.0000000000,
542             57.0000000000,
543             4.0000000000,
544             12.0000000000,
545             5.0000000000,
546             29.0000000000,
547             3.0000000000,
548             21.0000000000,
549         ];
550         let summ = &Summary {
551             sum: 167.0000000000,
552             min: 2.0000000000,
553             max: 57.0000000000,
554             mean: 16.7000000000,
555             median: 11.5000000000,
556             var: 287.7888888889,
557             std_dev: 16.9643416875,
558             std_dev_pct: 101.5828843560,
559             median_abs_dev: 13.3434000000,
560             median_abs_dev_pct: 116.0295652174,
561             quartiles: (4.2500000000, 11.5000000000, 22.5000000000),
562             iqr: 18.2500000000,
563         };
564         check(val, summ);
565     }
566     #[test]
567     fn test_exp10b() {
568         let val = &[
569             24.0000000000,
570             17.0000000000,
571             6.0000000000,
572             38.0000000000,
573             25.0000000000,
574             7.0000000000,
575             51.0000000000,
576             2.0000000000,
577             61.0000000000,
578             32.0000000000,
579         ];
580         let summ = &Summary {
581             sum: 263.0000000000,
582             min: 2.0000000000,
583             max: 61.0000000000,
584             mean: 26.3000000000,
585             median: 24.5000000000,
586             var: 383.5666666667,
587             std_dev: 19.5848580967,
588             std_dev_pct: 74.4671410520,
589             median_abs_dev: 22.9803000000,
590             median_abs_dev_pct: 93.7971428571,
591             quartiles: (9.5000000000, 24.5000000000, 36.5000000000),
592             iqr: 27.0000000000,
593         };
594         check(val, summ);
595     }
596     #[test]
597     fn test_exp10c() {
598         let val = &[
599             71.0000000000,
600             2.0000000000,
601             32.0000000000,
602             1.0000000000,
603             6.0000000000,
604             28.0000000000,
605             13.0000000000,
606             37.0000000000,
607             16.0000000000,
608             36.0000000000,
609         ];
610         let summ = &Summary {
611             sum: 242.0000000000,
612             min: 1.0000000000,
613             max: 71.0000000000,
614             mean: 24.2000000000,
615             median: 22.0000000000,
616             var: 458.1777777778,
617             std_dev: 21.4050876611,
618             std_dev_pct: 88.4507754589,
619             median_abs_dev: 21.4977000000,
620             median_abs_dev_pct: 97.7168181818,
621             quartiles: (7.7500000000, 22.0000000000, 35.0000000000),
622             iqr: 27.2500000000,
623         };
624         check(val, summ);
625     }
626     #[test]
627     fn test_exp25() {
628         let val = &[
629             3.0000000000,
630             24.0000000000,
631             1.0000000000,
632             19.0000000000,
633             7.0000000000,
634             5.0000000000,
635             30.0000000000,
636             39.0000000000,
637             31.0000000000,
638             13.0000000000,
639             25.0000000000,
640             48.0000000000,
641             1.0000000000,
642             6.0000000000,
643             42.0000000000,
644             63.0000000000,
645             2.0000000000,
646             12.0000000000,
647             108.0000000000,
648             26.0000000000,
649             1.0000000000,
650             7.0000000000,
651             44.0000000000,
652             25.0000000000,
653             11.0000000000,
654         ];
655         let summ = &Summary {
656             sum: 593.0000000000,
657             min: 1.0000000000,
658             max: 108.0000000000,
659             mean: 23.7200000000,
660             median: 19.0000000000,
661             var: 601.0433333333,
662             std_dev: 24.5161851301,
663             std_dev_pct: 103.3565983562,
664             median_abs_dev: 19.2738000000,
665             median_abs_dev_pct: 101.4410526316,
666             quartiles: (6.0000000000, 19.0000000000, 31.0000000000),
667             iqr: 25.0000000000,
668         };
669         check(val, summ);
670     }
671     #[test]
672     fn test_binom25() {
673         let val = &[
674             18.0000000000,
675             17.0000000000,
676             27.0000000000,
677             15.0000000000,
678             21.0000000000,
679             25.0000000000,
680             17.0000000000,
681             24.0000000000,
682             25.0000000000,
683             24.0000000000,
684             26.0000000000,
685             26.0000000000,
686             23.0000000000,
687             15.0000000000,
688             23.0000000000,
689             17.0000000000,
690             18.0000000000,
691             18.0000000000,
692             21.0000000000,
693             16.0000000000,
694             15.0000000000,
695             31.0000000000,
696             20.0000000000,
697             17.0000000000,
698             15.0000000000,
699         ];
700         let summ = &Summary {
701             sum: 514.0000000000,
702             min: 15.0000000000,
703             max: 31.0000000000,
704             mean: 20.5600000000,
705             median: 20.0000000000,
706             var: 20.8400000000,
707             std_dev: 4.5650848842,
708             std_dev_pct: 22.2037202539,
709             median_abs_dev: 5.9304000000,
710             median_abs_dev_pct: 29.6520000000,
711             quartiles: (17.0000000000, 20.0000000000, 24.0000000000),
712             iqr: 7.0000000000,
713         };
714         check(val, summ);
715     }
716     #[test]
717     fn test_pois25lambda30() {
718         let val = &[
719             27.0000000000,
720             33.0000000000,
721             34.0000000000,
722             34.0000000000,
723             24.0000000000,
724             39.0000000000,
725             28.0000000000,
726             27.0000000000,
727             31.0000000000,
728             28.0000000000,
729             38.0000000000,
730             21.0000000000,
731             33.0000000000,
732             36.0000000000,
733             29.0000000000,
734             37.0000000000,
735             32.0000000000,
736             34.0000000000,
737             31.0000000000,
738             39.0000000000,
739             25.0000000000,
740             31.0000000000,
741             32.0000000000,
742             40.0000000000,
743             24.0000000000,
744         ];
745         let summ = &Summary {
746             sum: 787.0000000000,
747             min: 21.0000000000,
748             max: 40.0000000000,
749             mean: 31.4800000000,
750             median: 32.0000000000,
751             var: 26.5933333333,
752             std_dev: 5.1568724372,
753             std_dev_pct: 16.3814245145,
754             median_abs_dev: 5.9304000000,
755             median_abs_dev_pct: 18.5325000000,
756             quartiles: (28.0000000000, 32.0000000000, 34.0000000000),
757             iqr: 6.0000000000,
758         };
759         check(val, summ);
760     }
761     #[test]
762     fn test_pois25lambda40() {
763         let val = &[
764             42.0000000000,
765             50.0000000000,
766             42.0000000000,
767             46.0000000000,
768             34.0000000000,
769             45.0000000000,
770             34.0000000000,
771             49.0000000000,
772             39.0000000000,
773             28.0000000000,
774             40.0000000000,
775             35.0000000000,
776             37.0000000000,
777             39.0000000000,
778             46.0000000000,
779             44.0000000000,
780             32.0000000000,
781             45.0000000000,
782             42.0000000000,
783             37.0000000000,
784             48.0000000000,
785             42.0000000000,
786             33.0000000000,
787             42.0000000000,
788             48.0000000000,
789         ];
790         let summ = &Summary {
791             sum: 1019.0000000000,
792             min: 28.0000000000,
793             max: 50.0000000000,
794             mean: 40.7600000000,
795             median: 42.0000000000,
796             var: 34.4400000000,
797             std_dev: 5.8685603004,
798             std_dev_pct: 14.3978417577,
799             median_abs_dev: 5.9304000000,
800             median_abs_dev_pct: 14.1200000000,
801             quartiles: (37.0000000000, 42.0000000000, 45.0000000000),
802             iqr: 8.0000000000,
803         };
804         check(val, summ);
805     }
806     #[test]
807     fn test_pois25lambda50() {
808         let val = &[
809             45.0000000000,
810             43.0000000000,
811             44.0000000000,
812             61.0000000000,
813             51.0000000000,
814             53.0000000000,
815             59.0000000000,
816             52.0000000000,
817             49.0000000000,
818             51.0000000000,
819             51.0000000000,
820             50.0000000000,
821             49.0000000000,
822             56.0000000000,
823             42.0000000000,
824             52.0000000000,
825             51.0000000000,
826             43.0000000000,
827             48.0000000000,
828             48.0000000000,
829             50.0000000000,
830             42.0000000000,
831             43.0000000000,
832             42.0000000000,
833             60.0000000000,
834         ];
835         let summ = &Summary {
836             sum: 1235.0000000000,
837             min: 42.0000000000,
838             max: 61.0000000000,
839             mean: 49.4000000000,
840             median: 50.0000000000,
841             var: 31.6666666667,
842             std_dev: 5.6273143387,
843             std_dev_pct: 11.3913245723,
844             median_abs_dev: 4.4478000000,
845             median_abs_dev_pct: 8.8956000000,
846             quartiles: (44.0000000000, 50.0000000000, 52.0000000000),
847             iqr: 8.0000000000,
848         };
849         check(val, summ);
850     }
851     #[test]
852     fn test_unif25() {
853         let val = &[
854             99.0000000000,
855             55.0000000000,
856             92.0000000000,
857             79.0000000000,
858             14.0000000000,
859             2.0000000000,
860             33.0000000000,
861             49.0000000000,
862             3.0000000000,
863             32.0000000000,
864             84.0000000000,
865             59.0000000000,
866             22.0000000000,
867             86.0000000000,
868             76.0000000000,
869             31.0000000000,
870             29.0000000000,
871             11.0000000000,
872             41.0000000000,
873             53.0000000000,
874             45.0000000000,
875             44.0000000000,
876             98.0000000000,
877             98.0000000000,
878             7.0000000000,
879         ];
880         let summ = &Summary {
881             sum: 1242.0000000000,
882             min: 2.0000000000,
883             max: 99.0000000000,
884             mean: 49.6800000000,
885             median: 45.0000000000,
886             var: 1015.6433333333,
887             std_dev: 31.8691595957,
888             std_dev_pct: 64.1488719719,
889             median_abs_dev: 45.9606000000,
890             median_abs_dev_pct: 102.1346666667,
891             quartiles: (29.0000000000, 45.0000000000, 79.0000000000),
892             iqr: 50.0000000000,
893         };
894         check(val, summ);
895     }
896
897     #[test]
898     fn test_sum_f64s() {
899         assert_eq!([0.5f64, 3.2321f64, 1.5678f64].sum(), 5.2999);
900     }
901     #[test]
902     fn test_sum_f64_between_ints_that_sum_to_0() {
903         assert_eq!([1e30f64, 1.2f64, -1e30f64].sum(), 1.2);
904     }
905 }
906
907 #[cfg(test)]
908 mod bench {
909     use Bencher;
910     use stats::Stats;
911
912     #[bench]
913     pub fn sum_three_items(b: &mut Bencher) {
914         b.iter(|| { [1e20f64, 1.5f64, -1e20f64].sum(); })
915     }
916     #[bench]
917     pub fn sum_many_f64(b: &mut Bencher) {
918         let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60];
919         let v = (0..500).map(|i| nums[i % 5]).collect::<Vec<_>>();
920
921         b.iter(|| { v.sum(); })
922     }
923
924     #[bench]
925     pub fn no_iter(_: &mut Bencher) {}
926 }