Skip to content

Random number generator

Urs Haehner edited this page Jul 19, 2018 · 3 revisions

Monte Carlo integration relies on drawing random numbers. In the quantum Monte Carlo solvers of DCA++, we provide each walker with its own random number generator (RNG). There are different options for the type of the RNG. DCA++ features a wrapper class for the random number library of C++11. Using the CMake variable DCA_RNG one can choose the underlying std random number engine:

std::mt19937_64 (default)
std::ranlux48	

Alternatively, any other RNG that satisfies the specified interface can be plugged into DCA++. This is done by selecting the custom option of DCA_RNG and providing the class name (including namespaces) and the header file of the RNG, and the library, if required:

$ cmake ../dca_source \
	-DDCA_RNG=custom \
	-DDCA_RNG_CLASS=mynamespace::MyRng \
	-DDCA_RNG_HEADER=/path/to/my_rng.hpp \
	-DDCA_RNG_LIBRARY=/path/to/my_rng.a \
	...

Interface

Contructor

RandomNumberGenerator(const int proc_id, const int num_procs, const uint64_t seed = 0);

proc_id: (MPI) process ID
num_procs: total number of (MPI) processes

Seeding

In order to sample uncorrelated configurations in the Markov Chain Monte Carlo procedure, it is important that the RNG of each walker is uniquely seeded. For this purpose, we provide the following utility functions declared in the header random_utils.hpp, that we recommend to use in the constructor of the RNG (see std_random_wrapper.hpp).

getGlobalId computes a unique global ID from the local_id (= ID within the process) and the process_id, where num_procs is the total number of processes:

int getGlobalId(const int local_id, const int process_id, const int num_procs);

generateSeed computes a unique seed from the unique global_rng_id, where the parameter offset can be used to generate different seeds:

uint64_t generateSeed(const int global_rng_id, const uint64_t offset = 0);

operator()

double operator()();

Generates the next random number in the interval [0,1).

Non-copyable, but movable

To prevent undesired correlations, RNGs should be non-copyable. However, to store them in an STL-container like std::vector, they have to be move-constructible. For example, a std::vector containing num_rngs RNGs is easily and efficiently created by using emplace_back:

std::vector<RandomNumberGenerator> rngs;
for (int i = 0; i < num_rngs; ++i)
	rngs.emplace_back(proc_id, num_procs, seed);

Wrapper for random number library of C++11

Defined in header std_random_wrapper.hpp.
The wrapper class for the random number library of C++11 is templated on the type of the random number engine:

template <typename Engine>
class StdRandomWrapper;

For example, a RNG that uses the 64-bit Mersenne Twister algorithm is constructed by:

StdRandomWrapper<std::mt19937_64> rng(proc_id, num_procs, seed);