Random generator for intensive random computations. More...
#include <Random.h>
Public Member Functions | |
double | normal (double mean, double stddev) |
double | normal (GaussDistribution &gd) |
double | ran2 () |
Random (int seed=0) | |
Random (const QByteArray &s) | |
QByteArray | state () const |
void | testDistribution (double max, qint64 nReset) |
void | testPeriod () |
int | uniform (int min, int max) |
double | uniform (double min, double max) |
Random generator for intensive random computations.
QGpCoreTools::Random::Random | ( | int | seed = 0 | ) |
Initialize random generator with seed. If seed is null, a random number is calculated from current time.
References IA1, IM1, IQ1, IR1, RANDOM_NTAB, and TRACE.
{ TRACE; if(seed==0) _idum=time(NULL)%9999999; else if(seed<0) _idum=-seed; else _idum=seed; // Initialize ran2 generation _idum2=_idum; long k; int j; for(j=RANDOM_NTAB+7;j>=0;j--) { // Load the shuffle table (after 8 warm-ups). k=_idum/IQ1; _idum=IA1*(_idum-k*IQ1)-k*IR1; if(_idum < 0) _idum += IM1; if(j < RANDOM_NTAB) _iv[j]=_idum; } _iy=_iv[0]; //_nCalls=0; }
QGpCoreTools::Random::Random | ( | const QByteArray & | s | ) |
Create a random generator from an old random generator state saved in s.
s size must be 35 integers.
References RANDOM_NTAB, RANDOM_STATE_SIZE, and TRACE.
{ TRACE; ASSERT(s.size()==RANDOM_STATE_SIZE); const qint64 * sPtr=reinterpret_cast<const qint64 *>(s.data()); _idum=sPtr[0]; _idum2=sPtr[1]; _iy=sPtr[2]; for(int i=0; i<RANDOM_NTAB; i++) { _iv[i]=sPtr[i+3]; } }
double QGpCoreTools::Random::normal | ( | double | mean, |
double | stddev | ||
) |
Returns a normal (gauss distribution) deviates with mean and stddev
{ TRACE; // Construct a normal variable from uniform deviates // Based on Central Limit theorem. // n=100 values are stacks and variable defined by // mean+stddev*sqrt(12/n)*(sum(1...n)[yi]-n/2) // a-has a normal distribution. double sum=0; for(int i=0;i<100;i++) sum+=ran2(); return mean+stddev*0.346410161514*(sum-50.0); }
double QGpCoreTools::Random::normal | ( | GaussDistribution & | gd | ) | [inline] |
References QGpCoreTools::GaussDistribution::mean(), normal(), and QGpCoreTools::GaussDistribution::stddev().
Referenced by normal().
{return normal(gd.mean(),gd.stddev());}
double QGpCoreTools::Random::ran2 | ( | ) |
Inspired from Numerical recipes in C
Long period (> 2e18) random number generator of L'Ecuyer with Bays-Durham shuffle and added safeguards. Returns a uniform random deviate between 0.0 and 1.0 (exclusive of the endpoint values). Call with idum a negative integer to initialize; thereafter, do not alter idum between successive deviates in a sequence. RNMX should approximate the largest floating value that is less than 1.
Implemented and adapted by Marc Wathelet (oct 2002) to generates double floating point values between 0.0 and 1.0 exclusive.
References AM, IA1, IA2, IM1, IM2, IMM1, IQ1, IQ2, IR1, IR2, NDIV, RNMX, and TRACE.
Referenced by normal(), testDistribution(), testPeriod(), DinverCore::UniqueRandom::uniform(), and uniform().
{ TRACE; //_nCalls++; int j; long k; double temp; k=(_idum)/IQ1; // Start here when not initializing. _idum=IA1*(_idum-k*IQ1)-k*IR1; // Compute idum=(IA1*idum) % IM1 if(_idum<0) _idum+=IM1; // without over ows by Schrage s method. k=_idum2/IQ2; _idum2=IA2*(_idum2-k*IQ2)-k*IR2; // Compute idum2=(IA2*idum) % IM2 likewise. if(_idum2<0) _idum2+=IM2; j=_iy/NDIV; // Will be in the range 0..RANDOM_NTAB-1. _iy=_iv[j]-_idum2; // Here idum is shuffled, idum and idum2 _iv[j]=_idum; // are combined to generate output. if(_iy<1) _iy+=IMM1; // Because users don't expect endpoint values. if((temp=AM*_iy)>RNMX) return RNMX; else return temp; }
QByteArray QGpCoreTools::Random::state | ( | ) | const |
Returns internal state into a newly allocated buffer.
References RANDOM_NTAB, RANDOM_STATE_SIZE, and TRACE.
Referenced by main().
{ TRACE; QByteArray s; s.resize(RANDOM_STATE_SIZE); qint64 * sPtr=reinterpret_cast<qint64 *>(s.data()); sPtr[0]=_idum; sPtr[1]=_idum2; sPtr[2]=_iy; for(int i=0; i<RANDOM_NTAB; i++) { sPtr[i+3]=_iv[i]; } return s; }
void QGpCoreTools::Random::testDistribution | ( | double | max, |
qint64 | nReset0 | ||
) |
Checks that distribution is uniform. Values are randomly generated between 0 and 1. An histogram is computed for values between 0 and max (<=1). It is reset to 0 after generating nReset0 random values. This latter argument lets you check the random generator at various "ages".
References N_CLASSES, ran2(), and TRACE.
Referenced by main().
{ TRACE; #define N_CLASSES 16 QVector<qint64> histogram(N_CLASSES); for(int i=0;i<N_CLASSES;i++) { histogram[i]=0; } qint64 nPrint=16, nReset=nReset0, nPrint0=0; double factor=N_CLASSES/max; qint64 i=0; while(true) { double v=ran2(); int ci=(int)floor(v*factor); if(ci<N_CLASSES) histogram[ci]++; i++; if(i==nPrint0+nPrint) { qint64 sum=0; for(int j=0;j<N_CLASSES;j++) { sum+=histogram[j]; } double f=1.0/((double)sum*max); printf("%15lli ",i); for(int j=0;j<N_CLASSES;j++) { printf("%9lf ", histogram[j]*f); } printf("\n"); nPrint*=2; } if(i==nReset) { nPrint=16; nPrint0=i; for(int j=0;j<N_CLASSES; j++) { histogram[j]=0; } nReset+=nReset0; } } }
void QGpCoreTools::Random::testPeriod | ( | ) |
Checks periodicity of random generator. Stores the first 50 values and wait for a matching pattern.
References QGpCoreTools::endl(), ran2(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.
Referenced by main().
{ TRACE; QVector<double> series; for(int i=0;i<50;i++) { series.append(ran2()); } int p=0; qint64 i=0; while(true) { i++; if(ran2()==series[p]) { p++; App::stream() << tr("Repeating sequence on %1 samples after %2 generations").arg(p).arg(i) << endl; if(p==50) break; } else { p=0; } } }
int QGpCoreTools::Random::uniform | ( | int | min, |
int | max | ||
) | [inline] |
Returns a uniform integer deviate between min and max inclusive.
Reimplemented in DinverCore::UniqueRandom.
References ran2().
Referenced by DinverCore::AbstractForward::firstModel(), main(), QGpCoreTools::DoubleMatrix::random(), and DinverCore::ModelRepository::start().
{ return min+(int)round((max-min)*ran2()); }
double QGpCoreTools::Random::uniform | ( | double | min, |
double | max | ||
) | [inline] |
Returns a uniform deviate between min and max exclusive.
Reimplemented in DinverCore::UniqueRandom.
References ran2().
{ return min+(max-min)*ran2(); }