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