115 lines
4.7 KiB
C++
115 lines
4.7 KiB
C++
/***************************************************************************
|
|
* 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__
|
|
|
|
namespace ArvoMath {
|
|
|
|
// 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
|