(module distributions mzscheme
(require (lib "math.ss")
)
(define RANDOM-GRAIN (sub1 (expt 2 31)))
(define-struct distribution (continuous?
d-func
mean
variance
rand
))
(define (print-distribution dist)
(print (format "continuous?: ~a, mean: ~a, variance: ~a"
(distribution-continuous? dist)
(distribution-mean dist)
(distribution-variance dist))))
(define (ln n)
(/ (log n)
(log e)))
(define fac
(lambda (n)
(if (zero? n)
1
(* n (fac (- n 1))))))
(define choose
(lambda (a b)
(/ (fac a)
(* (fac b)
(fac (- a b))))))
(define myround
(lambda (n)
(- n
(- n (round n)))))
(define (make-uniform-mgf theta1 theta2)
(lambda (t)
(/ (- (exp (* t theta2))
(exp (* t theta1)))
(* t
(- theta2 theta1)))))
(define (make-normal-mgf mu sigma)
(lambda (t)
(exp (+ (* mu t)
(/ (* (sqr t) (sqr sigma))
2)))))
(define (make-exponential-mgf bete)
'dummy)
(define (make-binomial-mgf n p)
'dummy)
(define (make-uniform-distribution theta1 theta2)
(make-distribution #t
(lambda (y)
(if (or (< y theta1)
(< theta2 y))
0
(/ (- theta2 theta1))))
(/ (+ theta1 theta2)
2)
(/ (sqr (- theta2 theta1))
12)
(lambda ()
(uniform-random theta1 theta2))
))
(define (make-normal-distribution mu sigma)
(make-distribution #t
(lambda (y)
(* (/ (* sigma (sqrt (* 2 pi))))
(exp (- (* (/ (* 2 (sqr sigma)))
(sqr (- y mu)))))))
mu
(sqr sigma)
(lambda ()
(normal-random mu sigma))
))
(define (make-exponential-distribution beta)
(make-distribution #t
(lambda (y)
(if (< 0 y)
(* (/ beta)
(exp (/ (- y)
beta)))
0))
beta
(sqr beta)
(lambda ()
(exponential-random beta))
))
(define (make-binomial-distribution n p)
(make-distribution #f
(lambda (y)
(* (choose n y)
(expt p y)
(expt (- 1 p)
(- n y))))
(* n p)
(* n p (- 1 p))
(lambda ()
(binomial-random n p))
))
(define (uniform-random theta1 theta2)
(+ theta1 (* (/ (- theta2 theta1) (sub1 RANDOM-GRAIN)) (random RANDOM-GRAIN))))
(define (open-uniform-random theta1 theta2)
(+ theta1 (* (/ (- theta2 theta1) RANDOM-GRAIN) (add1 (random (sub1 RANDOM-GRAIN))))))
(define r 0)
(define ind 1)
(define (ranf)
(open-uniform-random 0 1))
(define (standard-normal-random-guts)
(let* ([x1 (- (* 2 (ranf)) 1)]
[x2 (- (* 2 (ranf)) 1)]
[w (+ (* x1 x1) (* x2 x2))])
(if (> w 1)
(standard-normal-random-guts)
(let ([w2 (sqrt (/ (* (ln w) -2) w))])
(set! r (* x2 w2))
(* x1 w2)))))
(define (standard-normal-random)
(set! ind (- ind))
(if (> ind 0)
(standard-normal-random-guts)
r))
(define (normal-random mu sigma)
(+ (* sigma (standard-normal-random)) mu))
(define (exponential-random beta)
(let ([rand (/ (add1 (random (sub1 RANDOM-GRAIN))) RANDOM-GRAIN)])
(* (- (ln rand)) beta)))
(define (gammln xx)
(let* ([ser 1.000000000190015]
[cof1 76.18009172947146]
[cof2 -86.50532032941677]
[cof3 24.01409824083091]
[cof4 -1.231739572450155]
[cof5 0.001208650973866179]
[cof6 -0.000005395239384953]
[x xx]
[y xx]
[tmp (- (+ x 5.5)
(* (+ x 0.5)
(ln (+ x 5.5))))]
[ser2 (+ ser
(/ cof1 (+ y 1))
(/ cof2 (+ y 2))
(/ cof3 (+ y 3))
(/ cof4 (+ y 4))
(/ cof5 (+ y 5))
(/ cof6 (+ y 6)))])
(+ (- tmp)
(ln (* 2.5066282746310005
(/ ser2
x))))))
(define pg 0)
(define poldm -1.0)
(define psq -1)
(define palxm -1)
(define (poisson-random xm)
(if (> 12 xm)
(begin
(unless (= xm poldm)
(set! poldm xm)
(set! pg (exp (- xm))))
(let loop ([em 0] [t (ranf)])
(if (> t pg)
(loop (add1 em) (* t (ranf)))
em)))
(begin
(unless (= xm poldm)
(set! poldm xm)
(set! psq (sqrt (* 2.0 xm)))
(set! palxm (ln xm))
(set! pg (- (* xm palxm) (gammln (+ xm 1)))))
(poisson-random-guts xm))))
(define (poisson-random-guts xm)
(let loop ([y (tan (* (ranf) pi))])
(let ([em (+ (* psq y)
xm)])
(if (< em 0)
(loop (tan (* (ranf) pi)))
(let* ([fem (floor em)]
[t (* 0.9
(+ 1.0 (* y y))
(exp (- (* fem palxm)
(gammln (+ fem 1))
pg)))])
(if (> (ranf) t)
(loop (tan (* pi (ranf))))
fem))))))
(define bnold -1)
(define bpold -1)
(define boldg -1)
(define (binomial-random n pp)
(let* ([p (if (<= pp 0.5)
pp
(- 1 pp))]
[am (* n p)])
(if (< n 25)
(let loop ([bnl 0] [j 1])
(if (<= n j)
(if (= p pp)
bnl
(- n bnl))
(if (< (ranf) p)
(loop (add1 bnl) (add1 j))
(loop bnl (add1 j)))))
(if (< am 1)
(let ([g (exp (- am))])
(let loop ([t 1] [j 0])
(if (not (<= j n))
(if (= p pp)
n
0)
(let ([t2 (* t (ranf))])
(if (< t g)
(if (< t g)
(if (= p pp)
j
(- n j))
(loop t2 (add1 j))))))))
(begin
(unless (= n bnold)
(set! boldg (gammln (+ n 1)))
(set! bnold n))
(let* ([en n]
[pc (- 1 p)]
[plog (ln p)] [pclog (ln pc)] [sq (sqrt (* 2 am pc))] )
(let loop ([angle (* pi (ranf))])
(let* ([y (tan angle)]
[em (+ (* sq y) am)])
(if (or (< em 0) (>= em (+ en 1)))
(loop (* pi (ranf)))
(let ([fem (floor em)]
[t (* 1.2
sq
(+ (* y y) 1)
(exp (+ boldg
(- (gammln (+ em 1)))
(- (gammln (+ en (- em) 1)))
(* em plog)
(* (- en em) pclog))))])
(if (> (ranf) t)
(loop (* pi (ranf)))
(if (= p pp)
em
(- n em)))))))))))))
(provide (all-defined))
)