0

だから私は、関数 x^2 + y^2 < 1 に適応 2D 台形規則を実装するプログラムを持っていますが、再帰が機能していないようです-ここのプログラムは (機能する) 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;
}
4

2 に答える 2

1

実際には永遠に実行されるわけではありませんが、実際には非常に長い間実行され、永遠に実行されていると思われます。それが理由です。最初の実行levelは1回で、関数はあなたif自身を4回呼び出します。 : それはまた入力され、ifそれ自体をさらに 4 回呼び出して続行します ... 指定した入力のように正しく選択された入力の場合、状態abs(fine - coarse)は常にtrueそうであり、フローが入力するのを止めることができるのは、増加してから減少することだけifですlevel。そのため、関数はほぼ呼び出されます。これ4^30は、1 時間か 2 時間では終了が見えないほど大きな数です。

于 2012-10-21T01:40:57.807 に答える
0

BigBoss がすでに書いたように、プログラムは終了するはずです。30 回の再帰は4^30の関数呼び出しを意味するためatrap1、長い時間がかかり1152921504606846976ます。その数を沈めさせてください。

さらに考慮すべき事項を次に示します。

  • おそらく、「ブレーク状態」のfabs代わりに使用したかったでしょう。abs(これについては、整数変換または同様の警告が表示されるはずだと思います)またはパラメータabsに対して予測できない値を返す可能性があります。非常に高い値floatdouble

  • tol目標精度値を表す変数のようです。ただし、再帰ごとに、このターゲット精度をさらに上げます。10回目の再帰では、すでに約1E-11です。これが意図されているかどうかはわかりません。どんなtol意味でも。

    /4.0おそらく、再帰呼び出しでは(.0ちなみに冗長です) は必要ありません。

  • これを最適化してコンパイルしますよね?

  • trapezoidalminLevelmaxLevelマクロである可能性があります。

  • levelあなたの関数は静的であるため、スレッド化された実行が好きではありません。のパラメータにする必要がありますatrap1

于 2012-10-22T09:11:19.607 に答える