【问题标题】:Generating random reals uniformly using Boost [closed]使用 Boost 统一生成随机实数 [关闭]
【发布时间】:2013-12-30 21:06:04
【问题描述】:

我正在尝试为蒙特卡洛积分生成一些统一的实数,但我构建的例程返回了一些非常奇怪的值。经过仔细检查,我注意到 Boost 返回了一些看起来很疯狂的随机数,例如:

     temp = -0.185276
     temp = -0.864523
     temp = -0.0942081
     temp = -0.164991
     temp = -0.873013
     temp = -0.0311322
     temp = -0.0866241
     temp = -0.778966
     temp = -0.367641
     temp = -0.691833
     temp = 5.66499e-310
     temp = 9.42007e-311
     temp = 6.29821e-310
     temp = 5.80603e-310
     temp = 8.82973e-311
     temp = 6.73679e-310
     temp = 6.35094e-310
     temp = 1.53691e-310
     temp = 4.39696e-310
     temp = 2.14277e-310

虽然这些数字在技术上仍然是在 -1 和 1 之间生成的实数,但如果它们不是那么小,我会更喜欢它!

我对 boost 的调用的实现是在一个多次调用的函数中(针对不同的边界值),如下所示:

// Define Boost typedefs
typedef boost::mt19937 Engine;
typedef boost::uniform_real<double> Distribution;
typedef boost::variate_generator <Engine, Distribution> Generator;

int main (void) {
    ...
    Integral = MCRecursion(...);
    ...
    return 0;
}

double MCRecursion (int Count, double Lower, double Upper, double (*Integrand)(double)) {

// Define Boost objects
Engine       Eng;
Distribution Dist (Lower, Upper);
Generator    RandomGen (Eng, Dist);

Eng.seed(time(0));

// Variables for Monte Carlo sample sums
double Sum = 0.0;
double temp;

for (int i = 0; i < Count; i++) {
    temp = RandomGen();
    std::cout << "         temp = " << temp << std::endl;
    Sum += Integrand(temp);
}

return (Upper - Lower) * Sum / Count;
}

我认为问题出在我的实现上,但我找不到任何错误。任何和所有的帮助表示赞赏! 干杯, 杰克

编辑

调用MCRecursion的代码:

我正在编写的代码在我感兴趣的整个域 [Lower, Upper] 上运行 Monte Carlo,然后再次查看整个域的左半部分和域的右半部分。 例如如果我们在 -a 和 a 之间积分 f(x),我会使用以下方法计算完整积分:

double FullDomain = MCRecursion (1e5, LowerBound, UpperBound, f);
double Centre = (Upper + Lower) / 2.0;
double LeftHalf = MCRecursion (1e5, LowerBound, Centre, f);
double RightHalf = MCRecursion (1e5, Centre, UpperBound, f);

然后我通过计算来查看不确定性: 双差 = fabs(FullDomain - LeftHalf - Righthalf); 看看更多的样本在某种意义上是否“值得” 杰克

【问题讨论】:

  • 嗯,这对我来说似乎很好。如果您希望您的值具有保证的最小绝对值,则必须在 [eps, 1] 上创建一个分布,并在另一个上创建一个用于选择符号的分布。这些值是否会导致任何问题?
  • 是的@stefan,因为数字的负载约为 0.0 无论我使用什么函数我积分都在接近零的情况下过度采样,所以假设我正在积分 f(x)=x 那么我的蒙特卡洛总和将显着低于预期。
  • 您能否显示调用MCRescursion 的代码并确保输出实际上是您发布的代码的输出?这个问题对我来说是无法重现的,我做了一个测试用例,得到了均匀分布的随机数。
  • 我猜@Nabla 所说的另一种说法是“请构造一个minimal test-case”;)

标签: c++ boost random montecarlo


【解决方案1】:

根据提问者在 cmets 中发布的 pastebin:

这不是随机库的问题,而是一个简单的编程错误。编译代码会抛出警告:

../src/Test.cpp: In function ‘double AdaptiveMCRecursion(double, double, double, double, int, double, double (*)(double))’:
../src/Test.cpp:100:72: warning: ‘Right’ is used uninitialized in this function [-Wuninitialized]
         double Right = MCSample (Count, Central, Right,   Integrand);

因此,从该行开始的所有行为基本上都是未定义的。特别是它会导致使用未确定的Upper 参数调用函数MCSample。所以你的结果并不意外。你真的很幸运程序运行了。

【讨论】:

  • 你说的很对,MCSample 的参数应该是(Count, Central, UPPER, Integrand)!干杯@nabla
  • @JackMedley 这就是为什么你应该认真对待编译器警告。
  • 或者只是在运行快速编译时不要忘记添加 -Werror ;)
猜你喜欢
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 2016-09-02
  • 2011-01-16
  • 2011-09-18
  • 2013-04-15
  • 1970-01-01
相关资源
最近更新 更多