blob: 9086adf8f79144b0ae5bf9ab197a95f8e1a84ab1 [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
John Stiles886a9042020-07-14 16:28:33 -040011#include <algorithm>
12#include <vector>
13
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/core/SkString.h"
15#include "include/private/SkFloatingPoint.h"
mtklein40b32be2014-07-09 08:46:49 -070016
mtklein62386882014-07-15 10:30:31 -070017#ifdef SK_BUILD_FOR_WIN
18 static const char* kBars[] = { ".", "o", "O" };
19#else
20 static const char* kBars[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" };
21#endif
mtklein5d9d10e2014-07-11 11:57:07 -070022
mtklein90c471e2014-06-16 14:04:32 -070023struct Stats {
Mike Klein512a2442018-09-27 10:44:56 -040024 Stats(const SkTArray<double>& samples, bool want_plot) {
cdaltone1b89582015-06-25 19:17:08 -070025 int n = samples.count();
26 if (!n) {
27 min = max = mean = var = median = 0;
28 return;
29 }
30
mtklein90c471e2014-06-16 14:04:32 -070031 min = samples[0];
32 max = samples[0];
33 for (int i = 0; i < n; i++) {
34 if (samples[i] < min) { min = samples[i]; }
35 if (samples[i] > max) { max = samples[i]; }
36 }
37
38 double sum = 0.0;
39 for (int i = 0 ; i < n; i++) {
40 sum += samples[i];
41 }
42 mean = sum / n;
43
44 double err = 0.0;
45 for (int i = 0 ; i < n; i++) {
46 err += (samples[i] - mean) * (samples[i] - mean);
47 }
Mike Kleina4c277b2018-11-06 14:24:55 -050048 var = sk_ieee_double_divide(err, n-1);
mtklein40b32be2014-07-09 08:46:49 -070049
John Stiles886a9042020-07-14 16:28:33 -040050 std::vector<double> sorted(samples.begin(), samples.end());
51 std::sort(sorted.begin(), sorted.end());
mtklein40b32be2014-07-09 08:46:49 -070052 median = sorted[n/2];
mtklein5d9d10e2014-07-11 11:57:07 -070053
mtkleina189ccd2014-07-14 12:28:47 -070054 // Normalize samples to [min, max] in as many quanta as we have distinct bars to print.
Mike Klein512a2442018-09-27 10:44:56 -040055 for (int i = 0; want_plot && i < n; i++) {
mtkleina189ccd2014-07-14 12:28:47 -070056 if (min == max) {
57 // All samples are the same value. Don't divide by zero.
58 plot.append(kBars[0]);
59 continue;
60 }
61
mtklein5d9d10e2014-07-11 11:57:07 -070062 double s = samples[i];
mtklein5d9d10e2014-07-11 11:57:07 -070063 s -= min;
64 s /= (max - min);
65 s *= (SK_ARRAY_COUNT(kBars) - 1);
Mike Klein91294772014-07-16 19:59:32 -040066 const size_t bar = (size_t)(s + 0.5);
djsollenf2b340f2016-01-29 08:51:04 -080067 SkASSERT_RELEASE(bar < SK_ARRAY_COUNT(kBars));
mtklein5d9d10e2014-07-11 11:57:07 -070068 plot.append(kBars[bar]);
69 }
mtklein90c471e2014-06-16 14:04:32 -070070 }
71
72 double min;
73 double max;
mtklein5d9d10e2014-07-11 11:57:07 -070074 double mean; // Estimate of population mean.
75 double var; // Estimate of population variance.
mtklein40b32be2014-07-09 08:46:49 -070076 double median;
mtklein5d9d10e2014-07-11 11:57:07 -070077 SkString plot; // A single-line bar chart (_not_ histogram) of the samples.
mtklein90c471e2014-06-16 14:04:32 -070078};
79
80#endif//Stats_DEFINED