Random Number Generators and related classes
The two classes `RNG' and `Random' are used together to generate a
variety of random number distributions. A distinction must be made
between *random number generators*, implemented by class `RNG', and
*random number distributions*. A random number generator produces a
series of randomly ordered bits. These bits can be used directly, or
cast to other representations, such as a floating point value. A
random number generator should produce a *uniform* distribution. A
random number distribution, on the other hand, uses the randomly
generated bits of a generator to produce numbers from a distribution
with specific properties. Each instance of `Random' uses an instance
of class `RNG' to provide the raw, uniform distribution used to produce
the specific distribution. Several instances of `Random' classes can
share the same instance of `RNG', or each instance can use its own copy.
Random distributions are constructed from members of class `RNG',
the actual random number generators. The `RNG' class contains no data;
it only serves to define the interface to random number generators.
The `RNG::asLong' member returns an unsigned long (typically 32 bits)
of random bits. Applications that require a number of random bits can
use this directly. More often, these random bits are transformed to a
uniform random number:
// Return random bits converted to either a float or a double
using either `asFloat' or `asDouble'. It is intended that `asFloat'
and `asDouble' return differing precisions; typically, `asDouble' will
draw two random longwords and transform them into a legal `double',
while `asFloat' will draw a single longword and transform it into a
legal `float'. These members are used by subclasses of the `Random'
class to implement a variety of random number distributions.
Class `ACG' is a variant of a Linear Congruential Generator
(Algorithm M) described in Knuth, *Art of Computer Programming, Vol
III*. This result is permuted with a Fibonacci Additive Congruential
Generator to get good independence between samples. This is a very high
quality random number generator, although it requires a fair amount of
memory for each instance of the generator.
The `ACG::ACG' constructor takes two parameters: the seed and the
size. The seed is any number to be used as an initial seed. The
performance of the generator depends on having a distribution of bits
through the seed. If you choose a number in the range of 0 to 31, a
seed with more bits is chosen. Other values are deterministically
modified to give a better distribution of bits. This provides a good
random number generator while still allowing a sequence to be repeated
given the same initial seed.
The `size' parameter determines the size of two tables used in the
generator. The first table is used in the Additive Generator; see the
algorithm in Knuth for more information. In general, this table is
`size' longwords long. The default value, used in the algorithm in
Knuth, gives a table of 220 bytes. The table size affects the period of
the generators; smaller values give shorter periods and larger tables
give longer periods. The smallest table size is 7 longwords, and the
longest is 98 longwords. The `size' parameter also determines the size
of the table used for the Linear Congruential Generator. This value is
chosen implicitly based on the size of the Additive Congruential
Generator table. It is two powers of two larger than the power of two
that is larger than `size'. For example, if `size' is 7, the ACG table
is 7 longwords and the LCG table is 128 longwords. Thus, the default
size (55) requires 55 + 256 longwords, or 1244 bytes. The largest table
requires 2440 bytes and the smallest table requires 100 bytes.
Applications that require a large number of generators or applications
that aren't so fussy about the quality of the generator may elect to
use the `MLCG' generator.
The `MLCG' class implements a *Multiplicative Linear Congruential
Generator*. In particular, it is an implementation of the double MLCG
described in *"Efficient and Portable Combined Random Number
Generators"* by Pierre L'Ecuyer, appearing in *Communications of the
ACM, Vol. 31. No. 6*. This generator has a fairly long period, and has
been statistically analyzed to show that it gives good inter-sample
The `MLCG::MLCG' constructor has two parameters, both of which are
seeds for the generator. As in the `MLCG' generator, both seeds are
modified to give a "better" distribution of seed digits. Thus, you can
safely use values such as `0' or `1' for the seeds. The `MLCG'
generator used much less state than the `ACG' generator; only two
longwords (8 bytes) are needed for each generator.
A random number generator may be declared by first declaring a `RNG'
and then a `Random'. For example, `ACG gen(10, 20); NegativeExpntl rnd
(1.0, &gen);' declares an additive congruential generator with seed 10
and table size 20, that is used to generate exponentially distributed
values with mean of 1.0.
The virtual member `Random::operator()' is the common way of
extracting a random number from a particular distribution. The base
class, `Random' does not implement `operator()'. This is performed by
each of the subclasses. Thus, given the above declaration of `rnd', new
random values may be obtained via, for example, `double next_exp_rand =
rnd();' Currently, the following subclasses are provided.
The binomial distribution models successfully drawing items from a
pool. The first parameter to the constructor, `n', is the number of
items in the pool, and the second parameter, `u', is the probability of
each item being successfully drawn. The member `asDouble' returns the
number of samples drawn from the pool. Although it is not checked, it
is assumed that `n>0' and `0 <= u <= 1'. The remaining members allow
you to read and set the parameters.
The `Erlang' class implements an Erlang distribution with mean
`mean' and variance `variance'.
The `Geometric' class implements a discrete geometric distribution.
The first parameter to the constructor, `mean', is the mean of the
distribution. Although it is not checked, it is assumed that `0 <=
mean <= 1'. `Geometric()' returns the number of uniform random samples
that were drawn before the sample was larger than `mean'. This
quantity is always greater than zero.
The `HyperGeometric' class implements the hypergeometric
distribution. The first parameter to the constructor, `mean', is the
mean and the second, `variance', is the variance. The remaining
members allow you to inspect and change the mean and variance.
The `NegativeExpntl' class implements the negative exponential
distribution. The first parameter to the constructor is the mean. The
remaining members allow you to inspect and change the mean.
The `Normal'class implements the normal distribution. The first
parameter to the constructor, `mean', is the mean and the second,
`variance', is the variance. The remaining members allow you to
inspect and change the mean and variance. The `LogNormal' class is a
subclass of `Normal'.
The `LogNormal'class implements the logarithmic normal distribution.
The first parameter to the constructor, `mean', is the mean and the
second, `variance', is the variance. The remaining members allow you
to inspect and change the mean and variance. The `LogNormal' class is
a subclass of `Normal'.
The `Poisson' class implements the poisson distribution. The first
parameter to the constructor is the mean. The remaining members allow
you to inspect and change the mean.
The `DiscreteUniform' class implements a uniform random variable over
the closed interval ranging from `[low..high]'. The first parameter to
the constructor is `low', and the second is `high', although the order
of these may be reversed. The remaining members allow you to inspect
and change `low' and `high'.
The `Uniform' class implements a uniform random variable over the
open interval ranging from `[low..high)'. The first parameter to the
constructor is `low', and the second is `high', although the order of
these may be reversed. The remaining members allow you to inspect and
change `low' and `high'.
The `Weibull' class implements a weibull distribution with
parameters `alpha' and `beta'. The first parameter to the class
constructor is `alpha', and the second parameter is `beta'. The
remaining members allow you to inspect and change `alpha' and `beta'.
The `RandomInteger' class is *not* a subclass of Random, but a
stand-alone integer-oriented class that is dependent on the RNG
classes. RandomInteger returns random integers uniformly from the
closed interval `[low..high]'. The first parameter to the constructor
is `low', and the second is `high', although both are optional. The
last argument is always a generator. Additional members allow you to
inspect and change `low' and `high'. Random integers are generated
using `asInt()' or `asLong()'. Operator syntax (`()') is also
available as a shorthand for `asLong()'. Because `RandomInteger' is
often used in simulations for which uniform random integers are desired
over a variety of ranges, `asLong()' and `asInt' have `high' as an
optional argument. Using this optional argument produces a single
value from the new range, but does not change the default range.
[ Dokumentation lokal installierter Software ]