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
-~----------~----~----~----~------~----~------~--~---

Reply via email to