/******************************************************************* * File: Uniform.cpp * Description: * Author: Subhasis Ray * E-mail: ray.subhasis@gmail.com * Created: 2008-02-21 17:12:55 ********************************************************************/ /********************************************************************** ** This program is part of 'MOOSE', the ** Messaging Object Oriented Simulation Environment, ** also known as GENESIS 3 base code. ** copyright (C) 2003-2005 Upinder S. Bhalla. and NCBS ** It is made available under the terms of the ** GNU General Public License version 2 ** See the file COPYING.LIB for the full notice. **********************************************************************/ #ifndef _UNIFORM_CPP #define _UNIFORM_CPP #include <cassert> #include <iostream> #include <vector> #include "Uniform.h" #include "randnum.h" #include "utility/numutil.h" using namespace std; Uniform::Uniform() { min_ = 0.0; max_ = 1.0; } Uniform::Uniform(double min, double max) { if ( min >= max ) { cerr << "ERROR: specified lowerbound is greater than upper bound." << endl; min_ = 0.0; max_ = 1.0; return; } min_ = min; max_ = max; } double Uniform::getMean() const { return (max_ + min_) / 2.0; } double Uniform::getVariance()const { return (max_- min_) * (max_ - min_)/12.0; } double Uniform::getMin() const { return min_; } double Uniform::getMax() const { return max_; } void Uniform::setMin(double min) { min_ = min; } void Uniform::setMax(double max) { max_ = max; } double Uniform::getNextSample() const { assert( max_ > min_ ); return mtrand()*(max_-min_)+min_; } #ifdef DO_UNIT_TESTS void doTest(double min, double max, unsigned count) { Uniform rng; rng.setMin(min); rng.setMax(max); assert(isClose<double>(min, rng.getMin(), DBL_EPSILON)); assert(isClose<double>(max, rng.getMax(), DBL_EPSILON)); vector <double> seq; double mean = 0.0; for (unsigned ii = 0; ii < count; ++ii ) { double sample; sample = rng.getNextSample(); mean += sample; seq.push_back(sample); } mean /= count; double var = 0.0; for(unsigned ii = 0; ii <seq.size(); ++ii) { var += (mean - seq[ii]) * (mean - seq[ii]); } var = var / count; cout << "theoretical mean: " << rng.getMean() << ", sample mean: " << mean << ", theoretical var: " << rng.getVariance() << ", sample var: " << var << ", sample size: " << count << endl; } void testUniform() { cout << "testUniform(): testing uniform rng.\n"; doTest(-10.0, 10.0, 1000); doTest(1e-10, 1.1e-10, 1000); } #endif // DO_UNIT_TESTS #if defined( TEST_MAIN ) && defined(DO_UNIT_TESTS) int main(void) { testUniform(); } #endif // !defined( TEST_MAIN ) && defined(DO_UNIT_TESTS) #endif