Add CL style
[clnl] / src / main / random.lisp
1 (in-package #:clnl-random)
2
3 ; This is a wrapper around the very nice mersenne twister mt19937 to match
4 ; NetLogo's implementation that tries to match how java.util.Random works
5
6 (defun set-seed (n)
7  (setf mt19937:*random-state* (funcall
8                                (symbol-function (intern "MAKE-RANDOM-OBJECT" :mt19937))
9                                :state (mt19937:init-random-state n))))
10
11 (defun next-int (n)
12  (if
13   (= n (logand n (- n) ))
14   (ash (* n (ash (mt19937:random-chunk mt19937:*random-state*) -1) ) -31)
15   (rem (ash (mt19937:random-chunk mt19937:*random-state*) -1) n)))
16
17 (defun next-double (&optional (n 1d0))
18  (let
19   ((y (mt19937:random-chunk mt19937:*random-state*))
20    (z (mt19937:random-chunk mt19937:*random-state*)))
21   (*
22    (/
23     (+ (ash (ash y -6) 27) (ash z -5))
24     (coerce (ash 1 53) 'double-float))
25    n)))
26
27 ; Oh, export world, you WILL be mine
28 (defun export ()
29  (let
30   ((state
31     (map
32      'list
33      (lambda (x) (if (logbitp (1- 32) x) (dpb x (byte 32 0) -1) x))
34      (funcall (symbol-function (intern "RANDOM-STATE-STATE" :mt19937)) mt19937:*random-state*))))
35   (format nil "0 ~A ~A ~A 0.0 false ~{~A~^ ~}"
36    (first state) (second state) (third state)
37    (nthcdr 3 state))))