设置较大的n时,我的代码编译速度很慢。我不知道如何设置循环

时间:2018-10-10 09:58:32

标签: c++ c++11

c ++编译非常慢 二维向量

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 :(得分:4)

  
      
  • 此代码集成了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点的精确结果。 这个正交是最简单的一个。 我的测试代码是here

一维集成:

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;
}

二维集成:

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

最后,对于数值积分,有各种正交函数。 如果在此高斯被积中插入函数,则建议使用Hermite正交或快速高斯变换(FGT)。