annotate Histogram.c @ 25:ff7dedcd2e3f

version for Tamer
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Mon, 17 Sep 2012 11:07:07 +0200
parents 6cee2e00eacb
children 7664da1180fd
rev   line source
Me@0 1 /*
Me@0 2 * Copyright 2010 OpenSourceStewardshipFoundation.org
Me@0 3 * Licensed under GNU General Public License version 2
Me@0 4 *
Me@0 5 * Author: seanhalle@yahoo.com
Me@0 6 *
Me@0 7 */
Me@4 8 #include <stdio.h>
seanhalle@22 9 #include <string.h>
nengel@25 10 #include <stdlib.h>
Me@0 11 #include "Histogram.h"
nengel@25 12 #include "../VMS_Implementations/VMS_impl/VMS.h"
Me@0 13
Me@0 14
Me@0 15 /*This Histogram Abstract Data Type has a number of bins plus a range of
Me@0 16 * values that the bins span, both chosen at creation.
Me@0 17 *
Me@0 18 *One creates a Histogram instance using the makeHistogram function, then
Me@0 19 * updates it with the addToHist function, and prints it out with the
Me@0 20 * printHist function.
Me@0 21 *
Me@0 22 *Note, the bin width is an integer, so the end of the range is adjusted
Me@0 23 * accordingly. Use the bin-width to calculate the bin boundaries.
Me@0 24 */
Me@0 25
Me@0 26
Me@0 27 Histogram *
SeanHalle@5 28 makeHistogram( int32 numBins, int32 startOfRange, int32 endOfRange )
Me@0 29 {
Me@0 30 Histogram *hist;
SeanHalle@5 31 int32 i;
Me@0 32
Me@0 33
Me@16 34 hist = VMS_int__malloc( sizeof(Histogram) );
Me@16 35 hist->bins = VMS_int__malloc( numBins * sizeof(int32) );
Me@0 36
Me@0 37 hist->numBins = numBins;
Me@0 38 hist->binWidth = (endOfRange - startOfRange) / numBins;
Me@0 39 hist->endOfRange = startOfRange + hist->binWidth * numBins;
Me@0 40 hist->startOfRange = startOfRange;
Me@0 41
Me@0 42 for( i = 0; i < hist->numBins; i++ )
Me@0 43 {
Me@0 44 hist->bins[ i ] = 0;
Me@0 45 }
Me@0 46
Me@7 47 hist->name = NULL;
Me@7 48 return hist;
Me@7 49 }
Me@7 50
Me@7 51 inline void
Me@7 52 makeHist_helper( Histogram *hist, int32 numBins,
Me@7 53 int32 startOfRange, int32 binWidth, char *nameCopy )
Me@7 54 {
Me@7 55 hist->numBins = numBins;
Me@7 56 hist->binWidth = binWidth;
Me@7 57 hist->endOfRange = startOfRange + hist->binWidth * numBins;
Me@7 58 hist->startOfRange = startOfRange;
Me@7 59 hist->name = nameCopy;
Me@7 60 memset( hist->bins, 0, numBins * sizeof(int32) );
Me@7 61 }
Me@7 62
Me@7 63
Me@7 64 Histogram *
Me@7 65 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
Me@7 66 char *name )
Me@7 67
Me@7 68 {
Me@7 69 Histogram *hist;
Me@7 70
Me@16 71 hist = VMS_int__malloc( sizeof(Histogram) );
Me@16 72 hist->bins = VMS_int__malloc( numBins * sizeof(int32) );
Me@7 73
seanhalle@22 74 char *nameCopy = (char *)VMS_int__strDup(name);
seanhalle@22 75 makeHist_helper( hist, numBins, startOfRange, binWidth, nameCopy);
Me@7 76
Me@7 77 return hist;
Me@7 78 }
Me@7 79
Me@7 80 Histogram *
Me@15 81 makeFixedBinHistExt( int32 numBins, int32 startOfRange, int32 binWidth,
Me@7 82 char *name )
Me@7 83
Me@7 84 {
Me@7 85 Histogram *hist;
Me@7 86
Me@7 87 hist = malloc( sizeof(Histogram) );
Me@7 88 hist->bins = malloc( numBins * sizeof(int32) );
Me@7 89
Me@7 90 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
Me@7 91
Me@0 92 return hist;
Me@0 93 }
Me@0 94
SeanHalle@5 95 void inline
SeanHalle@5 96 addToHist( int32 value, Histogram *hist )
Me@0 97 {
SeanHalle@5 98 int32 binIdx;
Me@0 99
Me@0 100 if( value < hist->startOfRange )
Me@0 101 { binIdx = 0;
Me@0 102 }
Me@0 103 else if( value > hist->endOfRange )
Me@0 104 { binIdx = hist->numBins - 1;
Me@0 105 }
Me@0 106 else
Me@0 107 {
Me@0 108 binIdx = (value - hist->startOfRange) / hist->binWidth;
Me@0 109 }
Me@0 110
Me@0 111 hist->bins[ binIdx ] += 1;
Me@0 112 }
Me@0 113
Me@8 114 void inline
Me@8 115 subFromHist( int32 value, Histogram *hist )
Me@8 116 {
Me@8 117 int32 binIdx;
Me@8 118
Me@8 119 if( value < hist->startOfRange )
Me@8 120 { binIdx = 0;
Me@8 121 }
Me@8 122 else if( value > hist->endOfRange )
Me@8 123 { binIdx = hist->numBins - 1;
Me@8 124 }
Me@8 125 else
Me@8 126 {
Me@8 127 binIdx = (value - hist->startOfRange) / hist->binWidth;
Me@8 128 }
Me@8 129
Me@8 130 hist->bins[ binIdx ] -= 1;
Me@8 131 }
Me@8 132
SeanHalle@5 133
Me@7 134 /*Inline because use with RDTSC in innermost code so need ultra-fast
Me@7 135 */
SeanHalle@5 136 void inline
msach@10 137 addIntervalToHist( uint32 startIntvl, uint32 endIntvl, Histogram *hist )
SeanHalle@5 138 {
SeanHalle@5 139 int32 value;
SeanHalle@5 140
SeanHalle@5 141 value = endIntvl - startIntvl;
SeanHalle@5 142 if( value < 0 || value > 10000000 ) return; //sanity check
SeanHalle@5 143 addToHist( value, hist );
SeanHalle@5 144 }
SeanHalle@5 145
Me@8 146 void inline
Me@8 147 subIntervalFromHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
Me@8 148 {
Me@8 149 int32 value;
Me@8 150
Me@8 151 value = endIntvl - startIntvl;
Me@8 152 if( value < 0 || value > 10000000 ) return; //sanity check
Me@8 153 subFromHist( value, hist );
Me@8 154 }
Me@8 155
Me@0 156 void
msach@10 157 saveHistToFile(Histogram *hist)
msach@10 158 {
msach@10 159 FILE *output;
msach@10 160 int32 binIdx, binStart, binEnd, centerValue, width;
msach@10 161 int32 maxHeight, i,n;
msach@11 162 float32 total, total2, expectedValue1, expectedValue2;
msach@10 163
msach@10 164 if(hist == NULL || hist->name == NULL)
msach@10 165 return;
msach@10 166
msach@10 167 //Calculate the average
msach@10 168 //do all except the top bin
msach@10 169 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
msach@10 170 for( i = 0; i < hist->numBins -1; i++ )
msach@10 171 {
msach@10 172 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
msach@10 173 total += hist->bins[ i ];
msach@10 174 binStart = hist->startOfRange + hist->binWidth * i;
msach@10 175 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
msach@10 176 }
msach@10 177 //copy and calc expected value minus the top bin
msach@10 178 expectedValue2 = expectedValue1;
msach@10 179 expectedValue2 /= total;
msach@10 180 total2 = total;
msach@10 181 //now do last iteration, to add the top bin
msach@10 182 if(maxHeight < hist->bins[ i ])
msach@10 183 maxHeight = hist->bins[ i ];
msach@10 184 total += hist->bins[ i ];
msach@10 185 binStart = hist->startOfRange + hist->binWidth * i;
msach@10 186 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
msach@10 187
msach@10 188 expectedValue1 /= total;
msach@10 189
msach@10 190
msach@10 191
msach@10 192
msach@10 193 //If a histogram directory does not exist, do not save to file.
msach@10 194 //TODO change to argument
msach@10 195 char filename[255];
msach@10 196 for(n=0;n<255;n++)
msach@10 197 {
msach@10 198 sprintf(filename, "./histograms/%s.%d.dat", hist->name,n);
msach@10 199 output = fopen(filename,"r");
msach@10 200 if(output)
msach@10 201 {
msach@10 202 fclose(output);
msach@10 203 }else{
msach@10 204 break;
msach@10 205 }
msach@10 206 }
msach@10 207 printf("Saving Hist to File: %s ...\n", filename);
msach@10 208 output = fopen(filename,"w+");
msach@10 209 if(output == NULL){
msach@10 210 printf("[!]No histogram was saved. To save histograms create folder 'histograms'.\n");
msach@10 211 return;
msach@10 212 }
msach@10 213
msach@10 214 fprintf(output, "#\n# Histogram Name: %s\n", hist->name);
msach@10 215 fprintf(output, "# Expected Values\n");
msach@10 216 fprintf(output, "#\tnum samples: %d | expected value: %3.2f \n",
msach@10 217 (int)total, expectedValue1 );
msach@10 218 fprintf(output, "#\tminus top bin, num samples: %d | expected value: %3.2f \n",
msach@10 219 (int)total2, expectedValue2 );
msach@10 220 fprintf(output, "#\n# [Interval] [Center Value] [Count] [relative Count] [Width]\n");
msach@10 221
msach@10 222 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
msach@10 223 {
msach@10 224 binStart = hist->startOfRange + hist->binWidth * binIdx;
msach@10 225 binEnd = binStart + hist->binWidth - 1;
msach@10 226 centerValue = (binStart+binEnd)/2;
msach@10 227 width = (binEnd-binStart)+1;
msach@10 228 fprintf(output, "%d-%d\t%d\t%d\t%.4f\t%d\n", binStart, binEnd, centerValue,
msach@10 229 hist->bins[ binIdx ],
msach@10 230 hist->bins[ binIdx ]/total, width);
msach@10 231 }
msach@10 232
msach@10 233 fclose(output);
msach@10 234 fflush(stdout);
msach@10 235 }
msach@10 236
msach@10 237 void
Me@0 238 printHist( Histogram *hist )
Me@0 239 {
Me@7 240 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
Me@8 241 float32 total, total2, binPercent, expectedValue1, expectedValue2;
Me@0 242
Me@8 243 if( hist == NULL ) return;
Me@8 244
Me@7 245 //do all except the top bin
Me@7 246 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
Me@7 247 for( i = 0; i < hist->numBins -1; i++ )
Me@0 248 {
Me@0 249 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
Me@7 250 total += hist->bins[ i ];
Me@7 251 binStart = hist->startOfRange + hist->binWidth * i;
Me@7 252 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
Me@0 253 }
Me@7 254 //copy and calc expected value minus the top bin
Me@8 255 expectedValue2 = expectedValue1;
Me@7 256 expectedValue2 /= total;
Me@8 257 total2 = total;
Me@7 258 //now do last iteration, to add the top bin
Me@7 259 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
Me@7 260 total += hist->bins[ i ];
Me@7 261 binStart = hist->startOfRange + hist->binWidth * i;
Me@7 262 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
Me@7 263
Me@7 264 expectedValue1 /= total;
Me@7 265
Me@7 266 printf( "histogram: " );
Me@7 267 if( hist->name != NULL ) printf( "%s\n", hist->name );
Me@7 268 else printf( "\n" );
Me@8 269 printf( " num samples: %d | expected value: %3.2f \n",
Me@8 270 (int)total, expectedValue1 );
Me@8 271 printf( "minus top bin, num samples: %d | expected value: %3.2f \n",
Me@8 272 (int)total2, expectedValue2 );
Me@7 273
msach@10 274 if(maxHeight < 60){
msach@10 275 barValue = 1;
msach@10 276 printf("Single Bar Value: %i\n", barValue);
msach@10 277 }else{
msach@10 278 barValue = maxHeight / 60; //60 spaces across page for tallest bin
msach@10 279 printf("Single Bar Value: %0.3f\n", (float)maxHeight /60);
msach@10 280 }
msach@10 281
Me@8 282 if( barValue == 0 ) { printf("error: bar val zero\n"); return; }
Me@0 283 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
Me@0 284 {
Me@0 285 binStart = hist->startOfRange + hist->binWidth * binIdx;
Me@0 286 binEnd = binStart + hist->binWidth - 1;
Me@7 287 binPercent = 100 * hist->bins[ binIdx ] / total;
Me@7 288 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
Me@0 289
Me@0 290 numBars = hist->bins[ binIdx ] / barValue;
Me@0 291 //print one bin, height of bar is num dashes across page
Me@0 292 for( i = 0; i < numBars; i++ )
Me@0 293 {
Me@0 294 printf("-");
Me@0 295 }
Me@0 296 printf("\n");
Me@0 297 }
Me@0 298 }
Me@0 299
Me@3 300 void
Me@3 301 freeHist( Histogram *hist )
Me@3 302 {
Me@16 303 VMS_int__free( hist->bins );
Me@16 304 VMS_int__free( hist->name );
Me@16 305 VMS_int__free( hist );
Me@15 306 }
Me@15 307 void
Me@15 308 freeHistExt( Histogram *hist )
Me@15 309 {
Me@7 310 free( hist->bins );
Me@7 311 free( hist->name );
Me@7 312 free( hist );
Me@7 313 }