# Random Variate Generation Routines

This module provides facilities for basic pseudo-random number generation, and for generation of random variates from various common distributions.

All the random generation procedures use the same underlying "stream" of random numbers. This stream is generated using the `nrand48` pseudo-random generation procedure found on most Unix systems, with the output being combined with a limited supply of real random numbers from the file "randfile" in the source directory for this software, in order to reduce the chances that the pseudo-random numbers aren't random enough.

A pseudo-random number stream is determined by an integer seed, which is typically set by the user for each experimental run (eg, to 1, 2, 3, etc. for successive runs). The state of the random number stream can be saved in a structure of type `rand_state`, and later restored. For example, the state could be saved in a file at the end of a run, and restored if it is later decided that the run should be continued for longer.

The methods for generating random variates from various distributions are mostly taken from the following reference:

> Devroye, L. (1986) Non-Uniform Random Variate Generation, New York: Springer-Verlag.

The methods used here are not necessarily the fastest available. They were selected to be reasonably fast while also being easy to write.

Header file required: `rand.h`

Setting and saving the state

rand_seed: Set the state from an integer seed.

>     void rand_seed
>     ( int seed;  /* Seed to set state based on */
>     )

Sets the random number generator to a state that is determined from the integer `seed`. Setting the seed the same on two occasions, and then calling exactly the same sequence of random generation procedures, should produce exactly the same sequence of random variates. (Note: this may not be true, however, if computers with different architectures are used on the two occasions.)

Sequential seeds should produce streams that are pretty much independent (unlike the situation for some pseudo-random number generators). Setting the seed randomly according to the time or day, or some such, without recording what it was, is not recommended, since the results are then not reproducible.

rand_get_state: Get a pointer to the current state.

>     rand_state *rand_get_state (void)

Returns a pointer to the current state of the random number generator, which is a structure of type `rand_state`. The only use for this pointer is to use it to save a copy of the current state someplace.

rand_use_state: Set the state to use from now on.

>     void rand_use_state
>     ( rand_state *state  /* Pointer to a previously saved state */
>     )

Sets the random number generator to the state pointed to by the argument. This state must be valid. The only way to get a valid state is by using `rand_get_state`.

Generating uniform random variates

rand_uniform: Generate uniformly from [0,1).

>     double rand_uniform (void)

Returns a random number that is uniformly distributed between 0 and 1, with a value of exactly 0 being possible, but with a value of exactly 1 not being possible.

rand_uniopen: Generate uniformly from (0,1).

>     double rand_uniopen (void)

Returns a random number that is uniformly distributed between 0 and 1, with neither a value of exactly 0 nor a value of exactly 1 being possible.

Generating discrete random variates

rand_int: Pick an integer uniformly from 0 to n-1.

>     int rand_int
>     ( int n  /* Number of integers (from 0) to pick from */
>     )

Randomly picks an integer from the set { `0, 1, ..., n-1` }, with each integer being equally probable. The probabilities may become somewhat unequal, however, if `n` is very large, approaching 231.

rand_pickd: Pick an integer from 0 to n-1 with given probabilities (as doubles).

>     int rand_pickd
>     ( double *p,  /* Array of probabilities, of length n */
>       int n       /* Number of integers (from 0) to pick from */
>     )

Randomly picks an integer from the set { `0, 1, ..., n-1` }, with probabilities given by the array of double-precision numbers passed as the first argument. These numbers need not sum to one, but they must be non-negative, and must not all be zero. The actual probabilities used are obtained by dividing each number in this array by the sum of all the numbers.

If one of the probabilities is exactly zero, it is guaranteed that the corresponding integer will not be picked.

rand_pickf: Pick an integer from 0 to n-1 with given probabilities (as floats).

>     int rand_pickf
>     ( float *p,  /* Array of probabilities, of length n */
>       int n      /* Number of integers (from 0) to pick from */
>     )

This procedure is the same as `rand_pickd` except that the array giving the probabilities is an array of single-precision floating point numbers, rather than double-precision.

Generating continuous random variates

rand_gaussian: Generate a standard Gaussian (normal) random variate.

>     double rand_gaussian (void)

Generates a random value drawn from the Gaussian (normal) distribution with mean zero and standard deviation one, whose density function is proportional to exp(-x2/2), with x being any real value.

rand_logistic: Generate a logistic random variate.

>     double rand_logistic (void)

Generates a random value drawn from the logistic distribution with location parameter zero and width parameter one, whose density function is proportional to exp(-x) / [1 + exp(-x)]2, with x being any real value.

rand_cauchy: Generate a Cauchy random variate.

>     double rand_cauchy (void)

Generates a random value drawn from the Cauchy distribution with centre at zero and width one, whose density function is proportional to 1 / (1+x2), with x being any real value.

rand_gamma: Generate a gamma-distributed random variate.

>     double rand_gamma
>     ( double A   /* Shape parameter */
>     )

Generates a random value drawn from the gamma distribution with positive shape parameter A, whose density function is proportional to xA-1 exp(-x), with x being any positive real. This procedure will never return a value that is exactly zero.

rand_exp: Generate an exponentially-distributed random variate.

>     double rand_exponential (void)

Generates a random value drawn from the exponential distribution with mean one, whose density function is exp(-x), with x being any positive real. This procedure will never return a value that is exactly zero.

Note: This is a common special case of the gamma distribution.

rand_beta: Generate a beta-distributed random variate.

>     double rand_beta
>     ( double A,  /* Parameters of distribution */
>       double B
>     )

Generates a random value drawn from the beta distribution with positive parameters A and B, whose density function is proportional to xA-1(1-x)B-1, with x being any real in the interval (0,1). This procedure will never return a value that is exactly zero or exactly one.

Back to index for LDPC software