Skip to content

Instantly share code, notes, and snippets.

@nfunato
Last active December 19, 2022 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nfunato/efc167986b91435bee49a3e8936eceb3 to your computer and use it in GitHub Desktop.
Save nfunato/efc167986b91435bee49a3e8936eceb3 to your computer and use it in GitHub Desktop.
;; based on https://marui.hatenablog.com/entry/2022/12/13/222030
(defun mapfn-into (arr fn &rest args)
(loop for i below (array-total-size arr)
do (setf (row-major-aref arr i) (apply fn args))
finally (return arr)))
(defun box-muller-random-sampling ()
"Return a pair of independent, standard, normally distributed
(zero expectation, unit variance) random number, using a random
number sampling method known as the Box–Muller transform."
(flet ((rndm () (loop for x = (random 1.0) when (plusp x) return x))
(bmrs (u1 u2)
(values (* (sqrt (* -2 (log u1))) (cos (* 2 pi u2)))
(* (sqrt (* -2 (log u1))) (sin (* 2 pi u2))))))
(bmrs (rndm) (rndm))))
(let ((stock nil))
(defun randn ()
"Return a random number following uniform and normal distribion."
(if (null stock)
(multiple-value-bind (r1 r2) (box-muller-random-sampling)
(progn (setq stock r2) r1))
(prog1 stock (setq stock nil)))))
(defun make-randn-array (dims)
(mapfn-into (make-array dims) #'randn))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment