00001 /// \file CATStats.h 00002 /// \brief Basic statistics class 00003 /// \ingroup CAT 00004 /// 00005 /// Copyright (c) 2002-2008 by Michael Ellison. 00006 /// See COPYING.txt for the \ref gaslicense License (MIT License). 00007 /// 00008 // $Author: mikeellison $ 00009 // $Date: 2008-01-19 19:19:35 -0600 (Sat, 19 Jan 2008) $ 00010 // $Revision: $ 00011 // $NoKeywords: $ 00012 00013 #include "CATStats.h" 00014 #include <algorithm> 00015 #include <math.h> 00016 #include <float.h> 00017 00018 CATStats::CATStats() 00019 { 00020 fNumEntries = 0; 00021 fSum = 0; 00022 fSumSquares = 0; 00023 fMin = 0; 00024 fMax = 0; 00025 } 00026 00027 CATStats::~CATStats() 00028 { 00029 this->Clear(); 00030 } 00031 00032 void CATStats::Clear() 00033 { 00034 fEntryList.clear(); 00035 fNumEntries = 0; 00036 fSum = 0; 00037 fSumSquares = 0; 00038 fMin = 0; 00039 fMax = 0; 00040 } 00041 00042 bool CATStats::AddValue(CATFloat64 value) 00043 { 00044 // Add it to our data list 00045 fEntryList.push_back(value); 00046 00047 // It's added, so now add to our running calculations 00048 fSum += value; 00049 fSumSquares += value*value; 00050 00051 // Set min/max values if value goes out of current bounds or is first value 00052 (fNumEntries == 0)?fMin = value:fMin = min(fMin,value); 00053 (fNumEntries == 0)?fMax = value:fMax = max(fMax,value); 00054 00055 fNumEntries += 1; 00056 return true; 00057 } 00058 00059 00060 CATFloat64 CATStats::Mean() 00061 { 00062 return fSum / (CATFloat64)fNumEntries; 00063 } 00064 00065 CATFloat64 CATStats::Median() 00066 { 00067 std::sort(fEntryList.begin(), fEntryList.end(), FloatSortCallback); 00068 CATFloat64 median = fEntryList[fEntryList.size()/2]; 00069 return median; 00070 } 00071 00072 CATFloat64 CATStats::Min() 00073 { 00074 return fMin; 00075 } 00076 00077 CATFloat64 CATStats::Max() 00078 { 00079 return fMax; 00080 } 00081 00082 CATFloat64 CATStats::Variance() 00083 { 00084 if (fNumEntries == 0) 00085 { 00086 return 0; 00087 } 00088 00089 CATFloat64 meanSquared = this->Mean(); 00090 meanSquared *= meanSquared; 00091 00092 CATFloat64 variance = (fSumSquares/(CATFloat64)fNumEntries) - meanSquared; 00093 return variance; 00094 } 00095 00096 CATFloat64 CATStats::Variance(CATFloat64 sample) 00097 { 00098 if (fNumEntries == 0) 00099 { 00100 return 0; 00101 } 00102 CATFloat64 mean = this->Mean(); 00103 return ((sample - mean)*(sample - mean) / (CATFloat64)fNumEntries); 00104 } 00105 00106 CATFloat64 CATStats::StdDev(CATFloat64 sample) 00107 { 00108 if (fNumEntries == 0) 00109 { 00110 return 0; 00111 } 00112 00113 return sqrt(Variance(sample)); 00114 } 00115 00116 CATFloat64 CATStats::AvgDev() 00117 { 00118 if (fNumEntries == 0) 00119 { 00120 return 0; 00121 } 00122 00123 // Avg deviation requires recalc with current mean afaik 00124 CATFloat64 avgDev = 0; 00125 CATFloat64 mean = this->Mean(); 00126 00127 for (CATUInt32 i = 0; i < fNumEntries; i++) 00128 { 00129 CATFloat64 curVal = fEntryList[i]; 00130 avgDev += fabs((curVal) - mean); 00131 } 00132 avgDev /= (CATFloat64)fNumEntries; 00133 return avgDev; 00134 } 00135 00136 CATFloat64 CATStats::StdDev() 00137 { 00138 if (fNumEntries == 0) 00139 { 00140 return 0; 00141 } 00142 00143 return sqrt(Variance()); 00144 } 00145 00146 bool CATStats::FloatSortCallback(const CATFloat64 p1, const CATFloat64 p2) 00147 { 00148 return p1 < p2; 00149 } 00150 00151 CATFloat64 CATStats::GetValue(CATUInt32 index) 00152 { 00153 if (index < fNumEntries) 00154 { 00155 return fEntryList[index]; 00156 } 00157 00158 return 0.0; 00159 } 00160 00161 CATFloat64 CATStats::Mode(CATUInt32 steps) 00162 { 00163 CATFloat64 mode = fMax; 00164 CATFloat64 stepSize = (fMax - fMin); 00165 if ((stepSize > DBL_EPSILON*steps) || (stepSize < -DBL_EPSILON*steps)) 00166 { 00167 CATUInt32 *histogram = new CATUInt32[steps]; 00168 memset(histogram,0,sizeof(CATUInt32)*steps); 00169 00170 CATUInt32 maxIndex = (CATUInt32)-1; 00171 CATUInt32 maxVal = 0; 00172 00173 for (CATUInt32 i=0; i < fNumEntries; i++) 00174 { 00175 CATUInt32 stepPos = (CATUInt32)((fEntryList[i] - fMin) / stepSize); 00176 histogram[stepPos]++; 00177 if (histogram[stepPos] >= maxVal) 00178 { 00179 maxIndex = stepPos; 00180 maxVal = histogram[stepPos]; 00181 mode = (stepPos * stepSize) + fMin; 00182 } 00183 } 00184 00185 delete [] histogram; 00186 00187 return mode; 00188 } 00189 else 00190 { 00191 return mode; 00192 } 00193 }