00001 #ifndef HISTOGRAM_H 00002 #define HISTOGRAM_H 00003 00004 #include <vector> 00005 00006 using namespace std; 00007 00017 class Hash { 00018 public: 00019 double mVal; 00020 int mCnt; 00021 00022 public: 00023 00027 Hash( double val ) { 00028 mVal = val; 00029 mCnt = 1; 00030 } 00031 00032 00036 void incCnt( ) { 00037 mCnt++; 00038 } 00039 00040 00044 double getVal( ) { 00045 return mVal; 00046 } 00047 00048 00052 int getCnt( ) { 00053 return mCnt; 00054 } 00055 }; 00056 00068 class Histogram { 00069 private: 00070 int mLen; // LENGTH OF THE DATASET 00071 int mMaxCnt; // MAX COUNT OF ALL VALUES 00072 double mMin; // MIN DATA VALUE 00073 double mMax; // MAX DATA VALUE 00074 00075 vector<Hash> mHist; // THE HISTOGRAM 00076 00082 void insert( double val ) { 00083 Hash hash( val ); 00084 mHist.insert( (vector<Hash>::iterator)findGt( val ), hash ); 00085 } 00086 00090 Hash* find( double val ) { 00091 int l; // LEFT POS IN ARRAY 00092 int r; // RIGHT POS IN ARRAY 00093 int m; // MID POS BETWEEN LEFT & RIGHT 00094 00095 // ---------------------------------------------------------------- 00096 // INITIALIZE POSITIONS 00097 l = 0; 00098 r = mHist.size() -1; 00099 00100 // NOTHING TO SEARCH? 00101 if ( r == -1 ) 00102 return NULL; 00103 00104 m = r / 2; 00105 // ---------------------------------------------------------------- 00106 00107 // ---------------------------------------------------------------- 00108 // FIND THE POSITION OF THE Hash WITH val 00109 while ( l < r-1 ) { 00110 if ( val > mHist[m].mVal ) 00111 l = m; 00112 else if ( val < mHist[m].mVal ) 00113 r = m; 00114 else 00115 return &mHist[m]; 00116 00117 m = ((r - l) / 2) + l; 00118 } 00119 00120 if ( val == mHist[l].mVal ) 00121 return &mHist[l]; 00122 00123 if ( val == mHist[r].mVal ) 00124 return &mHist[r]; 00125 // ---------------------------------------------------------------- 00126 00127 // THERE'S NO Hash WITH val 00128 return NULL; 00129 } 00130 00135 Hash* findGt( double val ) { 00136 int l; // LEFT POS IN ARRAY 00137 int r; // RIGHT POS IN ARRAY 00138 int m; // MID POS BETWEEN LEFT & RIGHT 00139 00140 // ---------------------------------------------------------------- 00141 // INITIALIZE POSITIONS 00142 l = 0; 00143 r = mHist.size() -1; 00144 00145 // NOTHING TO SEARCH? 00146 if ( r == -1 ) 00147 return NULL; 00148 00149 m = r / 2; 00150 // ---------------------------------------------------------------- 00151 00152 // ---------------------------------------------------------------- 00153 // FIND THE POSITION OF THE Hash WITH val 00154 while ( l < r-1 ) { 00155 if ( val > mHist[m].getVal() ) 00156 l = m; 00157 else 00158 r = m; 00159 00160 m = ((r - l) / 2) + l; 00161 } 00162 00163 if ( val <= mHist[l].getVal() ) 00164 return &mHist[l]; 00165 00166 if ( val <= mHist[r].getVal() ) 00167 return &mHist[r]; 00168 // ---------------------------------------------------------------- 00169 00170 // *************************************************** 00171 // This seems wrong. If r==0 and it gets here it should 00172 // crash. FIX! 00173 // *************************************************** 00174 return &mHist[r+1]; 00175 } 00176 00177 public: 00178 00179 Histogram( ) { 00180 mLen = 0; 00181 mMaxCnt = 0; 00182 mMin = 0; 00183 mMax = 255; 00184 } 00193 template<class DType> 00194 void calcHist( DType *data, int len ) { 00195 Hash *hash = NULL; // THE RESULTING HISTOGRAM 00196 int iVal = 0; // ARRAY INDEX 00197 00198 mLen = len; 00199 00200 // ---------------------------------------------------------------- 00201 // LOOP THROUGH DATASET & CALC HISTOGRAM 00202 for ( ; iVal < mLen; iVal++ ) { 00203 hash = find( (double)data[iVal] ); 00204 00205 if ( hash ) 00206 hash->incCnt(); 00207 else 00208 insert( (double)data[iVal] ); 00209 } 00210 // ---------------------------------------------------------------- 00211 00212 // ---------------------------------------------------------------- 00213 // DETERMINE THE HASH WITH THE GREATEST COUNT 00214 mMaxCnt = -1; 00215 for ( unsigned int i=0; i < mHist.size(); i++ ) 00216 if ( mHist[i].mCnt > mMaxCnt ) 00217 mMaxCnt = mHist[i].mCnt; 00218 // ---------------------------------------------------------------- 00219 00220 // SINCE THIS IS AN ORDERED SET, THE MIN & MAX ARE ON THE ENDS 00221 mMin = mHist[0].mVal; 00222 mMax = mHist[mHist.size()-1].mVal; 00223 00224 } 00225 00229 vector<Hash> getHist( ) { 00230 return mHist; 00231 } 00232 00233 00237 double getMin( ) { 00238 return mMin; 00239 } 00240 00241 00245 double getMax( ) { 00246 return mMax; 00247 } 00248 00249 00255 int getLen( ) { 00256 return mLen; 00257 } 00258 00259 00263 int getMaxCnt( ) { 00264 return mMaxCnt; 00265 } 00266 }; 00267 #endif 00268 00269 00270
Home |
Search |
Disclaimers & Privacy |
Contact Us GLIMSView Maintainer: dsoltesz@usgs.gov |