Harvey> (defun one-normal-rand ()
Harvey>   (let* ((u (random 1d0))
Harvey>          (u1 (random 1d0))
Harvey>          (v (* SQRT2OVERE (- (* 2d0  u1) 1d0)))
Harvey>          (x (/ v u))
Harvey>          (y (/ (* x x) 4d0)))
Harvey>     (if (and (> y (- 1d0 u))
Harvey>              (> y (- (log u))))
Harvey>         (one-normal-rand)
Harvey>       x)))


I think random numbers is quite expensive; generating the gaussians
pairwise gives an efficiency of pi/4:

(defun gausspair (&optional (state *random-state*))
  (declare (optimize (speed 3) (safety 0)))
  (loop
    for u of-type double-float = (- (random 2.d0 state) 1.d0)
    for v of-type double-float = (- (random 2.d0 state) 1.d0)
    for r of-type double-float = (+ (expt u 2) (expt v 2))
    until (< r 1.d0)
    finally (let* ((l (log r))
                   (d (sqrt (/ (* -2.d0 l) r))))
              (declare (type double-float l d))
              (return (values (* u d) (* v d))))))

Ole

Reply via email to