blob: 526198efef6433605e9862f78652d3e7c59cd456 [file] [log] [blame]
cdaltone1b89582015-06-25 19:17:08 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
mtklein90c471e2014-06-16 14:04:32 -07008#ifndef Stats_DEFINED
9#define Stats_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkString.h"
12#include "include/private/SkFloatingPoint.h"
13#include "src/core/SkTSort.h"
mtklein40b32be2014-07-09 08:46:49 -070014
mtklein62386882014-07-15 10:30:31 -070015#ifdef SK_BUILD_FOR_WIN
16 static const char* kBars[] = { ".", "o", "O" };
17#else
18 static const char* kBars[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" };
19#endif
mtklein5d9d10e2014-07-11 11:57:07 -070020
mtklein90c471e2014-06-16 14:04:32 -070021struct Stats {
Mike Klein512a2442018-09-27 10:44:56 -040022 Stats(const SkTArray<double>& samples, bool want_plot) {
cdaltone1b89582015-06-25 19:17:08 -070023 int n = samples.count();
24 if (!n) {
25 min = max = mean = var = median = 0;
26 return;
27 }
28
mtklein90c471e2014-06-16 14:04:32 -070029 min = samples[0];
30 max = samples[0];
31 for (int i = 0; i < n; i++) {
32 if (samples[i] < min) { min = samples[i]; }
33 if (samples[i] > max) { max = samples[i]; }
34 }
35
36 double sum = 0.0;
37 for (int i = 0 ; i < n; i++) {
38 sum += samples[i];
39 }
40 mean = sum / n;
41
42 double err = 0.0;
43 for (int i = 0 ; i < n; i++) {
44 err += (samples[i] - mean) * (samples[i] - mean);
45 }
Mike Kleina4c277b2018-11-06 14:24:55 -050046 var = sk_ieee_double_divide(err, n-1);
mtklein40b32be2014-07-09 08:46:49 -070047
48 SkAutoTMalloc<double> sorted(n);
cdaltone1b89582015-06-25 19:17:08 -070049 memcpy(sorted.get(), samples.begin(), n * sizeof(double));
mtklein40b32be2014-07-09 08:46:49 -070050 SkTQSort(sorted.get(), sorted.get() + n - 1);
51 median = sorted[n/2];
mtklein5d9d10e2014-07-11 11:57:07 -070052
mtkleina189ccd2014-07-14 12:28:47 -070053 // Normalize samples to [min, max] in as many quanta as we have distinct bars to print.
Mike Klein512a2442018-09-27 10:44:56 -040054 for (int i = 0; want_plot && i < n; i++) {
mtkleina189ccd2014-07-14 12:28:47 -070055 if (min == max) {
56 // All samples are the same value. Don't divide by zero.
57 plot.append(kBars[0]);
58 continue;
59 }
60
mtklein5d9d10e2014-07-11 11:57:07 -070061 double s = samples[i];
mtklein5d9d10e2014-07-11 11:57:07 -070062 s -= min;
63 s /= (max - min);
64 s *= (SK_ARRAY_COUNT(kBars) - 1);
Mike Klein91294772014-07-16 19:59:32 -040065 const size_t bar = (size_t)(s + 0.5);
djsollenf2b340f2016-01-29 08:51:04 -080066 SkASSERT_RELEASE(bar < SK_ARRAY_COUNT(kBars));
mtklein5d9d10e2014-07-11 11:57:07 -070067 plot.append(kBars[bar]);
68 }
mtklein90c471e2014-06-16 14:04:32 -070069 }
70
71 double min;
72 double max;
mtklein5d9d10e2014-07-11 11:57:07 -070073 double mean; // Estimate of population mean.
74 double var; // Estimate of population variance.
mtklein40b32be2014-07-09 08:46:49 -070075 double median;
mtklein5d9d10e2014-07-11 11:57:07 -070076 SkString plot; // A single-line bar chart (_not_ histogram) of the samples.
mtklein90c471e2014-06-16 14:04:32 -070077};
78
79#endif//Stats_DEFINED