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