牛顿拉夫森在C

时间:2012-11-13 16:18:43

标签: c algorithm numerical-methods

我已经实现了用于在C中查找根的牛顿raphson算法。我想尽可能打印出最精确的根的近似,而不是进入南地。我的策略是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
Took 20 operation(s) to approximate a proper root of 2.000002
within a range of 0.000001

(当我输入2.999时)

λ newton_raphson 2.999
Took 1 operation(s) to approximate a proper root of 2.000000
within a range of 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;
 }

2 个答案:

答案 0 :(得分:2)

您致电trunc(x0),将2.999变为2.0。当然,当你从正确答案开始时,不需要迭代!换句话说,虽然您打算使用2.999作为起始值,但实际上使用了2.0

只需移除对trunc()的调用。

答案 1 :(得分:1)

值得指出:采取20步收敛是异常;因为你正在收敛到一个多根,所以收敛只是线性的,而不是Newton-Raphson在一般情况下给出的典型二次收敛。你可以看到这一点,你的错误在每次迭代时减半(通常的二次收敛,你会得到每次迭代的正确数字的两倍,收敛得更快,更快)。

相关问题