NMath User's Guide

TOC | Previous | Next | Index

9.1 Scalar Random Number Generators (.NET, C#, CSharp, VB, Visual Basic, F#)

NMath provides scalar generator classes that return random deviates from a variety of probability distributions.

Table 7 – Scalar Random Number Generators

Class

Description

RandGenUniform

Uniform distribution.

RandGenBeta

Beta distribution.

RandGenBinomial

Binomial distribution.

RandGenExponential

Exponential distribution.

RandGenGamma

Gamma distribution.

RandGenGeometric

Geometric distribution.

RandGenJohnson

Johnson distribution.

RandGenLogNormal

Log-normal distribution.

RandGenNormal

Normal distribution.

RandGenPareto

Pareto distribution.

RandGenPoisson

Poisson distribution.

RandGenTriangular

Triangular distribution.

RandGenWeibull

Weibull distribution.

Underlying Uniform Generators

All NMath scalar random number generators, regardless of the distribution, require an underlying uniform random number generator that returns random deviates in the range zero to one. Each generator first generates a random uniform deviate in the range zero to one, then from this deviate derives a random number from the appropriate probability distribution. Thus, the statistical properties and performance of the generators largely depend on the statistical properties and performance of the underlying random number generator.

By default, all scalar generators use the NMath class RandGenMTwist as the underlying uniform generator. RandGenMTwist implements the Mersenne Twister algorithm, developed by Makoto Matsumoto and Takuji Nishimura in 1996-1997. This algorithm is faster and more efficient, and has a far longer period and far higher order of equidistribution, than other existing generators.

If you have your own uniform random number generator that you wish to use, all NMath random number generators provide constructor overloads that accept a RandomNumberGenerator.UniformRandomNumber function delegate. The function must generate uniform deviates in the range zero to one, and return a double.

For example, this code creates a delegate object from the method System.Random.NextDouble(), then constructs a binomial random number generator that uses this delegate:

Code Example – C# random number generators

var sysRand = new Random();
var uniformDeviates = 
   new RandomNumberGenerator.UniformRandomNumber( 
       sysRand.NextDouble );

int trials = 2000;
double prob = .002;
var binRand =
   new RandGenBinomial( trials, prob, uniformDeviates );

Code Example – VB random number generators

Dim SysRand As New Random()
Dim UniformDeviates As New 
  RandomNumberGenerator.UniformRandomNumber(
    AddressOf SysRand.NextDouble)

Dim Trials As Integer = 2000
Dim Prob As Double = 0.002
Dim BinRand As New RandGenBinomial(Trials, Prob, UniformDeviates)

All generators inherit a UniformDeviateMethod property from RandNumberGenerator for accessing and modify the underlying delegate method. For example, this code changes the delegate used by binRand:

Code Example – C# random number generators

var mt = new RandGenMTwist( );
binRand.UniformDeviateMethod = 
   new RandomNumberGenerator.UniformRandomNumber( mt.NextDouble );

Code Example – VB random number generators

Dim MT As New RandGenMTwist()
BinRand.UniformDeviateMethod =
  New RandomNumberGenerator.UniformRandomNumber(AddressOf 
    MT.NextDouble)

Generating Random Numbers

All NMath generators provide a Next() method that returns a random deviate as a double, except for RandGenBinomial and RandGenPoisson that return an int. For example, this code prints out 100 random deviates from a normal distribution with mean of -12.9 and variance of 2.066:

Code Example – C# random number generators

double mean = -12.9;
double variance = 2.066;
var gen = new RandGenNormal( mean, variance );

for (int i=0; i<100; i++) 
{
   Console.WriteLine( gen.Next() );
}

Code Example – VB random number generators

Dim Mean As Double = -12.9
Dim Variance As Double = 2.066
Dim Gen As New RandGenNormal(Mean, Variance)

For I As Integer = 0 To 99
  Console.WriteLine(Gen.Next())
Next

The base class RandomNumberGenerator also provides the abstract method NextDouble(), which is equivalent to calling Next(). This is a common method for applications that require polymorphic random number generation across the different generators, but also incurs the extra overhead of a virtual function call.

The Fill() method enables you to fill an array of float, double, FloatComplex, or DoubleComplex with random values. Thus:

Code Example – C# random number generators

var array1 = new double[ 100 ];
var array2 = new FloatComplex[ 100 ];

var gen = new RandGenPoisson();
gen.Fill( array1 );
gen.Fill( array2 );

Code Example – VB random number generators

Dim Array1(100) As Double
Dim Array2(100) As FloatComplex

Dim Gen As New RandGenPoisson()
Gen.Fill(Array1)
Gen.Fill(Array2)

Lastly, as a convenience, NMath vector and matrix classes provide constructor overloads that initialize all elements with random values. For example:

Code Example – C# random number generators

var gen = new RandGenUniform( 0, 100 );
var v = new DoubleVector( 10, gen );
var A = new DoubleComplexMatrix( 25, 25, gen );

Code Example – VB random number generators

Dim Gen As New RandGenUniform(0, 100)
Dim V As New DoubleVector(10, Gen)
Dim A As New DoubleComplexMatrix(25, 25, Gen)

Random Seeds

As described above, all NMath random number generators, regardless of the distribution, use an underlying uniform random number generator to generate random deviates in the range (0,1), then derive from the deviate a random number from the appropriate probability distribution. Thus, the seed that determines the pseudorandom sequence is associated with the underlying uniform generator, not with the wrapping generator.

All NMath random number generator classes have Reset() and Reset(int) methods that attempt to reset the underlying uniform generator with the time of day, for the no argument reset, or the given seed, for the integer argument version. These methods return true if the reset was successful and false if it was not. The reset methods succeed if the following conditions are met:

1. The uniform generator delegate is an instance method; that is, the Target property of the Delegate class returns a non-null reference.

2. The object reference thus obtained has a method named Initialize() that returns void and takes no arguments, for the Reset() method, or a single integer argument for the Reset(int) method.

For example, this code attempts to generate two identical sequences by explicitly setting and resetting the seed:

Code Example – C# random number generators

int seed = 0x124;
var mt = new RandGenMTwist( seed );
var uniformDeviates = 
   new RandomNumberGenerator.UniformRandomNumber( mt.NextDouble );

var gen = new RandGenNormal( 50, 5, uniformDeviates );
var randomSequence1 = new DoubleVector( 100, gen );

if ( gen.Reset(seed) ) {
   var randomSequence2 = new DoubleVector( 100, gen );
}
else {
   Console.WriteLine( "Could not reset generator" ); 
}

Code Example – VB random number generators

Dim Seed As Integer = &H124
Dim MT As New RandGenMTwist(Seed)
Dim UniformDeviates As New 
 RandomNumberGenerator.UniformRandomNumber(AddressOf MT.NextDouble)

Dim Gen As New RandGenNormal(50, 5, UniformDeviates)
Dim RandomSequence1 As New DoubleVector(100, Gen)

If Gen.Reset(Seed) Then
  Dim RandomSequence2 As New DoubleVector(100, Gen)
Else
  Console.WriteLine("Could not reset generator")
End If

Top

Top