1#ifndef Stats_DEFINED
2#define Stats_DEFINED
3
4#include "SkString.h"
5#include "SkTSort.h"
6
7#ifdef SK_BUILD_FOR_WIN
8    static const char* kBars[] = { ".", "o", "O" };
9#else
10    static const char* kBars[] = { "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█" };
11#endif
12
13struct Stats {
14    Stats(const double samples[], int n) {
15        min = samples[0];
16        max = samples[0];
17        for (int i = 0; i < n; i++) {
18            if (samples[i] < min) { min = samples[i]; }
19            if (samples[i] > max) { max = samples[i]; }
20        }
21
22        double sum = 0.0;
23        for (int i = 0 ; i < n; i++) {
24            sum += samples[i];
25        }
26        mean = sum / n;
27
28        double err = 0.0;
29        for (int i = 0 ; i < n; i++) {
30            err += (samples[i] - mean) * (samples[i] - mean);
31        }
32        var = err / (n-1);
33
34        SkAutoTMalloc<double> sorted(n);
35        memcpy(sorted.get(), samples, n * sizeof(double));
36        SkTQSort(sorted.get(), sorted.get() + n - 1);
37        median = sorted[n/2];
38
39        // Normalize samples to [min, max] in as many quanta as we have distinct bars to print.
40        for (int i = 0; i < n; i++) {
41            if (min == max) {
42                // All samples are the same value.  Don't divide by zero.
43                plot.append(kBars[0]);
44                continue;
45            }
46
47            double s = samples[i];
48            s -= min;
49            s /= (max - min);
50            s *= (SK_ARRAY_COUNT(kBars) - 1);
51            const size_t bar = (size_t)(s + 0.5);
52            SK_ALWAYSBREAK(bar < SK_ARRAY_COUNT(kBars));
53            plot.append(kBars[bar]);
54        }
55    }
56
57    double min;
58    double max;
59    double mean;    // Estimate of population mean.
60    double var;     // Estimate of population variance.
61    double median;
62    SkString plot;  // A single-line bar chart (_not_ histogram) of the samples.
63};
64
65#endif//Stats_DEFINED
66