4

我已经实现了用于在 C 中查找根的 newton raphson 算法。我想在不进入 nan 土地的情况下尽可能打印出最准确的根近似值。我的策略是while (!(isnan(x0)) { dostuff(); }但这会继续多次打印出结果。理想情况下,我想设置一个范围,以便在我的情况下,当前一个电流小于某个范围 .000001 时,每个计算的 x 截距近似值之间的差异将停止。我在下面有一个可能的实现。当我输入 2.999 时只需要一步,但是当我输入 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
进行了 20 次操作来逼近 2.000002 的正确根
在 0.000001 范围内

(当我输入 2.999 时)

λ newton_raphson 2.999
进行了 1 次操作来逼近 2.000000 的正确根
在 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)which2.999变成2.0. 自然,当您从正确的答案开始时,就不需要迭代了!换句话说,虽然您打算将其2.999用作起始值,但实际上却使用了2.0.

只需删除对trunc().

于 2012-11-13T16:28:44.427 回答
1

值得指出的是:采取 20 步收敛也是异常的;因为您正在收敛到多重根,所以收敛只是线性的,而不是牛顿-拉夫森在一般情况下给出的典型二次收敛。您可以看到,每次迭代您的错误都会减半(使用通常的二次收敛,每次迭代您将获得两倍的正确数字,并且收敛速度要快得多)。

于 2012-11-16T16:18:15.790 回答