On 14.12.2008, at 08:19, Mark H. wrote:
> So I'm going to stop pretending like I'm an expert and actually post
> some Clojure code. Be constructively critical 'cause I'm a n00b in
> that regard ;-) This is a pseudorandom number generator for the
> Gaussian (0,1) distribution.
...
Isn't that the standard Box-Muller transform?
Anyway, I tried to rewrite your code into a function that takes an
input stream of uniformly distributed random numbers and transforms
it into a stream of Gaussian random numbers. The advantage is that
there is no need to keep track explicitly of the state of the
calculation. In the following, I construct my input stream by
repeatedly calling Clojure's (rand), but you could easily substitute
any other source, including java.Util.Random.
Konrad.
(defn rng-uniform
"Return an infinite lazy sequence of random numbers"
[]
(drop 1 (iterate (fn [_] (rand)) nil)))
(defn transform-to-gaussian
"Transform a sequence of uniform random number in the interval [0, 1)
into a sequence of Gaussian random numbers."
[uniform-seq]
(let [[U1 U2 & uniform-rest] uniform-seq
V1 (- (* 2.0 U1) 1.0)
V2 (- (* 2.0 U2) 1.0)
S (+ (* V1 V1) (* V2 V2))
LS (. Math sqrt (/ (* -2.0 (. Math log S)) S))
X1 (* V1 LS)
X2 (* V2 LS)]
(if (or (>= S 1) (= S 0))
(recur uniform-rest)
(lazy-cons X1 (lazy-cons X2 (transform-to-gaussian uniform-
rest))))))
; Get 10 Gaussian random numbers
(take 10 (rng-gaussian))
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---