annotate 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
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 }