Add RNG
[clnl] / src / main / random.lisp
1 (defpackage #:cl-nl.random
2  (:use :common-lisp)
3  (:export :set-seed :next-int :next-double))
4
5 (in-package #:cl-nl.random)
6
7 ; This is a wrapper around the very nice mersenne twister mt19937 to match
8 ; NetLogo's implementation that tries to match how java.util.Random works
9  
10 (defun set-seed (n)
11  (setf mt19937:*random-state* (mt19937::make-random-object :state (mt19937:init-random-state n))))
12
13 (defun next-int (n)
14  (rem (ash (mt19937:random-chunk mt19937:*random-state*) -1) n))
15
16 (defun next-double (&optional (n 1d0))
17  (let
18   ((y (mt19937:random-chunk mt19937:*random-state*))
19    (z (mt19937:random-chunk mt19937:*random-state*)))
20  (*
21   (/
22    (+ (ash (ash y -6) 27) (ash z -5))
23    (coerce (ash 1 53) 'double-float))
24   n)))