CMSDK 2.0.1
Cross-platform C++ base library and SDK for the Psyclone AIOS platform
Loading...
Searching...
No Matches
Stats.cpp
Go to the documentation of this file.
1
7#include "MovingAverage.h"
8#include "UnitTestFramework.h"
9
10namespace cmlabs {
11
13 this->maxCount = maxCount;
14}
15
17 mutex.enter();
18 entries.clear();
19 mutex.leave();
20}
21
23 mutex.enter();
24 entries.clear();
25 mutex.leave();
26 return true;
27}
28
29bool Stats::add(double val) {
30 mutex.enter();
31 entries.push_back(val);
32 while (entries.size() > maxCount)
33 entries.pop_front();
34 mutex.leave();
35 return true;
36}
37
38double Stats::getSum() {
39 double result = 0;
40 mutex.enter();
41 std::list<double>::iterator i, e;
42 for (i=entries.begin(), e=entries.end(); i!=e; i++)
43 result += *i;
44 mutex.leave();
45 return result;
46}
47
49 double result;
50 mutex.enter();
51 result = getSum()/entries.size();
52 mutex.leave();
53 return result;
54}
55
57 double variance, average, size;
58 mutex.enter();
59 if ( (size = (double)entries.size()) <= 1) {
60 mutex.leave();
61 return 0;
62 }
63 variance = 0;
64 average = getSum()/size;
65 std::list<double>::iterator i, e;
66 for (i=entries.begin(), e=entries.end(); i!=e; i++)
67 variance += (*i-average)*(*i-average);
68 variance /= size;
69 mutex.leave();
70 return variance;
71}
72
74 double result;
75 uint32 size, half;
76 mutex.enter();
77 size = (uint32)entries.size();
78 if (!size) { mutex.leave(); return 0; }
79 else if (size == 1) { result = entries.front(); mutex.leave(); return result; }
80 else if (size == 2) { result = (entries.front() + entries.back()) / 2.0; mutex.leave(); return result; }
81
82 half = size / 2;
83 entries.sort();
84 std::list<double>::iterator i = entries.begin(), e = entries.end();
85 if (size % 2) {
86 // odd count: the middle element is at index half
87 for (uint32 n = 0; n < half; n++)
88 i++;
89 result = *i;
90 }
91 else {
92 // even count: average the two middle elements at indices half-1 and half
93 for (uint32 n = 0; n < half - 1; n++)
94 i++;
95 result = *i;
96 i++;
97 result = (result + (*i)) / 2.0;
98 }
99 mutex.leave();
100 return result;
101}
102
104 return sqrt(getVariance());
105}
106
108 uint32 result;
109 mutex.enter();
110 result = (uint32)entries.size();
111 mutex.leave();
112 return result;
113}
114
115
117 unittest::progress(10, "populate sample");
118 Stats stats;
119 stats.add(1);
120 stats.add(3);
121 stats.add(10);
122 stats.add(-5);
123 stats.add(8);
124 stats.add(100);
125 stats.add(10);
126 stats.add(1);
127
128 unittest::progress(30, "count and sum");
129 if (stats.getCount() != 8) {
130 unittest::fail("Stats test: getCount expected 8, got %u", stats.getCount());
131 return false;
132 }
133 if (stats.getSum() != 128) {
134 unittest::fail("Stats test: getSum expected 128, got %f", stats.getSum());
135 return false;
136 }
137
138 unittest::progress(50, "average");
139 if (stats.getAverage() != 16) {
140 unittest::fail("Stats test: getAverage expected 16, got %f", stats.getAverage());
141 return false;
142 }
143
144 unittest::progress(65, "median");
145 // Sorted sample: {-5, 1, 1, 3, 8, 10, 10, 100}; even count -> mean of the two
146 // middle elements (3 and 8) -> 5.5
147 if (stats.getMedian() != 5.5) {
148 unittest::fail("Stats test: getMedian expected 5.5, got %f", stats.getMedian());
149 return false;
150 }
151
152 unittest::progress(80, "variance");
153 // Population variance (sum of squared deviations / n) = 8252 / 8 = 1031.5
154 if (stats.getVariance() != 1031.5) {
155 unittest::fail("Stats test: getVariance expected 1031.5, got %f", stats.getVariance());
156 return false;
157 }
158
159 unittest::progress(90, "standard deviation");
160 if (abs(stats.getStdDev() - 32.11697) > 0.0001) {
161 unittest::fail("Stats test: getStdDev expected ~32.11697, got %f", stats.getStdDev());
162 return false;
163 }
164
165 unittest::progress(100, "done");
166 return true;
167}
168
171 "Statistics: count, sum, average, median, variance, standard deviation", "core");
172}
173
174
175} // namespace cmlabs
Time-binned moving average / throughput tracker.
Small, dependency-free unit test harness used by all CMSDK object tests.
double getMedian()
Definition Stats.cpp:73
double getStdDev()
Definition Stats.cpp:103
Stats(uint32 maxCount=10000)
Create a collector.
Definition Stats.cpp:12
uint32 getCount()
Definition Stats.cpp:107
std::list< double > entries
Definition Stats.h:67
double getSum()
Definition Stats.cpp:38
double getAverage()
Definition Stats.cpp:48
bool clear()
Remove all samples.
Definition Stats.cpp:22
double getVariance()
Definition Stats.cpp:56
bool add(double val)
Add a sample, evicting the oldest when the window is full.
Definition Stats.cpp:29
uint32 maxCount
Definition Stats.h:65
static bool UnitTest()
Self test.
Definition Stats.cpp:116
utils::Mutex mutex
Definition Stats.h:66
static UnitTestRunner & instance()
Access the singleton (created on first use).
void registerTest(const char *name, UnitTestFunc func, const char *description="", const char *category="", bool inDefaultRun=true)
Register a test with the runner.
void fail(const char *fmt,...)
Set an explanatory reason shown on the FAIL line.
void progress(int percent, const char *action)
Report progress with a short description of the current action.
void Register_Stats_Tests()
Definition Stats.cpp:169