Ignore:
Timestamp:
Dec 21, 2009, 11:54:55 PM (10 years ago)
Author:
rme
Message:

Move INIT-RANDOM-STATE-SEEDS here from ccl:level-0;l0-numbers.lisp.

Add functions to create random state objects used by the new random
number generator, namely: %cons-mrg31k3p-state, initialize-mrg31k3p-state,
and random-mrg31k3p-state.

New function INITIAL-RANDOM-STATE, used to return the initial random
state used by a thread.

Updated make-random-state to create random state objects for the
mrg31k3p generator. x86-only for the moment, but PPC will follow
shortly.

New function %random-state-equalp, called from equalp.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/new-random/level-1/l1-numbers.lisp

    r13067 r13313  
    422422      nil)))
    423423
     424#-x86-target
    424425(defun %cons-random-state (seed-1 seed-2)
    425426  #+32-bit-target
     
    431432;;; random associated stuff except for the print-object method which
    432433;;; is still in "lib;numbers.lisp"
     434#-x86-target
    433435(defun initialize-random-state (seed-1 seed-2)
    434436  (unless (and (fixnump seed-1) (%i<= 0 seed-1) (%i< seed-1 #x10000))
     
    438440    (%cons-random-state seed-1 seed-2))
    439441
     442(defun init-random-state-seeds ()
     443  (let* ((ticks (ldb (byte 32 0)
     444                     (+ (mixup-hash-code (%current-tcr))
     445                        (let* ((iface (primary-ip-interface)))
     446                          (or (and iface (ip-interface-addr iface))
     447                              0))
     448                        (mixup-hash-code
     449                         (logand (get-internal-real-time)
     450                                 (1- target::target-most-positive-fixnum))))))
     451         (high (ldb (byte 16 16) (if (zerop ticks) #x10000 ticks)))
     452         (low (ldb (byte 16 0) ticks)))
     453    (declare (fixnum high low))
     454    (values high low)))
     455
     456(defun %cons-mrg31k3p-state (x0 x1 x2 x3 x4 x5)
     457  (let ((array (make-array 6 :element-type '(unsigned-byte 32)
     458                           :initial-contents (list x0 x1 x2 x3 x4 x5))))
     459    (%istruct 'random-state array)))
     460
     461(defun initialize-mrg31k3p-state (x0 x1 x2 x3 x4 x5)
     462  (let ((args (list x0 x1 x2 x3 x4 x5)))
     463    (declare (dynamic-extent args))
     464    (dolist (a args)
     465      (unless (and (fixnump a) (%i<= 0 a) (< a mrg31k3p-limit))
     466        (report-bad-arg a `(integer 0 (,mrg31k3p-limit)))))
     467    (when (and (zerop x0) (zerop x1) (zerop x2))
     468      (error "The first three arguments must not all be zero."))
     469    (when (and (zerop x3) (zerop x4) (zerop x5))
     470      (error "The second three arguments must not all be zero."))
     471    (%cons-mrg31k3p-state x0 x1 x2 x3 x4 x5)))
     472
     473(defun random-mrg31k3p-state ()
     474  (loop repeat 6
     475        for n = (init-random-state-seeds)
     476        ;; The first three seed elements must not be all zero, and
     477        ;; likewise for the second three.  Avoid the issue by
     478        ;; excluding zero values.
     479        collect (1+ (mod n (1- mrg31k3p-limit))) into seed
     480        finally (return (apply #'%cons-mrg31k3p-state seed))))
     481
     482(defun initial-random-state ()
     483  #-x86-target
     484  (initialize-random-state #xFBF1 9)
     485  #+x86-target
     486  (initialize-mrg31k3p-state 12345 12345 12345 12345 12345 12345))
     487
     488#-x86-target
    440489(defun make-random-state (&optional state)
    441   "Make a random state object. If STATE is not supplied, return a copy
    442   of the default random state. If STATE is a random state, then return a
    443   copy of it. If STATE is T then return a random state generated from
    444   the universal time."
     490  "Make a new random state object. If STATE is not supplied, return a
     491  copy of the default random state. If STATE is a random state, then
     492  return a copy of it. If STATE is T then return a randomly
     493  initialized random state."
    445494  (let* ((seed-1 0)
    446495         (seed-2 0))
     
    458507    (%cons-random-state seed-1 seed-2)))
    459508
     509#+x86-target
     510(defun make-random-state (&optional state)
     511  "Make a new random state object. If STATE is not supplied, return a
     512  copy of the current random state. If STATE is a random state, then
     513  return a copy of it. If STATE is T then return a randomly
     514  initialized random state."
     515  (if (eq state t)
     516    (random-mrg31k3p-state)
     517    (progn
     518      (setq state (require-type (or state *random-state*) 'random-state))
     519      (let ((seed (coerce (random.mrg31k3p-state state) 'list)))
     520        (apply #'%cons-mrg31k3p-state seed)))))
     521
    460522(defun random-state-p (thing) (istruct-typep thing 'random-state))
     523
     524(defun %random-state-equalp (x y)
     525  ;; x and y are both random-state objects
     526  #-x86-target
     527  (and (= (random.seed-1 x) (random.seed-1 y))
     528       #+32-bit-target
     529       (= (random.seed-2 x) (random.seed-2 y)))
     530  #+x86-target
     531  (equalp (random.mrg31k3p-state x) (random.mrg31k3p-state y)))
    461532
    462533;;; transcendental stuff.  Should go in level-0;l0-float
Note: See TracChangeset for help on using the changeset viewer.