/*************************************************************************** * Rand.h (Random Number Generators) * * * * Header file for Rand.C, pseudo-random number utilities. Rand is the * * base class for several different algorithms for generating pseudo-random * * numbers. Any method can generate individual samples or arrays of * * samples using "Eval". The random seed can be reset at any time by * * calling "Seed" with any integer. Random permutations of the integers * * 0,1,...(n-1) are generated by "Perm(n,P)". * * * * HISTORY * * Name Date Description * * * * arvo 08/04/97 Changed to virtual functions. * * arvo 06/06/93 Optimization, especially for array evaluators. * * arvo 10/06/91 Converted to C++ * * arvo 11/20/89 Added "gen_seed" function to handle. * * arvo 10/30/89 "state" allocation now done in rand_alloc. * * arvo 07/08/89 Initial coding. * * * *--------------------------------------------------------------------------* * Copyright (C) 1989, James Arvo * * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation. See http://www.fsf.org/copyleft/gpl.html * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT EXPRESS OR IMPLIED WARRANTY of merchantability or fitness for * * any particular purpose. See the GNU General Public License for more * * details. * * * ***************************************************************************/ #ifndef __RAND_INCLUDED__ #define __RAND_INCLUDED__ // Base class for random number generators. This class contains // several pure virtual functions, so it cannot be instanced directly. class RandGen { public: RandGen() {} virtual float Eval( ) = 0; virtual void Eval( int n, float x[] ) = 0; virtual void Seed( long seed ) = 0; public: void Perm( int n, int P[] ); float Interval( float a, float b ); void Eval( float &x ) { x = Eval(); } }; // Method 1: From "Numerical Recipes," by William H. Press, Brian P. // Flannery, Saul A. Teukolsky, and William T. Vetterling, p. 197. class RandGen_1 : public RandGen { public: RandGen_1( ) { Seed( 1 ); } RandGen_1( long seed ) { Seed( seed ); } virtual float Eval( ); virtual void Eval( int n, float x[] ); virtual void Seed( long seed ); private: long index; long seed; long shuffle[ 98 ]; }; // Method 2: From "The Multiple Prime Random Number Generator," by // Alexander Haas, ACM Transactions on Mathematical Software, // Vol. 13, No. 4, December 1987, pp. 368-381. * class RandGen_2 : public RandGen { public: RandGen_2( ) { Seed( 1 ); } RandGen_2( long seed ) { Seed( seed ); } virtual float Eval( ); virtual void Eval( int n, float x[] ); virtual void Seed( long seed ); private: long r; long m; long i; long j; }; // Method 3: From "A More Portable Fortran Random Number Generator," // by Linus Schrage, ACM Transactions on Mathematical Software, // Vol. 5, No, 2, June 1979, pp. 132-138. * class RandGen_3 : public RandGen { public: RandGen_3( ) { Seed( 1 ); } RandGen_3( long seed ) { Seed( seed ); } virtual float Eval( ); virtual void Eval( int n, float x[] ); virtual void Seed( long seed ); private: long ix; }; inline float RandGen::Interval( float a, float b ) { return ( a < b ) ? a + Eval() * ( b - a ) : b + Eval() * ( a - b ) ; } #endif