public
Description: Random number generation for common lisp
Homepage: http://code.google.com/p/cl-randist/
Clone URL: git://github.com/lvaruzza/cl-randist.git
Search Repo:
cl-randist / cut-point.lisp
100644 45 lines (37 sloc) 0.828 kb
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
39
40
41
42
43
44
45
(in-package :randist)
 
(declaim (optimize (debug 3)))
 
(defun setup-cut-point-randist (p)
  (let* ((L 0)
   (J 0)
   (M (length p))
   (S 0d0)
   (I (make-array M))
   (Qj 0d0)
   (Q (map 'vector #'(lambda (x) (setf S (+ S x))) p)))
 
 
  (tagbody
   start
     (incf j)
     (setf Qj (* M (aref Q (1- J))))
   test
     (when (<= Qj L)
       (go start))
     (incf L)
     (setf (aref I (1- L)) J)
     (when (< L M)
       (go test)))
  (values I Q)))
 
(defun make-discrete-monotone-random-var (p)
  (multiple-value-bind (I Q) (setup-cut-point-randist p)
    (let ((M (length p)))
      #'(lambda ()
   (let* ((U (random-uniform))
     (X (aref I (floor (* M U)))))
   (tagbody
   start
   (if (<= U (aref Q (1- X)))
     (go end)
     (progn
     (incf X)
     (go start)))
   end)
   (1- X))))))