1 ;;; srfi-27.scm --- Sources of Random Bits
3 ;; Copyright (C) 2010 Free Software Foundation, Inc.
5 ;; This library is free software; you can redistribute it and/or
6 ;; modify it under the terms of the GNU Lesser General Public
7 ;; License as published by the Free Software Foundation; either
8 ;; version 3 of the License, or (at your option) any later version.
10 ;; This library is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ;; Lesser General Public License for more details.
15 ;; You should have received a copy of the GNU Lesser General Public
16 ;; License along with this library. If not, see
17 ;; <http://www.gnu.org/licenses/>.
21 ;; This module is fully documented in the Guile Reference Manual.
25 (define-module (srfi srfi-27)
26 #:export (random-integer
31 random-source-state-ref
32 random-source-state-set!
33 random-source-randomize!
34 random-source-pseudo-randomize!
35 random-source-make-integers
36 random-source-make-reals)
37 #:use-module (srfi srfi-9))
39 (cond-expand-provide (current-module) '(srfi-27))
41 (define-record-type :random-source
42 (%make-random-source state)
44 (state random-source-state set-random-source-state!))
46 (define (make-random-source)
47 (%make-random-source (seed->random-state 0)))
49 (define (random-source-state-ref s)
50 (random-state->datum (random-source-state s)))
52 (define (random-source-state-set! s state)
53 (set-random-source-state! s (datum->random-state state)))
55 (define (random-source-randomize! s)
56 (let ((time (gettimeofday)))
57 (set-random-source-state! s (seed->random-state
58 (+ (* (car time) 1e6) (cdr time))))))
60 (define (random-source-pseudo-randomize! s i j)
61 (set-random-source-state! s (seed->random-state (i+j->seed i j))))
63 (define (i+j->seed i j)
64 (logior (ash (spread i 2) 1)
67 (define (spread n amount)
68 (let loop ((result 0) (n n) (shift 0))
72 (ash (logand n 1) shift))
76 (define (random-source-make-integers s)
78 (random n (random-source-state s))))
80 (define random-source-make-reals
85 (let ((x (random:uniform (random-source-state s))))
90 (or (and (real? unit) (< 0 unit 1))
91 (error "unit must be real between 0 and 1" unit))
92 (random-source-make-reals s))))
94 (define default-random-source (make-random-source))
95 (define random-integer (random-source-make-integers default-random-source))
96 (define random-real (random-source-make-reals default-random-source))