递归问题(2d求积分)

时间:2012-10-20 23:53:24

标签: c++ numerical-methods

所以我有一个程序在函数x ^ 2 + y ^ 2< 2上实现自适应2D梯形规则。 1,但似乎递归不起作用 - 这里的程序是(工作)1D梯形方法的修改形式,所以我不确定代码在哪里发生故障,它应该返回PI:

double trapezoidal(d_fp_d f,
                   double a, double b,
                   double c, double d) { //helper function
    return 0.25*(b-a)*(d-c)*
    (f(a, c)+f(a, d) +
     f(b, c)+f(b, d));
}

double atrap( double a, double b, double c, double d, d_fp_d f, double tol )
 {// helper function

 return atrap1(a, b, c, d, f, tol );
 }
double atrap1( double a, double b, double c, double d, d_fp_d f, double tol)
{
 //implements 2D trap rule 
    static int level = 0;
    const static int minLevel = 4;
    const static int maxLevel = 30;
    ++level;
    double m1 = (a + b)/2.0;
    double m2 = (c + d)/2.0;
    double coarse = trapezoidal(f,a,b,c,d);
    double fine = 
      trapezoidal(f, a, m1, c, m2)
    + trapezoidal(f, a, m1, m2, d)
    + trapezoidal(f, m1, b, c, m2)
    + trapezoidal(f, m1, b, m2, d);
    ++fnEvals;
    if( level< minLevel
       || ( abs( fine - coarse ) > 3.0*tol && level < maxLevel ) ){

            fine =  atrap1( a, m1, c, m2, f,tol/4.0)
            + atrap1( a, m1, m2, d, f, tol/4.0)
            + atrap1(m1, b, c, m2, f, tol/4.0)
            + atrap1(m1, b, m2, d, f,tol/4.0);

        }

    --level;
    return fine;
}

其中函数由

给出
double ucircle( double x, double y)
{
    return x*x + y*y < 1 ? 1.0 : 0.0;
}

我的主要功能是

int main()
{
   double a, b, c, d;
    cout << "Enter a: " <<endl;
    cin >> a;
    cout << "Enter b: " <<endl;
    cin >> b;
    cout << "Enter c: " <<endl;
    cin >> c;
    cout << "Enter d: " <<endl;
    cin >> d;

    cout << "The approximate integral is: " << atrap( a, b, c, d, ucircle, 1.0e-5) << endl;

    return 0;
}

2 个答案:

答案 0 :(得分:1)

它实际上不会永远运行,但它实际上运行了很长时间,你认为它一直在运行,这就是原因:在第一次运行level是一个并且函数输入你的{{1并且它自己调用了4次,现在考虑第一次:它也进入if并再调用4次并继续...正确选择输入,就像你指定的那样,条件{{1总是if所以只有阻止流进入abs(fine - coarse)的内容才会true增加然后减少,所以你的函数几乎会调用if这真是一个很大的数字,你无法在一小时或两小时内看到它的终结!

答案 1 :(得分:0)

就像BigBoss已经写过的那样,你的程序应该完成,因为30次递归意味着4^30 atrap1 1152921504606846976函数调用只需要很长时间,这是fabs。只要让这个号码沉入其中。

以下是一些需要考虑的事项:

  • 您可能希望在“中断条件”中使用abs而不是abs。 (我认为你应该收到整数转换的警告 - 或类似的东西 - 为此)float可能会为doubletol参数返回不可预测的值。 非常高的值

  • 1E-11似乎是一个表示目标精度值的变量。但是,每次递归都会进一步提高此目标精度。在第10次递归时,它已经是tol。不确定这是有意的。无论/4.0是什么意思。

    在递归调用中,您可能不希望.0trapezoidal是多余的)。

  • 你用优化编译它,对吗?

  • minLevelmaxLevellevel可以是宏。

  • 由于atrap1是静态的,您的函数不喜欢线程执行。您应该将其设为{{1}}的参数。