[英]how to ask boost::normal_distribution to generate a large vector of random variables without for loop
我有一个很大的向量,我想添加具有正态分布的噪声。 我现在在做什么对于循环来说是微不足道的:
for (int i=0 ; i<size ; i++){ //size is of order 1000000
boost::mt19937 gen;
gen.seed(i);
boost::normal_distribution<> nd(0.0 , 1.0);
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> >
randNormal (gen,nd);
noise = randNormal();
nsyData[i] = data[i] + sd*noise;
}
有一种有效的方法可以做到这一点吗? 像MATLAB一样吗?
这是我的看法:
#include <boost/random/normal_distribution.hpp>
#include <boost/random.hpp>
int main()
{
boost::mt19937 gen(42); // seed it once
boost::normal_distribution<double> nd(0.0, 1.0);
boost::variate_generator<boost::mt19937&, boost::normal_distribution<double> > randNormal(gen, nd);
std::vector<double> data(100000, 0.0), nsyData;
nsyData.reserve(data.size());
double sd = 415*randNormal();
std::transform(data.begin(), data.end(), std::back_inserter(nsyData),
[sd,&randNormal](double data) { return data + sd*randNormal(); });
}
请注意,您在循环的每次迭代中都播种了mersenne扭曲器。 恐怕这完全破坏了所生成随机数的任何质量保证。 播种一次发电机。 (显然,如果需要不确定的种子,请使用其他种子,例如,使用random_device的种子)。
看到这个Live on Coliru
更新在评论中来回反复后,这是一个c ++ 03版本,虽然仍然可以理解,但实际上应该不会太糟糕:
#include <boost/random/normal_distribution.hpp>
#include <boost/random.hpp>
#include <boost/bind.hpp>
struct Xfrm {
typedef double result_type;
template <typename Gen>
double operator()(double sd, Gen& randNormal, double data) const {
return data + sd*randNormal();
}
};
int main()
{
boost::mt19937 gen(42); // seed it once
boost::normal_distribution<double> nd(0.0, 1.0);
boost::variate_generator<boost::mt19937&, boost::normal_distribution<double> > randNormal(gen, nd);
std::vector<double> data(100000, 0.0), nsyData;
nsyData.reserve(data.size());
double sd = 415*randNormal();
std::transform(data.begin(), data.end(), std::back_inserter(nsyData),
boost::bind(Xfrm(), sd, boost::ref(randNormal), ::_1));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.