4

C で根を見つけるためのニュートン ラフソン アルゴリズムを実装しました。これに対する私の戦略は次のとおりですがwhile (!(isnan(x0)) { dostuff(); }、これは結果を何度も出力し続けます。理想的には、計算された各 x インターセプト近似の差が、以前の電流が私の場合、ある範囲 .000001 より小さい場合に停止するように、範囲を設定したいと思います。以下に可能な実装があります。2.999 を入力すると 1 ステップしかかかりませんが、3.0 を入力すると 20 ステップかかります。これは私には間違っているようです。

(3.0と入力した場合)

λ newton_raphson 3
2.500000
2.250000
2.125000
2.062500
2.031250
2.015625
2.007812
2.003906
2.001953
2.000977
2.000488
2.000244
2.000122
2.000061
2.000031
2.000015
2.000008
2.000004
2.000002
2.000001
2.000002 の適切な根を近似するのに 20 回の操作が必要でした
0.000001の範囲内

(2.999と入力した場合)

λ newton_raphson 2.999
2.000000 の適切な根を近似するのに 1 回の操作が必要でした
0.000001の範囲内

私のコード:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define RANGE 0.000001


double absolute(double number)
{
    if (number < 0) return -number;
    else return number;
}

 double newton_raphson(double (*func)(double), double (*derivative)(double), double x0){
    int count;
    double temp;
    count = 0;
    while (!isnan(x0)) {
            temp = x0;
            x0 = (x0 - (func(x0)/derivative(x0)));
            if (!isnan(x0))
                printf("%f\n", x0);
            count++;
            if (absolute(temp - x0) < RANGE && count > 1)
                break;
    }
    printf("Took %d operation(s) to approximate a proper root of %6f\nwithin a range of 0.000001\n", count, temp);
    return x0;
 }


/* (x-2)^2 */
 double func(double x){ return pow(x-2.0, 2.0); }
/* 2x-4 */
 double derivative(double x){ return 2.0*x - 4.0; }

 int main(int argc, char ** argv)
 {
   double x0 = atof(argv[1]);
   double (*funcPtr)(double) = &func; /* this is a user defined function */
   double (*derivativePtr)(double) = &derivative; /* this is the derivative of that function */

   double result = newton_raphson(funcPtr, derivativePtr, x0);
   return 0;
 }
4

2 に答える 2

2

trunc(x0)変わる呼び出します。当然、正しい答えから始めれば、反復は必要ありません! つまり、開始値としてを使用するつもりでしたが、実際には を使用しました。2.9992.02.9992.0

への呼び出しを削除するだけtrunc()です。

于 2012-11-13T16:28:44.427 に答える
1

指摘する価値があります: 収束するために 20 歩かかること異常です。多重根に収束しているため、一般的なケースでニュートン・ラフソンが与える典型的な二次収束ではなく、収束は線形のみです。これは、反復ごとにエラーが半分になるという事実でわかります (通常の二次収束では、反復ごとに 2 倍の正しい数字が得られ、はるかに速く収束します)。

于 2012-11-16T16:18:15.790 に答える