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