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