Hi Stuart,

A lot of parallel processing problems seem to lend themselves to a
mapreduce approach. I've written a few blog entries on mapreduce in
the past:

http://bc.tech.coop/blog/060105.html
http://bc.tech.coop/blog/070520.html
http://bc.tech.coop/blog/070601.html

Bill

On Tue, Oct 28, 2008 at 8:08 AM, Stuart Halloway
<[EMAIL PROTECTED]> wrote:
>
> 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