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