view Histogram.c @ 32:20f99e6710b3

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