Random Number Generation

The PLT Scheme Science Collection provides additional functionality to the PLT Scheme implementation of SRFI 27 by Sabastian Egner, which, in turn, is a 54-bit implementation of Pierre L'Ecuyer's MRG32k3a pseudo-random number generator.4

The functions described in this chapter are defined in the random-source.ss file in the science collection and are made available using the form:

(require (planet "random-source.ss" ("williams" "science.plt")))

6.1  The SRFI 27 Specification

The following functions are defined in the SRFI specification and are, in turn, provided by the random-source module. The contract shows here are for documentation purposes only - the PLT Scheme implementation of SRFI 27 does not define contracts for its functions.

random-integer

Function:
(random-integer n)

Contract:

(-> (integer-in 1 +inf.0) natural-number?)

This functions returns the next integer in {0, ..., n - 1} obtained from the default- random-source. Subsequent results of this function appear to be independent uniformly distributed over the range {0, ..., n - 1}. The argument n must be a positive integer, otherwise an error is signaled.

random-real

Function:
(random-real)

Contract:

(-> (real-in 0.0 1.0))

This function returns the next number, x, 0 < x < 1 obtained from default-random-source. Subsequent results of this procedure appear to be independently uniformly distributed.

default-random-source

Variable:
default-random-source

Defines the random source from which random-integer and random-real have been derived using random-source-make-integers and random-source-make-reals. Note that an assignment to default-random-source does not change the behavior of random or random-integer; it is strongly recommended not to assign a new value to default-random-source.

make-random-source

Function:
(make-random-source)

Contract:

(-> random-source?)

This function creates a new random source. A random source created with make-random-source represents a deterministic stream of random bits. Each random stream obtained as (make-random-source) generates the same stream of values unless the state is modified with one of the functions below.

random-source?

Function:
(random-source? x)

Contract:

(-> any? boolean?)

This function returns true, #t, if x is a random source, otherwise false, #f, is returned.

random-source-state-ref random-source-state-set!

Function:
(random-source-state-ref s)

Contract:

(-> random-source? any)

Function:

(random-source-state-set! s state)

Contract:

(-> random-source? any? any)

These functions get and set the current state of the random source s. The implementation of the internal state of a random source is not defined.

random-source-randomize!

Function:
(random-source-randomize! s)

Contract:

(-> random-source? any)

This function makes an effort to set the state if the random source s to a truly random state.

random-source-pseudo-randomize!

Function:
(random-source-pseudo-randomize! s i j)

Contract:

(-> random-source? natural-number? natural-number> any)

This function changes the state of the random stream s into the initial state of the (i, j)th independent random source, where i and j are non-negative integers. This procedure provides a mechanism to obtain a large number of independent random sources, indexed by two integers. In contrast to random-source-randomize!, this procedure is entirely deterministic.

random-source-make-integers

Function:
(random-source-make-integers s)

Contract:

(-> random-source? procedure?)

This function returns a procedure to generate random integers using the random source s. The resulting procedure takes a single argument n, which must be a positive integer, and returns the next independent uniformly distributed integer from the interval {0, ..., n - 1} by advancing the state of the random source s.

random-source-make-reals

Function:
(random-source-make-reals s unit)

Function:

(random-source-make-reals s)

Contract:

(case-> (-> random-source? real? procedure?
        (-> random-source? procedure?))

This function returns a procedure to generate random real numbers 0 < x < 1 using the random source s. The resulting procedure is called without arguments.

6.2  Additional Random Number Functionality

The science collection provides additional functionality to that provided by SRFI 27.

6.2.1  The current-random-source Parameter

The main additional functionality is to define a parameter5, current-random-source, which provides a separate random source reference for each thread. The default value for this random source reference is default-random-stream.

The use of the current-random-source parameter overcomes the difficulty with assignment to default-random-source. However, the routines random-integer and random-real use the default-random-source variable and are unaware of the current- random-source parameter.

current-random-source

Function:
(current-random-source s)

Function:

(current-random-source)

Contract:

(case-> (-> random-source? any)
        (-> random-source?))

Gets or sets the current random source. A guard procedure ensures that the value of current-random-source is indeed a random source, as determined by random-source?, otherwise a type error is raised.

with-random-source

Macro:
(with-random-source s
   body ...)

Executes the body with current-random-source set to the random source s.

with-new-random-source

Macro:
(with-new-random-source s
   body ...)

Executes the body with current-random-source set to a newly created random source.

6.2.2  Uniform Random Numbers

The science collection provides alternatives to the random-integer and random-real functions that are aware of the current-random-source parameter. They also provide a more convenient interface than random-source-make-integers and random-source- make-reals.

random-uniform-int

Function:
(random-uniform-int s n)

Function:

(random-uniform-int n)

Contract:

(case->
   (-> random-source? (integer-in 1 +inf.0)
       natural-number?)
   (-> (integer-in 1 +inf.0) natural-number?))

This function returns the next integer in {0, ..., n - 1} obtained from the random source s or (current-random-source) if s is not specified. Subsequent results of this function appear to be independent uniformly distributed over the range {0, ..., n - 1}. The argument n must be a positive integer.

random-uniform

Function:
(random-uniform s)

Function:

(random-uniform)

Contract:

(case-> random-source? (real-in 0.0 1.0))
        (real-in 0.0 1.0)))

This function returns the next number x, 0 < x < 1, obtained from the random source s or (current-random-source) if s is not specified. Subsequent results of this function appear to be independent uniformly distributed.

6.2.3  Miscellaneous Functions

These functions provide an alternative set of functions to get or set the state of a random state. These functions match the conventions for structures in PLT Scheme.

random-source-state

Function:
(random-source-state s)

Contract:

(-> random-source? any)

The same as random-source-state-ref.

set-random-source-state!

Function:
(set-random-source-state! s state)

Contract:

(-> random-source? any? any)

The same as random-source-state-set!.

6.2.4  Random Source Vectors

These function provide a convenient method for generating a vector of repeatable random sources.

make-random-source-vector

Function:
(make-random-source-vector n i)

Function:

(make-random-source-vector n)

Contract:

(case-> (-> natural-number/c natural-number/c
            (vectorof random-source?))
        (-> natural-number/c (vectorof random-source?)))

This funtion returns a vector of random sources of length n. If i is provided, the jth random source is initialized using (random-source-pseudo-randomize! i j). If i is not provided, the ith random dource is initialized using (random-source-pseudo-randomize! i 0). Note that this is not the same as having i default to 0.

6.3  Examples

Example: Histogram of uniform random numbers.

(require (planet "random-source.ss" ("williams" "science.plt")))
(require (planet "histogram-with-graphics.ss"
                 ("williams" "science.plt")))

(let ((h (make-histogram-with-ranges-uniform 40 0 1))
      (s (make-random-source)))
  (random-source-randomize! s)
  (with-random-source s
    (do ((i 0 (+ i 1)))
        ((= i 10000) (void))
      (histogram-increment! h (random-uniform))))
  (histogram-plot h "Histogram of Uniform Random Numbers"))

Figure 18 shows an example of the resulting histogram.

[random-Z-G-1.gif]
Figure 18:  Histogram of Uniform Random Numbers

Example: Histogram of uniform random integers.

(require (planet "random-source.ss" ("williams" "science.plt")))
(require (planet "histogram-with-graphics.ss"
                 ("williams" "science.plt")))

(let ((h (make-discrete-histogram))
      (s (make-random-source)))
  (random-source-randomize! s)
  (with-random-source s
    (do ((i 0 (+ i 1)))
        ((= i 10000) (void))
      (discrete-histogram-increment! h (random-uniform-int 10))))
  (discrete-histogram-plot
   h "Histogram of Uniform Random Integers"))

Figure 19 shows an example of the resulting histogram.

[random-Z-G-2.gif]
Figure 19:  Histogram of Uniform Random Integers


4 This is equivalent to the gsl-rmg-cmrg combined multiple recursive generator by L'Ecuyer in the GSL.

5 See PLT Scheme: Reference Manual, Section 7.7 Parameters