00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <math.h>
00034 #include "StatisticalFilter.h"
00035 #include "massert.h"
00036
00037 using std::set;
00038 using std::less;
00039
00040 StatisticalFilter::StatisticalFilter(int history) : total(0), total_square(0),
00041 standard_deviation(0),
00042 measurements(0),
00043 keep_history(history) {
00044 }
00045
00046 StatisticalFilter::~StatisticalFilter() {
00047 }
00048
00049 void StatisticalFilter::update(double incoming) {
00050 total += incoming;
00051 total_square += incoming * incoming;
00052 measurements++;
00053 standard_deviation = sqrt((total_square * measurements - (total * total)) /
00054 (measurements * (measurements - 1)));
00055 value = total / measurements;
00056
00057 if (keep_history) {
00058 contents.insert(incoming);
00059 }
00060 }
00061
00062 double StatisticalFilter::getDeviation() const {
00063 return standard_deviation;
00064 }
00065
00066 double StatisticalFilter::percentileToValue(double percentile) const {
00067
00068 if (percentile < 0 || percentile > 1.0 || !keep_history ||
00069 contents.size() == 0) {
00070 return -1;
00071 }
00072
00073 int which = (int)((double)(contents.size() - 1) * percentile);
00074 std::multiset<double, less<double> >::const_iterator element;
00075 int counter = 0;
00076
00077 for(element = contents.begin(); element != contents.end(); element++) {
00078 if (counter == which) {
00079 return *element;
00080 }
00081 counter++;
00082 }
00083
00084 return *contents.rbegin();
00085 }
00086
00087 double StatisticalFilter::valueToPercentile(double value) const {
00088
00089 if (!keep_history || contents.size() == 0) {
00090 return -1;
00091 }
00092
00093 std::multiset<double, less<double> >::const_iterator element;
00094 int counter = 0;
00095
00096 if (value >= *contents.rbegin()) {
00097
00098 return 1;
00099 }
00100
00101 for(element = contents.begin(); element != contents.end(); element++) {
00102 if (*element > value) {
00103 return (double)counter / contents.size();
00104 }
00105 counter++;
00106 }
00107
00108 ASSERT(0);
00109 }
00110
00111 double StatisticalFilter::getMin() const {
00112 if (!keep_history || contents.size() == 0) {
00113 return -1;
00114 }
00115 return *contents.begin();
00116 }
00117
00118 double StatisticalFilter::getMax() const {
00119 if (!keep_history || contents.size() == 0) {
00120 return -1;
00121 }
00122 return *contents.rbegin();
00123 }
00124
00125 int StatisticalFilter::getCount() const {
00126 return measurements;
00127 }
00128
00129 int StatisticalFilter::reset(){
00130 measurements = 0;
00131 value = 0;
00132 total = 0;
00133 total_square = 0;
00134 standard_deviation = 0;
00135 contents.clear();
00136 return 0;
00137 }