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 clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---