迭代法求根c语言程序对数方程,【实验一】方程求根:牛顿迭代法

如果有时间,我会渐渐的把数值分析的实验写完。总共8个实验,今天写的是方程求根里的通过牛顿迭代法求一元多次方程的根。

若函数f(x)连续可导,将f(x)在点x_k 处进行一阶泰勒展开,有:

令 f(x) = 0, 当f'(x_k) != 0 时,有:

于是,我们可以得到迭代公式:

关于牛顿迭代法了解到这就行了, 既然有了迭代公式,最主要的是如何通过编程实现它。

一.输入

既然是解方程,方程是必须输入的。但方程不可能原样的输入,所以我们要找到我们所需要的 必要信息:各项的系数、最高次幂、以及我们手动取的一个近似值

系数和当前项的幂可以通过一个数组来解决。数组是种有序的线性结构,元素在里面是顺序存放的,所以从高次到低次顺序输入就可以了。为了方便,即使系数是0,0也需要输入,不能省略。输入最高次幂是为了分配数组空间和之后的计算服务的。

二.计算f(x) 、f`(x)

牛顿迭代法的关键就是迭代公式,迭代公式的关键就是计算函数值和函数导数的值。

这里很简单,理清思路就可以了:

// f(x)、f`(x)

double f(double x, double *a, int n){

double res = 0;

int i;

for(i = 0; i <= n; i++){

res += a[i] * pow(x, n - i);

}

return res;

}

double ff(double x, double *a, int n){

double res = 0;

int i;

for(i = 0; i <= n; i++){

res += a[i] * (n - i) * (n - i - 1 >= 0 ? pow(x, n - i - 1) : 0);

}

return res;

}

注意一下f`(x)的计算,如果套用前面的求导方法就会出错。最后常数项应该单独处理,常数项的导数为0。

三.不断迭代到合适的精度

迭代过程就是一个不断逼近准确根的过程,所以在精度已经足够好了,也就是说 x_k 和 x_k + 1 差值足够小的时候,结束迭代就可以了。

// 初始时令last != x_k, 并保存x的值

x_first = (last = x_k + 1) - 1;

// 前后两次差值 < 0.00001 就结束循环

while(fabs(x_k - last) > 0.00001){

last = x_k;

x_k = last - f(last, a, n) / ff(last, a, n);

}

四.例题 && 测试

图片来自 《计算方法(李桂成)》

测试

五.完整代码(C语言)

C代码:

// 牛顿迭代法求一元n次方程根

#include

#include

#include

// f(x)、f`(x)

double f(double x, double *a, int n){

double res = 0;

int i;

for(i = 0; i <= n; i++){

res += a[i] * pow(x, n - i);

}

return res;

}

double ff(double x, double *a, int n){

double res = 0;

int i;

for(i = 0; i <= n; i++){

res += a[i] * (n - i) * (n - i - 1 >= 0 ? pow(x, n - i - 1) : 0);

}

return res;

}

int main(){

// n次幂、存储各项系数的数组a、循环变量i

int n;

double *a;

int i;

// x_k

double x_k, last, x_first;

// 输入n次幂

printf("输入方程的次幂:");

scanf("%d", &n);

// 为a分配空间

a = (double*) malloc(sizeof(double) * (n + 1));

// 输入各项系数

printf("输入方程各项系数(从高次到低次):");

for(i = 0; i <= n ; i++){

scanf("%lf", a + i);

}

// 开始秀

printf("输入x的初始值:");

scanf("%lf", &x_k);

// 初始时令last != x_k, 并保存x的值

x_first = (last = x_k + 1) - 1;

// 前后两次差值 < 0.00001 就结束循环

while(fabs(x_k - last) > 0.00001){

last = x_k;

x_k = last - f(last, a, n) / ff(last, a, n);

}

// 输出求得的根

printf("方程在x = %.1lf 附近的根为:%.5lf", x_first, x_k);

// end

getchar();

return 0;

}

你可能感兴趣的:(迭代法求根c语言程序对数方程)