annotate Histogram.c @ 7:fa6a281bd854

Nov 14 vers -- add makeFixedBinHist & Ext version & expected value &fxd name bug
author Me
date Sun, 14 Nov 2010 11:11:44 -0800
parents a2388fae93ff
children c83c27796fad
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"
Me@0 11
Me@0 12
Me@0 13 /*This Histogram Abstract Data Type has a number of bins plus a range of
Me@0 14 * values that the bins span, both chosen at creation.
Me@0 15 *
Me@0 16 *One creates a Histogram instance using the makeHistogram function, then
Me@0 17 * updates it with the addToHist function, and prints it out with the
Me@0 18 * printHist function.
Me@0 19 *
Me@0 20 *Note, the bin width is an integer, so the end of the range is adjusted
Me@0 21 * accordingly. Use the bin-width to calculate the bin boundaries.
Me@0 22 */
Me@0 23
Me@0 24
Me@0 25 Histogram *
SeanHalle@5 26 makeHistogram( int32 numBins, int32 startOfRange, int32 endOfRange )
SeanHalle@6 27
Me@0 28 {
Me@0 29 Histogram *hist;
SeanHalle@5 30 int32 i;
Me@0 31
Me@0 32
Me@3 33 hist = VMS__malloc( sizeof(Histogram) );
SeanHalle@6 34 hist->bins = VMS__malloc( numBins * sizeof(int32) );
Me@0 35
Me@0 36 hist->numBins = numBins;
Me@0 37 hist->binWidth = (endOfRange - startOfRange) / numBins;
Me@0 38 hist->endOfRange = startOfRange + hist->binWidth * numBins;
Me@0 39 hist->startOfRange = startOfRange;
Me@0 40
Me@0 41 for( i = 0; i < hist->numBins; i++ )
Me@0 42 {
Me@0 43 hist->bins[ i ] = 0;
Me@0 44 }
Me@0 45
Me@7 46 hist->name = NULL;
Me@7 47 return hist;
Me@7 48 }
Me@7 49
Me@7 50 inline void
Me@7 51 makeHist_helper( Histogram *hist, int32 numBins,
Me@7 52 int32 startOfRange, int32 binWidth, char *nameCopy )
Me@7 53 {
Me@7 54 hist->numBins = numBins;
Me@7 55 hist->binWidth = binWidth;
Me@7 56 hist->endOfRange = startOfRange + hist->binWidth * numBins;
Me@7 57 hist->startOfRange = startOfRange;
Me@7 58 hist->name = nameCopy;
Me@7 59 memset( hist->bins, 0, numBins * sizeof(int32) );
Me@7 60 }
Me@7 61
Me@7 62
Me@7 63 Histogram *
Me@7 64 makeFixedBinHist( int32 numBins, int32 startOfRange, int32 binWidth,
Me@7 65 char *name )
Me@7 66
Me@7 67 {
Me@7 68 Histogram *hist;
Me@7 69
Me@7 70 hist = VMS__malloc( sizeof(Histogram) );
Me@7 71 hist->bins = VMS__malloc( numBins * sizeof(int32) );
Me@7 72
Me@7 73 makeHist_helper( hist, numBins, startOfRange, binWidth,VMS__strDup(name));
Me@7 74
Me@7 75 return hist;
Me@7 76 }
Me@7 77
Me@7 78 Histogram *
Me@7 79 makeFixedBinHistExt( int32 numBins, int32 startOfRange, int32 binWidth,
Me@7 80 char *name )
Me@7 81
Me@7 82 {
Me@7 83 Histogram *hist;
Me@7 84
Me@7 85 hist = malloc( sizeof(Histogram) );
Me@7 86 hist->bins = malloc( numBins * sizeof(int32) );
Me@7 87
Me@7 88 makeHist_helper( hist, numBins, startOfRange, binWidth, strdup(name));
Me@7 89
Me@0 90 return hist;
Me@0 91 }
Me@0 92
SeanHalle@5 93 void inline
SeanHalle@5 94 addToHist( int32 value, Histogram *hist )
Me@0 95 {
SeanHalle@5 96 int32 binIdx;
Me@0 97
Me@0 98 if( value < hist->startOfRange )
Me@0 99 { binIdx = 0;
Me@0 100 }
Me@0 101 else if( value > hist->endOfRange )
Me@0 102 { binIdx = hist->numBins - 1;
Me@0 103 }
Me@0 104 else
Me@0 105 {
Me@0 106 binIdx = (value - hist->startOfRange) / hist->binWidth;
Me@0 107 }
Me@0 108
Me@0 109 hist->bins[ binIdx ] += 1;
Me@0 110 }
Me@0 111
SeanHalle@5 112
Me@7 113 /*Inline because use with RDTSC in innermost code so need ultra-fast
Me@7 114 */
SeanHalle@5 115 void inline
SeanHalle@5 116 addIntervalToHist( int32 startIntvl, int32 endIntvl, Histogram *hist )
SeanHalle@5 117 {
SeanHalle@5 118 int32 value;
SeanHalle@5 119
SeanHalle@5 120 value = endIntvl - startIntvl;
SeanHalle@5 121 if( value < 0 || value > 10000000 ) return; //sanity check
SeanHalle@5 122 addToHist( value, hist );
SeanHalle@5 123 }
SeanHalle@5 124
Me@0 125 void
Me@0 126 printHist( Histogram *hist )
Me@0 127 {
Me@7 128 int32 binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;
Me@7 129 float32 total, binPercent, expectedValue1, expectedValue2;
Me@0 130
Me@0 131
Me@7 132 //do all except the top bin
Me@7 133 maxHeight = 0; total = 0.0; expectedValue1 = 0.0;
Me@7 134 for( i = 0; i < hist->numBins -1; i++ )
Me@0 135 {
Me@0 136 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
Me@7 137 total += hist->bins[ i ];
Me@7 138 binStart = hist->startOfRange + hist->binWidth * i;
Me@7 139 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
Me@0 140 }
Me@7 141 //copy and calc expected value minus the top bin
Me@7 142 expectedValue2 = expectedValue1;
Me@7 143 expectedValue2 /= total;
Me@7 144
Me@7 145 //now do last iteration, to add the top bin
Me@7 146 if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
Me@7 147 total += hist->bins[ i ];
Me@7 148 binStart = hist->startOfRange + hist->binWidth * i;
Me@7 149 expectedValue1 += hist->bins[ i ] * (binStart + hist->binWidth/2.0);
Me@7 150
Me@7 151 expectedValue1 /= total;
Me@7 152
Me@0 153 barValue = maxHeight / 60; //60 spaces across page for tallest bin
Me@0 154
Me@7 155 printf( "histogram: " );
Me@7 156 if( hist->name != NULL ) printf( "%s\n", hist->name );
Me@7 157 else printf( "\n" );
Me@7 158 printf( "expected value: %3.2f \n", expectedValue1 );
Me@7 159 printf( "expected value minus top bin: %3.2f \n", expectedValue2 );
Me@7 160
Me@0 161 if( barValue == 0 ) printf("error printing histogram\n");
Me@0 162 for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
Me@0 163 {
Me@0 164 binStart = hist->startOfRange + hist->binWidth * binIdx;
Me@0 165 binEnd = binStart + hist->binWidth - 1;
Me@7 166 binPercent = 100 * hist->bins[ binIdx ] / total;
Me@7 167 printf("bin range: %d - %d | %3.2f", binStart, binEnd, binPercent );
Me@0 168
Me@0 169 numBars = hist->bins[ binIdx ] / barValue;
Me@0 170 //print one bin, height of bar is num dashes across page
Me@0 171 for( i = 0; i < numBars; i++ )
Me@0 172 {
Me@0 173 printf("-");
Me@0 174 }
Me@0 175 printf("\n");
Me@0 176 }
Me@0 177 }
Me@0 178
Me@3 179 void
Me@3 180 freeHist( Histogram *hist )
Me@3 181 {
Me@3 182 VMS__free( hist->bins );
Me@7 183 VMS__free( hist->name );
Me@3 184 VMS__free( hist );
Me@3 185 }
Me@7 186 void
Me@7 187 freeHistExt( Histogram *hist )
Me@7 188 {
Me@7 189 free( hist->bins );
Me@7 190 free( hist->name );
Me@7 191 free( hist );
Me@7 192 }