00001 #ifndef Impala_Core_Histogram_Histogram1dTem_h
00002 #define Impala_Core_Histogram_Histogram1dTem_h
00003
00004 #include <iostream>
00005 #include "Core/Vector/VectorTem.h"
00006 #include "Core/Array/Element/ArithTypes.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Histogram
00013 {
00014
00022 template <class ElemT>
00023 class Histogram1dTem : public Vector::VectorTem<ElemT>
00024 {
00025 public:
00026
00027 Histogram1dTem(ElemT low, ElemT high, int binCount, ElemT* outliers)
00028 : Vector::VectorTem<ElemT>(binCount)
00029 {
00030 mBinCount = binCount;
00031 SetRange(low, high);
00032 Vector::VectorTem<ElemT>::operator=(0);
00033 mOutliers = (outliers) ? outliers : &mLocalOutliers;
00034 }
00035
00036 Histogram1dTem(ElemT low, ElemT high, int binCount, ElemT* outliers,
00037 ElemT* data)
00038 : Vector::VectorTem<ElemT>(binCount, data, true)
00039 {
00040 mBinCount = binCount;
00041 SetRange(low, high);
00042 mOutliers = (outliers) ? outliers : &mLocalOutliers;
00043 }
00044
00045 virtual ~Histogram1dTem()
00046 {
00047 }
00048
00049 ElemT
00050 GetLow()
00051 {
00052 return mLow;
00053 }
00054
00055 ElemT
00056 GetHigh()
00057 {
00058 return mHigh;
00059 }
00060
00061 int
00062 GetBinCount()
00063 {
00064 return mBinCount;
00065 }
00066
00067 void
00068 GetBinRange(int bin, ElemT& low, ElemT& high)
00069 {
00070 low = mLow + bin*mBinWidth;
00071 high = mLow + (bin+1)*mBinWidth;
00072 }
00073
00074 void
00075 SetRange(ElemT low, ElemT high)
00076 {
00077 mLow = low;
00078 mHigh = high;
00079 mBinWidth = (high-low) / ((ElemT) mBinCount);
00080 }
00081
00082 void
00083 Clear()
00084 {
00085 Vector::VectorTem<ElemT>::operator=(0);
00086 *mOutliers = 0;
00087 }
00088
00089 void
00090 AddWeight(ElemT value, double weight = 1.)
00091 {
00092 Vector::VectorTem<ElemT>::Elem(ValueToBin(value)) += weight;
00093 }
00094
00095 void
00096 AddWeightSafe(ElemT value, double weight = 1.)
00097 {
00098 int index = ValueToBin(value);
00099 if (index<0 || index>=this->Size())
00100 {
00101 *mOutliers += weight;
00102 }
00103 else
00104 this->Elem(index) += weight;
00105 }
00106
00107 ElemT
00108 GetWeight(ElemT value)
00109 {
00110 return Vector::VectorTem<ElemT>::Elem(ValueToBin(value));
00111 }
00112
00113 ElemT
00114 TotalWeight() const
00115 {
00116 ElemT sum = 0;
00117 for(int i=0 ; i<this->Size() ; i++)
00118 sum += this->Elem(i);
00119 return sum;
00120 }
00121
00122 void
00123 Normalize()
00124 {
00125 ElemT tot = TotalWeight();
00126
00127 if(abs(tot) < 0.0000001) tot = 1;
00128 for(int i=0 ; i<this->Size() ; i++)
00129 this->Elem(i) /= tot;
00130
00131 if(*mOutliers != 0){
00132 *mOutliers = *mOutliers / tot;
00133 }
00134 }
00135
00136 void
00137 MakeCumulative()
00138 {
00139 for(int i = 1; i < this->Size(); i++)
00140 this->Elem(i) += this->Elem(i-1);
00141 }
00142
00143 int
00144 ValueToBin(ElemT value)
00145 {
00146 return (int)((value-mLow) / mBinWidth);
00147 }
00148
00149 Impala::Real64
00150 OutlierPercentage()
00151 {
00152 if (*mOutliers == 0)
00153 return 0;
00154 ElemT sum = TotalWeight() + *mOutliers;
00155 return ((Impala::Real64) *mOutliers) / ((Impala::Real64) sum) * 100;
00156 }
00157
00158 void
00159 Dump(bool doData)
00160 {
00161 std::cout << "hist range [" << mLow << "," << mHigh << "] with "
00162 << mBinCount << " bins. Values: " << std::endl;
00163 if (doData)
00164 for (int i=0 ; i<mBinCount ; i++)
00165 std::cout << "h[" << i << "] = " << this->Elem(i) << std::endl;
00166 std::cout << "Total weight: " << TotalWeight() << ", outlier %: "
00167 << OutlierPercentage() << std::endl;
00168 std::cout << std::endl;
00169 }
00170
00171 private:
00172
00173 ElemT mLow;
00174 ElemT mHigh;
00175 ElemT mBinWidth;
00176 int mBinCount;
00177 ElemT* mOutliers;
00178 ElemT mLocalOutliers;
00179
00180 };
00181
00182 }
00183 }
00184 }
00185
00186 #endif