# NMath User's Guide

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

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 8) and discrete (Table 9) distributions.

 Class Description Beta distribution. FloatRandomCauchyDistribution Cauchy distribution. Exponential distribution Gamma distribution. Gaussian distribution. Gumbel distribution. Laplace distribution. Log-normal distribution. Rayleigh distribution. Uniform distribution. Weibull distribution.

 Class Description Bernoulli distribution. Binomial distribution. Geometric Distribution Hypergeometric distribution. Negative Binomial distribution. Poisson distribution. Possion distribution with vary­ing mean. Uniform distribution. Integer values with uniform bit distribution.

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

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim Mean = 1.0
Dim Sigma = 1.0
Dim Dist As New DoubleRandomGaussianDistribution(Mean, Sigma)
```

Generating Random Numbers

Class 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].

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim Seed As Integer = &H345
Dim Stream As New RandomNumberStream(Seed,
RandomNumberStream.BasicRandGenType.MersenneTwister
```

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

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim N As Integer = 100
Dim Start As Integer = 0
Dim A(N) As Double
Dist.Fill(Stream, A, Start, N)
```

Or to fill a new vector or matrix:

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim V As 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 , which uses a stream to buffer the random numbers internally.

For instance:

Code Example – C# random number generators

```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}", rnd.Next());
}
```

Code Example – VB random number generators

```Dim BufferSize As Integer = 100
Dim RND As New RandomNumbers(Of Double,
DoubleRandomGaussianDistribution)(Seed, Dist, BufferSize)

For I As Integer = 0 To 9
Console.WriteLine("Next() = {0}", RND.Next())
Next
```

Independent Streams

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

In the leapfrog method, the independent sequences are created by splitting the original sequence into k disjoint subsets, where k is the number of independent streams, is such a way that the first stream generates the random numbers x1, xk+1, x2k+1, x3k+1,..., the second stream generates the numbers x2, xk+2, x2k+2, x3k+2,..., and, finally, the kth stream would generate xk, x2k, x3k... Class uses the leapfrog method.

In the skip-ahead, or block-splitting, method, the independent sequences are created by splitting the original sequence into non-overlapping blocks, where k is the number of independent streams. Each stream generates numbers only from its corresponding block. Class uses the skip-ahead method.

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

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim Seed = &H124
Dim GenType =
RandomNumberStream.BasicRandGenType.MultiplicativeCongruent31
Dim NStreams = 10
Dim StreamLen = 100
Dim Gen As New SkipAheadRandomStreams(Seed, GenType, NStreams,
StreamLen)
```

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

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim Dist As New DoubleRandomUniformDistribution()
Dim A As New DoubleMatrix(StreamLen, NStreams)
Gen.Fill(Dist, A)
```

Or to create a new matrix:

Code Example – C# random number generators

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

Code Example – VB random number generators

```Dim Dist As New DoubleRandomLogNormalDistribution()
Dim B As DoubleMatrix = Gen.Next(Dist)
```

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

Code Example – C# random number generators

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

Code Example – VB random number generators

```nstreams = 3
Dim IntDists(NStreams) As IRandomNumberDistribution(Of Double)
IntDists(0) = New DoubleRandomUniformDistribution()
IntDists(1) = New DoubleRandomBetaDistribution()
IntDists(2) = New DoubleRandomCauchyDistribution()
Dim Gen = New SkipAheadRandomStreams(Seed, GenType, NStreams,
StreamLen)
Dim C As DoubleMatrix = 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. generates quasirandom numbers using the Niederreiter method; uses the Sobol method.

For example:

Code Example – C# quasirandom numbers

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

Code Example – VB quasirandom numbers

```Dim Dimensions As Integer = 3
Dim NQRG As New NiederreiterQuasiRandomGenerator(Dimensions)
```

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.)

Code Example – C# quasirandom numbers

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

Code Example – VB quasirandom numbers

```Dim NumPts As Integer = 5000
Dim A As New DoubleMatrix(NQRG.Dimension, NumPts)
NQRG.Fill(A)
```

Or create a new matrix:

Code Example – C# quasirandom numbers

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

Code Example – VB quasirandom numbers

```Dim B As DoubleMatrix = NQRG.Next(
New DoubleRandomUniformDistribution(), NumPts)
```

The quasirandom numbers will follow the given distribution.

Top

Top