view Histogram.c @ 9:060d63cb5d34

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