I don’t see it as necessarily bad to use a separate instance of MersenneTwister in each agent.  It will use extra memory, but whether that’s problematic depends on your situation.  

There’s a view that implies that in an ABM, there’s a remote chance that using a single RNG could be bad in some cases:  A good pseudorandom number generator, such as Mersenne Twister, is one in which it’s difficult to find cycles or other simple patterns in the sequence of numbers generated.  However, one can’t rule out any possibility that there are some patterns hidden in the numbers generated.  A pattern, in this case, needn’t mean getting the same number repeatedly.  It could be something more subtle about the numbers.  (An unsubtle, famous or perhaps apocryphal example: An old version of Unix had a random number generator function that alternated between even and odd numbers.)  

Since ABMs involve typically involve making different agents do things that are in some sense the same, over and over again, you could worry that you might someday get results that are an artifact of some pattern in output of the RNG that’s “discovered” by patterns in your simulation.  That’s unlikely, but a way to avoid this remote possibility is to use separate instances of MersenneTwister in each agent, each seeded by a different random number (e.g. from another instance of MersenneTwister).


On Sep 4, 2016, at 3:59 PM, Steven Pousty <[log in to unmask]> wrote:

Yeah that is what I thought the code would look like and no I am parellelizing the model now. I am actually thinking of using OpenShift and the simulation running in a docker container. I would have all the models output to Cassandra (or something like that) and then divide up the total number of simulations into X number of containers.

Per the manual I also think I will do a burn in for each new VonMises in the constructor

Thanks for your help!

On Sun, Sep 4, 2016 at 6:44 AM, Joey Harrison <[log in to unmask]> wrote:
Unless you're parallelizing your model, it would be fine to use the same RNG for every agent, but that's not what I am suggesting. I am suggesting you use runner.random.nextLong() to produce seeds for all the RNGs for each agent. Right now they're only getting five different seeds for 40 agents because the seed is based on the current time. Try this:

Change line 25 of Animal.java to this:
private VonMises vonMises;

Then add a constructor:

public Animal(Runner runner) {
   vonMises = new VonMises(0.0000001, new ec.util.MersenneTwisterFast(runner.random.nextLong()));

And then change line 25 of Runner.java to:
p = new Animal(this);

See what that does.


On Sun, Sep 4, 2016 at 4:03 AM, Steven Pousty <[log in to unmask]> wrote:
I am with you on #3 and I had that thought this morning but I thought it surely uses something more interesting. I think I might pass in the random generator from the Runner to use for the random.nextLong(). I should do that rather than reusing the same generator inside each agent because, if I remember correctly it is not threadsafe:

There are actually two versions of Mersenne Twister: the class ec.util.MersenneTwister and the class ec.util.MersenneTwisterFast. The former is a drop-in subclass replacement for java.util.Random, and is threadsafe. The latter is not threadsafe, is not a subclass of java.util.Random, and has many methods (perhaps nowadays unnecessarily) heavily inlined, and as a result is significantly faster. MersenneTwisterFast is the only class provided with and used by MASON.

Which, in my limited understanding, makes me think re-using it in every Agent is a bad idea. Does that agree with your understanding?


On Sat, Sep 3, 2016 at 10:22 PM, Joey Harrison <[log in to unmask]> wrote:
A couple quick thoughts:

1) My first thought is that there's a transient phase (or something else strange) in your RNG. Try writing a test program that calls vonMises.nextDouble() 1000 times and save the values in a text file. Read the file into R or whatever you use and plot the distribution. Does it look like what you expect? Do there happen to be five clusters or are your samples nearly uniform?

2) The κ you picked, 1e-7, should give you a distribution very close to uniform. Try using MASON's RNG instead, which is uniform, and see what happens. 
Change this:
double direction = vonMises.nextDouble();
To this:
double direction = (runner.random.nextDouble() - 0.5) * 2 * Math.PI;

If it looks normal, you know there's something strange happening with the vonMises RNG.

3) It's possible that you're creating a bunch of RNGs with the same seed. When you instantiate a MersenneTwisterFast without giving it a seed, it uses System.currentTimeMillis(). I'm guessing it takes about 5 milliseconds to create all your agents, which is why you see only five different angles. Either seed them with an incrementing value, or use random.nextLong().

I'm pretty sure it's #3.

Good luck,

On Sat, Sep 3, 2016 at 11:41 PM, Steven Pousty <[log in to unmask]> wrote:
Greetings all:
I am writing an agent based model to explore wildflife corridor selection. I started by taking the woims example from the tutorial and then modifying it. Everything was going fine until I implemented choosing movement based on a random angle and a random distance.

I had to use the COLT library integration for the Von Mise distribution (typically used for circular valued numbers). I put in the burn for the constructor to see if that would help. I also 

I am seeing that on the first step, there is only a small number different angles being chosen but then for the rest of the steps it seems to working as expected. I tried debugging and seeing that I am generating new agents each with their own instance of the MersenneTwister. 

I would really love if someone could look at the code and see what I am missing (I do not believe anything is broken in MASON or COLT - things are just broken in my brain ;)  ). 

Here is the agent code

and here is the runnable

I have attached the screen shot showing the weird behavior on step 1 for multiple simulations. 

I am sure others have seen this and I am just forgetting something important.  

Thanks in advance!