Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate a massive amount of high quality Random Numbers?

I'm working on a random walk simulation of particles moving in a lattice. For that reason I must create a massive amount of random numbers, about 10^12 and above. Currently I'm using the possibilities C++11 provides with <random>. When profiling my program, I see that a major amount of time is spent in <random>. The vast majority of those numbers are between 0 and 1, evenly distributed. Here a then I need a number from a binomial distribution. But the focus lies on the 0..1 numbers.

The question is: What can I do to reduce the CPU time needed to generate these numbers and what would the impact be on their quality?

As you can see, I tried different engines, but that had no big effect on CPU time. Further, what is the difference between my uniform01(gen) and generate_canonical<double,numeric_limits<double>::digits>(gen) anyhow?

Edit: Reading through the answers I conclude that there is not THE ideal solution for my problem. Thus I decided to first make my program multi threading capable and run multiple RNG in different threads (seeded with one random_device number + an thread individual increment). For the time being this seams to be the most unavoidable step (multi threading would be required anyhow). As a further step, pending on exact requirements I consider switching to the suggested Intel RNG or to Thrust. Meaning that my RNG implementation should not be to complex, which, currently is is not. But for now I like to focus on the physical correctness of my model and not on programming stuff, this comes as soon as the output of my program is physically correct. Thrust Concerning Intel RNG

Here is what I do currently:

class Generator {
public:
    Generator();
    virtual ~Generator();
    double rand01(); //random number [0,1)
    int binomial(int n, double p); //binomial distribution with n samples with probability p
private:
    std::random_device randev; //seed
    /*Engines*/
    std::mt19937_64 gen;
    //std::mt19937 gen;
    //std::default_random_engine gen;
    /*Distributions*/
    std::uniform_real_distribution<double> uniform01;
    std::binomial_distribution<> binomialdist;
};

Generator::Generator() : randev(), gen(randev()), uniform01(0.,1.), binomial(1,1.) {
}

Generator::~Generator() { }

double Generator::rand01() {
    //return uniform01(gen);
    return generate_canonical<double,numeric_limits<double>::digits>(gen);
}

int Generator::binomialdist(int n, double p) {
    binomial.param(binomial_distribution<>::param_type(n,p));
    return binomial(gen);
}
like image 512
dani Avatar asked Sep 26 '14 05:09

dani


1 Answers

You can pre-process random numbers and use them when you need.

If you need true random numbers I suggest you to use a service like http://www.random.org/ that ensures random numbers calculated by environment ambient instead that some algorithm.

And, speaking about random numbers, you must also check this:

enter image description here

like image 108
Jepessen Avatar answered Sep 29 '22 17:09

Jepessen