【发布时间】:2012-11-13 16:18:43
【问题描述】:
我已经实现了用于在 C 中查找根的牛顿拉夫森算法。我想在不进入 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;
}
【问题讨论】:
-
我知道这可能不是生产代码,但请在使用它们之前使用检查参数,例如
if (NULL == argv[1]) { ... print help ... ; return 0; }。否则你的程序没有参数的段错误。 -
您在计算中使用了双精度,但未显示 printf() 中的所有数字。将格式字符串更改为 "%.15f\n" 以获得更多数字。
标签: c algorithm numerical-methods