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