我即将生成一组正态分布的伪随机数。据我所知,std库提供了以下代码:
std::random_device rd;
std::mt19937 gen(rd());
std::normal_distribution<> d(mean,std);
...
double number = d(gen);
问题在于我想使用Sobol'的准随机序列而不是Mersenne Twister伪随机生成器。所以,我的问题是: 是否可以使用用户定义的随机生成器运行std :: normal_distribution(在我的情况下使用Sobol'准随机序列生成器)?
更多细节:我有一个名为RandomGenerators的类,用于生成Sobol'的准随机数:
RandomGenerator randgen;
double number = randgen.sobol(0,1);
答案 0 :(得分:5)
是的,有可能。只要使其符合统一随机数发生器的要求(第26.5.1.3段第2和第3段):
2类
G
满足统一随机数的要求 如果表116中显示的表达式有效且具有 表示语义,如果G
也满足所有其他要求 这部分。在该表和整个部分中:a)
T
是G’s associated
result_type`命名的类型,b)
g
的值为G
。表116 - 统一随机数发生器要求
Expression | Return type | Pre/post-condition | Complexity ---------------------------------------------------------------------- G::result_type | T | T is an unsigned integer | compile-time | | type (§3.9.1). | ---------------------------------------------------------------------- g() | T | Returns a value in the | amortized constant | | closed interval | | | [G::min(), G::max()]. | ---------------------------------------------------------------------- G::min() | T | Denotes the least value | compile-time | | potentially returned by | | | operator(). | ---------------------------------------------------------------------- G::max() | T | Denotes the greatest value | compile-time | | potentially returned by | | | operator(). |
3以下关系应成立:
G::min() < G::max()
。
答案 1 :(得分:1)
这里要谨慎一点 - 当我实施这个时,我遇到了一个大问题。似乎如果max()/ min()/ operator()的返回类型不是64位,那么分布将重新取样。我的(无符号)32位Sobol实现每个偏差都被采样两次,从而破坏了数字的属性。此代码重现:
#include <random>
#include <limits>
#include <iostream>
#include <cstdint>
typedef uint32_t rng_int_t;
int requested = 0;
int sampled = 0;
struct Quasi
{
rng_int_t operator()()
{
++sampled;
return 0;
}
rng_int_t min() const
{
return 0;
}
rng_int_t max() const
{
return std::numeric_limits<rng_int_t>::max();
}
};
int main()
{
std::uniform_real_distribution<double> dist(0.0,1.0);
Quasi q;
double total = 0.0;
for (size_t i = 0; i < 10; ++i)
{
dist(q);
++requested;
}
std::cout << "requested: " << requested << std::endl;
std::cout << "sampled: " << sampled << std::endl;
}
输出(使用g ++ 5.4):
requested: 10
sampled: 20
甚至在使用-m32编译时。如果将rng_int_t更改为64位,问题就会消失。我的解决方法是将32位值粘贴到返回值的最高位,例如
return uint64_t(val) << 32;
答案 2 :(得分:0)
您现在可以直接使用Boost生成Sobol序列。参见boost / random / sobol.hpp。