mars0i / popco2

Cultural transmission with analogy biases.
GNU General Public License v3.0
3 stars 0 forks source link

Rewrite sampling functions used in speak.clj to prevent cross-thread refs to RNGs #5

Closed mars0i closed 10 years ago

mars0i commented 10 years ago

At present, receive-utterances is pmaped by default, but it calls the Incanter sample, which indirectly uses Clojure's rand. This probably means that the separate threads have to coordinate access to a single RNG. i.e. you wouldn't want to just copy it to each thread; then each thread would repeat the same sequence of numbers. Try the following a few times:

(def nums (doall (repeat 10000 1)))
(time (def rs (doall (map rand nums))))
(time (def rs (doall (pmap rand nums))))

The pmap version is an order of magnitude slower.

Maybe the right thing to do is to create a distinct RNG with a different seed for each person??

mars0i commented 10 years ago

Consider using clojure.data.generators or bigml/sampling rather than Incanter or default Clojure functions.

mars0i commented 10 years ago

Note that the sampling functions are no longer in receive-utterances, but in speak.clj. Sampling functions are now defined in random.clj, and take a rand-idx function. Clojure's rand-int does the job, but other functions definable via random.clj allow using a different rand-idx based on a different RNG object for each person. At the moment the code just uses rand-int. Next step is to add a :rand-idx field to persons, and initialize it with rand-idx functions based on randomly-seeded RNGs. (Then the seed used to initialize that 0th RNG can be stored.)