Random Number Generation (MIT/GNU Scheme 12.0.90)

Previous: Fixnum and Flonum Operations, Up: Numbers [Contents][Index]

### 4.9 Random Number Generation

MIT/GNU Scheme provides a facility for random number generation. The current implementation uses the ChaCha stream cipher, reseeding itself at each request so that past outputs cannot be distinguished from uniform random even if the state of memory is compromised in the future.

The interface described here is a mixture of the Common Lisp and SRFI 27 systems.

procedure: random m [state] ¶

  The argument m must be either an exact positive integer, or an inexact positive real.

  - If m is an exact positive integer, then `random` returns an exact nonnegative integer below m with uniform distribution.
  - If m is an inexact positive real, then `random` returns an inexact real in the interval [0, m) with uniform distribution.

  If state is given and not `#f`, it must be a random-state object; otherwise, it defaults to the `default-random-source`. This object is used to maintain the state of the pseudorandom number generator and is altered as a side effect of the `random` procedure.

  Use of the default random state requires synchronization between threads, so it is better for multithreaded programs to use explicit states.

      (random 1.0)    ⇒  .32744744667719056
      (random 1.0)    ⇒  .01668326768172354
      (random 10)     ⇒  3
      (random 10)     ⇒  8
      (random 100)    ⇒  38
      (random 100)    ⇒  63

procedure: flo:random-unit-closed state ¶
procedure: flo:random-unit-open state ¶

  State must be a random-state object. `Flo:random-unit-closed` returns a flonum in the closed interval [0,1] with uniform distribution. In practical terms, the result is in the half-closed interval (0,1] because the probability of returning 0 is 2^{-1075}, far below the standard probability 2^{-128} that means “never” in cryptographic engineering terms.

  `Flo:random-unit-open` is like `flo:random-unit-closed`, but it explicitly rejects `0.0` and `1.0` as outputs, so that the result is a floating-point number in the open interval (0,1). `(flo:random-unit-open)` is equivalent `(random 1.)`, except that it is faster.

  Callers should generally use `flo:random-unit-closed`, because for the uniform distribution on the interval [0,1] of real numbers, the probability of a real number that is rounded to the floating-point `1.0` is the small but nonnegligible 2^{-54}, and arithmetic downstream should be prepared to handle results that are rounded to `1.0` much more readily than results that are rounded to `0.0` — in other words, a requirement to use `flo:random-unit-open` is evidence of bad numerics downstream.

procedure: flo:random-unit state ¶

  Deprecated alias for `flo:random-unit-open`.

procedure: random-bytevector n [state] ¶

  Returns a bytevector of n bytes drawn independently uniformly at random from state.

procedure: random-bytevector! bytevector [start end state] ¶

  Replaces the bytes in bytevector from start to end by bytes drawn independently uniformly at random from state.

The next three definitions concern random-state objects. In addition to these definitions, it is important to know that random-state objects are specifically designed so that they can be saved to disk using the `fasdump` procedure, and later restored using the `fasload` procedure. This allows a particular random-state object to be saved in order to replay a particular pseudorandom sequence.

variable: *random-state* ¶

  This variable is deprecated; pass an explicit state instead.

procedure: make-random-state [state] ¶

  This procedure returns a new random-state object, suitable for use as as the state argument to `random`. If state is not given or `#f`, `make-random-state` returns a copy of `default-random-source`. If state is a random-state object, a copy of that object is returned. If state is `#t`, then a new random-state object is returned that has been “randomly” initialized by some means (such as by a time-of-day clock).

procedure: random-state? object ¶

  Returns `#t` if object is a random-state object, otherwise returns `#f`.

procedure: export-random-state state ¶
procedure: import-random-state state ¶

  `Export-random-state` returns an external representation of a random state — an object that can be safely read and written with `read` and `write`, consisting only of nested lists, vectors, symbols, and small exact integers. `Import-random-state` creates a random state from its external representation.

In the MIT/GNU Scheme implementation of the SRFI 27 API, a “random source” happens to be the same as a random state, but users should not rely on this.

procedure: make-random-source ¶

  [SRFI 27] Returns a random source. Every random source created by `make-random-source` returns the same sequence of outputs unless modified by `random-source-state-set!`, `random-source-randomize!`, or `random-source-pseudo-randomize!`.

procedure: random-source? object ¶

  [SRFI 27] Returns `#t` if object is a random source, otherwise returns `#f`.

constant: default-random-source ¶

  [SRFI 27] The default random source, used by the various random procedures if no explicit state is specified and `*random-state*` is false.

procedure: random-source-state-ref source ¶
procedure: random-source-state-set! source exported-state ¶

  [SRFI 27] `Random-source-state-ref` returns an external representation of a random source — an object that can be safely read and written with `read` and `write`, consisting only of nested lists, vectors, symbols, and small exact integers. `Random-source-state-set!` replaces the innards of source by the source represented by exported-state from `random-source-state-ref`.

procedure: random-source-randomize! source ¶

  [SRFI 27] Loads entropy from the environment into source so that its subsequent outputs are nondeterministic.

  Warning: Most implementations of SRFI 27 do not make subsequent outputs unpredictable with cryptography, so don’t rely on this.

procedure: random-source-pseudo-randomize! source i j ¶

  [SRFI 27] The arguments i and j must be exact nonnegative integers below 2^{128}. This procedure sets source to generate one of 2^{256} distinct possible streams of output, so that if i and j are chosen uniformly at random, it is hard to distinguish the outputs of the source from uniform random.

  Warning: Most implementations of SRFI 27 do not make it hard to distinguish the outputs of the source from uniform random even if the indices i and j are uniform random, so don’t rely on this.

procedure: random-integer n ¶

  [SRFI 27] Returns an exact nonnegative integer below n chosen uniformly at random.

  Equivalent to:

      ((random-source-make-integers default-random-source) n)

procedure: random-real ¶

  [SRFI 27] Returns an inexact real in the open interval (0, 1) with uniform distribution.

  Equivalent to:

      ((random-source-make-reals default-random-source))

procedure: random-source-make-integers source ¶

  [SRFI 27] Returns a procedure of one argument, n, that deterministically draws from source an exact nonnegative integer below n with uniform distribution.

procedure: random-source-make-reals source [unit] ¶

  [SRFI 27] Returns a procedure of zero arguments that deterministically draws from source an inexact real in the interval (0,1) with uniform distribution. If unit is specified, the results are instead uniform random integral multiples of unit in (0,1) and of the same exactness as unit.

Previous: Fixnum and Flonum Operations, Up: Numbers [Contents][Index]