1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38: (define-module srfi-27
39: (use math.mt-random)
40: (use srfi-4)
41: (export random-integer random-real default-random-source
42: make-random-source random-source?
43: random-source-state-ref random-source-state-set!
44: random-source-randomize! random-source-pseudo-randomize!
45: random-source-make-integers random-source-make-reals
46: ))
47: (select-module srfi-27)
48:
49:
50:
51:
52: (define-constant random-source <mersenne-twister>)
53:
54:
55: (define (make-random-source) (make random-source))
56: (define (random-source? obj) (is-a? obj random-source))
57: (define default-random-source (make-random-source))
58:
59: (define (random-source-state-ref source)
60: (mt-random-get-state source))
61: (define (random-source-state-set! source state)
62: (mt-random-set-state! source state))
63:
64:
65: (define (random-source-randomize! source)
66: (unless (random-source? source)
67: (error "random source required, but got" source))
68: (mt-random-set-seed! source
69: (let1 s (* (inexact->exact (sys-time)) (sys-getpid))
70: (logior s (ash s -16)))))
71:
72: (define (random-source-pseudo-randomize! source i j)
73:
74:
75:
76:
77:
78:
79: (define (interleave-i i j lis)
80: (if (zero? i)
81: (if (zero? j) lis (interleave-j 0 j (cons 0 lis)))
82: (receive (q r) (quotient&remainder i #x100000000)
83: (interleave-j q j (cons r lis)))))
84:
85: (define (interleave-j i j lis)
86: (if (zero? j)
87: (if (zero? i) lis (interleave-i i 0 (cons 0 lis)))
88: (receive (q r) (quotient&remainder j #x100000000)
89: (interleave-i i q (cons r lis)))))
90:
91:
92: (unless (random-source? source)
93: (error "random source required, but got" source))
94: (when (or (not (integer? i)) (not (integer? j))
95: (negative? i) (negative? j))
96: (errorf "indices must be non-negative integers: ~s, ~s" i j))
97: (mt-random-set-seed! source
98: (list->u32vector (interleave-i i j '(#xffffffff))))
99: )
100:
101:
102: (define (random-source-make-integers source)
103: (unless (random-source? source)
104: (error "random source required, but got" source))
105: (lambda (n) (mt-random-integer source n)))
106:
107: (define (random-source-make-reals source . maybe-unit)
108: (unless (random-source? source)
109: (error "random source required, but got" source))
110: (if (null? maybe-unit)
111: (lambda () (mt-random-real source))
112: (let1 unit (car maybe-unit)
113: (unless (< 0 unit 1)
114: (error "unit must be between 0.0 and 1.0 (exclusive), but got" unit))
115: (let* ((1/unit (/ unit))
116: (range (inexact->exact (ceiling 1/unit))))
117: (lambda ()
118: (/ (make-random-integer range) 1/unit))))))
119:
120:
121: (define-values (random-integer random-real)
122: (let1 src default-random-source
123: (values (lambda (n) (mt-random-integer src n))
124: (lambda () (mt-random-real src)))))
125:
126: (provide "srfi-27")