Print

Print


On Sep 5, 2016, at 11:09 PM, Marshall <[log in to unmask]> wrote:

> I have in fact used forking in simulations—with your MersenneTwister lib, in fact, though not with MASON.  Nothing that has the basis of a publication, fortunately.
> 
> With the forking issue, is the idea that the relationship between subsequent outputs of MersenneTwister, used as seeds, and the way that the new instances of MT will respond to those seeds, is such that there’s a possibility that there could be correlations between the sequences of numbers generated by different instances of MT seeded in this way?

Yes.  Is there a *big* concern?  Probably not: it probably won't be an issue for your simulation.  But this is the kind of thing that gives statistical random number generator designers the screaming heebie-jeebies.

Why it's not a huge issue: you're probably forking by doing this:

	a = new MersenneTwister(oldMersenneTwister.nextInt());
	b = new MersenneTwister(oldMersenneTwister.nextInt());
	c = new MersenneTwister(oldMersenneTwister.nextInt());
	...

So what does this do exactly?  The MersenneTwister generates an internal array of 624 ints.  When you call nextInt() it gives you one of those ints [modified a bit].  When it runs out of ints to offer, it generates a new array by performing a magic function on the original array, and keeps on going.

So what you're doing is generating new MersenneTwisters based on subsequent ints in that table.  The way the new tables in a, b, and c above are generated is by using a fairly simple Knuth generator which does NOT make very random initial tables (hence the suggestion to pulse your new MersenneTwister at least 624 times, maybe more, to flush that first table).

The ints provided are uncorrelated -- that's the whole point of random number generation -- but no guarantees are made about the relationships between the generated tables of a, b, and c above.

So long story short, the MT is *not designed* to be forked.  I wouldn't fork it unless you really had a need to, just to be on the super-conservative safe side.  In contrast, there are very good generators which are designed to be forked.  However it *probably* won't be an issue, and it's probably even publishable.  But I would definitely at LEAST do this:

	int q = 0;
	do { q = oldMersenneTwister.nextInt(); } while (q == 0);
	a = new MersenneTwister(q);
	for(int i = 0; i < 624 * 2; i++) a.nextInt();
	do { q = oldMersenneTwister.nextInt(); } while (q == 0);
	b = new MersenneTwister(q);
	for(int i = 0; i < 624 * 2; i++) b.nextInt();
	do { q = oldMersenneTwister.nextInt(); } while (q == 0);
	c = new MersenneTwister(oldMersenneTwister.nextInt());
	for(int i = 0; i < 624 * 2; i++) c.nextInt();

Sean