Re: Advice on managing random number generators across threads

2014-06-07 Thread Mars0i
On Saturday, June 7, 2014 7:09:53 PM UTC-5, Alexander Hudek wrote:
>
> Keep in mind that there could be accuracy reasons why you might want to 
> use multiple random number generators (aka multiple streams). See the 
> section "Single Versus Multiple Streams" here:
>
> http://www.cse.msu.edu/~cse808/CSIM_Notes03/cse808/html_c/16random.htm
>

Very nice--thanks.  I had never heard of this issue, but it makes sense.  
 

> Also, the built in java random number generator is ok, but not 
> state-of-the-art in terms of quality. A more popular high quality generator 
> is the Mersenne twister. There are several java implementations available. 
>

That's what I thought, and I was leaning toward using a Mersenne twister.  
An additional advantage of sampling libraries like data.generators and 
bigml/sampling that allow one to specify the RNG is the ability to use a 
different RNG algorithm.

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-07 Thread Alexander Hudek
Keep in mind that there could be accuracy reasons why you might want to use 
multiple random number generators (aka multiple streams). See the section 
"Single Versus Multiple Streams" here:

http://www.cse.msu.edu/~cse808/CSIM_Notes03/cse808/html_c/16random.htm

Also, the built in java random number generator is ok, but not 
state-of-the-art in terms of quality. A more popular high quality generator 
is the Mersenne twister. There are several java implementations available. 


On Friday, June 6, 2014 11:33:04 PM UTC-4, Mars0i wrote:
>
> Wow.  Linus, thanks for the very detailed answer.
>
> It sounds as your view is that there's no problem with the logic of my 
> proposed solution, but it seems wasteful to create 100 RNGs, when I don't 
> actually need to have so many of them.  Your solutions provide ways to get 
> the same result without maintaining so many RNG objects in a simulation 
> run.  Is that roughly correct?
>
> On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:
>>
>> (I think your stepwise problem is better to be solved without agents, see 
>> below.)
>>
>> I realized that the *rng* actually is conflated, it keeps both the state 
>> for the random number generator AND the algorithm used for the random 
>> number generation. This is usually not a problem, since the state-size and 
>> usage is dependent on the particular random number generator, but it 
>> becomes a problem when we need to separate and multithread things 
>>
>
> Interesting point.  OK.  But seem my comment below about sharing of code 
> between RNG objects.
>  
>
>> One solution would be to either re-implement the algorithm (by Knuth) 
>> used in the original Sun Java random implementation, or use the 
>> experimental library Four [1] by Gary Fredericks that does exactly this.
>>
>
> Four looks very nice.  Its stateless RNGs return a new RNG, rather than an 
> RNG state, btw:
> (class (rs/java-random 1001))
> ;==>  four.stateless.JavaRandom
> (map class (rs/next-long (rs/java-random 1001)))
> ;==> (java.lang.Long four.stateless.JavaRandom)
>  I can see how this might be useful, though.
>
> What you would like to do is to be able to feed the rng-algorithm with the 
>> state (it is just a 64 bit long), and simply take the random-result 
>> generated from it, and store the state in the agent together with the rest 
>> of the simulation state.
>>
>> Dubious Speculations:
>> This makes it necessary to know that the agents are called in the same 
>> order (if the influence on each other). 
>>
>
>  
>
>> Given the non-guarantee of ordering in the nature of Java Threads and how 
>> agents rely on them I don't think you can expect your result to be 
>> reproducible. 
>>
>
> Right.  I can guarantee the order in which the random numbers are used 
> when I use map to cause each person to do its work, but I assume that I 
> can't guarantee this order when I use pmap.
>  
>
>> Here I assume that the incoming calls to agents aren't guaranteed to 
>> strictly ordered among different agents, even though the agents reside in 
>> one of two thread-pools (the send- vs. send-off pools). If two agents sent 
>> messages that arrived a third agent in different order, the rng-state would 
>> differ between the runs). Please correct me if I'm wrong on this one. 
>>
>
> No, there's no issue about the order in which messages are received, I 
> believe.  Communication is effectively simultaneous, because all sending 
> happens in one step, and all receiving happens in another step.
>  
> (Here are the details, if you're interested:  Each Person random chooses 
> other Persons to send a message to, and then randomly chooses a message to 
> send.  The pmap over the Persons ends, and all of the messages are 
> collected into a single hashmap.  Then a separate pmap goes through each 
> Person, applying the messages in the hashmap that are supposed to be sent 
> to that Person.  Thus, although Persons perform their work in some order, 
> the sending and the receiving of the messages are separated, so that 
> message sending and receipt occurs as if all messages were sent 
> simultaneously.  In the next timestep, the messages received by a Person 
> affect the probabilities that various messages will be chosen to send to 
> another Person.)
>  
>
>> A possible clever way around this could be to send the rng state together 
>> with the message arriving at the agent, to make the agent at least react to 
>> the state in a similar way. 
>>
>
> Interesting idea.  I don't think I'll need this, though.
>  
>
>> If you have some kind of continous magnitudes in the simulation - like 
>> pheromones - the simulation would maybe converge to similar results since 
>> the interaction effects would be reproducible but this is indeed a very 
>> far-fetched hypothesis.
>>
>
> The simulation converges, but the same parameters can allow convergence to 
> different outcomes.  I usually have to run the simulation many times with 
> the same parameters so that I can get a 

Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i


On Friday, June 6, 2014 10:33:04 PM UTC-5, Mars0i wrote:
>
> On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:
>>
>> Here I assume that the incoming calls to agents aren't guaranteed to 
>> strictly ordered among different agents, even though the agents reside in 
>> one of two thread-pools (the send- vs. send-off pools). If two agents sent 
>> messages that arrived a third agent in different order, the rng-state would 
>> differ between the runs). Please correct me if I'm wrong on this one. 
>>
>
> No, there's no issue about the order in which messages are received, I 
> believe.  Communication is effectively simultaneous, because all sending 
> happens in one step, and all receiving happens in another step.
>  
> (Here are the details, if you're interested:  Each Person random chooses 
> other Persons to send a message to, and then randomly chooses a message to 
> send.  The pmap over the Persons ends, and all of the messages are 
> collected into a single hashmap.  Then a separate pmap goes through each 
> Person, applying the messages in the hashmap that are supposed to be sent 
> to that Person.  Thus, although Persons perform their work in some order, 
> the sending and the receiving of the messages are separated, so that 
> message sending and receipt occurs as if all messages were sent 
> simultaneously.  In the next timestep, the messages received by a Person 
> affect the probabilities that various messages will be chosen to send to 
> another Person.) 
>

One more point about the detailed description: The immediate effects of 
messages on a Person who receives them are commutative (literally: they are 
additions).  Nothing else happens until all of the immediate effects of all 
messages are applied.

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
Wow.  Linus, thanks for the very detailed answer.

It sounds as your view is that there's no problem with the logic of my 
proposed solution, but it seems wasteful to create 100 RNGs, when I don't 
actually need to have so many of them.  Your solutions provide ways to get 
the same result without maintaining so many RNG objects in a simulation 
run.  Is that roughly correct?

On Friday, June 6, 2014 2:26:25 PM UTC-5, Linus Ericsson wrote:
>
> (I think your stepwise problem is better to be solved without agents, see 
> below.)
>
> I realized that the *rng* actually is conflated, it keeps both the state 
> for the random number generator AND the algorithm used for the random 
> number generation. This is usually not a problem, since the state-size and 
> usage is dependent on the particular random number generator, but it 
> becomes a problem when we need to separate and multithread things 
>

Interesting point.  OK.  But seem my comment below about sharing of code 
between RNG objects.
 

> One solution would be to either re-implement the algorithm (by Knuth) used 
> in the original Sun Java random implementation, or use the experimental 
> library Four [1] by Gary Fredericks that does exactly this.
>

Four looks very nice.  Its stateless RNGs return a new RNG, rather than an 
RNG state, btw:
(class (rs/java-random 1001))
;==>  four.stateless.JavaRandom
(map class (rs/next-long (rs/java-random 1001)))
;==> (java.lang.Long four.stateless.JavaRandom)
 I can see how this might be useful, though.

What you would like to do is to be able to feed the rng-algorithm with the 
> state (it is just a 64 bit long), and simply take the random-result 
> generated from it, and store the state in the agent together with the rest 
> of the simulation state.
>
> Dubious Speculations:
> This makes it necessary to know that the agents are called in the same 
> order (if the influence on each other). 
>

 

> Given the non-guarantee of ordering in the nature of Java Threads and how 
> agents rely on them I don't think you can expect your result to be 
> reproducible. 
>

Right.  I can guarantee the order in which the random numbers are used when 
I use map to cause each person to do its work, but I assume that I can't 
guarantee this order when I use pmap.
 

> Here I assume that the incoming calls to agents aren't guaranteed to 
> strictly ordered among different agents, even though the agents reside in 
> one of two thread-pools (the send- vs. send-off pools). If two agents sent 
> messages that arrived a third agent in different order, the rng-state would 
> differ between the runs). Please correct me if I'm wrong on this one. 
>

No, there's no issue about the order in which messages are received, I 
believe.  Communication is effectively simultaneous, because all sending 
happens in one step, and all receiving happens in another step.
 
(Here are the details, if you're interested:  Each Person random chooses 
other Persons to send a message to, and then randomly chooses a message to 
send.  The pmap over the Persons ends, and all of the messages are 
collected into a single hashmap.  Then a separate pmap goes through each 
Person, applying the messages in the hashmap that are supposed to be sent 
to that Person.  Thus, although Persons perform their work in some order, 
the sending and the receiving of the messages are separated, so that 
message sending and receipt occurs as if all messages were sent 
simultaneously.  In the next timestep, the messages received by a Person 
affect the probabilities that various messages will be chosen to send to 
another Person.)
 

> A possible clever way around this could be to send the rng state together 
> with the message arriving at the agent, to make the agent at least react to 
> the state in a similar way. 
>

Interesting idea.  I don't think I'll need this, though.
 

> If you have some kind of continous magnitudes in the simulation - like 
> pheromones - the simulation would maybe converge to similar results since 
> the interaction effects would be reproducible but this is indeed a very 
> far-fetched hypothesis.
>

The simulation converges, but the same parameters can allow convergence to 
different outcomes.  I usually have to run the simulation many times with 
the same parameters so that I can get a frequency distribution over 
outcomes.
 

> So only if your Person transform functions are commutative (ie gives the 
> same result whichever order they was called in every timestep) the 
> simulation could be reproducible by storing the local random generator seed 
> in each Person.
>

I see.  I think I understand now.  If I store the state and not the RNG 
code, but I am able to pass the state into the RNG code, that's all that I 
need to store in each Person.  I think the idea is that this would do the 
same work as in my proposal, but with less storage.

But wouldn't the RNG code be shared between RNG objects anyway?  For 
example, don't all java.util.Random objects share t

Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
Thanks Lee.  It looks like this could be useful.

On Friday, June 6, 2014 4:19:11 PM UTC-5, Lee wrote:
>
>
> I don't know if this will be helpful in your application, or even if it's 
> the best approach for our own work (or if java 1.7 provides a simpler 
> approach?), but FWIW one of my projects deals with the thread-local RNG 
> issue via: https://clojars.org/clj-random 
>
>  -Lee 
>

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-06 Thread Lee Spector

I don't know if this will be helpful in your application, or even if it's the 
best approach for our own work (or if java 1.7 provides a simpler approach?), 
but FWIW one of my projects deals with the thread-local RNG issue via: 
https://clojars.org/clj-random

 -Lee

On Jun 6, 2014, at 12:28 PM, Mars0i  wrote:

> I'm writing an agent-based simulation framework, in which agents are Clojure 
> records called Persons.  There are 40-100 persons at present, but conceivably 
> the number could go up to 1000.  In each timestep, Persons' states are 
> functionally updated by mapping update functions across the collection of 
> Persons.  The application is designed to be able to run in a single thread, 
> or to be run in multiple threads, depending on whether I do the mapping using 
> map or pmap.  (The application is generally faster with pmap (and all I had 
> to do was add "p"), but I think there might be contexts in which 
> single-threaded operation is preferable.)
> 
> At one point in the Person-update process, each Person randomly samples a 
> small number (1 to 50) of elements from some small collections (size 10 up to 
> the max number of persons).  When the application is multi-threaded, I'd 
> rather not have separate threads accessing the same random number generator.  
> (Java 1.7 allows a way of dealing with that, but for now I'd rather be 
> compatible with Java 1.6 as well.)
> 
> Does the following solution make sense?
> 
> 1. During initialization, I'll get a random number generator from 
> java.util.Random, initialized with the system time or something else that 
> varies.
> 
> 2. I'll give each person a field :rng, and will initialize each one with a 
> sparate call to java.util.Random, with a seed determined by the RNG mentioned 
> in the previous line.  (After this I can let the inititial RNG to be garbage 
> collected.)
> 
> 3. During the steps in which each Person needs to sample from collections, 
> the code will get the RNG from the Person's :rng file, and use it to 
> determine what elements are sampled.  
> 
> There is more than one way that I could implement step 3.  Here are some 
> options I'm considering:
> (a) Bind data.generators/*rnd* to the RNG, and then call functions in 
> data.generators.
> (b) Pass the Person's RNG to functions from bigml/sampling (which allow you 
> to pass in an RNG).
> (c) Write my own sampling functions that use the RNG from the Person.
> 
> Further remarks:
> 
> When the application is single-threaded, each Person will use a different 
> RNG, which isn't necessary, but it won't hurt, since the RNGs will have 
> different seeds, except that I waste memory by creating multiple RNGs.  When 
> the application is multi-threaded, I still don't need one RNG per person, 
> strictly speaking, since the number of threads will be much less than the 
> number of Persons.  However, giving each Person its own RNG is simpler.  It 
> means that my code can ignore  threads and let Clojure figure out how to 
> manage them.
> 
> 
> What do you think?  Thanks in advance for any help.

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-06 Thread Linus Ericsson
(I think your stepwise problem is better to be solved without agents, see
below.)

I realized that the *rng* actually is conflated, it keeps both the state
for the random number generator AND the algorithm used for the random
number generation. This is usually not a problem, since the state-size and
usage is dependent on the particular random number generator, but it
becomes a problem when we need to separate and multithread things.

One solution would be to either re-implement the algorithm (by Knuth) used
in the original Sun Java random implementation, or use the experimental
library Four [1] by Gary Fredericks that does exactly this.

What you would like to do is to be able to feed the rng-algorithm with the
state (it is just a 64 bit long), and simply take the random-result
generated from it, and store the state in the agent together with the rest
of the simulation state.

Dubious Speculations:
This makes it necessary to know that the agents are called in the same
order (if the influence on each other). Given the non-guarantee of ordering
in the nature of Java Threads and how agents rely on them I don't think you
can expect your result to be reproducible. Here I assume that the incoming
calls to agents aren't guaranteed to strictly ordered among different
agents, even though the agents reside in one of two thread-pools (the send-
vs. send-off pools). If two agents sent messages that arrived a third agent
in different order, the rng-state would differ between the runs). Please
correct me if I'm wrong on this one. A possible clever way around this
could be to send the rng state together with the message arriving at the
agent, to make the agent at least react to the state in a similar way. If
you have some kind of continous magnitudes in the simulation - like
pheromones - the simulation would maybe converge to similar results since
the interaction effects would be reproducible but this is indeed a very
far-fetched hypothesis.

So only if your Person transform functions are commutative (ie gives the
same result whichever order they was called in every timestep) the
simulation could be reproducible by storing the local random generator seed
in each Person.

If it's just speed you are after, do use either the java 1.7
ThreadLocalRandom (at least try out if this really gives any performance
boost).

A naive ThreadLocalImplementation implementation of clojure.core/rand would
be:

(defn rand
  "Returns a random floating point number between 0 (inclusive) and
  n (default 1) (exclusive)."
  {:added "1.0"
   :static true}
*  ([] (.nextDouble (java.util.concurrent.ThreadLocalRandom/current)))*
  ([n] (* n (rand

but as you can see in the source code, random integers are generated using
a call to (rand), multiplied with the integer and floored (when converting
to int), so there are ways to get an limited range int more efficiently
(check the source code for java.util.Random, which makes various tricks for
getting just enough random bits out.

As always, measure performance (Hugo Duncans Criterium,
criterium.core/bench is a really good start). Numerical double operations
are cheap, memory accesses - in this case to resulting data structures or
other agents and likely context switches - could as well be the more
expensive part.

BTW: It looks like the problem you want to solve would benefit much from
being formulated as a two-step problem, one where you applied all the
incoming calls to each Person, and another where you sorted the messages to
each Person in some reproducible order, like

* = has an incoming message

initial state: Person A will hit Person B, just for the lulz.

apply "map": A* B C
resulting actions sorted by Receiver: [A hits B]
apply these: A B* C
[B gets mad and throw raspberry pies at both A and C]
A* B C*
[A yells at B, C yells at B] <- mind the ordering! Always apply A's action
before Cs (or let B's random seed shuffle a sorted ordering of the same to
avoid ordering biases and make it reproducible)
A B* C
[B sends a stern look to A and C]


If you makes the message passing explicit instead of
Java-thread-call-uncertain-implicit (which IS possible and parallelizeable
in a stepwise simulation!) you can still parallelize it in many ways (for
example with reducers) and at the same time make simulations reproducible,
and you'll avoid a lot (N²) of potentially expensive context switching.

/Linus - take everything I say with a sand-pile avalanche of salt-grains.

[1] https://github.com/fredericksgary/four


2014-06-06 18:37 GMT+02:00 Mars0i :

> One more point:
>
> I would save the system-time-determined seed of the initial RNG to a file
> (i.e. the RNG used to generate seeds for each Person's RNG).  I believe
> this will allow me to re-run a simulation with identical results, by
> seeding the initial RNG with the seed saved from the previous simulation
> run.  Let me know if this doesn't make sense.  Thanks.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Cl

Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
On Friday, June 6, 2014 2:05:16 PM UTC-5, Gunnar Völkel wrote:
>
> In Java 7 you would use ThreadLocalRandom you said in another thread. 
> Well, in Java 6 you already have ThreadLocal [1] and thus you are able to 
> build a thread local Random yourself to keep Java 6 as minimum requirement.
>
> [1] 
> http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ThreadLocal.html
>

OK, that's good to know.  Great.  I may use that.  Thanks Gunnar.  

I still wonder whether the scheme I outlined would be a good strategy for 
preventing delays due to contention by different threads for the same RNG. 
  In my scheme, none of the RNGs would actually be local to threads.  Each 
would be globally accessible in principle, but no RNG would be accessed 
from more than one thread at a time.  (I like keeping things simple, but 
maybe I'm being simplistic.)

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-06 Thread Gunnar Völkel
In Java 7 you would use ThreadLocalRandom you said in another thread. Well, 
in Java 6 you already have ThreadLocal [1] and thus you are able to build a 
thread local Random yourself to keep Java 6 as minimum requirement.

[1] 
http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/ThreadLocal.html

-- 
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/d/optout.


Re: Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
One more point:

I would save the system-time-determined seed of the initial RNG to a file 
(i.e. the RNG used to generate seeds for each Person's RNG).  I believe 
this will allow me to re-run a simulation with identical results, by 
seeding the initial RNG with the seed saved from the previous simulation 
run.  Let me know if this doesn't make sense.  Thanks.

-- 
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/d/optout.


Advice on managing random number generators across threads

2014-06-06 Thread Mars0i
I'm writing an agent-based simulation framework, in which agents are 
Clojure records called Persons.  There are 40-100 persons at present, but 
conceivably the number could go up to 1000.  In each timestep, Persons' 
states are functionally updated by mapping update functions across the 
collection of Persons.  The application is designed to be able to run in a 
single thread, or to be run in multiple threads, depending on whether I do 
the mapping using map or pmap.  (The application is generally faster with 
pmap (and all I had to do was add "p"), but I think there might be contexts 
in which single-threaded operation is preferable.)

At one point in the Person-update process, each Person randomly samples a 
small number (1 to 50) of elements from some small collections (size 10 up 
to the max number of persons).  When the application is multi-threaded, I'd 
rather not have separate threads accessing the same random number 
generator.  (Java 1.7 allows a way of dealing with that, but for now I'd 
rather be compatible with Java 1.6 as well.)

Does the following solution make sense?

1. During initialization, I'll get a random number generator from 
java.util.Random, initialized with the system time or something else that 
varies.

2. I'll give each person a field :rng, and will initialize each one with a 
sparate call to java.util.Random, with a seed determined by the RNG 
mentioned in the previous line.  (After this I can let the inititial RNG to 
be garbage collected.)

3. During the steps in which each Person needs to sample from collections, 
the code will get the RNG from the Person's :rng file, and use it to 
determine what elements are sampled.  

There is more than one way that I could implement step 3.  Here are some 
options I'm considering:
(a) Bind data.generators/*rnd* to the RNG, and then call functions in 
data.generators .
(b) Pass the Person's RNG to functions from bigml/sampling 
 (which allow you to pass in an RNG).
(c) Write my own sampling functions that use the RNG from the Person.

Further remarks:

When the application is single-threaded, each Person will use a different 
RNG, which isn't necessary, but it won't hurt, since the RNGs will have 
different seeds, except that I waste memory by creating multiple RNGs.  
When the application is multi-threaded, I still don't need one RNG per 
person, strictly speaking, since the number of threads will be much less 
than the number of Persons.  However, giving each Person its own RNG is 
simpler.  It means that my code can ignore  threads and let Clojure figure 
out how to manage them.


What do you think?  Thanks in advance for any help.

-- 
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/d/optout.