nvidia-texture-tools/src/nvtt/bc7/arvo/Rand.h
2010-05-29 02:47:57 +00:00

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