Action #354

Updated by Knödlseder Jürgen almost 12 years ago

In the actual implementation, the state of the random number generator at the start of observation N+1 depends on the state of the random number generator at the end of observation N. This has to be modified to allow a deterministic parallelization of the code.

For the moment, the @ctobssim@ class has one global random number generator @m_ran@:
<pre>
GRan m_ran; //!< Random number generator
</pre>
This should be replaced by a vector of random number generators, one for each observation:
<pre>
std::vector<GRan> m_ran; //!< Random number generators
</pre>

The assignment of the seed values for the random number generators is done in @ctobssim::get_parameters@. Actually the code is:
<pre>
// Get other parameters
m_seed = (*this)["seed"].integer();

// Initialise random number generator
m_ran.seed(m_seed);
</pre>

What is needed here is a code that initializes the vector of random number generators with deterministic seed values, that differ however from observation to observation. This is a tricky task, as different seed values should always lead to statistically different datasets.

If one would for example simply increment seed by 1 from one observation to the next, a @ctobssim@ run for which the seed parameter is incremented by one with respect to another run would virtually produce the same data (only two observations would be different).

I guess a pretty clean method would be to use a random number generator to assign seed values for all random number generators, avoiding that a given seed value is used twice (if a given seed value would be used twice we would have two simulated observations with an identical set of events). Something like:
<pre>
GRan master(m_seed);
std::vector<unsigned long long int> seed;
for (int i = 0; i < m_obs.size(); ++i) {
unsigned long long int new_seed;
do {
new_seed = (unsigned long long int)(master * 1.0e20);
bool repeat = false;
for (int j = 0; j < seed.size(); ++j) {
if (new_seed == seed[j]) {
repeat = true;
break;
}
}
} while(repeat);
seed.push_back(new_seed);
}
</pre>

Now we should have a set of seed values that is fully deterministic, but that guarantees at the same time that each observation is simulated with a different seed value. In a subsequent loop, we can initialise random number generators with these seed values and push them on the vector, e.g.
<pre>
m_ran.push_back(GRan(seed[i]));
</pre>
This code should be okay, as the GRan copy operator copies the seed value, but it should be checked that the random number generator in the vector produces the same sequence of numbers as the random number generator that was pushed.

Finally, we have to modify the @ctobssim::run@ method to explicitly select a random number generator from the vector. For this purpose, one probably has to add the random number generator as parameter to the @ctobssim::simulate_source@ and @ctobssim::simulate_background@ methods, and modify these routines so that the use the random number generator passed in the argument.

Back