Random number generator class using George Marsaglia's multiply with carry algorithm.

View versions (1)

Interface

Overview

This class provides a very fast random number generator using George Marsaglia's multiply with carry algorithm. It produces uniformly distributed pseudo-random 32-bit values with period of

T_0 = 2^{60}
(1)

George Marsaglia's original posting can be found at this link:
http://groups-beta.google.com/group/sci.math/msg/fa034083b193adf0?hl=en&lr=&ie=UTF-8

Algorithm:

It uses the following recurrence relation :

x_n = a \cdot x_{n-1} + \,\mathrm{carry}\, \,\mathrm{mod}\, 2^{32}
(2)

where

a = 2083801278
(3)

Any other value of a can be chosen such that both

a \cdot 2^{32} - 1 \,\mbox{and}\, 2^{31} - 1
(4)

are prime.

To give you an idea of the running time for each of the functions, here are the results for generating 100,000,000 random numbers on a 750MHz microprocessor :

  • genReal() 4 seconds
  • genInt() 4 seconds
1/carry-378.png

This diagram is obtained by generating two sequences of 1000 uniform floating point random numbers in the (0, 1) interval and then plotting them one versus the other. It shows that the distribution is indeed uniform.

References

  • George Marsaglia's original post of the multiply with carry random number generator, http://groups-beta.google.com/group/sci.math/msg/fa034083b193adf0?hl=en&lr=&ie=UTF-8
  • The Newran03 random number generator library of Robert Davies, http://www.robertnz.net/nr03doc.htm

Example 1

The following example displays 20 random floating point numbers and 20 random large integers. It uses two different generators to achieve this. The first generator uses the system timer to initialize the seed, while the second is simply initialized with a particular value. Notice that it was necessary to divide the timer with the CARRYDIV value in order to keep the seed in the (0, 1) interval. The output of the first generator will obviously vary with each execution of the program, while the output of the second will always be the same if the seed is never changed.

#include <iostream>
#include <time.h>

#include <codecogs/statistics/random/carry.h>
using namespace std;

#define CARRYDIV    4294967296.0

int main() 
{
    Stats::Random::Carry A(time(0) / CARRYDIV);
    Stats::Random::Carry B(0.113);

    for (int i = 0; i < 20; ++i)
        cout << A.genReal() << endl;
    cout << endl;

    for (int i = 0; i < 20; ++i)
        cout << B.genInt() << endl;
    return 0;
}
GPL Licence — free for non commercial use. See Licence details.

Members of Carry

CLASS METHOD

Carry

Parameters

s
Default value = 0.46875

CLASS METHOD

Carry

CLASS METHOD

genReal

CLASS METHOD

genInt

CLASS METHOD

setSeed

Parameters

s
Seed must be in the (0, 1) interval (endpoints are excluded).

CLASS METHOD

getSeed

CLASS METHOD

Next

CLASS METHOD

Next