1

与えられた精度 (0.0001 など) で (1-x)^0.25 を近似する必要があります。ウィキペディアにある (1+x)^0.25 の展開を使用しています。現在の式が精度よりも低い場合、近似を停止する必要があります。

long double s(long double x, long double d) {
    long double w = 1;
    long double n = 1; // nth expression in series
    long double tmp = 1;

    // sum while last expression is greater than accuracy
    while (fabsl(tmp) >= d) {
        tmp *= (1.25 / n - 1) * (-x); // the next expression
        w += tmp; // is added to approximation
        n++; 
    } 

    return w;
}

long double n は気にしないでください。:P これは、現在の式の値をチェックしているのではなく、1000 以上の式を計算しているときにうまく機能します。関数の定義域は <-1;1> で、s() は <-1;~0.6> で x の近似をうまく計算します。引数が大きいほど計算誤差が大きくなります。0.6からは精度を超えています。

私は英語の数学言語をよく知らないので、問題が十分に明確かどうかわかりません. 問題は、 while 条件の問題と、関数 s() が正しく近似されない理由です。

編集: 問題はほとんど解決しました。x>0 の場合、連続する式の絶対値を 1 から引く必要があります。

if (x<0)
   w += tmp;
else
   w -= fabsl(tmp);

その後、精度は大幅に向上します (もちろん fox x>0)。重複エラーは、長い double 不正確性に起因します。それで全部です。とにかくあなたたちに感謝します。

4

2 に答える 2

1

あなたの問題は、アルゴリズムの反復部分は問題ありませんが、終了はあなたが思っているものではないということです。

使用しているテイラー級数展開は、無限和が評価されるときに正確です。ただし、その無限の合計を評価することはできず、切り捨てられます。

whentmpが希望の許容範囲よりも小さくなると想定していると思いますが、誤差wもその許容範囲よりも小さくなります。

しかし、これは正しくありません。各反復での誤差は、残りの項の無限和です。それはあなたが捨てている無数の用語の合計です。これらのうちの最初の 1 つ、tmp終了時点での の値は許容範囲よりも小さい場合がありますが、それらすべての合計は許容範囲よりも大きくなる可能性があります。

(-x) が負の場合、 の交互符号がtmp有利に働くため、たまたまそれを回避できます。(-x) が正の場合、xがゼロに近い場合は問題ありません。

ただし、単純な汎用停止基準を思い付く簡単な方法があるとは確信していません。あなたが捨てている用語にいくつかの境界を置くことができなければならないでしょう. これは、プログラミングの問題ではなく、数学の問題になります。

于 2011-03-17T17:09:35.160 に答える
1

関数のグラフを描いてみる

abs((1.0+x) alpha - binomial_formula(alpha,x,tolerance))
[-0.5;0.5] のような近い x 範囲でも、次のような結果が得られます。 ここに画像の説明を入力

これは、二項展開の実装が不安定であることを意味します。x が 0 から遠ざかるにつれて、一定の精度を得るには、シリーズにさらに多くの項を含める必要があります。しかし、現在の拡張実装でこれを行うと、壊滅的なキャンセルが発生します (いくつかの浮動小数点エラー累積メカニズム)。数値的に安定したアルゴリズムを設計する方法についてのリンクを読んでみてください。

ところで、本当に興味深い問題をありがとう!

于 2011-03-17T15:58:55.760 に答える