Now using the rng for export
[clnl] / src / main / random.lisp
1 (in-package #:cl-nl.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* (mt19937::make-random-object :state (mt19937:init-random-state n))))
8
9 (defun next-int (n)
10  (rem (ash (mt19937:random-chunk mt19937:*random-state*) -1) n))
11
12 (defun next-double (&optional (n 1d0))
13  (let
14   ((y (mt19937:random-chunk mt19937:*random-state*))
15    (z (mt19937:random-chunk mt19937:*random-state*)))
16  (*
17   (/
18    (+ (ash (ash y -6) 27) (ash z -5))
19    (coerce (ash 1 53) 'double-float))
20   n)))
21
22 ; Oh, export world, you WILL be mine
23 (defun export ()
24  (let
25   ((state
26     (map
27      'list
28      (lambda (x) (if (logbitp (1- 32) x) (dpb x (byte 32 0) -1) x))
29      (mt19937::random-state-state mt19937:*random-state*))))
30   (format nil "0 ~A ~A ~A 0.0 false ~{~A~^ ~}"
31    (first state) (second state) (third state)
32    (nthcdr 3 state))))