00001 #ifndef Impala_Core_Array_Statistics_h
00002 #define Impala_Core_Array_Statistics_h
00003
00004 #include <list>
00005 #include <vector>
00006 #include "Core/Array/Arrays.h"
00007 #include "Core/Array/Set.h"
00008 #include "Core/Array/SetVal.h"
00009 #include "Core/Array/Add.h"
00010 #include "Core/Array/Mul.h"
00011 #include "Core/Array/Abs.h"
00012 #include "Core/Array/Minimum.h"
00013 #include "Core/Array/Maximum.h"
00014 #include "Core/Array/Sub.h"
00015 #include "Core/Array/DivVal.h"
00016 #include "Core/Array/Sqrt.h"
00017 #include "Core/Array/PixStat.h"
00018
00019 namespace Impala
00020 {
00021 namespace Core
00022 {
00023 namespace Array
00024 {
00025
00026
00027 template<class ArrayT>
00028 class Statistics
00029 {
00030 public:
00031
00032 Statistics(int maxNrSamples = 50, bool running = false)
00033 {
00034 mMaxNrSamples = maxNrSamples;
00035 mRunning = running;
00036
00037 mDoneInit = false;
00038 mNum = 0;
00039 mMinVal = 0;
00040 mMaxVal = 0;
00041 mSum = 0;
00042 mSumSqr = 0;
00043 mSumAbs = 0;
00044 mTmp = 0;
00045
00046 mStatValid = false;
00047 mMean = 0;
00048 mVariance = 0;
00049
00050 mStDevValid = false;
00051 mStDev = 0;
00052 }
00053
00054 ~Statistics()
00055 {
00056 if (mMinVal)
00057 {
00058 delete mMinVal;
00059 delete mMaxVal;
00060 delete mSum;
00061 delete mSumSqr;
00062 delete mSumAbs;
00063 delete mTmp;
00064 }
00065 if (mMean)
00066 {
00067 delete mMean;
00068 delete mVariance;
00069 }
00070 if (mStDev)
00071 delete mStDev;
00072 for (int i=0 ; i<mRunList.size() ; i++)
00073 delete mRunList[i];
00074 }
00075
00076 bool
00077 IsDoingStat()
00078 {
00079 return mNum < mMaxNrSamples;
00080 }
00081
00082 void
00083 DoArray(ArrayT* a)
00084 {
00085 if (mRunning)
00086 {
00087 ArrayT* newA = 0;
00088 Set(newA, a);
00089 if (mNum >= mMaxNrSamples)
00090 {
00091 delete mRunList[0];
00092 mRunList.erase(mRunList.begin());
00093 }
00094 else
00095 {
00096 mNum++;
00097 }
00098 mRunList.push_back(newA);
00099 mStatValid = false;
00100 mStDevValid = false;
00101 }
00102 else
00103 {
00104 if (mNum >= mMaxNrSamples)
00105 return;
00106 mStatValid = false;
00107 mStDevValid = false;
00108 if (!mDoneInit)
00109 {
00110 InitNotRunning(a);
00111 return;
00112 }
00113 mNum++;
00114 Minimum(mMinVal, mMinVal, a);
00115 Maximum(mMaxVal, mMaxVal, a);
00116 Add(mSum, mSum, a);
00117 Mul(mTmp, a, a);
00118 Add(mSumSqr, mSumSqr, mTmp);
00119 Abs(mTmp, a);
00120 Add(mSumAbs, mSumAbs, mTmp);
00121 }
00122 }
00123
00124 ArrayT*
00125 GetMinimum()
00126 {
00127 if (mRunning)
00128 {
00129 Set(mMinVal, mRunList[0]);
00130 for (int i=1 ; i<mRunList.size() ; i++)
00131 Minimum(mMinVal, mMinVal, mRunList[i]);
00132 }
00133 return mMinVal;
00134 }
00135
00136 ArrayT*
00137 GetMaximum()
00138 {
00139 if (mRunning)
00140 {
00141 Set(mMaxVal, mRunList[0]);
00142 for (int i=1 ; i<mRunList.size() ; i++)
00143 Maximum(mMaxVal, mMaxVal, mRunList[i]);
00144 }
00145 return mMaxVal;
00146 }
00147
00148 ArrayT*
00149 GetMean()
00150 {
00151 CheckStatValid();
00152 return mMean;
00153 }
00154
00155 ArrayT*
00156 GetVariance()
00157 {
00158 CheckStatValid();
00159 return mVariance;
00160 }
00161
00162 ArrayT*
00163 GetStDev()
00164 {
00165 CheckStDevValid();
00166 return mStDev;
00167 }
00168
00169 void
00170 Reset()
00171 {
00172 mDoneInit = false;
00173 mStatValid = false;
00174 mStDevValid = false;
00175 mNum = 0;
00176 for (int i=0 ; i<mRunList.size() ; i++)
00177 delete mRunList[i];
00178 mRunList.clear();
00179 }
00180
00181 private:
00182
00183 void
00184 InitNotRunning(ArrayT* a)
00185 {
00186 mNum = 1;
00187 Set(mMinVal, a);
00188 Set(mMaxVal, a);
00189 Set(mSum, a);
00190 Mul(mSumSqr, a, a);
00191 Abs(mSumAbs, a);
00192 Set(mTmp, a);
00193 mDoneInit = true;
00194 }
00195
00196 void
00197 CheckStatValid()
00198 {
00199 if (mStatValid)
00200 return;
00201
00202 typedef typename ArrayT::ArithType ArithT;
00203 ArithT num = Element::E1Cast(mNum, ArithT());
00204 ArithT num1 = num - Element::E1Cast(1, ArithT());
00205 if (mRunning)
00206 {
00207 Set(mSum, mRunList[0]);
00208 Mul(mSumSqr, mSum, mSum);
00209 Abs(mSumAbs, mSum);
00210 if (mTmp == 0)
00211 Set(mTmp, mSum);
00212 for (int i=1 ; i<mRunList.size() ; i++)
00213 {
00214 Add(mSum, mSum, mRunList[i]);
00215 Mul(mTmp, mRunList[i], mRunList[i]);
00216 Add(mSumSqr, mSumSqr, mTmp);
00217 Abs(mTmp, mRunList[i]);
00218 Add(mSumAbs, mSumAbs, mTmp);
00219 }
00220 }
00221 DivVal(mMean, mSum, num);
00222 if (mNum == 1)
00223 SetVal(mVariance, mTmp, Element::E1Cast(0, ArithT()));
00224 else
00225 {
00226 Mul(mTmp, mSum, mSum);
00227 DivVal(mTmp, mTmp, num);
00228 Sub(mTmp, mSumSqr, mTmp);
00229 DivVal(mVariance, mTmp, num1);
00230 }
00231 mStatValid = true;
00232 }
00233
00234 void
00235 CheckStDevValid()
00236 {
00237 if (mStDevValid)
00238 return;
00239
00240 CheckStatValid();
00241 Sqrt(mStDev, mVariance);
00242 mStDevValid = true;
00243
00244
00245
00246
00247 }
00248
00249 int mMaxNrSamples;
00250 bool mRunning;
00251
00252 bool mDoneInit;
00253 int mNum;
00254 ArrayT* mMinVal;
00255 ArrayT* mMaxVal;
00256 ArrayT* mSum;
00257 ArrayT* mSumSqr;
00258 ArrayT* mSumAbs;
00259 ArrayT* mTmp;
00260
00261 bool mStatValid;
00262 ArrayT* mMean;
00263 ArrayT* mVariance;
00264
00265 bool mStDevValid;
00266 ArrayT* mStDev;
00267
00268 std::vector<ArrayT*> mRunList;
00269
00270 };
00271
00272 }
00273 }
00274 }
00275
00276 #endif