提问者:小点点

用蒙特卡罗法确定积分不具有可接受的误差


我想计算e^(-landax)cosx从零到正无穷大的积分。精确解是landa/((landa^2)+1)。我试图解决的例子迫使我有0.01的最大误差。这里,我采用的方法是,首先从均匀分布函数[0,1]生成一个随机数,然后通过(-1/landa ln(x))对其进行变换,这样,现在每个变量将具有(landa*e^(-landa x))的概率。我不明白的是,当我把N从100万增加到1亿时,误差以以下方式变化,当然这不符合问题的标准,奇怪的是,从1000000的N增加到10000000的N,误差在增加。与N相对应的错误为:

N=1000000    0.0997496
N=100000000  0.0999462
N=100000000  0.0999341 

下面是我的代码:

#include <iostream>
#include <random>
#include <fstream>
#include <iomanip>
using namespace std;
double landa = 1;
double function(double x) {
    return (exp(-landa * x) * cos(x));
}

int main()
{
    unsigned seed = 0;
    srand(seed);
    double exact_solution = landa / (pow(landa, 2) + 1);
    const int N = 100000000;
    default_random_engine g(seed);
    uniform_real_distribution<double> distribution(0.0f, nextafter(1.0f, DBL_MAX));
    double sum = 0.0;
    double app;
    double error;
    for (int i = 0; i < N; i++) {
    double x = distribution(g);
    // transform xs 
    x = (-1.0 / landa) * log(x);
    sum = sum + function(x);
    }

    app = sum / static_cast<double> (N);
    error = exact_solution - app;
    cout << N << "\t" << error << endl; 

}

共1个答案

匿名用户

您产生了一个混乱:一旦您生成了具有适当分布的x,那么您必须简单地集成cos(x)

    sum = sum + cos(x);

输出:

1000000         -0.0010428
10000000        0.000105266
100000000       -2.08618e-05