Random Class Reference

## Public Member Functions

| Random (long s=0x7654321)
int | Binary ()
double | Next ()
unsigned long | NextInt ()
double | Normal ()
void | Reset (long s)
void | InitMersenne (unsigned long s)
| operator double ()
double | Uniform (double lo=0.0, double hi=1.0)
void | Choose (int *array, int n, int k)
void | Choose (int *array, float *weights, int n, int k)

## Protected Attributes

long | seed
long | last
long * | shuffler
int | normSaved
double | normStore
double | mersenneMult
unsigned long * | mt
int | mti

## Detailed Description

Definition at line 69 of file Random.h.

## Constructor & Destructor Documentation

## Random()

Random::Random | ( | long | s = `0x7654321` | ) |

Definition at line 89 of file Random.cpp.

{
#ifndef __NO_MERSENNE
mt = new unsigned long [MERSENNE_N];
mti = MERSENNE_N + 1;
mersenneMult = 1.0/4294967296.0;
#else
shuffler = new long [NTAB];
#endif
Reset(s);
}

## ~Random()

Random::~Random | ( |  | ) |

Definition at line 101 of file Random.cpp.

{
#ifndef __NO_MERSENNE
delete [] mt;
#else
delete [] shuffler;
#endif
}

## Member Function Documentation

## Binary()

int Random::Binary | ( |  | ) |

Definition at line 148 of file Random.cpp.

{
return Next() > 0.5 ? 1 : 0;
}

## Choose() [1/2]

void Random::Choose | ( | int * | array,
|  | float * | weights,
|  | int | n,
|  | int | k
| ) |  |

Definition at line 341 of file Random.cpp.

{
int choices = 1, others = 0;
if (k > n / 2)
{
choices = 0;
others = 1;
k = n - k;
}
// First calculate cumulative sums of weights ...
float * cumulative = new float [n + 1];
cumulative[0] = 0;
for (int i = 1; i <= n; i++)
cumulative[i] = cumulative[i - 1] + weights[i - 1];
float & sum = cumulative[n], reject = 0.0;
for (int i = 0; i < n; i++)
array[i] = others;
while (k > 0)
{
float weight = Next() * sum;
int hi = n, lo = 0, i = 0;
while (hi >= lo)
{
i = (hi + lo) / 2;
if (cumulative[i + 1] <= weight)
lo = i + 1;
else if (cumulative[i] >= weight)
hi = i - 1;
else break;
}
if (array[i] == choices) continue;
array[i] = choices;
reject += weights[i];
// After selecting a substantial number of elements, update the cumulative
// distribution -- to ensure that at least half of our samples produce a hit
if (reject > sum * 0.50)
{
cumulative[0] = 0;
for (int i = 1; i <= n; i++)
if (array[i] != choices)
cumulative[i] = cumulative[i - 1] + weights[i - 1];
else
cumulative[i] = cumulative[i - 1];
reject = 0.0;
sum = cumulative[n];
}
k--;
}
delete [] cumulative;
}

## Choose() [2/2]

void Random::Choose | ( | int * | array,
|  | int | n,
|  | int | k
| ) |  |

Definition at line 316 of file Random.cpp.

{
int choices = 1, others = 0;
if (k > n / 2)
{
choices = 0;
others = 1;
k = n - k;
}
for (int i = 0; i < n; i++)
array[i] = others;
while (k > 0)
{
int i = NextInt() % n;
if (array[i] == choices) continue;
array[i] = choices;
k--;
}
}

## InitMersenne()

void Random::InitMersenne | ( | unsigned long | s | ) |

Definition at line 133 of file Random.cpp.

{
mt[0]= s & 0xffffffffUL;
for (mti = 1; mti < MERSENNE_N; mti++)
{
mt[mti] = (1812433253UL * (mt[mti-1] ^(mt[mti-1] >> 30)) + mti);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array mt[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
mt[mti] &= 0xffffffffUL;
}
}

## Next()

double Random::Next | ( |  | ) |

Definition at line 155 of file Random.cpp.

{
unsigned long y;
// mag01[x] = x * MATRIX_A for x=0,1
static unsigned long mag01[2]={0x0UL, MATRIX_A};
if (mti >= MERSENNE_N)
{
/* generate MERSENNE_N words at one time */
int kk;
// If InitMersenne() has not been called, a default initial seed is used
if (mti == MERSENNE_N+1)
InitMersenne(5489UL);
for (kk=0; kk < MERSENNE_N-MERSENNE_M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+MERSENNE_M] ^(y >> 1) ^ mag01[y & 0x1UL];
}
for (; kk < MERSENNE_N-1; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+(MERSENNE_M - MERSENNE_N)] ^(y >> 1) ^ mag01[y & 0x1UL];
}
y = (mt[MERSENNE_N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[MERSENNE_N-1] = mt[MERSENNE_M-1] ^(y >> 1) ^ mag01[y & 0x1UL];
mti = 0;
}
y = mt[mti++];
// Tempering
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (mersenneMult *((double) y + 0.5));
}

## NextInt()

unsigned long Random::NextInt | ( |  | ) |

Definition at line 202 of file Random.cpp.

{
unsigned long y;
// mag01[x] = x * MATRIX_A for x=0,1
static unsigned long mag01[2]={0x0UL, MATRIX_A};
if (mti >= MERSENNE_N)
{
/* generate MERSENNE_N words at one time */
int kk;
// If InitMersenne() has not been called, a default initial seed is used
if (mti == MERSENNE_N + 1)
InitMersenne(5489UL);
for (kk= 0; kk < MERSENNE_N - MERSENNE_M; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+MERSENNE_M] ^(y >> 1) ^ mag01[y & 0x1UL];
}
for (; kk< MERSENNE_N-1; kk++)
{
y = (mt[kk] & UPPER_MASK) | (mt[kk+1] & LOWER_MASK);
mt[kk] = mt[kk+(MERSENNE_M - MERSENNE_N)] ^(y >> 1) ^ mag01[y & 0x1UL];
}
y = (mt[MERSENNE_N-1] & UPPER_MASK) | (mt[0] & LOWER_MASK);
mt[MERSENNE_N-1] = mt[MERSENNE_M-1] ^(y >> 1) ^ mag01[y & 0x1UL];
mti = 0;
}
y = mt[mti++];
// Tempering
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}

## Normal()

double Random::Normal | ( |  | ) |

Definition at line 290 of file Random.cpp.

{
double v1, v2, fac, rsq;
if (!normSaved) // Do we need new numbers?
{
do
{
v1 = 2.0 * Next() - 1.0; // Pick two coordinates from
v2 = 2.0 * Next() - 1.0; // -1 to +1 and check if they
rsq = v1*v1 + v2*v2; // are in unit circle...
}
while (rsq >= 1.0 || rsq == 0.0);
fac = sqrt(-2.0 * log(rsq)/rsq); // Apply the Box-Muller
normStore = v1 * fac; // transformation and save
normSaved = 1; // one deviate for next time
return v2 * fac;
}
else
{
normSaved = 0;
return normStore;
}
}

## operator double()

Random::operator double | ( |  | ) |

inline

Definition at line 114 of file Random.h.

{
return Next();
}

## Reset()

void Random::Reset | ( | long | s | ) |

Definition at line 110 of file Random.cpp.

{
normSaved = 0;
#ifndef __NO_MERSENNE
InitMersenne(s);
#else
// 'Continuous' Random Generator
if ((seed = s) < 1)
seed = s == 0 ? 1 : -s; // seed == 0 would be disastrous
for (int j=NTAB+7; j>=0; j--) // Warm up and set shuffle table
{
long k = seed / IQ;
seed = IA * (seed - k * IQ) - IR * k;
if (seed < 0) seed += IM;
if (j < NTAB) shuffler[j] = seed;
}
last=shuffler[0];
#endif
}

## Uniform()

double Random::Uniform | ( | double | lo = `0.0`,
|  | double | hi = `1.0`
| ) |  |

inline

Definition at line 120 of file Random.h.

{
return lo + (hi - lo) * Next();
}

## Member Data Documentation

## last

long Random::last

protected

Definition at line 77 of file Random.h.

## mersenneMult

double Random::mersenneMult

protected

Definition at line 84 of file Random.h.

## mt

unsigned long* Random::mt

protected

Definition at line 87 of file Random.h.

## mti

int Random::mti

protected

Definition at line 90 of file Random.h.

## normSaved

int Random::normSaved

protected

Definition at line 81 of file Random.h.

## normStore

double Random::normStore

protected

Definition at line 82 of file Random.h.

## seed

long Random::seed

protected

Definition at line 76 of file Random.h.

## shuffler

long* Random::shuffler

protected

Definition at line 78 of file Random.h.

The documentation for this class was generated from the following files:

- general/Random.h
- general/Random.cpp