]> git.lizzy.rs Git - rust.git/blob - src/libtest/stats.rs
Rollup merge of #48270 - leodasvacas:refactor-casts, r=nikomatsakis
[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 // Helper function: extract a value representing the `pct` percentile of a sorted sample-set, using
283 // linear interpolation. If samples are not sorted, return nonsensical value.
284 fn percentile_of_sorted(sorted_samples: &[f64], pct: f64) -> f64 {
285     assert!(!sorted_samples.is_empty());
286     if sorted_samples.len() == 1 {
287         return sorted_samples[0];
288     }
289     let zero: f64 = 0.0;
290     assert!(zero <= pct);
291     let hundred = 100f64;
292     assert!(pct <= hundred);
293     if pct == hundred {
294         return sorted_samples[sorted_samples.len() - 1];
295     }
296     let length = (sorted_samples.len() - 1) as f64;
297     let rank = (pct / hundred) * length;
298     let lrank = rank.floor();
299     let d = rank - lrank;
300     let n = lrank as usize;
301     let lo = sorted_samples[n];
302     let hi = sorted_samples[n + 1];
303     lo + (hi - lo) * d
304 }
305
306 /// Winsorize a set of samples, replacing values above the `100-pct` percentile
307 /// and below the `pct` percentile with those percentiles themselves. This is a
308 /// way of minimizing the effect of outliers, at the cost of biasing the sample.
309 /// It differs from trimming in that it does not change the number of samples,
310 /// just changes the values of those that are outliers.
311 ///
312 /// See: <http://en.wikipedia.org/wiki/Winsorising>
313 pub fn winsorize(samples: &mut [f64], pct: f64) {
314     let mut tmp = samples.to_vec();
315     local_sort(&mut tmp);
316     let lo = percentile_of_sorted(&tmp, pct);
317     let hundred = 100 as f64;
318     let hi = percentile_of_sorted(&tmp, hundred - pct);
319     for samp in samples {
320         if *samp > hi {
321             *samp = hi
322         } else if *samp < lo {
323             *samp = lo
324         }
325     }
326 }
327
328 // Test vectors generated from R, using the script src/etc/stat-test-vectors.r.
329
330 #[cfg(test)]
331 mod tests {
332     use stats::Stats;
333     use stats::Summary;
334     use std::f64;
335     use std::io::prelude::*;
336     use std::io;
337
338     macro_rules! assert_approx_eq {
339         ($a: expr, $b: expr) => {{
340             let (a, b) = (&$a, &$b);
341             assert!(
342                 (*a - *b).abs() < 1.0e-6,
343                 "{} is not approximately equal to {}",
344                 *a,
345                 *b
346             );
347         }};
348     }
349
350     fn check(samples: &[f64], summ: &Summary) {
351         let summ2 = Summary::new(samples);
352
353         let mut w = io::sink();
354         let w = &mut w;
355         (write!(w, "\n")).unwrap();
356
357         assert_eq!(summ.sum, summ2.sum);
358         assert_eq!(summ.min, summ2.min);
359         assert_eq!(summ.max, summ2.max);
360         assert_eq!(summ.mean, summ2.mean);
361         assert_eq!(summ.median, summ2.median);
362
363         // We needed a few more digits to get exact equality on these
364         // but they're within float epsilon, which is 1.0e-6.
365         assert_approx_eq!(summ.var, summ2.var);
366         assert_approx_eq!(summ.std_dev, summ2.std_dev);
367         assert_approx_eq!(summ.std_dev_pct, summ2.std_dev_pct);
368         assert_approx_eq!(summ.median_abs_dev, summ2.median_abs_dev);
369         assert_approx_eq!(summ.median_abs_dev_pct, summ2.median_abs_dev_pct);
370
371         assert_eq!(summ.quartiles, summ2.quartiles);
372         assert_eq!(summ.iqr, summ2.iqr);
373     }
374
375     #[test]
376     fn test_min_max_nan() {
377         let xs = &[1.0, 2.0, f64::NAN, 3.0, 4.0];
378         let summary = Summary::new(xs);
379         assert_eq!(summary.min, 1.0);
380         assert_eq!(summary.max, 4.0);
381     }
382
383     #[test]
384     fn test_norm2() {
385         let val = &[958.0000000000, 924.0000000000];
386         let summ = &Summary {
387             sum: 1882.0000000000,
388             min: 924.0000000000,
389             max: 958.0000000000,
390             mean: 941.0000000000,
391             median: 941.0000000000,
392             var: 578.0000000000,
393             std_dev: 24.0416305603,
394             std_dev_pct: 2.5549022912,
395             median_abs_dev: 25.2042000000,
396             median_abs_dev_pct: 2.6784484591,
397             quartiles: (932.5000000000, 941.0000000000, 949.5000000000),
398             iqr: 17.0000000000,
399         };
400         check(val, summ);
401     }
402     #[test]
403     fn test_norm10narrow() {
404         let val = &[
405             966.0000000000,
406             985.0000000000,
407             1110.0000000000,
408             848.0000000000,
409             821.0000000000,
410             975.0000000000,
411             962.0000000000,
412             1157.0000000000,
413             1217.0000000000,
414             955.0000000000,
415         ];
416         let summ = &Summary {
417             sum: 9996.0000000000,
418             min: 821.0000000000,
419             max: 1217.0000000000,
420             mean: 999.6000000000,
421             median: 970.5000000000,
422             var: 16050.7111111111,
423             std_dev: 126.6914010938,
424             std_dev_pct: 12.6742097933,
425             median_abs_dev: 102.2994000000,
426             median_abs_dev_pct: 10.5408964451,
427             quartiles: (956.7500000000, 970.5000000000, 1078.7500000000),
428             iqr: 122.0000000000,
429         };
430         check(val, summ);
431     }
432     #[test]
433     fn test_norm10medium() {
434         let val = &[
435             954.0000000000,
436             1064.0000000000,
437             855.0000000000,
438             1000.0000000000,
439             743.0000000000,
440             1084.0000000000,
441             704.0000000000,
442             1023.0000000000,
443             357.0000000000,
444             869.0000000000,
445         ];
446         let summ = &Summary {
447             sum: 8653.0000000000,
448             min: 357.0000000000,
449             max: 1084.0000000000,
450             mean: 865.3000000000,
451             median: 911.5000000000,
452             var: 48628.4555555556,
453             std_dev: 220.5186059170,
454             std_dev_pct: 25.4846418487,
455             median_abs_dev: 195.7032000000,
456             median_abs_dev_pct: 21.4704552935,
457             quartiles: (771.0000000000, 911.5000000000, 1017.2500000000),
458             iqr: 246.2500000000,
459         };
460         check(val, summ);
461     }
462     #[test]
463     fn test_norm10wide() {
464         let val = &[
465             505.0000000000,
466             497.0000000000,
467             1591.0000000000,
468             887.0000000000,
469             1026.0000000000,
470             136.0000000000,
471             1580.0000000000,
472             940.0000000000,
473             754.0000000000,
474             1433.0000000000,
475         ];
476         let summ = &Summary {
477             sum: 9349.0000000000,
478             min: 136.0000000000,
479             max: 1591.0000000000,
480             mean: 934.9000000000,
481             median: 913.5000000000,
482             var: 239208.9888888889,
483             std_dev: 489.0899599142,
484             std_dev_pct: 52.3146817750,
485             median_abs_dev: 611.5725000000,
486             median_abs_dev_pct: 66.9482758621,
487             quartiles: (567.2500000000, 913.5000000000, 1331.2500000000),
488             iqr: 764.0000000000,
489         };
490         check(val, summ);
491     }
492     #[test]
493     fn test_norm25verynarrow() {
494         let val = &[
495             991.0000000000,
496             1018.0000000000,
497             998.0000000000,
498             1013.0000000000,
499             974.0000000000,
500             1007.0000000000,
501             1014.0000000000,
502             999.0000000000,
503             1011.0000000000,
504             978.0000000000,
505             985.0000000000,
506             999.0000000000,
507             983.0000000000,
508             982.0000000000,
509             1015.0000000000,
510             1002.0000000000,
511             977.0000000000,
512             948.0000000000,
513             1040.0000000000,
514             974.0000000000,
515             996.0000000000,
516             989.0000000000,
517             1015.0000000000,
518             994.0000000000,
519             1024.0000000000,
520         ];
521         let summ = &Summary {
522             sum: 24926.0000000000,
523             min: 948.0000000000,
524             max: 1040.0000000000,
525             mean: 997.0400000000,
526             median: 998.0000000000,
527             var: 393.2066666667,
528             std_dev: 19.8294393937,
529             std_dev_pct: 1.9888308788,
530             median_abs_dev: 22.2390000000,
531             median_abs_dev_pct: 2.2283567134,
532             quartiles: (983.0000000000, 998.0000000000, 1013.0000000000),
533             iqr: 30.0000000000,
534         };
535         check(val, summ);
536     }
537     #[test]
538     fn test_exp10a() {
539         let val = &[
540             23.0000000000,
541             11.0000000000,
542             2.0000000000,
543             57.0000000000,
544             4.0000000000,
545             12.0000000000,
546             5.0000000000,
547             29.0000000000,
548             3.0000000000,
549             21.0000000000,
550         ];
551         let summ = &Summary {
552             sum: 167.0000000000,
553             min: 2.0000000000,
554             max: 57.0000000000,
555             mean: 16.7000000000,
556             median: 11.5000000000,
557             var: 287.7888888889,
558             std_dev: 16.9643416875,
559             std_dev_pct: 101.5828843560,
560             median_abs_dev: 13.3434000000,
561             median_abs_dev_pct: 116.0295652174,
562             quartiles: (4.2500000000, 11.5000000000, 22.5000000000),
563             iqr: 18.2500000000,
564         };
565         check(val, summ);
566     }
567     #[test]
568     fn test_exp10b() {
569         let val = &[
570             24.0000000000,
571             17.0000000000,
572             6.0000000000,
573             38.0000000000,
574             25.0000000000,
575             7.0000000000,
576             51.0000000000,
577             2.0000000000,
578             61.0000000000,
579             32.0000000000,
580         ];
581         let summ = &Summary {
582             sum: 263.0000000000,
583             min: 2.0000000000,
584             max: 61.0000000000,
585             mean: 26.3000000000,
586             median: 24.5000000000,
587             var: 383.5666666667,
588             std_dev: 19.5848580967,
589             std_dev_pct: 74.4671410520,
590             median_abs_dev: 22.9803000000,
591             median_abs_dev_pct: 93.7971428571,
592             quartiles: (9.5000000000, 24.5000000000, 36.5000000000),
593             iqr: 27.0000000000,
594         };
595         check(val, summ);
596     }
597     #[test]
598     fn test_exp10c() {
599         let val = &[
600             71.0000000000,
601             2.0000000000,
602             32.0000000000,
603             1.0000000000,
604             6.0000000000,
605             28.0000000000,
606             13.0000000000,
607             37.0000000000,
608             16.0000000000,
609             36.0000000000,
610         ];
611         let summ = &Summary {
612             sum: 242.0000000000,
613             min: 1.0000000000,
614             max: 71.0000000000,
615             mean: 24.2000000000,
616             median: 22.0000000000,
617             var: 458.1777777778,
618             std_dev: 21.4050876611,
619             std_dev_pct: 88.4507754589,
620             median_abs_dev: 21.4977000000,
621             median_abs_dev_pct: 97.7168181818,
622             quartiles: (7.7500000000, 22.0000000000, 35.0000000000),
623             iqr: 27.2500000000,
624         };
625         check(val, summ);
626     }
627     #[test]
628     fn test_exp25() {
629         let val = &[
630             3.0000000000,
631             24.0000000000,
632             1.0000000000,
633             19.0000000000,
634             7.0000000000,
635             5.0000000000,
636             30.0000000000,
637             39.0000000000,
638             31.0000000000,
639             13.0000000000,
640             25.0000000000,
641             48.0000000000,
642             1.0000000000,
643             6.0000000000,
644             42.0000000000,
645             63.0000000000,
646             2.0000000000,
647             12.0000000000,
648             108.0000000000,
649             26.0000000000,
650             1.0000000000,
651             7.0000000000,
652             44.0000000000,
653             25.0000000000,
654             11.0000000000,
655         ];
656         let summ = &Summary {
657             sum: 593.0000000000,
658             min: 1.0000000000,
659             max: 108.0000000000,
660             mean: 23.7200000000,
661             median: 19.0000000000,
662             var: 601.0433333333,
663             std_dev: 24.5161851301,
664             std_dev_pct: 103.3565983562,
665             median_abs_dev: 19.2738000000,
666             median_abs_dev_pct: 101.4410526316,
667             quartiles: (6.0000000000, 19.0000000000, 31.0000000000),
668             iqr: 25.0000000000,
669         };
670         check(val, summ);
671     }
672     #[test]
673     fn test_binom25() {
674         let val = &[
675             18.0000000000,
676             17.0000000000,
677             27.0000000000,
678             15.0000000000,
679             21.0000000000,
680             25.0000000000,
681             17.0000000000,
682             24.0000000000,
683             25.0000000000,
684             24.0000000000,
685             26.0000000000,
686             26.0000000000,
687             23.0000000000,
688             15.0000000000,
689             23.0000000000,
690             17.0000000000,
691             18.0000000000,
692             18.0000000000,
693             21.0000000000,
694             16.0000000000,
695             15.0000000000,
696             31.0000000000,
697             20.0000000000,
698             17.0000000000,
699             15.0000000000,
700         ];
701         let summ = &Summary {
702             sum: 514.0000000000,
703             min: 15.0000000000,
704             max: 31.0000000000,
705             mean: 20.5600000000,
706             median: 20.0000000000,
707             var: 20.8400000000,
708             std_dev: 4.5650848842,
709             std_dev_pct: 22.2037202539,
710             median_abs_dev: 5.9304000000,
711             median_abs_dev_pct: 29.6520000000,
712             quartiles: (17.0000000000, 20.0000000000, 24.0000000000),
713             iqr: 7.0000000000,
714         };
715         check(val, summ);
716     }
717     #[test]
718     fn test_pois25lambda30() {
719         let val = &[
720             27.0000000000,
721             33.0000000000,
722             34.0000000000,
723             34.0000000000,
724             24.0000000000,
725             39.0000000000,
726             28.0000000000,
727             27.0000000000,
728             31.0000000000,
729             28.0000000000,
730             38.0000000000,
731             21.0000000000,
732             33.0000000000,
733             36.0000000000,
734             29.0000000000,
735             37.0000000000,
736             32.0000000000,
737             34.0000000000,
738             31.0000000000,
739             39.0000000000,
740             25.0000000000,
741             31.0000000000,
742             32.0000000000,
743             40.0000000000,
744             24.0000000000,
745         ];
746         let summ = &Summary {
747             sum: 787.0000000000,
748             min: 21.0000000000,
749             max: 40.0000000000,
750             mean: 31.4800000000,
751             median: 32.0000000000,
752             var: 26.5933333333,
753             std_dev: 5.1568724372,
754             std_dev_pct: 16.3814245145,
755             median_abs_dev: 5.9304000000,
756             median_abs_dev_pct: 18.5325000000,
757             quartiles: (28.0000000000, 32.0000000000, 34.0000000000),
758             iqr: 6.0000000000,
759         };
760         check(val, summ);
761     }
762     #[test]
763     fn test_pois25lambda40() {
764         let val = &[
765             42.0000000000,
766             50.0000000000,
767             42.0000000000,
768             46.0000000000,
769             34.0000000000,
770             45.0000000000,
771             34.0000000000,
772             49.0000000000,
773             39.0000000000,
774             28.0000000000,
775             40.0000000000,
776             35.0000000000,
777             37.0000000000,
778             39.0000000000,
779             46.0000000000,
780             44.0000000000,
781             32.0000000000,
782             45.0000000000,
783             42.0000000000,
784             37.0000000000,
785             48.0000000000,
786             42.0000000000,
787             33.0000000000,
788             42.0000000000,
789             48.0000000000,
790         ];
791         let summ = &Summary {
792             sum: 1019.0000000000,
793             min: 28.0000000000,
794             max: 50.0000000000,
795             mean: 40.7600000000,
796             median: 42.0000000000,
797             var: 34.4400000000,
798             std_dev: 5.8685603004,
799             std_dev_pct: 14.3978417577,
800             median_abs_dev: 5.9304000000,
801             median_abs_dev_pct: 14.1200000000,
802             quartiles: (37.0000000000, 42.0000000000, 45.0000000000),
803             iqr: 8.0000000000,
804         };
805         check(val, summ);
806     }
807     #[test]
808     fn test_pois25lambda50() {
809         let val = &[
810             45.0000000000,
811             43.0000000000,
812             44.0000000000,
813             61.0000000000,
814             51.0000000000,
815             53.0000000000,
816             59.0000000000,
817             52.0000000000,
818             49.0000000000,
819             51.0000000000,
820             51.0000000000,
821             50.0000000000,
822             49.0000000000,
823             56.0000000000,
824             42.0000000000,
825             52.0000000000,
826             51.0000000000,
827             43.0000000000,
828             48.0000000000,
829             48.0000000000,
830             50.0000000000,
831             42.0000000000,
832             43.0000000000,
833             42.0000000000,
834             60.0000000000,
835         ];
836         let summ = &Summary {
837             sum: 1235.0000000000,
838             min: 42.0000000000,
839             max: 61.0000000000,
840             mean: 49.4000000000,
841             median: 50.0000000000,
842             var: 31.6666666667,
843             std_dev: 5.6273143387,
844             std_dev_pct: 11.3913245723,
845             median_abs_dev: 4.4478000000,
846             median_abs_dev_pct: 8.8956000000,
847             quartiles: (44.0000000000, 50.0000000000, 52.0000000000),
848             iqr: 8.0000000000,
849         };
850         check(val, summ);
851     }
852     #[test]
853     fn test_unif25() {
854         let val = &[
855             99.0000000000,
856             55.0000000000,
857             92.0000000000,
858             79.0000000000,
859             14.0000000000,
860             2.0000000000,
861             33.0000000000,
862             49.0000000000,
863             3.0000000000,
864             32.0000000000,
865             84.0000000000,
866             59.0000000000,
867             22.0000000000,
868             86.0000000000,
869             76.0000000000,
870             31.0000000000,
871             29.0000000000,
872             11.0000000000,
873             41.0000000000,
874             53.0000000000,
875             45.0000000000,
876             44.0000000000,
877             98.0000000000,
878             98.0000000000,
879             7.0000000000,
880         ];
881         let summ = &Summary {
882             sum: 1242.0000000000,
883             min: 2.0000000000,
884             max: 99.0000000000,
885             mean: 49.6800000000,
886             median: 45.0000000000,
887             var: 1015.6433333333,
888             std_dev: 31.8691595957,
889             std_dev_pct: 64.1488719719,
890             median_abs_dev: 45.9606000000,
891             median_abs_dev_pct: 102.1346666667,
892             quartiles: (29.0000000000, 45.0000000000, 79.0000000000),
893             iqr: 50.0000000000,
894         };
895         check(val, summ);
896     }
897
898     #[test]
899     fn test_sum_f64s() {
900         assert_eq!([0.5f64, 3.2321f64, 1.5678f64].sum(), 5.2999);
901     }
902     #[test]
903     fn test_sum_f64_between_ints_that_sum_to_0() {
904         assert_eq!([1e30f64, 1.2f64, -1e30f64].sum(), 1.2);
905     }
906 }
907
908 #[cfg(test)]
909 mod bench {
910     use Bencher;
911     use stats::Stats;
912
913     #[bench]
914     pub fn sum_three_items(b: &mut Bencher) {
915         b.iter(|| {
916             [1e20f64, 1.5f64, -1e20f64].sum();
917         })
918     }
919     #[bench]
920     pub fn sum_many_f64(b: &mut Bencher) {
921         let nums = [-1e30f64, 1e60, 1e30, 1.0, -1e60];
922         let v = (0..500).map(|i| nums[i % 5]).collect::<Vec<_>>();
923
924         b.iter(|| {
925             v.sum();
926         })
927     }
928
929     #[bench]
930     pub fn no_iter(_: &mut Bencher) {}
931 }