1 
2 /* Web Polygraph       http://www.web-polygraph.org/
3  * Copyright 2003-2011 The Measurement Factory
4  * Licensed under the Apache License, Version 2.0 */
5 
6 #include "base/polygraph.h"
7 
8 #include "xstd/h/math.h"
9 
10 #include "base/ILog.h"
11 #include "base/OLog.h"
12 #include "base/AggrStat.h"
13 #include "xstd/gadgets.h"
14 
15 
AggrStat()16 AggrStat::AggrStat() {
17 	reset();
18 }
19 
reset()20 void AggrStat::reset() {
21 	theCount = 0;
22 	theSum = theSqSum = 0;
23 	theMax = theMin = -1;
24 }
25 
record(Val v)26 void AggrStat::record(Val v) {
27 
28 	if (theCount++) {
29 		theSum += v;
30 		theSqSum += v*(double)v;
31 
32 		if (theMax < v)
33 			theMax = v;
34 		else
35 		if (theMin > v)
36 			theMin = v;
37 	} else {
38 		theSum = theMin = theMax = v;
39 		theSqSum = v*(double)v;
40 	}
41 }
42 
operator +=(const AggrStat & s)43 AggrStat &AggrStat::operator +=(const AggrStat &s) {
44 	if (s.theCount) {
45 		if (theCount) {
46 			theCount += s.theCount;
47 			theSum += s.theSum;
48 			theSqSum += s.theSqSum;
49 			theMax = Max(theMax, s.theMax);
50 			theMin = Min(theMin, s.theMin);
51 		} else {
52 			theCount = s.theCount;
53 			theSum = s.theSum;
54 			theSqSum = s.theSqSum;
55 			theMax = s.theMax;
56 			theMin = s.theMin;
57 		}
58 	}
59 	return *this;
60 }
61 
stdDev() const62 double AggrStat::stdDev() const {
63 	if (theCount < 2)
64 		return -1;
65 
66 	const double diff = theSqSum - theSum*theSum/theCount;
67 	if (diff < 0)
68 		return 0; // should not happen
69 
70 	return sqrt(diff / (theCount-1));
71 }
72 
relDevp() const73 double AggrStat::relDevp() const {
74 	return theCount > 1 ? 100*Ratio(stdDev(), mean()) : -1.0;
75 }
76 
store(OLog & log) const77 void AggrStat::store(OLog &log) const {
78 	log << theCount;
79 	if (theCount)
80 		log << theMin << theMax << theSum << theSqSum;
81 }
82 
load(ILog & log)83 void AggrStat::load(ILog &log) {
84 	log >> theCount;
85 	if (theCount)
86 		log >> theMin >> theMax >> theSum >> theSqSum;
87 }
88 
sane() const89 bool AggrStat::sane() const {
90 	return !theCount ||
91 		(theCount > 0 && theMin <= theMax && theSqSum >= 0);
92 }
93 
print(ostream & os,const String & pfx) const94 ostream &AggrStat::print(ostream &os, const String &pfx) const {
95 	return os
96 		<< pfx << "count:  \t " << theCount << endl
97 		<< pfx << "mean:   \t " << mean() << endl
98 		<< pfx << "min:    \t " << theMin << endl
99 		<< pfx << "max:    \t " << theMax << endl
100 		<< pfx << "std_dev:\t " << stdDev() << endl
101 		<< pfx << "rel_dev:\t " << relDevp() << endl
102 		<< pfx << "sum:    \t " << theSum << endl
103 		;
104 }
105