NMath User's Guide

TOC |  Previous |  Next |  Index

9.2 Vectorized Random Number Generators (.NET, C#, CSharp, Visual Basic, VB.NET)

Unlike scalar-type generators, whose output is a successive random number (Section 9.1), vectorized generators produce a vector of n successive random numbers from a given distribution. Vectorized generators typically outperform scalar generators because the overhead expense of a function call is comparable to the total time required for computation.

NMath provides vectorized distribution classes for many continuous (Table 6) and discrete (Table 7) distributions.

Table 6 - Continuous Distributions
Class
Description
Beta distribution.
Cauchy distribution.
Exponential distribution
Gamma distribution.
Gaussian distribution.
Gumbel distribution.
Laplace distribution.
Log-normal distribution.
Rayleigh distribution.
Uniform distribution.
Weibull distribution.

Table 7 - Discrete Distributions
Class
Description
Bernoulli distribution.
Binomial distribution.
Geometric Distribution
Hypergeometric distribution.
Negative Binomial distribution.
Poisson distribution.
Possion distribution with varying mean.
Uniform distribution.
Integer values with uniform bit distribution.

Distribution objects are constructed from the relevant distribution parameters. For example:

double mean = 1.0;
double sigma = 1.0;
DoubleRandomGaussianDistribution dist =
    new DoubleRandomGaussianDistribution(mean, sigma);

Generating Random Numbers

Class RandomNumberStream encapsulates a vectorized random number generator which yields a stream of random numbers.

A stream is constructed from an optional seed, and an optional enumerated value specifying which algorithm to use for generating random numbers uniformly distributed in the interval [0, 1].

int seed = 0x345;
RandomNumberStream stream =
    new RandomNumberStream(seed, 
        RandomNumberStream.BasicRandGenType.MersenneTwister);

You can use a stream and distribution to fill an array:

int n = 100;
int start = 0;
double[] a = new double[n];
dist.Fill(stream, a, start, n);

Or to fill a new vector or matrix:

DoubleVector v = new DoubleVector(n, stream, dist);

Successive Random Numbers

If you want the performance of a vectorized random number generator, but still need to access the random deviates sequentially, NMath provides class RandomNumbers, which uses a stream to buffer the random numbers internally.

For instance:

int bufferSize = 100;
RandomNumbers<double, DoubleRandomGaussianDistribution> rnd =
  new RandomNumbers<double, DoubleRandomGaussianDistribution>(seed, 
    dist, bufferSize);

for (int i = 0; i < 10; i++)
{
  Console.WriteLine("Next() = {0}", (double)rnd.Next());
}

Independent Streams

NMath provides classes for generating several independent streams of random numbers using two methods:

For example, this code creates 10 streams of length 100 using the skip-ahead method:

int seed = 0x124;
RandomNumberStream.BasicRandGenType genType = 
    RandomNumberStream.BasicRandGenType.MultiplicativeCongruent31;
int nstreams = 10;
int streamLen = 100;
SkipAheadRandomStreams gen =
    new SkipAheadRandomStreams(seed, genType, nstreams, streamLen);

You can use a single distribution to fill an array or matrix:

DoubleRandomUniformDistribution dist =
    new DoubleRandomUniformDistribution();
DoubleMatrix A = new DoubleMatrix(streamLen, nstreams);
gen.Fill(dist, A);

Or to create a new matrix:

DoubleRandomLogNormalDistribution dist =
    new DoubleRandomLogNormalDistribution();
DoubleMatrix B = gen.Next(dist);

You can also use an array of distributions, one per stream:

nstreams = 3;
IRandomNumberDistribution<double>[] intDists =
    new IRandomNumberDistribution<double>[nstreams];
intDists[0] = new DoubleRandomUniformDistribution();
intDists[1] = new DoubleRandomBetaDistribution();
intDists[2] = new DoubleRandomCauchyDistribution();
gen =
    new SkipAheadRandomStreams(seed, genType, nstreams, streamLen);
DoubleMatrix C = gen.Next(intDists);

Quasirandom Numbers

NMath provides classes for generating sequences of quasirandom points. A quasirandom sequence is a sequence of n-tuples that fills n-space more uniformly than uncorrelated random points. NiederreiterQuasiRandomGenerator generates quasirandom numbers using the Niederreiter method; SobolQuasiRandomGenerator uses the Sobal method.

For example:

int dim = 3;
NiederreiterQuasiRandomGenerator nqrg =
    new NiederreiterQuasiRandomGenerator(dim);

You can fill an existing matrix or array. (The points are the columns of the matrix, so the number of rows in the given matrix must be equal to the Dimension of the quasirandom number generator.)

int numPts = 5000;
DoubleMatrix A = new DoubleMatrix(nqrg.Dimension, numPts);
nqrg.Fill(A);

Or create a new matrix:

DoubleMatrix B = 
    nqrg.Next(new DoubleRandomUniformDistribution(), numPts);

The quasirandom numbers will follow the given distribution.

TOC |  Previous |  Next |  Index