con*_*ise 2 c++ random prng c++11
我是一名物理学家,编写的程序涉及从高斯分布中生成几个(数十亿的数量级)随机数.我正在尝试使用C++ 11.这些随机数的生成由一个应该花费很少时间的操作分开.我最担心的是,如果我生成如此多的随机数,并且时间间隔很小,则可能导致性能欠佳.我正在测试某些统计属性,这些属性严重依赖于数字随机性的独立性,因此,我的结果对这些问题特别敏感.我的问题是,我在下面的代码中提到的数字类型(我的实际代码的简化版本),我做的事情显然(甚至是巧妙地)错了吗?
#include <random>
// Several other includes, etc.
int main () {
int dim_vec(400), nStats(1e8);
vector<double> vec1(dim_vec), vec2(dim_vec);
// Initialize the above vectors, which are order 1 numbers.
random_device rd;
mt19937 generator(rd());
double y(0.0);
double l(0.0);
for (int i(0);i<nStats;i++)
{
for (int j(0);j<dim_vec;j++)
{
normal_distribution<double> distribution(0.0,1/sqrt(vec1[j]));
l=distribution(generator);
y+=l*vec2[j];
}
cout << y << endl;
y=0.0;
}
}
Run Code Online (Sandbox Code Playgroud)
该normal_distribution允许有状态.并且通过这种特定的分布,通常与每个其他调用成对地生成数字,并且在奇数调用上,返回第二个缓存的数字.通过在每次调用中构建新的分发,您将丢弃该缓存.
幸运的是,你可以通过调用不同的normal_distribution :: param_type来"塑造"单个发行版:
normal_distribution<double> distribution;
using P = normal_distribution<double>::param_type;
for (int i(0);i<nStats;i++)
{
for (int j(0);j<dim_vec;j++)
{
l=distribution(generator, P(0.0,1/sqrt(vec1[j])));
y+=l*vec2[j];
}
cout << y << endl;
y=0.0;
}
Run Code Online (Sandbox Code Playgroud)
我不熟悉所有的实现std::normal_distribution.但是我为libc ++写了一个.所以我可以肯定地告诉你,我对你的代码的轻微改写将产生积极的性能影响.我不确定它会对质量产生什么影响,只是说我知道它不会降低质量.
更新
关于Severin Pappadeux下面关于在分布中一次生成数字对的合法性的评论:参见N1452,其中讨论了这种技术并允许:
分布有时会在调用其运算符()的过程中存储来自相关随机数源的值.例如,用于生成正态分布的随机数的常用方法是检索两个均匀分布的随机数并从中计算出两个正态分布的随机数.为了将分发的随机数缓存重置为定义的状态,每个分发都有一个重置成员函数.只要交换或恢复相关引擎,就应该在分发中调用它.