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!