Using One Persistent Mersenne Twister for Monte Carlo Sampling
Summary
The note diagnoses repeated or biased-looking Monte Carlo samples caused by constructing new Mersenne Twister random number generators inside each loop iteration. Its remedy is to create the generator once before the loop and draw successive values from that persistent instance. It also observes that separate generators for choosing a sign and generating a magnitude are unnecessary.
For a uniform sample over the interval from negative one to one, the answer recommends transforming a draw from the generator’s zero-to-one uniform range by scaling and shifting it. It further cautions that generator lifetime may need to extend beyond a single function if repeated calls would otherwise restart the same sequence. The discussion is practical advice tied to the described Java library use; it does not cover seeding policy, statistical testing, or simulation-specific distribution requirements.
Key ideas
- Create the random number generator once and reuse it across Monte Carlo draws.
- Repeatedly initializing generators inside a loop can produce repeated sequences.
- A uniform draw on the unit interval can be scaled and shifted to span negative one to one.
- A single generator can provide both the random sign and magnitude implicitly through the transformation.
- Generator lifetime may need to extend beyond one function to avoid restarting sequences.
Tags
Full text
# Mersenne twister random number generator in Java for Monte Carlo Sim.
# Mersenne twister random number generator in Java for Monte Carlo Sim.
I am using the Mersenne twister random number generator in Java for a Monte Carlo Simulation. I need a uniform distribution of values between -1 and 1. My code is below (I am importing org.apache.commons.math.random.MersenneTwister, which is a Apache Commons library that contains the methods I am calling).
```
for(int i = 0; i<= NumberOfTrials-1; i++ ) {
MersenneTwister mtsign = new MersenneTwister();
boolean sign = mtsign.nextBoolean(); // random true or false
MersenneTwister mt = new MersenneTwister();
if (sign=true){
random[i] = mt.nextDouble(); } //i.e. (random number between 0 and 1)
else if (sign=false){
random[i] = - mt.nextDouble(); } // i.e. random number beween -1 and 0
}
```
Each index of the resulting array, `random[]`, contains the same value for some reason (and all are positive as boolean keeps returning true). Any thoughts/advice is greatly appreciated.
## Answer by NPE (score 7, accepted)
https://quant.stackexchange.com/a/758
The problem is that you are creating a new random number generator for each iteration. Move `new MersenneTwister()` out of the loop:
```
MersenneTwister mtsign = new MersenneTwister();
MersenneTwister mt = new MersenneTwister();
for(int i = 0; i<= NumberOfTrials-1; i++ ) {
// use mtsign and mt here
...
}
```
Furthermore, you don't need two generators, you can just rescale:
```
MersenneTwister mt = new MersenneTwister();
for(int i = 0; i<= NumberOfTrials-1; i++ ) {
random[i] = mt.nextDouble() * 2 - 1;
}
```
Lastly, in your code, you may need to push the generator even further up the call tree to avoid generating the same sequence repeatedly.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.