lvaruzza / cl-randist

Random number generation for common lisp
http://code.google.com/p/cl-randist/
20 stars 10 forks source link

RANDOM-MT seems to disrupt repeatability because of its treatment of random states #6

Open rpgoldman opened 10 years ago

rpgoldman commented 10 years ago
(defun random-mt (n &optional state)
  "There is a bit of optimization to do..."
  (assert (plusp n))
  (when state
    (assert (mt-random-state-p state))
    ;; Save a copy of the random state.
    (setq *mt-random-state* (make-mt-random-state state)))
  (if (integerp n)
      (mod (do ((bits-needed  (log n 2)                             )
                (bit-count            0             (+ 32 bit-count))
                (r                    0  (+ (ash r 32) (mt-genrand))))
               ((>= bit-count bits-needed) r))
           n)
    (* (mt-genrand) +mt-k-inverse-2^32f+ n)))

Why does this set *mt-random-state* instead of using LET to bind it around the following call? As I read this, it leaks a side-effect of changing the value of the random seed....

lvaruzza commented 10 years ago

Actually a didn´t wrote this part of the code, I copied it from Gene Michael Stover.

rpgoldman commented 10 years ago

This actually seems quite odd because, if I understand it correctly, this will ensure that the random state is not changed when you run this multiple times. If you are trying to get reproducible results for a stream of random numbers, that's precisely not what you want -- you should be leaving it to the caller to copy the random state. After all, the caller has the ability to copy the random state object, but the caller does not have the ability to "un-copy" it if you make a non-destructive version of this function.

If I get a chance, I will provide a patch. Meanwhile, I urge you to leave this issue open until it's fixed.