/* Histogram.c Specification of a Histogram Class [Taken from requirements found at http://ciips.ee.uwa.edu.au/~morris/clp110/hist_req.html.] Author: J Morris Date Last Modified: 5 October, 1997 */ #include #include #include #include struct histogram { int bin_count, sample_count, max_index, max_frequency; double factor; double offset; double total; int *bins; }; #include "Histogram.h" #define EPS 1.0e-8 Histogram ConsHistogram( int max_bins, double reduce_factor ) { Histogram h; assert( max_bins > 0 ); assert( reduce_factor != 0.0 ); h = (Histogram)malloc( sizeof(struct histogram) ); if ( h != NULL ) { h->bin_count = max_bins; h->factor = reduce_factor; h->bins = (int *)malloc( (max_bins+1)*sizeof(int) ); h->offset = 0.0; if( h->bins == NULL ) { printf("ConsHistogram: Insuff mem\n" ); free( h ); h = NULL; } else ClearHistogram( h ); } else { printf("ConsHistogram: Insuff mem\n" ); } return h; } Histogram ConsHistRange( int max_bins, double min, double max ) { double reduce_factor; Histogram h; reduce_factor = max_bins/((1.0+EPS)*max-min); h = ConsHistogram( max_bins, reduce_factor ); if( h != NULL ) { h->offset = min; } return h; } int DeleteHistogram( Histogram h ) { /* Delete a histogram. Pre-cond: h is a valid Histogram Post-cond: space used by d has been freed returns TRUE if no errors, FALSE on error */ assert( h != NULL ); assert( h->bins != NULL ); free( h->bins ); free( h ); return TRUE; } int ClearHistogram( Histogram h ) { /* Reset the Histogram h (allows the same space to be re-used, without Pre-cond: h is a valid Histogram Post-cond: entries in h have all been cleared, max_bins and reduce_factor unaltered */ int i; assert( h != NULL ); assert( h->bins != NULL ); for( i=0;ibin_count;i++ ) { h->bins[i] = 0; } h->sample_count = h->max_index = h->max_frequency = 0; h->total = 0.0; return TRUE; } int Bins( Histogram h ) { assert( h != NULL ); assert( h->bins != NULL ); return h->bin_count; } int TotalPoints( Histogram h ) { /* Count total points in the histogram Pre-cond: h is a valid Histogram Post-cond: returns count of points added to the Histogram */ assert( h != NULL ); assert( h->bins != NULL ); return h->sample_count; } int AddDatum( Histogram h, double x ) { /* Add a new translation to the histogram Pre-cond: h is a valid Histogram x is in the defined range Post-cond: TotPoints( h ) = old TotPoints( h ) + 1 h[floor(x*reduce_factor)] incremented by 1 */ int i; assert( h != NULL ); assert( h->bins != NULL ); i = floor(x*h->factor); assert( (i>=0) && (i<=h->bin_count) ); h->bins[i]++; /* Update the maximum frequency */ if ( h->bins[i] > h->max_frequency ) { h->max_frequency = h->bins[i]; h->max_index = i; } h->total = h->total + x; h->sample_count++; return TRUE; } int BinCount( Histogram h, int index ) { /* Return the count of items in bin index Pre-cond: h is a valid Histogram and index >= 0 and index < max_bins */ assert( h != NULL ); assert( h->bins != NULL ); assert( index >= 0 ); assert( index <= h->bin_count ); return h->bins[index]; } double SampleMedian( Histogram h, int *index ) { /* Return the sample median Pre-cond: h is a valid Histogram Post-cond: returns the median of the data points added so far */ int i, m, n; assert( h != NULL ); assert( h->bins != NULL ); /* Find the bin which has the median point in it */ m = h->sample_count/2; n = i = 0; while( n < m ) { n = n + h->bins[i]; if ( n>m ) break; i++; } *index = i; return i*h->factor; } double SampleMean( Histogram h ) { /* Return the sample mean Pre-cond: h is a valid Histogram Post-cond: returns the mean of the data points added so far */ assert( h != NULL ); assert( h->bins != NULL ); return h->total/h->sample_count; } int MaxFrequency( Histogram h, int *index ) { assert( h != NULL ); assert( h->bins != NULL ); *index = h->max_index; return h->max_frequency; } double BinSize( Histogram h ) { return 1.0/h->factor; }