我正在用适配器类包装 boost 随机数生成器来实现 Monte Carlo 例程。在对类的成员函数编写单元测试时,我假设 .discard(unsigned int N) 的行为是抽取 N 个随机数而不存储它们,从而推进 rng 的状态。升压代码是:
void discard(boost::uintmax_t z)
{
if(z > BOOST_RANDOM_MERSENNE_TWISTER_DISCARD_THRESHOLD) {
discard_many(z);
} else {
for(boost::uintmax_t j = 0; j < z; ++j) {
(*this)();
}
}
}
这支持了我的假设。但是,我发现 .discard(1) 产生的序列与没有丢弃的相同序列不是一个数字。编码:
#include <iostream>
#include <iomanip>
#include <random>
#include <boost/random.hpp>
int main()
{
boost::mt19937 uGenOne(1);
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > distOne(uGenOne, boost::normal_distribution<>());
boost::mt19937 uGenTwo(1);
boost::variate_generator<boost::mt19937&, boost::normal_distribution<> > distTwo(uGenTwo, boost::normal_distribution<>());
distTwo.engine().discard(1);
unsigned int M = 10;
std::vector<double> variatesOne(M);
std::vector<double> variatesTwo(M);
for (unsigned int m = 0; m < M; ++m) {
variatesOne[m] = distOne();
variatesTwo[m] = distTwo();
}
for (unsigned int m = 0; m < M; ++m)
std::cout << std::left << std::setw(15) << variatesOne[m] << variatesTwo[m] << std::endl;
return 0;
}
输出
2.28493 0.538758
-0.668627 -0.0017866
0.00680682 0.619191
0.26211 0.26211
-0.806832 -0.806832
0.751338 0.751338
1.50612 1.50612
-0.0631903 -0.0631903
0.785654 0.785654
-0.923125 -0.923125
我对 .discard 如何运作的解释不正确吗?为什么前三个输出中的两个序列不同,然后相同?
(此代码在 cygwin 上的 msvc 19.00.23918 和 g++ 4.9.2 上编译,结果相同)。