00001
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cstdio>
00023 #include <cmath>
00024 #include <iostream>
00025 #include <fstream>
00026
00027 using namespace std;
00028
00029 #include "Histogram.h"
00030
00031 Histogram::Histogram(float minimum_data_value,
00032 float maximum_data_value,
00033 unsigned int bands_per_dimension,
00034 unsigned int dimensionality)
00043 : min_val (minimum_data_value),
00044 max_val (maximum_data_value),
00045 bands_per_dim (bands_per_dimension),
00046 dim (dimensionality),
00047 max_prob (0),
00048 max_freq (0)
00049 {
00050 band_size = (maximum_data_value - minimum_data_value) / bands_per_dim;
00051
00052 no_bins = (unsigned int)pow((double)bands_per_dimension, (double)dim);
00053
00054 frequency_data = new unsigned int[no_bins];
00055 probs = new float[no_bins];
00056
00057 reset_histogram() ;
00058 }
00059
00060
00061 Histogram::Histogram(char const* histfile)
00062 : frequency_data(0), probs(0)
00067 {
00068 load_histogram(histfile);
00069 }
00070
00071
00072 void Histogram::reset_histogram()
00078 {
00079 unsigned int cnt;
00080
00081 no_data_items = 0;
00082 for (cnt = 0; cnt < no_bins; cnt++) {
00083 frequency_data[cnt] = 0;
00084 }
00085 max_prob = 0;
00086 max_freq = 0;
00087 }
00088
00089
00090 void Histogram::add_new_data_item(int *data)
00096 {
00097 unsigned int increment;
00098 unsigned int d_cnt;
00099 unsigned int b_cnt;
00100 register float band_min;
00101 register float band_max;
00102 unsigned int bin_no = 0;
00103 register float d_val;
00104
00105 increment = 1;
00106
00107 for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00108
00109 band_min = min_val;
00110 band_max = min_val + band_size;
00111 d_val = (float)(data[d_cnt]);
00112
00113 for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++) {
00114
00115 if (d_val >= band_min && d_val <= band_max) break;
00116
00117 band_min += band_size;
00118 band_max += band_size;
00119 }
00120
00121 bin_no += b_cnt * increment;
00122
00123
00124 increment *= bands_per_dim;
00125 }
00126
00127
00128 frequency_data[bin_no]++;
00129 no_data_items++;
00130
00131 if (frequency_data[bin_no] > max_freq) max_freq = frequency_data[bin_no];
00132 }
00133
00134
00135
00136
00137 void Histogram::add_new_data_item(float *data)
00143 {
00144 unsigned int increment;
00145 unsigned int d_cnt;
00146 unsigned int b_cnt;
00147 float band_min;
00148 float band_max;
00149 unsigned int bin_no = 0;
00150
00151 increment = 1;
00152
00153 for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00154
00155 band_min = min_val;
00156 band_max = min_val + band_size;
00157 for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++){
00158
00159 if (data[d_cnt] >= band_min && data[d_cnt] <= band_max) break;
00160
00161 band_min += band_size;
00162 band_max += band_size;
00163 }
00164
00165 bin_no += b_cnt * increment;
00166
00167
00168 increment *= bands_per_dim;
00169 }
00170
00171
00172 frequency_data[bin_no]++;
00173 no_data_items++;
00174
00175 if (frequency_data[bin_no] > max_freq) max_freq = frequency_data[bin_no];
00176 }
00177
00178 void Histogram::calculate_probabilities()
00182 {
00183 unsigned int *f_ptr = frequency_data;
00184 float *p_ptr = probs;
00185 unsigned int cnt ;
00186
00187 if(no_data_items > 0){
00188 max_prob = 0 ;
00189 for (cnt = 0; cnt < no_bins; cnt++, f_ptr++, p_ptr++){
00190
00191 *p_ptr = (float)(*f_ptr) / (float)no_data_items;
00192 if (*p_ptr > max_prob) max_prob = *p_ptr;
00193 }
00194 }
00195 else{
00196 for (cnt = 0; cnt < no_bins; cnt++){
00197
00198 *p_ptr = 0;
00199 }
00200 max_prob = 0;
00201 }
00202
00203 }
00204
00205 float Histogram::calculate_proportion_threshold(float proportion)
00213 {
00214 float *p_ptr ;
00215 unsigned int cnt ;
00216 float min_p = 0 ;
00217 float new_min_p ;
00218 float p_above_thresh = 1.0 ;
00219 unsigned int no_with_p ;
00220
00221 while(p_above_thresh > proportion){
00222 new_min_p = 1.0 ;
00223 no_with_p = 0 ;
00224 for (cnt = 0, p_ptr = probs ; cnt < no_bins; cnt++, p_ptr++){
00225
00226 if(*p_ptr > min_p &&
00227 *p_ptr < new_min_p){
00228
00229 new_min_p = *p_ptr ;
00230 no_with_p = 1 ;
00231 }
00232 else if(*p_ptr > min_p &&
00233 *p_ptr == new_min_p){
00234
00235 no_with_p++ ;
00236 }
00237 }
00238 p_above_thresh -= new_min_p * no_with_p ;
00239 if(p_above_thresh == 1.0){
00240
00241 break ;
00242 }
00243 min_p = new_min_p ;
00244 }
00245
00246 return min_p ;
00247 }
00248
00249 void Histogram::calculate_histogram()
00255 {
00256 unsigned int *f_ptr = frequency_data;
00257 float *p_ptr = probs;
00258
00259 max_prob = 0 ;
00260 for (unsigned int cnt = 0; cnt < no_bins; cnt++, f_ptr++, p_ptr++){
00261
00262 *p_ptr = (float)(*f_ptr) / (float)max_freq;
00263 if (*p_ptr > max_prob) max_prob = *p_ptr;
00264 }
00265 }
00266
00267
00268 float Histogram::get_histogram_value(unsigned int *bin)
00276 {
00277 unsigned int bin_no = 0;
00278 unsigned int increment;
00279
00280 increment = 1;
00281
00282 for (unsigned int d_cnt = 0; d_cnt < dim; d_cnt++) {
00283
00284
00285 bin_no += bin[d_cnt] * increment;
00286 increment *= bands_per_dim;
00287 }
00288
00289 return probs[bin_no];
00290 }
00291
00292
00293 float Histogram::get_mapped_value(unsigned int *data)
00297 {
00298 #if 0
00299 for (unsigned int d_cnt = 0; d_cnt < dim; d_cnt++)
00300 data[d_cnt] /= (int) band_size;
00301
00302 return get_histogram_value(data);
00303 #else
00304 unsigned int increment;
00305 unsigned int d_cnt;
00306 unsigned int b_cnt;
00307 register float band_min;
00308 register float band_max;
00309 unsigned int bin_no = 0;
00310 register float d_val;
00311
00312 increment = 1;
00313
00314 for (d_cnt = 0; d_cnt < dim; d_cnt++) {
00315
00316 band_min = min_val;
00317 band_max = min_val + band_size;
00318 d_val = (float)(data[d_cnt]);
00319
00320 for (b_cnt = 0; b_cnt < bands_per_dim; b_cnt++) {
00321
00322 if (d_val >= band_min && d_val <= band_max) break;
00323
00324 band_min += band_size;
00325 band_max += band_size;
00326 }
00327
00328 bin_no += b_cnt * increment;
00329
00330
00331 increment *= bands_per_dim;
00332 }
00333
00334 return probs[bin_no];
00335 #endif
00336 }
00337
00338
00339 float Histogram::calculate_difference(Histogram *hist)
00346 {
00347 unsigned int b_cnt;
00348 float diff;
00349 float ret_val = 0;
00350 float *t_ptr;
00351 float *h_ptr;
00352
00353 t_ptr = probs;
00354 h_ptr = hist->probs;
00355 for (b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00356 diff = *t_ptr - *h_ptr;
00357 if (diff < 0) diff = -diff;
00358 ret_val += diff;
00359
00360 t_ptr++;
00361 h_ptr++;
00362 }
00363
00364 return ret_val;
00365 }
00366
00367
00368 void Histogram::save_histogram(char const* histfile)
00372 {
00373 FILE* fd = fopen(histfile, "w");
00374
00375 fprintf(fd, "<?xml version=\"1.0\" ?>\n\n");
00376
00377 fprintf(fd, "<histogram min-value=\"%f\" max-value=\"%f\" "
00378 "bands=\"%u\" dimensionality=\"%u\">\n",
00379 min_val, max_val, bands_per_dim, dim);
00380
00381 for (unsigned int b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00382 float p = probs[b_cnt];
00383 if (p) fprintf(fd, " <prob index=\"%u\">%f</prob>\n", b_cnt, p);
00384 }
00385
00386 fprintf(fd, "</histogram>\n");
00387 fclose(fd);
00388 }
00389
00390
00391 void Histogram::load_histogram(char const* histfile)
00395 {
00396 delete [] frequency_data;
00397 delete [] probs;
00398
00399 FILE* fd = fopen(histfile, "r");
00400 if (fd == 0) throw "Could not open hst file.";
00401
00402 int n;
00403
00404
00405
00406 float xmlversion = 0;
00407
00408 n = fscanf(fd, "<?xml version=\"%f\" ?>\n\n", &xmlversion);
00409
00410 if (xmlversion == 0) throw "Incompatible hst file format";
00411
00412
00413
00414
00415 n = fscanf(fd, "<histogram min-value=\"%f\" max-value=\"%f\" "
00416 "bands=\"%u\" dimensionality=\"%u\">\n",
00417 &min_val, &max_val, &bands_per_dim, &dim);
00418
00419 if (n != 4) throw "error in hst file, unable to import data.";
00420
00421 band_size = (max_val - min_val) / bands_per_dim;
00422 no_bins = (unsigned int) pow((double)bands_per_dim, (double)dim);
00423
00424 frequency_data = new unsigned int[no_bins];
00425 probs = new float[no_bins];
00426
00427 for (unsigned int cnt = 0; cnt < no_bins; cnt++) {
00428 frequency_data[cnt] = 0;
00429 probs[cnt] = 0.0;
00430 }
00431
00432
00433
00434
00435 unsigned int bin, i = 0;
00436 float p = 0;
00437
00438 n = fscanf(fd, " <prob index=\"%u\">%f</prob>\n", &bin, &p);
00439 max_prob = p;
00440 while (n == 2) {
00441 probs[bin] = p;
00442 n = fscanf(fd, " <prob index=\"%u\">%f</prob>\n", &bin, &p);
00443 if (p > max_prob) max_prob = p;
00444 i++;
00445 };
00446
00447
00448
00449 char last[2];
00450 n = fscanf(fd, "/histogram%[>]", last);
00451 if (n != 1)
00452 throw "Reading hst file.";
00453
00454 fclose(fd);
00455 }
00456
00457 void Histogram::get_best_bin(unsigned int *bin)
00461 {
00462 unsigned int best_bin = 0 ;
00463 unsigned int b_cnt ;
00464 unsigned int increment = 1 ;
00465 int d_cnt ;
00466 float highest_p = -1 ;
00467
00468 for (b_cnt = 0; b_cnt < no_bins; b_cnt++) {
00469
00470 if(probs[b_cnt] > highest_p){
00471 highest_p = probs[b_cnt] ;
00472 best_bin = b_cnt ;
00473 }
00474 }
00475
00476 for(d_cnt = dim-1 ; d_cnt> 0 ; d_cnt--){
00477 increment *= bands_per_dim;
00478 }
00479
00480 for(d_cnt = dim-1 ; d_cnt>= 0 ; d_cnt--){
00481 bin[d_cnt] = 0 ;
00482 while(best_bin >= increment){
00483 bin[d_cnt] ++ ;
00484 best_bin -= increment ;
00485 }
00486 increment /= bands_per_dim ;
00487 }
00488 }