Hi Andy, cej38, kovas:

Thanks for the replies. I plan to release the whole code soon (waiting for 
institutional authorization).

I do use lazyness both within the move function to select the allowed 
random displacements and when iterating the move function to generate the 
trajectory. Lazy structures are only consumed within the thread in which 
they are created.

Here is the core code where the computations happens:

(defn step-particle
  "Returns a new value for particle after moving particle once to a new 
position from the current one"
  [pdf-get-fn step-condition-fn calc-value-fns particle]
  (let [pos (particle :pos)
        disp (first (filter (fn [x] (step-condition-fn (particle :pos) x)) 
(repeatedly (fn [] (pdf-get-fn)))))
        new-pos (mapv + pos disp)
        new-base-particle {:pos new-pos :steps (inc (particle :steps))}
        new-trackers-results (if (seq calc-value-fns)
                               (zipmap
                                 (keys calc-value-fns)
                                 ((apply juxt (vals calc-value-fns)) 
particle new-base-particle))
                               {})]
    (merge new-trackers-results new-base-particle)))

(defn walk-particles
  "While there is work to do, create new particles, move them n-steps, then 
send them to particle container (agent)"
  [todo particles simul-info init-get-fn init-condition step-get-fn 
step-condition trackers-maps step-extract-fn]
  (let [init-value-fns (zipmap
                         (keys trackers-maps)
                         (map :create-fn (vals trackers-maps)))
        calc-value-fns (zipmap
                         (keys trackers-maps)
                         (map :compute-fn (vals trackers-maps)))
        move (partial step-particle step-get-fn step-condition 
calc-value-fns)]

    (while (> @todo 0)
      (swap! todo dec)
      (let [p (last (create-particle init-get-fn init-condition 
init-value-fns))
            lazy-steps (iterate move p)
            result (step-extract-fn lazy-steps)]
         (send-off particles (fn [x] (conj x result)))
        ))))

Each worker is created launching a future that executes walk-particles, 
each worker has a separate Mersenne Twister random number generator 
embedded into the pdf-get-fn (using partial on a common pdf-get function 
and different MT generators). In real calculations both number of particles 
and steps are at least 1e4. In the benchmarks I'm posting particles are 
1000, steps are 5000.

As expected conjoining to a single global vector poses no problem, I tested 
both conjoining to a single global vector and to separate global vectors 
(one per worker) and the computing time is the same.

I could test in another system with 16 cores. See the results attached for 
the 8 and 16 core systems.

Best,

Jose.

-- 
-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Attachment: benchmark.pdf
Description: Adobe PDF document

Reply via email to