mtwist(3)

NAME
mts_seed32new, mts_seed32, mts_seedfull, mts_seed, mts_goodseed, mts_bestseed, mts_savestate, mts_loadstate, mt_seed32new, mt_seed32, mt_seedfull, mt_seed, mt_goodseed, mt_bestseed, mt_getstate, mt_savestate, mt_loadstate, mts_lrand, mts_llrand, mts_drand, mts_ldrand, mt_lrand, mt_llrand, mt_drand, mt_ldrand, mt_prng - generate uniformly distributed pseudo-random numbers

SYNOPSIS
#defines (see below)
#include "mtwist.h"

C interface:

void mts_seed32(mt_state* state, uint32_t seed);

void mts_seed32new(mt_state* state, uint32_t seed);

void mts_seedfull(mt_state* state,
                  uint32_t seeds[MT_STATE_SIZE]);

uint32_t mts_seed(mt_state* state);

uint32_t mts_goodseed(mt_state* state);

void mts_bestseed(mt_state* state);

int mts_savestate(FILE* statefile, mt_state* state);

int mts_loadstate(FILE* statefile, mt_state* state);

void mt_seed32(uint32_t seed);

void mt_seed32new(uint32_t seed);

void mt_seedfull(uint32_t seeds[MT_STATE_SIZE]);

void mt_seed(void);

void mt_goodseed(void);

void mt_bestseed(void);

mt_state* mt_getstate(void);

int mt_savestate(FILE* statefile);

int mt_loadstate(FILE* statefile);

uint32_t mts_lrand(mt_state* state);

uint64_t mts_llrand(mt_state* state);

double mts_drand(mt_state* state);

double mts_ldrand(mt_state* state);

uint32_t mt_lrand(void);

uint64_t mt_llrand(void);

double mt_drand(void);

double mt_ldrand(void);

C++ interface:

mt_prng rng;

mt_prng rng(bool pickseed = false);

mt_prng rng(uint32_t seed);

mt_prng rng(uint32_t seeds[MT_STATE_SIZE]);

void rng.seed32(uint32_t seed);

void rng.seedfull(uint32_t seeds[MT_STATE_SIZE]);

void rng.seed();

void rng.goodseed();

void rng.bestseed();

uint32_t rng.lrand();

uint64_t rng.llrand();

double rng.drand();

double rng.ldrand();

double rng();

stream << rng;

stream >> rng;

DESCRIPTION
These functions generate pseudo-random numbers using Matsumoto and Nishimura's Mersenne Twist algorithm (see:

        http://www.math.keio.ac.jp/~matumoto/emt.html

for full information). The period of this pseudo random-number generator (PRNG) is 2^19337-1 which is vastly longer than the life of the universe even if the random numbers are being generated at an impossible rate. The generator also has excellent statistical properties.

The mtwist package assumes a 32-bit machine with a modern C or C++ compiler that supports inline functions and the inttypes.h header file. If these features are not present, the package must be modified.

All of the PRNG functions work from a state vector, which is of type mt_state in C and type mt_prng in C++. The state vector stores everything that the PRNG needs to generate new numbers in the proper sequence. By using multiple state vectors, programs can draw random numbers from independent sequences, which is important in applications such as simulation (where each independent random variable should be drawn from its own sequence to avoid unintentional correlations).

For convenience, the C interface also provides a built-in default state vector that can be used in simple applications. The mt_xxx functions use the default state vector to control their behavior, while the mts_xxx functions accept a user-provided state vector.

In C, a user-provided state vector has the following structure:

#define MT_STATE_SIZE 624
typedef struct {
uint32_t statevec[MT_STATE_SIZE];
/* Vector holding current state */
int stateptr;   /* Next state entry to be used */
int initialized;
/* NZ if state has been initialized */
} mt_state;

An uninitialized PRNG is indicated by zeros in both stateptr and initialized. It is the programmer's responsibility to ensure that these fields are zero before calling any of the mts_xxx functions.

It is occasionally useful to directly access the default state vector, so mt_getstate will return a pointer to the default state.

In both C and C++, the functionality is divided into two categories: seeding and pseudorandom-number generation. If one of the generation functions is called on an unseeded generator, a default seed (specified by Matsumoto and Nishimura) will be used. Usually, the programmer will wish to override the default seed and choose a more appropriate one. The simplest way to seed a PRNG is by calling one of the *seed32new functions. This will invoke Matsumoto and Nishimura's revised Knuth-style seed generator.

The *seed32 functions will invoke Matsumoto and Nishimura's original Knuth-style seed generator, which is now deprecated. In C++, the same effect can be achieved by passing a 32-bit (uint32_t) seed to the constructor. The original 32-bit seeder did not work correctly if the seed was zero, so in that case the default seed of 4357 will be substituted. The original seeder is still supported so that older software will continue to work in the same fashion without changes.

The *seed32new and *seed32 functions are simple to use, but they have the drawback that only 4 billion distinct pseudorandom sequences can be generated using them. To allow access to sequences beginning anywhere in the entire space of possibilities, the *seedfull functions can be passed an initial state vector of 624 32-bit numbers, or a C++ PRNG can be constructed with a 624-element array as an argument. The initialization vector must contain at least one nonzero value; if this rule is violated, the program will be aborted (unfortunately without a diagnostic message due to C/C++ portability issues).

The *seed32new, *seed32, and *seedfull functions allow fixed, reproducible seeds, which is useful for simulation and experimentation. For game-like applications, non-reproducible seeds are usually more appropriate. The mts_seed, mt_seed, and seed functions use /dev/urandom (or the system time if /dev/urandom is unavailable) to generate an argument to the *seed32new functions to satisfy this need. If the time is used, the microseconds portion of the time is included in the seed to enhance the probability that two programs will generate different random sequences. The actual seed used is returned so that it can be saved for reproducibility.

The *goodseed functions work in a similar manner, but use /dev/random as their source of (32-bit) randomness. C++ programmers can also invoke goodseed at construction time by passing an argument of true to the constructor. Depending on the current amount of randomness available, these functions may take a significant amount of (wall-clock) time.

For the most random seed possible, the *bestseed functions attempt to use /dev/random to acquire values for *seedfull, falling back to *goodseed if /dev/random is unavailable. The disadvantage of these functions is that it usually takes a very large amount of (wall-clock) time before /dev/random can produce enough entropy to provide a seed. Therefore, it is nearly always better to stick with the *goodseed functions. However, only the *seedfull functions can produce more than 32 bits of entropy. Because of the size of the state, the *seedfull functions do not return the seed used; if it is needed, the *savestate functions can be used to write it to a file.

Finally, it is often useful to be able to save and restore the PRNG state for later use. In C, the functions *savestate *loadstate will save the current state into an open stdio FILE as a single long line (in ASCII) and later restore it such that the restored PRNG will pick up where the saved one left off. In C++, the same effect can be achieved by writing to or reading from a C++ stream using the usual << and >> operators. As with all well-behaved C++ types, the << operator does not add a newline after the saved state.

Once a generator has been seeded, uniformly distributed pseudorandom numbers can be produced in several formats. (The functions in the randistrs(3) library can be used to produce other statistical distributions.) The *lrand and *llrand generate 32-bit and 64-bit random integers uniformly distributed between 0 and the maximum unsigned value. (The *llrand functions are only available on machines that support a 64-bit data type. The *drand functions generate a double-precision number in the range [0,1) (i.e., 0 is a possible value but 1 is not). The number generated by *drand has 32 bits of precision. For convenience, the C++ interface also defines a function operator that returns the same result as drand, so that a PRNG can be called as if it were a function. For applications that demand increased precision, the *ldrand functions generate a double-precision number in [0,1) with up to 64 bits of precision (usually 52 bits).

SEE ALSO
randistrs(3), drand48(3), rand(3), random(3)