Hi Bill, Thanks, that's a good point re: await. It would also be interesting to have the agents run for a certain length of time, rather than a certain number of iterations.
What do you think of using a map argument to a reduce fn? Idiomatic Clojure seems to prefer using a vector, but I am biased toward a map based on Ruby experience. I haven't decided which is more readable. Stuart > Hi Stuart, > > On Mon, Oct 27, 2008 at 7:06 PM, Stuart Halloway > <[EMAIL PROTECTED]> wrote: >> >> Hi all, >> >> The code below implements a Monte Carlo simulation to estimate the >> value of pi. It works, and it was easy to reuse the original single- >> threaded approach across multiple agents. >> >> How idiomatic is this use of agents? Other than bringing in ForkJoin, >> are there other idiomatic ways to parallelize divide-and-conquer in >> Clojure? >> >> Cheers, >> Stuart >> >> (defn in-circle? [[x y]] >> (<= (Math/sqrt (+ (* x x) (* y y))) 1)) >> >> (defn random-point [] >> [(dec (rand 2)) (dec (rand 2))]) >> >> ; take samples, tracking number that land >> ; :in circle and :total number >> (defn sample-for-pi [count] >> (reduce (fn [{in :in total :total} point] >> {:in (if (in-circle? point) (inc in) in) >> :total (inc total)}) >> {:in 0 :total 0} >> (take count (repeatedly random-point)))) >> >> >> (defn guess-from-samples [samples] >> (assoc samples :guess (/ (* 4.0 (:in samples)) (:total samples)))) >> >> ; guess pi by running Monte Carlo simulation count times >> (defn guess-pi [count] >> (guess-from-samples (sample-for-pi count))) >> >> ; guess pi by running Monte Carlo simulation count times >> ; spread across n agents >> (defn guess-pi-agent [n count] >> (let [count (quot count n) >> agents (for [_ (range n)] (agent count))] >> (doseq a agents (send a sample-for-pi)) >> (apply await agents) >> (guess-from-samples (reduce (fn [a1 a2] >> {:in (+ (:in @a1) (:in @a2)) >> :total (+ (:total @a1) (:total >> @a2))}) >> agents)))) > > I've not gotten around to playing with the concurrency features of > Clojure yet, so I'm just commenting "theoretically" on your code. In > "guess-pi-agent", you use "await" to wait for the results from the > agents. If one of the agents "dies", won't your code wait forever? I > would think that it would be preferable to use "await-for" (with a > timeout) so that the result can still be guessed based on the samples > that have come back from the other agents. If you plan to use a > variation of this code in a multi-processor example, some degree of > agent failure is even more likely. > > -- > Bill Clementson > > > --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---