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