histo/0040777000104000010010000000000007543240634012664 5ustar AdministratorsNonehisto/include/0040777000104000010010000000000007605704575014317 5ustar AdministratorsNonehisto/include/dbl_sort.h0100666000104000010010000000053007540001771016255 0ustar AdministratorsNone #ifndef _DBL_SORT_H_ #define _DBL_SORT_H_ #include "generic_sort.h" class dbl_sort : public generic_sort { protected: int compare( double a, double b) { int rslt = 0; if (a < b) rslt = -1; else if (a > b) rslt = 1; return rslt; } // compare }; // dbl_sort #endif histo/include/generic_sort.h0100666000104000010010000000755407540004350017141 0ustar AdministratorsNone #ifndef _GENERIC_SORT_H_ #define _GENERIC_SORT_H_ /** An abstract generic sort class This is an abstract class. The class that is derived from this class must define the compare function. The compare function returns an integer value that is less than, equal or greater than zero depending on the result of the comparision (the function is modeled after UNIX strcmp). This class is based on the Java quicksort algorithm by James Gosling at at Sun Microsystems (see below).

QSortAlgorithm.java 1.3 29 Feb 1996 James Gosling

Copyright (c) 1994-1996 Sun Microsystems, Inc. All Rights Reserved.

Permission to use, copy, modify, and distribute this software and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is hereby granted.

Please refer to the file http://www.javasoft.com/copy_trademarks.html for further important copyright and trademark information and to http://www.javasoft.com/licensing.html for further important licensing information for the Java (tm) Technology.

*/ template class generic_sort { private: /** Exchange element a[i] and a[j] */ void swap(T *a, int i, int j) { T t; t = a[i]; a[i] = a[j]; a[j] = t; } // swap /** This is a generic version of C.A.R Hoare's Quick Sort * algorithm. This will handle arrays that are already * sorted, and arrays with duplicate keys.
* * If you think of a one dimensional array as going from * the lowest index on the left to the highest index on the right * then the parameters to this function are lowest index or * left and highest index or right. The first time you call * this function it will be with the parameters 0, a.length - 1. * * @param a an integer array * @param lo0 left boundary of array partition * @param hi0 right boundary of array partition */ void QuickSort(T *a, int lo0, int hi0) { int lo = lo0; int hi = hi0; T mid; if ( hi0 > lo0) { /* Arbitrarily establishing partition element as the midpoint of * the array. */ mid = a[ ( lo0 + hi0 ) / 2 ]; // loop through the array until indices cross while( lo <= hi ) { /* find the first element that is greater than or equal to * the partition element starting from the left Index. */ while( ( lo < hi0 ) && ( compare(a[lo], mid) < 0 ) ) ++lo; /* find an element that is smaller than or equal to * the partition element starting from the right Index. */ while( ( hi > lo0 ) && ( compare(a[hi], mid) > 0) ) --hi; // if the indexes have not crossed, swap if( lo <= hi ) { swap(a, lo, hi); ++lo; --hi; } } // while /* If the right index has not reached the left side of array * must now sort the left partition. */ if( lo0 < hi ) QuickSort( a, lo0, hi ); /* If the left index has not reached the right side of array * must now sort the right partition. */ if( lo < hi0 ) QuickSort( a, lo, hi0 ); } } // QuickSort protected: /** This is an abstract function that should be defined by the class derived from generic_sort. This function is passed two objects, a and b. It compares them and should return the following values:
    If (a == b) return 0
    if (a < b) return -1
    if (a > b) return 1
*/ virtual int compare( T a, T b) = 0; private: generic_sort( const generic_sort &rhs ); public: generic_sort() {} ~generic_sort() {} void sort(T *a, size_t N) { QuickSort(a, 0, N-1); } // sort }; // generic_sort #endif histo/include/histogram.h0100666000076400010010000001134207604701165016303 0ustar AdministratorNone #ifndef _HISTOGRAM_H_ #define _HISTOGRAM_H_ #include /** Support for calculating histograms. The histogram class constructor is initialized with the number of bins to be used in the histogram. Each bin is a histo_bin object which contains information on the start and end value of the bin range and the frequency in the bin. The frequency is the number of values in the data set which are greater than or equal to start and less than end. Example: Given an array of 20 double values, calculate the histogram. The data does not need to be in sorted order. The histogram calculation will sort it. A vector of histo_bin objects is allocated by the histogram::bin_vec class constructor. The data, number of elements in the data set and the vector of histogram bins is passed to the histogram calculate function. This will initialize each of the histogram bins with a start, end and frequency.
    const size_t num_bins = 20;
    histogram::bin_vec binz( num_bins );
    histogram histo;

    histo.calculate( data, N, binz );

    for (size_t i = 0; i < num_bins; i++) {
      size_t freq = static_cast( binz[i] );
      printf("%7.4f %2d\n", binz.start(i), freq );
    }
Note that binz[i] returns the frequency as a double, which is cast to a size_t value. */ class histogram { private: // copy constructor histogram( const histogram &rhs ); class bin_vec; void init_bins( bin_vec &bins, const double min, const double max ); /** Get values from a double array. */ class value_pool { private: size_t ix_; const double *vec_; const size_t N_; public: value_pool( const double *vec, size_t N ) : vec_( vec ), N_( N ) { ix_ = 0; } bool get_val( double &val ) { bool rslt = false; val = 0.0; if (ix_ < N_) { rslt = true; val = vec_[ ix_ ]; ix_++; } return rslt; } // get_val }; // value_pool public: /** A histogram bin In a standard histogram a bin always contains a positive integer frequency (a.k.a. count of elements). This histogram bin object is designed to be operated on a floating point wavelet transform. So the frequency element is a double. */ class histo_bin { private: /** number of values, v, such that start <= v < end */ double frequency_; /** start of bin value range */ double start_; /** end of bin value range */ double end_; public: histo_bin() {} ~histo_bin() {} double frequency() { return frequency_; } void frequency( const double f ) { frequency_ = f; } double &freqPtr() { return frequency_; } double start() { return start_; } void start( const double s ) { start_ = s; } double end() { return end_; } void end( const double e ) { end_ = e; } }; // class histo_bin /** An array of histogram bins. This class overloads the array index operator []. For an instance of bin_vec named binz, binz[i] will return the frequency value at index i. The class constructor is passed a value for the number of bin_vec elements. It dynamically allocates an internal array. The class destructor deallocates the internal array. The start and end values for a given bin are referenced via the start and end functions. */ class bin_vec { private: bin_vec( const bin_vec &rhs ); const size_t num_bins; histo_bin *bins; public: bin_vec( size_t N ) : num_bins( N ) { bins = new histo_bin[ num_bins ]; } ~bin_vec() { delete [] bins; } size_t length() { return num_bins; } double start( const size_t i ) { assert( i < num_bins ); return bins[i].start(); } void start( const size_t i, const double val ) { assert( i < num_bins ); bins[i].start( val ); } double end( const size_t i ) { assert( i < num_bins ); return bins[i].end(); } void end( const size_t i, const double val ) { assert( i < num_bins ); bins[i].end( val ); } /** LHS [] operator */ double &operator[]( const size_t i ) { assert( i < num_bins ); return bins[i].freqPtr(); } /** RHS [] operator */ double operator[]( const size_t i ) const { assert( i < num_bins ); return bins[i].frequency(); } }; // class bin_vec public: histogram() {} ~histogram() {} void calculate( double *raw_data, const size_t N, bin_vec &binz ); }; // histogram #endif histo/include/wavethresh.h0100666000104000010010000001116607543240616016642 0ustar AdministratorsNone #ifndef _WAVETHRESH_H_ #define _WAVETHRESH_H_ #include #include /** Support for wavelet coefficient thresholding. In wavelet coefficient thresholding a selected set of the wavelet coefficients that result from the wavelet transform are modified. The algorithm used here uses the "Universal Threshold" that Donoho and Johnstone have discussed in their papers. Thresholds and the "Universal Threshold" are also discussed in Noise Reduction by Wavelet Thresholding by Jansen, Springer Verlag, 2001. The "Universal Threshold is:
     UnivThresh = sqrt( 2 * log( N ) ) * stdDev
  
Here stdDev is the standard deviation of N wavelet coefficients. Log is the natural log. Thresholding is used to remove noise. Another way to state this is that the signal is smoothed. This code uses "soft thresholding" where a wavelet coefficient that is less than the threshold is set to zero and a coefficient whose absolute value is greater than the threshold is moved toward zero by the threshold amount. This class provides globally accessible static functions. It is not meant to be declared as an object and has no state. */ template class wavethresh { private: wavethresh( const wavethresh &rhs ); wavethresh() {} ~wavethresh() {} public: /** A container for the mean and standard deviation */ class bellInfo { private: double mean_; double stdDev_; public: bellInfo() { mean_ = 0.0; stdDev_ = 0.0; } ~bellInfo() {} bellInfo( const bellInfo &rhs ) { mean_ = rhs.mean_; stdDev_ = rhs.stdDev_; } void mean( const double m ) { mean_ = m; } double mean() { return mean_; } void stdDev( const double s ) { stdDev_ = s; } double stdDev() { return stdDev_; } }; // bellInfo /** Calculate teh mean and standard deviation for the section of vec from start to (start+size)-1. \param vec An object or array where the [] operator returns a double. \param start the index of the first element in the data section \param size the size of the data section \param stats The result (mean and standard deviation) is returned in this argument. */ static void bellStats(const T &vec, const size_t start, const size_t size, bellInfo &stats ) { stats.mean( 0.0 ); stats.stdDev( 0.0 ); int i; // calculate the mean (a.k.a average) double sum = 0.0; for (i = start; i < start + size; i++) { sum = sum + vec[i]; } double mean = sum / static_cast(size); // calculate the standard deviation sum double stdDevSum = 0; double x; for (i = start; i < start + size; i++) { x = vec[i] - mean; stdDevSum = stdDevSum + (x * x); } double variance = stdDevSum / static_cast(size-1); double stdDev = sqrt( variance ); stats.mean( mean ); stats.stdDev( stdDev ); } // bellStats static double soft_thresh( const double val, const double tau ) { double sign = 1.0; double absval = fabs( val ); if (val < 0) sign = -1.0; double new_val; if (absval < tau) { new_val = 0.0; } else { new_val = sign * (absval - tau); } return new_val; } /** Calculate a wavelet threshold and apply it to the wavelet coefficients using soft thresholding. */ static void thresh(T &vec, const size_t start, const size_t size ) { bellInfo info; bellStats( vec, start, size, info ); double stdDev = info.stdDev(); double Tau = sqrt( 2 * log( size ) ) * stdDev; size_t i; for (i = start; i < start + size; i++) { vec[ i ] = soft_thresh( vec[i], Tau ); } } // thresh /** Print the mean and standard deviation for the wavelet coefficient bands whose length is greater than 32. \param vec An object or array where the [] operator returns a double \param N the number of data elements (doubles) in vec */ static void printHarmonicStdDev( const T &vec, const size_t N) { const size_t minSize = 32; size_t band = N / 2; bellInfo stats; while (band >= minSize ) { bellStats( vec, band, band, stats ); printf("coefficient band %3d: mean = %7.6f, stddev = %7.6f\n", band, stats.mean(), stats.stdDev() ); band = band / 2; } // while } // printHarmonicStdDev }; // wavethresh #endif histo/Makefile0100666000104000010010000000157607542502534014331 0ustar AdministratorsNone DEBUG = -Zi BROWSE = CFLAGS = $(BROWSE) $(DEBUG) -DWIN32 -Tp OBJ = obj EXE = .exe DOXYPATH = e:\doxygen\bin SYSINC = "d:\Program Files\Microsoft Visual Studio\Vc98\Include" INCLUDE = -I"include" -I"..\include" -I"..\data\include" -I$(SYSINC) SIGOBJ = yahooTS.$(OBJ) histogram.$(OBJ) ALL: wavehist wavehist: wavehist$(EXE) clean: rm -f *.obj *.pdb *.sbr *.ilk *.exe rm -f include/*~ rm -f src/*~ doxygen: $(DOXYPATH)\doxygen doxygenDocConfig wavehist$(EXE): $(SIGOBJ) wavehist.$(OBJ) $(CC) $(SIGOBJ) wavehist.$(OBJ) $(DEBUG) -GX -o wavehist$(EXE) wavehist.$(OBJ): src\$*.cpp $(CC) -c -GX $(INCLUDE) $(CFLAGS) src\$*.cpp histogram.$(OBJ): src\$*.cpp include\$*.h $(CC) -c -GX $(INCLUDE) $(CFLAGS) src\$*.cpp yahooTS.$(OBJ): ..\data\src\$*.cpp ..\data\include\$*.h $(CC) -c $(INCLUDE) $(CFLAGS) ..\data\src\$*.cpphisto/src/0040777000104000010010000000000007605704575013463 5ustar AdministratorsNonehisto/src/histogram.cpp0100666000076400010010000000413407604701205015776 0ustar AdministratorNone #include #include "dbl_sort.h" #include "histogram.h" /** Initialize the histogram bin array */ void histogram::init_bins( bin_vec &bins, const double min, const double max ) { size_t num_bins = bins.length(); double range = max - min; double bin_size = range / static_cast( num_bins ); double start = min; double end = min + bin_size; for (size_t i = 0; i < num_bins; i++) { bins[i] = 0; // initialize frequency to zero bins.start(i, start ); // initialize the i'th bin start value bins.end(i, end ); // initialize the i'th bin end value start = end; end = end + bin_size; } // The frequency in a bin is incremented if a value v is // in the range start <= v < end. This is fine until // we reach the last bin, which should also get values // which are in the range start <= v <= end. So add a // small amount to the end value to assure that the // end value of the last bin is beyond the value range. bins.end(num_bins-1, bins.end(num_bins-1) + (bin_size / 10.0) ); } // init_bins /** Calculate a histogram \param raw_data The raw data from which to calculate the histogram \param N The number of data values in raw_data \param bins An array of histo_bin objects \param num_bins The number of histogram bins (number of elements in histo_bin) */ void histogram::calculate( double *raw_data, const size_t N, bin_vec &bins ) { dbl_sort s; s.sort( raw_data, N ); double min = raw_data[0]; double max = raw_data[N-1]; size_t num_bins = bins.length(); init_bins( bins, min, max ); value_pool pool( raw_data, N ); size_t bin_ix = 0; double val; bool more_values = pool.get_val( val ); double end = bins.end(bin_ix); while (bin_ix < num_bins && more_values) { if (val < end) { bins[bin_ix] = bins[bin_ix] + 1; // increment the frequency more_values = pool.get_val( val ); } else { bin_ix++; end = bins.end(bin_ix); } } // while } // calculate histo/src/histotest.cpp0100666000104000010010000000221207541221062016167 0ustar AdministratorsNone /** \file Test the histogram code */ #include #include "histogram.h" double data[] = {68.23, 69.40, 69.47, 69.75, 70.00, 70.00, 70.00, 70.59, 70.70, 70.71, 70.99, 71.00, 71.25, 71.39, 71.40, 71.45, 71.49, 71.60, 71.60, 71.74, 72.15, 72.19, 72.25, 72.41, 72.70, 72.70, 73.48, 73.62, 73.90, 74.09, 74.20, 75.20, 75.95, 76.77, 76.90, 77.40, 77.50, 77.75, 78.25, 78.80, 78.85, 79.65, 80.50, 80.71, 80.91, 80.95, 81.87, 82.00, 82.05, 82.25, 82.29, 82.80, 83.00, 83.11, 83.50, 83.75, 84.39, 84.65, 84.80, 85.00, 85.05, 85.46, 85.48, 86.00, 86.40, 86.49 }; int main() { const size_t N = sizeof( data ) / sizeof( double ); const size_t num_bins = 20; histogram::bin_vec binz( num_bins ); histogram histo; histo.calculate( data, N, binz ); for (size_t i = 0; i < num_bins; i++) { printf("%7.4f %2d\n", binz.start(i), binz[i] ); } return 0; } histo/src/sort_test.cpp0100666000104000010010000000112607540004434016173 0ustar AdministratorsNone #include #include "dbl_sort.h" double data[] = { 32.0, 10.0, 20.0, 38.0, 37.0, 28.0, 38.0, 34.0, 18.0, 24.0, 18.0, 9.0, 23.0, 24.0, 28.0, 34.0 }; /** Print out a vector of doubles, one per line */ void pr_vec( const double *v, const size_t N ) { for (size_t i = 0; i < N; i++) { printf("%7.4f\n", v[i] ); } } int main() { const size_t N = sizeof( data ) / sizeof( double ); dbl_sort s; printf("Before:\n"); pr_vec( data, N ); s.sort( data, N ); printf("After:\n"); pr_vec( data, N ); return 0; } histo/src/wavehist.cpp0100666000104000010010000000655007543236263016017 0ustar AdministratorsNone #include #include #include "haar.h" #include "line.h" #include "daub.h" #include "yahooTS.h" #include "dbl_sort.h" #include "histogram.h" #include "wavethresh.h" /** \file Test wavelet histogramming The documentation in this file is formatted for doxygen (see www.doxygen.org).

Copyright and Use

You may use this source code without limitation and without fee as long as you include:
This software was written and is copyrighted by Ian Kaplan, Bear Products International, www.bearcave.com, 2002.
This software is provided "as is", without any warranty or claim as to its usefulness. Anyone who uses this source code uses it at their own risk. Nor is any support provided by Ian Kaplan and Bear Products International. Please send any bug fixes or suggested source changes to:
     iank@bearcave.com
@author Ian Kaplan */ /** Print out a vector of doubles, one per line */ void pr_vec( const double *v, const size_t N ) { for (size_t i = 0; i < N; i++) { // printf("%7.4f, %3d\n", v[i], i ); printf("%7.6f\n", v[i] ); } } /** Get a 1-day return time series calculated from a stock price (for example, the open or close price). Here return is rett = (pt - pt-1) / pt Where p is the stock price and t is in trading days. This formula gives the fractional return on a daily basis. To calculate N return values, there must be N+1 stock price values. The function will return true if the return time series is calculated without problem, false otherwise. */ bool get1DayRetTimeSeries(const char *ticker, double *ret, const size_t N ) { bool rslt = true; yahooTS ts( "..\\data\\equities\\" ); size_t n = N+1; double *price = new double[ N+1 ]; // fetch N+1 close price values ts.getTS( ticker, price, n, yahooTS::Close ); if (n == N+1) { for (size_t i = 1; i < N+1; i++) { ret[i-1] = (price[i] - price[i-1])/price[i-1]; } } else { rslt = false; } delete [] price; return rslt; } // get1DayRetTimeSeries /** Return the absolute value of "val" */ double abs( const double val ) { double new_val = val; if (val < 0) new_val = -val; return val; } // abs int main() { const size_t N = 512; double ret[ N ]; if (get1DayRetTimeSeries( "ibm", ret, N )) { const size_t num_binz = N; histogram::bin_vec binz( num_binz ); histogram histo; size_t i; histo.calculate( ret, N, binz ); // Normalized haar wavelet // haar w; // Daubechies D4 wavelet // Daubechies w; // Unnormalized Linear interpolation wavelet line w; w.forwardTrans( binz, N ); const size_t start = 16; const size_t size = N - start; wavethresh::thresh( binz, start, size ); w.inverseTrans( binz, N ); // convert frequency to probability for (i = 0; i < num_binz; i++) { binz[i] = binz[i] / static_cast( N ); } for (i = 0; i < num_binz; i++) { printf("%7.4f %7.4f\n", binz.start(i), binz[i] ); } } return 0; } rand/0040700000076400010010000000000007605704307012276 5ustar AdministratorNonerand/include/0040700000076400010010000000000007605704147013723 5ustar AdministratorNonerand/include/rand_base.h0100600000076400010010000000457207605703772016024 0ustar AdministratorNone #ifndef RAND_BASE_H #define RAND_BASE_H // // GNU Scientific Library includes // #include "gsl/gsl_rng.h" /** A base class for GNU Scientific Library (GSL) random number functions. The setup, initialization and clean-up is the same for all GSL random number functions. This class abstracts away these details, placing the stup and initialization in the class constructor and the clean-up in the class destructor. The class constructor is passed a seed value for the random number generator. A class that provides access to one or more GSL random number functions should be derived from this class. This class must provide an implementation for the nextRandVal() pure virtual function. The nextRandVal will call the specific random number function (for example gsl_ran_ugaussian() for Gaussian distribution or gsl_ran_flat() for a flat random number distribution). This class uses the default random number generator. At least on Windows XP using the Visual C++ 6.0 compiler the type definitions for the random functions (for example gsl_rng_mt19937 or gsl_rng_knuthran) would not link properly. Perhaps they are not properly exported from the pre-built library. I decided to use the GSL because is is supported on all major platforms (UNIX, Linux and Windows) and provides high quality pseudo-random number generation support. The standard POSIX rand() function is notorious for its poor quality. While the random() function on UNIX provides better pseudo-random number quality, but is still not as good as functions like MT19937. */ class rand_base { private: gsl_rng *rStatePtr_; private: rand_base( const rand_base &rhs ); protected: gsl_rng *state() { return rStatePtr_; } public: rand_base( int seedVal ) { const gsl_rng_type *T; // The gsl_rng_env_setup() function returns a pointer to the // type gsl_rng_mt19937, which is associated with the MT19937 // random number generator. T = gsl_rng_env_setup(); // Allocate a random number state structure rStatePtr_ = gsl_rng_alloc( T ); // set the seed gsl_rng_set( rStatePtr_, 127 ); } // rand_base constructor ~rand_base() { gsl_rng_free( rStatePtr_ ); } // rand_base destructor virtual double nextRandVal() = 0; }; // rand_base #endif rand/include/rand_flat.h0100600000076400010010000000142307605703772016030 0ustar AdministratorNone #ifndef RAND_FLAT_H #define RAND_FALT_H #include "rand_base.h" #include "gsl/gsl_randist.h" /** Random numbers in a flat, or uniform distribution The class constructor is given a seed and a lower and upper bound value for the uniform distribution. The random numbers that result will be a uniform distribution in the range
    lower <= randVal < upper
*/ class rand_flat : public rand_base { private: double lower_, upper_; public: rand_flat( int seedVal, double lower, double upper ) : rand_base( seedVal ), lower_(lower), upper_(upper) {} double nextRandVal() { return gsl_ran_flat( state(), lower_, upper_ ); } }; // rand_gauss #endif rand/include/rand_gauss.h0100600000076400010010000000070207605703772016223 0ustar AdministratorNone #ifndef RAND_GAUSS_H #define RAND_GAUSS_H #include "rand_base.h" #include "gsl/gsl_randist.h" /** Random numbers in a Gaussian distribution The class constructor is passed a seed value for the random number generator. */ class rand_gauss : public rand_base { public: rand_gauss( int seedVal ) : rand_base( seedVal ) {} double nextRandVal() { return gsl_ran_ugaussian( state() ); } }; // rand_gauss #endif rand/Makefile0100600000076400010010000000227707605704263013746 0ustar AdministratorNone # # Micro$oft NMAKE make file # # Build a simple random number generator test, which calculates # an array of random numbers and calculates a histogram from # this data. # # Random numbers are generated using the GNU Scientific Libreary (GSL). # This requires GSL includes and a link to the GSL library. # DEBUG = -Zi BROWSE = CFLAGS = $(BROWSE) $(DEBUG) -DWIN32 -Tp OBJ = obj EXE = .exe DOXYPATH = e:\doxygen\bin SYSINC = "c:\Program Files\Microsoft Visual Studio\VC98\Include" GSLINC = "c:\Program Files\GSL\include" INCLUDE = -I"include" -I"..\histo\include" -I$(GSLINC) -I$(SYSINC) GSLLIB = "c:\Program Files\GSL\lib\libgsl.lib" ALL: tests RANDOBJ = rantest.$(OBJ) histogram.$(OBJ) tests: rantest$(EXE) clean: rm -f *.obj *.pdb *.sbr *.ilk *.exe rm -f include/*~ rm -f src/*~ doxygen: $(DOXYPATH)\doxygen doxygenDocConfig rantest$(EXE): $(RANDOBJ) $(CC) $(RANDOBJ) $(GSLLIB) $(DEBUG) -GX -o $*$(EXE) rantest.$(OBJ): $*.cpp include\rand_gauss.h include\rand_base.h $(CC) -c $(INCLUDE) $(CFLAGS) $*.cpp histogram.$(OBJ): ..\histo\src\$*.cpp ..\histo\include\$*.h $(CC) -c $(INCLUDE) $(CFLAGS) ..\histo\src\$*.cpp rand/rantest.cpp0100600000076400010010000000160507605703772014470 0ustar AdministratorNone #include // Gaussian distribution #include "rand_gauss.h" // Flat, or uniform, distribution #include "rand_flat.h" // Histogram class #include "histogram.h" void plotHistogram( rand_base &randObj, const size_t N ) { double *randData = new double[ N ]; size_t i; for (i = 0; i < N; i++) { randData[i] = randObj.nextRandVal(); } const size_t numBins = 64; histogram::bin_vec binz( numBins ); histogram histo; histo.calculate( randData, N, binz ); for (i = 0; i < numBins; i++) { size_t freq = static_cast( binz[i] ); printf("%7.4f %4d\n", binz.start(i), freq ); } delete [] randData; } // plotHistogram main() { const size_t N = 100000; rand_gauss randGauss( 127 ); // plotHistogram( randGauss, N ); rand_flat randFlat( 127, -5.5, 4.5 ); plotHistogram( randFlat, N ); return 0; }