| 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@7
|
10 #include "../vutilities.h"
|
|
msach@9
|
11 #include "../vmalloc.h"
|
|
Me@0
|
12
|
|
Me@0
|
13
|
|
Me@0
|
14 /*This Histogram Abstract Data Type has a number of bins plus a range of
|
|
Me@0
|
15 * values that the bins span, both chosen at creation.
|
|
Me@0
|
16 *
|
|
Me@0
|
17 *One creates a Histogram instance using the makeHistogram function, then
|
|
Me@0
|
18 * updates it with the addToHist function, and prints it out with the
|
|
Me@0
|
19 * printHist function.
|
|
Me@0
|
20 *
|
|
Me@0
|
21 *Note, the bin width is an integer, so the end of the range is adjusted
|
|
Me@0
|
22 * accordingly. Use the bin-width to calculate the bin boundaries.
|
|
Me@0
|
23 */
|
|
Me@0
|
24
|
|
Me@0
|
25
|
|
Me@0
|
26 Histogram *
|
|
SeanHalle@5
|
27 makeHistogram( int32 numBins, int32 startOfRange, int32 endOfRange )
|
|
SeanHalle@6
|
28
|
|
Me@0
|
29 {
|
|
Me@0
|
30 Histogram *hist;
|
|
SeanHalle@5
|
31 int32 i;
|
|
Me@0
|
32
|
|
Me@0
|
33
|
|
Me@3
|
34 hist = VMS__malloc( sizeof(Histogram) );
|
|
SeanHalle@6
|
35 hist->bins = VMS__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@7
|
71 hist = VMS__malloc( sizeof(Histogram) );
|
|
Me@7
|
72 hist->bins = VMS__malloc( numBins * sizeof(int32) );
|
|
Me@7
|
73
|
|
Me@7
|
74 makeHist_helper( hist, numBins, startOfRange, binWidth,VMS__strDup(name));
|
|
Me@7
|
75
|
|
Me@7
|
76 return hist;
|
|
Me@7
|
77 }
|
|
Me@7
|
78
|
|
Me@7
|
79 Histogram *
|
|
Me@7
|
80 makeFixedBinHistExt( int32 numBins, int32 startOfRange, int32 binWidth,
|
|
Me@7
|
81 char *name )
|
|
Me@7
|
82
|
|
Me@7
|
83 {
|
|
Me@7
|
84 Histogram *hist;
|
|
Me@7
|
85
|
|
Me@7
|
86 hist = malloc( sizeof(Histogram) );
|
|
Me@7
|
87 hist->bins = malloc( numBins * sizeof(int32) );
|
|
Me@7
|
88
|
|
Me@7
|
89 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
|
|
Me@7
|
90
|
|
Me@0
|
91 return hist;
|
|
Me@0
|
92 }
|
|
Me@0
|
93
|
|
SeanHalle@5
|
94 void inline
|
|
SeanHalle@5
|
95 addToHist( int32 value, Histogram *hist )
|
|
Me@0
|
96 {
|
|
SeanHalle@5
|
97 int32 binIdx;
|
|
Me@0
|
98
|
|
Me@0
|
99 if( value < hist->startOfRange )
|
|
Me@0
|
100 { binIdx = 0;
|
|
Me@0
|
101 }
|
|
Me@0
|
102 else if( value > hist->endOfRange )
|
|
Me@0
|
103 { binIdx = hist->numBins - 1;
|
|
Me@0
|
104 }
|
|
Me@0
|
105 else
|
|
Me@0
|
106 {
|
|
Me@0
|
107 binIdx = (value - hist->startOfRange) / hist->binWidth;
|
|
Me@0
|
108 }
|
|
Me@0
|
109
|
|
Me@0
|
110 hist->bins[ binIdx ] += 1;
|
|
Me@0
|
111 }
|
|
Me@0
|
112
|
|
Me@8
|
113 void inline
|
|
Me@8
|
114 subFromHist( int32 value, Histogram *hist )
|
|
Me@8
|
115 {
|
|
Me@8
|
116 int32 binIdx;
|
|
Me@8
|
117
|
|
Me@8
|
118 if( value < hist->startOfRange )
|
|
Me@8
|
119 { binIdx = 0;
|
|
Me@8
|
120 }
|
|
Me@8
|
121 else if( value > hist->endOfRange )
|
|
Me@8
|
122 { binIdx = hist->numBins - 1;
|
|
Me@8
|
123 }
|
|
Me@8
|
124 else
|
|
Me@8
|
125 {
|
|
Me@8
|
126 binIdx = (value - hist->startOfRange) / hist->binWidth;
|
|
Me@8
|
127 }
|
|
Me@8
|
128
|
|
Me@8
|
129 hist->bins[ binIdx ] -= 1;
|
|
Me@8
|
130 }
|
|
Me@8
|
131
|
|
SeanHalle@5
|
132
|
|
Me@7
|
133 /*Inline because use with RDTSC in innermost code so need ultra-fast
|
|
Me@7
|
134 */
|
|
SeanHalle@5
|
135 void inline
|
|
SeanHalle@5
|
136 addIntervalToHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
|
|
SeanHalle@5
|
137 {
|
|
SeanHalle@5
|
138 int32 value;
|
|
SeanHalle@5
|
139
|
|
SeanHalle@5
|
140 value = endIntvl - startIntvl;
|
|
SeanHalle@5
|
141 if( value < 0 || value > 10000000 ) return; //sanity check
|
|
SeanHalle@5
|
142 addToHist( value, hist );
|
|
SeanHalle@5
|
143 }
|
|
SeanHalle@5
|
144
|
|
Me@8
|
145 void inline
|
|
Me@8
|
146 subIntervalFromHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
|
|
Me@8
|
147 {
|
|
Me@8
|
148 int32 value;
|
|
Me@8
|
149
|
|
Me@8
|
150 value = endIntvl - startIntvl;
|
|
Me@8
|
151 if( value < 0 || value > 10000000 ) return; //sanity check
|
|
Me@8
|
152 subFromHist( value, hist );
|
|
Me@8
|
153 }
|
|
Me@8
|
154
|
|
Me@0
|
155 void
|
|
Me@0
|
156 printHist( Histogram *hist )
|
|
Me@0
|
157 {
|
|
Me@7
|
158 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
|
|
Me@8
|
159 float32 total, total2, binPercent, expectedValue1, expectedValue2;
|
|
Me@0
|
160
|
|
Me@8
|
161 if( hist == NULL ) return;
|
|
Me@8
|
162
|
|
Me@7
|
163 //do all except the top bin
|
|
Me@7
|
164 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
|
|
Me@7
|
165 for( i = 0; i < hist->numBins -1; i++ )
|
|
Me@0
|
166 {
|
|
Me@0
|
167 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
|
|
Me@7
|
168 total += hist->bins[ i ];
|
|
Me@7
|
169 binStart = hist->startOfRange + hist->binWidth * i;
|
|
Me@7
|
170 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
|
|
Me@0
|
171 }
|
|
Me@7
|
172 //copy and calc expected value minus the top bin
|
|
Me@8
|
173 expectedValue2 = expectedValue1;
|
|
Me@7
|
174 expectedValue2 /= total;
|
|
Me@8
|
175 total2 = total;
|
|
Me@7
|
176 //now do last iteration, to add the top bin
|
|
Me@7
|
177 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
|
|
Me@7
|
178 total += hist->bins[ i ];
|
|
Me@7
|
179 binStart = hist->startOfRange + hist->binWidth * i;
|
|
Me@7
|
180 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
|
|
Me@7
|
181
|
|
Me@7
|
182 expectedValue1 /= total;
|
|
Me@7
|
183
|
|
Me@0
|
184 barValue = maxHeight / 60; //60 spaces across page for tallest bin
|
|
Me@0
|
185
|
|
Me@7
|
186 printf( "histogram: " );
|
|
Me@7
|
187 if( hist->name != NULL ) printf( "%s\n", hist->name );
|
|
Me@7
|
188 else printf( "\n" );
|
|
Me@8
|
189 printf( " num samples: %d | expected value: %3.2f \n",
|
|
Me@8
|
190 (int)total, expectedValue1 );
|
|
Me@8
|
191 printf( "minus top bin, num samples: %d | expected value: %3.2f \n",
|
|
Me@8
|
192 (int)total2, expectedValue2 );
|
|
Me@7
|
193
|
|
Me@8
|
194 if( barValue == 0 ) { printf("error: bar val zero\n"); return; }
|
|
Me@0
|
195 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
|
|
Me@0
|
196 {
|
|
Me@0
|
197 binStart = hist->startOfRange + hist->binWidth * binIdx;
|
|
Me@0
|
198 binEnd = binStart + hist->binWidth - 1;
|
|
Me@7
|
199 binPercent = 100 * hist->bins[ binIdx ] / total;
|
|
Me@7
|
200 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
|
|
Me@0
|
201
|
|
Me@0
|
202 numBars = hist->bins[ binIdx ] / barValue;
|
|
Me@0
|
203 //print one bin, height of bar is num dashes across page
|
|
Me@0
|
204 for( i = 0; i < numBars; i++ )
|
|
Me@0
|
205 {
|
|
Me@0
|
206 printf("-");
|
|
Me@0
|
207 }
|
|
Me@0
|
208 printf("\n");
|
|
Me@0
|
209 }
|
|
Me@0
|
210 }
|
|
Me@0
|
211
|
|
Me@3
|
212 void
|
|
Me@3
|
213 freeHist( Histogram *hist )
|
|
Me@3
|
214 {
|
|
Me@3
|
215 VMS__free( hist->bins );
|
|
Me@7
|
216 VMS__free( hist->name );
|
|
Me@3
|
217 VMS__free( hist );
|
|
Me@3
|
218 }
|
|
Me@7
|
219 void
|
|
Me@7
|
220 freeHistExt( Histogram *hist )
|
|
Me@7
|
221 {
|
|
Me@7
|
222 free( hist->bins );
|
|
Me@7
|
223 free( hist->name );
|
|
Me@7
|
224 free( hist );
|
|
Me@7
|
225 }
|