48 lines
1.4 KiB
Scheme
48 lines
1.4 KiB
Scheme
; linear congruential generator given in C99 section 7.20.2.1
|
|
(define ((c-rand seed)) (set! seed (remainder (+ (* 1103515245 seed) 12345) 2147483648)) (quotient seed 65536))
|
|
|
|
; uniform real numbers in open interval (0, 1)
|
|
(define (unif-rand seed) (let ((r (c-rand seed))) (lambda () (/ (+ (r) 1) 32769.0))))
|
|
|
|
; Box-Muller method to generate normal distribution
|
|
(define (normal-rand unif m s)
|
|
(let ((? #t) (! 0.0) (twopi (* 2.0 (acos -1.0))))
|
|
(lambda ()
|
|
(set! ? (not ?))
|
|
(if ? !
|
|
(let ((a (sqrt (* -2.0 (log (unif))))) (b (* twopi (unif))))
|
|
(set! ! (+ m (* s a (sin b))))
|
|
(+ m (* s a (cos b))))))))
|
|
|
|
(define rnorm (normal-rand (unif-rand 0) 1.0 0.5))
|
|
|
|
; auxiliary function to get a list of 'n random numbers from generator 'r
|
|
(define (rand-list r n) = (if (zero? n) '() (cons (r) (rand-list r (- n 1)))))
|
|
|
|
(define v (rand-list rnorm 1000))
|
|
|
|
v
|
|
#|
|
|
(-0.27965824722565835
|
|
-0.8870860825789542
|
|
0.6499618744638194
|
|
0.31336141955110863
|
|
...
|
|
0.5648743998193049
|
|
0.8282656735558756
|
|
0.6399951934564637
|
|
0.7699535302478072)
|
|
|#
|
|
|
|
; check mean and standard deviation
|
|
(define (mean-sdev v)
|
|
(let loop ((v v) (a 0) (b 0) (n 0))
|
|
(if (null? v)
|
|
(let ((mean (/ a n)))
|
|
(list mean (sqrt (/ (- b (* n mean mean)) (- n 1)))))
|
|
(let ((x (car v)))
|
|
(loop (cdr v) (+ a x) (+ b (* x x)) (+ n 1))))))
|
|
|
|
(mean-sdev v)
|
|
; (0.9562156817697293 0.5097087109575911)
|