牛顿迭代法求近似根与二分法求根

来源:互联网 发布:佛山cnc编程最新招聘 编辑:程序博客网 时间:2024/06/05 18:38

牛顿迭代法

设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f’(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f’(x0),称x1为r的一次近似值。过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f’(x1),称x2为r的二次近似值。重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f’(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式。

如图

**求1.5附近的根:
2x^3-4x^2+3x-6=0
代码如下:

//用牛顿迭代法求根#include<stdio.h>#include<math.h>int main(){    double x1,x0,f,f1;    x1=1.5;    do{        x0=x1;        f=2*pow(x0,3)-4*pow(x0,2)+3*x0-6;        f1=6*pow(x0,2)-8*x0+3;        x1=x0-f/f1;      //牛顿迭代公式,不断迭代自身,杯子倒水    }while(fabs(x0-x1)>=1e-5);    printf("根是:%f\n",x1);    return 0;}/*牛顿迭代法又称为牛顿切线法,先给x1赋初值,不断地把前一次的近似根x1赋给x0,再代入迭代式由x0求出新的近似根x1,再反复赋给x0...直到x0,x1很接近了,这条切线近似平行于x轴,此时可以认为与x轴相切,x1就是所求的根。

优化:可以求解不同方程的根
代码如下:

#include <stdio.h>#include <math.h>#define EPSILON 1e-6   double f(double x) {           return 2 * pow(x, 3) - 4 * pow(x, 2) + 3 * x - 6;}double f_prime(double x) {//导函数    return 6 * pow(x, 2) - 8 * x + 3;  }double h(double x){    return pow(x,3)-4*pow(x,2)+3*x-6;}double h_prime(double x){    return 3*pow(x,2)-8*x+3;}double newton(double(*f)(double),double(*f_prime)(double)) {  //牛顿法    double x = 1.5;   //为newton函数添加两个接收函数地址的参数  赋初值    while (fabs(f(x)) > EPSILON){     //求绝对值函数,f(x)接近0        x = x - f(x) / f_prime(x);         }    return x;}int main() {    printf("%g\n", newton(f,f_prime));    printf("%g\n",newton(h,h_prime));//求解不同方程的近似解    return 0;}

二分法求解方程根:

二分法,又称分半法,是一种方程式根的近似值求法。对于区间[a,b]上连续不断且f(a) ·f(b)<0的函数y=f(x),通过不断地把函数f(x)的零点所在的区间一分为二,使区间的两个端点逐步逼近零点,进而得到零点近似值的方法叫做二分法(bisection)。
这里写图片描述
算法如下:
1
如果要求已知函数 f(x) = 0 的根 (x 的解),那么
2
先要找出一个区间 [a, b],使得f(a)与f(b)异号。
根据介值定理,这个区间内一定包含着方程式的根。
3
求该区间的中点m=(a+b)/2,并找出 f(m) 的值。
4
若 f(m) 与 f(a) 正负号相同,则取 [m, b] 为新的区间, 否则取 [a, m]。
5
重复第3步和第4步,直到得到理想的精确度为止。

注意:
定区间,找中点,中值计算两边看。
同号去,异号算,零点落在异号间。
周而复始怎么办??精确度上来判断。

二分法求2x^3-4x^2+3x-6=0在(-10,10)之间的根:
代码如下:

#include<stdio.h>#include<math.h>double f(double x){    double f;    f=2*pow(x,3)-4*pow(x,2)+3*x-6;    return f;}int main(){    double x1,x2,x0;    x1=-10,x2=10;    do{                             x0=(x1+x2)/2;        if(f(x0)*f(x1)>0){                            x1=x0;        }else if(f(x0)*f(x1)<0){            x2=x0;        }/*写法一,二*/    }//while(f(x0)*f(x1)!=0);    while(fabs(f(x0))>=1e-5);  //直到f(x0)接近于一个很小的数,方程趋于0,即认为是他的根        printf("%f\n",x0);    return 0;}
0 0
原创粉丝点击