мой код очень медленно компилируется, когда я установил большое число n.я не знаю, как установить петли - PullRequest
0 голосов
/ 10 октября 2018

c ++ очень медленно компилируется для 2d вектора

std::vector< vector<double>  > V(n, vector<double> (n));
double sum2=0;

for(int i=0; i<n; i++)
{

    double xai=xa1+i*dxa;
    double dxr=(double)(xr2-xr1)/n;
    double sum1=0;
    for(int j=0; j<n; j++){

        double xri=xr1+dxr*j;
        V[i][j]=fun(xri,xai);
        double rect1=V[i][j]*dxr;
        sum1+=rect1;
    }
    double rect2=sum1*dxa;
    sum2+=rect2;    
}
return sum2;

1 Ответ

0 голосов
/ 15 октября 2018
  • этот код объединяет 2-мерное [(1/2 * pi) * exp (-xr ^ 2/2) * exp (-xa ^ 2/2)].

  • интеграл для этого уравнения равен 1 в бесконечности, поэтому в c ++ мы должны увеличить пределы и n, чтобы получить результат, равный 1 в теории.

Если мы применим квадратуру Ньютона – Котса к бесконечному интегралу

enter image description here

, нам нужно обрезать нижнюю и верхнюю границу этогоинтеграл.Интегральное выражение должно быть пренебрежимо малым в точках отсечения.Какое значение вы выбрали?

Интегралом вашей задачи является гауссовское значение, которое быстро уменьшается следующим образом:

 exp(-10*10/2) ~ 1.93 * 10^(-22)

, что было бы незначительным в текущей интеграции.Таким образом, если мы обрежем нижнюю и верхнюю границу на -10 и +10, соответственно, и установим достаточное количество точек в этом диапазоне, мы должны получить точный результат.

Я действительно получил точный результат с точками 100x100, используяследующая трапециевидная квадратура.Эта квадратура самая простая.Мой тестовый код здесь .

1-мерная интеграция:

template<typename F>
double integrate_trapezoidal(F func, std::size_t n, double lowerBnd, double upperBnd)
{
    if(lowerBnd == upperBnd){
        return 0.0;
    }

    auto integral = 0.0;

    auto x = lowerBnd;
    const auto dx = (upperBnd - lowerBnd)/n;

    auto left = func(x);
    for(std::size_t i = 0; i<n; ++i)    
    {
        x += dx;
        const auto right = func(x);
        integral += (left + right);
        left = right;
    }

    integral *= (0.5*dx);

    return integral;
}

2-мерная интеграция:

template<typename F>
double integrate_trapezoidal_2dim(
    F func_2dim,
    std::size_t n,
    double x_lowerBnd, double x_upperBnd,
    double y_lowerBnd, double y_upperBnd)
{
    auto func = [&](double x)
    {
        return integrate_trapezoidal(
            std::bind(func_2dim, x, std::placeholders::_1), 
            n, y_lowerBnd, y_upperBnd); 
    };

    return integrate_trapezoidal(func, n, x_lowerBnd, x_upperBnd);
}

Я беспокоюсь, что вы установили конечную, но очень большую верхнюю и нижнюю границу.В этом случае вам нужно установить много точек, чтобы увеличить количество точек в диапазоне -10

Наконец, существуют различные квадратуры для числовых интегрирований.Если вы вставляете какую-то функцию в эту гауссову подынтегральную функцию, то рекомендуется использовать квадратуру Эрмита или быстрое преобразование Гаусса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...