使用牛顿迭代法求解方程

尽管通过因式分解和利用求根公式可以很方便的得出多项式方程的根,但大多数时候这个多项式的次数都很高,计算将变得非常复杂,因此,我们必须转向一些近似解法。

牛顿迭代法是其中最好的方法之一。从根本上说,牛顿迭代法通过一系列的迭代操作使得到的结果不断逼近方程的实根。

首先,要选择一个初始值x=x0,使得该初始值接近实根的值。然后,迭代计算如下的公式:

xi+1 = xi - f(xi) / f '(xi)

直到xi+1达到一个满意的近似结果为止。在这个公式中,f(x)是要求解的多项式方程,而f '(x)是f(x)的导数。

多项式求导

多项式求导是微积分的基础,现在让我们来看看针对多项式求导的公式化描述。

要计算出多项式的求导结果,只需要对多项式的每一项套用如下两个公式

d/dx * k = 0, d/dx *kxr = krx r-1

这里的k是为常数,r是有理数,x是未知数。符号d/dx表示求导,其中x是多项式中的变量

对于多项式中的每一常数项,套用第一个公式;否则,就用第二个公式。假设有如下函数:

f(x) = x3 + 5x2 +3x +4

要得到求导后的结果f '(x),对该多项式的前三项套用第二个公式,最后一项套用第1个公式,得到结果如下:

f '(x) = 1 * 3x(3-1) + 5 * 2x(2-1) + 3 * 1x(1-1) + 0 = 3x2 + 10x +3

有时候也有必要进行高阶求导,即导数的导数。比如,f(x)的2阶求导可记为f ''(x),它是对f '(x)的求导结果。同理,f(x)的3阶求导可记为f '''(x),这是对f ''(x)的求导结果,以此类推。因此,在前面的例子中,如果要计算f(x)的2阶导数的话,我们按照如下的方式对f '(x)求导即可:

f ''(x) = 3 * 2x(2-1) + 10 * 1x(1-1) + 0 =6x +10

理解1阶和2阶导数

理解1阶和2阶导数的意义,是正确使用牛顿迭代法非常重要的一点。

f(x)在点x=x0处的1阶导数表示函数f(x)在点x0处的斜率。

1阶导数决定函数f(x)是递增的(从左到右上升)还是递减的(从左右到下降)。如果求导结果为正,f(x)就是递增的;而如果求导结果为负,f(x)就是递减的;如果求导结果为0,则f(x)即不是递增的也不是递减的。求导结果的大小表示f(x)递增或递减的速率。如下图所示,阴影部分表示函数的递增区间,因此这些区域里函数的1阶导数都为正值。而中间穿过横轴的部分里函数是单调递减的,因此这个区域内的1阶导数所表示的斜率都为负值。

图:函数f(x)的1阶和2阶导数的意义

f(x)在点x=x0处的2阶导数表示函数在该点处的凹凸性,也就是说函数图像是向上凸的还是向下凹的。

2阶导数值的大小表示函数图像的凹凸程度。在上图的a和c中,虚线表示函数凹凸性发生改变的位置(曲线上凸部和下凹部的分界点,也称为拐点),拐点必然是2阶导函数与x轴的交点

另一种表示函数f(x)在某点x=c处的导数的方法是:按照点斜式表示出与f(x)相切于点c的直线方程。直线点斜式方程可写作:

y - f(c) = f ' (c)(x-c)

因此,如果f(x) = x3 - x2 - 3x + 1.8如上图a所示,那么与f(x)相切于c=1.5的直线方程就可以表示为:

y - ((1.5)3 - (1.5)2 - 3*1.5 + 1.8) = (3 * 1.52 -2 * 1.5 - 3)(x - 1.5)

y + 1.575 = 0.75(x - 1.5)

上图d中画出了这条切线。

为牛顿迭代法确定迭代初始值

牛顿迭代法中至关重要的一点是选出一个合适的初始迭代值x0为了使牛顿迭代法能够收敛至我们要求的根,初始迭代值必须要足够接近于所求的根。下面有两条规则必须满足:

1、为x0确定一个区间[a,b],使得该区间内有且只有一个根存在。为了实现这个目的,需要选择两个值a和b,使得f(a)和f(b)的符号不同,且f '(x)的符号不会改变。如果f(a)和f(b)有不同的符号,则表示该区间内至少存在一个根。如果f '(x)的符号在区间[a,b]上不变,则可确定该区间内只包含一个根,因为该函数在此区间内只可能单调的递增或递减。

2、使x0=a或x0=b,这样f(x0)的符号就和f ''(x)在区间[a,b]上的符号相同这也说明了f ''(x)在区间[a,b]上的符号不会改变。回顾一下,f(x)的2次导数表示函数的凹凸性,如果f ''(x)的符号不变,则f(x0)就和f ''(x)拥有相同的符号。每经过一次牛顿迭代,就会在区间[a,b]上逐步逼近于根。如下图。

图:牛顿迭代法的收敛

在上图的4个部分中,f(x)以粗实线表示,a和b都表示为垂直的虚线。如果f(a)满足前面给出的规定,则从a开始迭代,且切线会朝着根收敛的方向倾斜。如果f(b)满足前面给定的规定,迭代就从b开始。且切线也会朝着根收敛的方向倾斜。

牛顿迭代法的工作过程

假设我们想找出方程f(x) = x3 - x2 - 3x + 1.8的根。根据函数图像(如下图),该方程会有三个根:一个在区间[-2,-1],另一个在区间[0,-1],第三个在区间[2,3]。一旦知道了方程的根的个数以及它们所在的区间,就根据上面的要求对每个区间做测试,以此挑出一个初始迭代值。要实现这一点,首先得知道如下信息:

f(x) = x3 - x2 - 3x + 1.8,f '(x) = 3x2 - 2x - 3,f ''(x) = 6x - 2

利用这些信息,我们发现[-1,-2]满足第一个要求,因为f(-2) = -4.2,f(-1) = 2.8,且f '(x)在该区间内没有改变符号(一直都是正的)。到这,我们知道在区间[-2,-1]内有且只有一个根。现在需要检查是否满足第二个要求,我们发现f ''(x)在区间上并没有改变过符号(一直都是负的)。因为f(-2)=-4.2也是负值,所以选择x0 = -2作为迭代的初始值。下图展示了在该区间内迭代计算根的过程,其精度达到了0.0001。只经过5次迭代就得到了这个近似值。

图:计算方程f(x) = x3 - x2 - 3x + 1.8 = 0的3个根的近似值,精确度0.0001

再来看看如何求出区间[0,1]上的根。我们能够看到第一个要求在该区间上是能够满足的,但是在该区间的f''(x)的符号并不是不变的,因此这个区间不能满足第二个要求。我们怀疑这个根更接近于1而不是0,因此我们接下来尝试使用区间[0.5,1],这个可以解决不满足第二个要求的问题了。f(0.5) = 0.175,f(1) = -1.2,f '(x)在这个区间内都是负值,因此第一个要求可以满足。要完成第二个要求让初始值x0 = 0.5,因为f(0.5)=0.175为正值,且同f ''(x)在区间[0.5,1]上的符号相同。上图也展示了在区间[0.5,1]上迭代计算根的过程,其精度达到了0.0001。最后用了4次迭代就达到了根的近似值。计算第3个根的过程也与此类似。

方程求解的接口定义

root


int root(double (*f)(double x), double (*g)(double x), double *x, int *n, double delta)

返回值:如果找到了根返回0;否则返回-1。

描述:采用牛顿迭代法,根据给定的初始值来计算方程f的根。初始值由x[0]指定。函数f的导数由参数g指定。参数n代表迭代的最大次数。参数delta表示逐次逼近的差值,用该值来决定何时应该结束迭代。函数返回后,迭代过程中计算出的近似值都保存在数组x中,此时n代表数组x中的元素个数。由调用者负责管理同x相关联的存储空间。

复杂度: O(n),这里n表示调用者希望进行的最大迭代次数。

方程求解的实现与分析

求解形如f(x) = 0的方程,本质上就是要找出它的根。函数root采用牛顿迭代法以给定的初始迭代值开始逐次迭代逼近,从而找到实际根。

root函数包含单个循环,该循环采用牛顿迭代公式来连续计算根的近似值。在本节给出的实现中,f就代表需要求解的方程,g代表f的导函数。每一次迭代,我们要判断当前得到的近似值是否满足需求。如果当前得到的近似值与前一轮迭代得到的近似值之差小于delta所指定的值,则认为当前的近似值满足要求。如果经过n次迭代后还是没有找到满足要求的近似根,则从函数中返回-1以表示没有找到近似根。

root函数的时间复杂度为O(n),这里n表示调用者希望进行迭代的最大次数。最坏情况是当没有找到所需要的近似根时,此时一共会进行n次迭代。

示例:方程求解的实现

#include <math.h>
#include "nummeths.h"int root(double (*f)(double x), double (*g)(double x), double *x, int *n, double delta)
{int satisfied,i;i = 0;satisfied = 0;while(!satisfied && i+1 < *n){/*x的下一个迭代值*/x[i+1] = x[i] - (f(x[i]) / g(x[i]));/*确定是否获得期望的近似值*/if(fabs(x[i+1] - x[i]) < delta)satisfied = 1;/*为下一次迭代做准备*/i++;}/*即使没有迭代,也表明一个值已经存储在x中*/if (i==0)*n=1;else *n=i+1;/*找到实根返回0,或者达到最大迭代次数仍没有找到实根,返回-1*/if(satisfied)return 0;else return -1;
}

转载于:https://www.cnblogs.com/idreamo/p/9108853.html

使用“牛顿迭代法”求解方程相关推荐

  1. 3.牛顿迭代法求解方程的根

    牛顿迭代法求解方程的根 引题:用牛顿迭代法求下列方程在值等于x附近的根: 2 x 3 − 4 x 2 + 3 x − 6 = 0 2x^3-4x^2+3x-6=0 2x3−4x2+3x−6=0 输入: ...

  2. 分别用二分法和牛顿迭代法求解方程x3 – 3x – 1 = 0在x = 2附近的实根

    编写程序,分别用二分法和牛顿迭代法求解方程x3 – 3x – 1 = 0在x = 2附近的实根,要求计算精确到小数点后七位数字为止,并将求出的近似结果与理论值2cos20 相比较,二分法的初始迭代区间 ...

  3. 二分法和简单迭代法的优缺点_二分法和牛顿迭代法求解方程的比较.doc

    您所在位置:网站首页 > 海量文档 &nbsp>&nbsp高等教育&nbsp>&nbsp理学 二分法和牛顿迭代法求解方程的比较.doc5页 本文档一共 ...

  4. matlab用牛顿迭代法求解方程,牛顿迭代法求方程解 程序如下

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 function [x_reality,n_reality] = Newt( f_name,x_start,tolerance,n_limit) %% % ...

  5. 1、编写程序,分别用二分法和牛顿迭代法求解方程x3 – 3x – 1 = 0在x = 2附近的实根,要求计算精确到小数点后七位数字为止,并将求出的近似结果与理论值2cos20 相比较,二分法的初始迭代

    二分法: #include<stdio.h> #include<math.h> void main() {     double x,x1=1,x2=3,f1,f2,f;    ...

  6. python迭代法求解方程_第一部分:趣味算法入门;第六题牛顿迭代法求一元三次方程的根...

    100个不同类型的python语言趣味编程题 在求解的过程中培养编程兴趣,拓展编程思维,提高编程能力. 第一部分:趣味算法入门:第六题SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键 ...

  7. mysql 立方根函数_Java实现牛顿迭代法求解平方根、立方根

    一.简介 牛顿迭代法(Newton's method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法. ...

  8. 牛顿迭代法求方程的根

    牛顿迭代法(牛顿-拉弗森方法) 五次及以上多项式方程没有根式解(就是没有像二次方程那样的万能公式),这个是被伽罗瓦用群论做出的最著名的结论.没有根式解不意味着方程解不出来,数学家也提供了很多方法,牛顿 ...

  9. 用牛顿迭代法求方程的根matlab,牛顿迭代法求方程根的MATLAB程序

    function [x_reality,n_reality] = Newt( f_name,x_start,tolerance,n_limit) %% %牛顿迭代法(切线法)求解方程f_name = ...

  10. 100个python算法超详细讲解:牛顿迭代法求方程根

    1.问题描述 编写用牛顿迭代法求方程根的函数.方程为ax 3 +bx 2 +cx+d=0,系数a. b.c.d由主函数输入,求x在1附近的一个实根.求出根后,由主函数输出. 2.问题分析 牛顿迭代法是 ...

最新文章

  1. Jmail的主要参数列表
  2. BZOJ1299[LLH邀请赛]巧克力棒——Nim游戏+搜索
  3. 一个好的APP需要后台产品经理么?
  4. centos 编译nginx php mariadb,centos7安装nginx+mariadb+php-fpm
  5. HTML5 Canvas 自定义笔刷
  6. java环境变量搭建
  7. 计算机网络之数据链路层:1、概述
  8. 阿里平头哥科学家亲述 RISC-V 2019 Summit 十大心得!
  9. P2030 - 【BJOI2006】狼抓兔子
  10. 图解java_图解 Java 中的数据结构及原理!
  11. Excel:自动录入学生的基本情况信息表(转)
  12. 软件模式、GRASP原则,GoF设计模式、设计模式分类、设计模式的优点。
  13. JLink重刷固件(win7/win8/win10亲测可用)
  14. 海洋cms播放器html,海洋cms怎么添加播放器
  15. grpc系列1-K8S集群,VIP,grpc._channel._InactiveRpcError connection reset by peer解决方案 Paddleserving服务化部署
  16. Python爬虫获取京东大数据!其实爬虫真的很简单!
  17. 关于PostMan发送请求获得响应
  18. C语言字模文件的使用,PCtoLCD2002(字模软件) 最新版 附使用指南
  19. python中函数的定义意思
  20. 对于javaScript设计模式的认知与学习

热门文章

  1. java中常量和变量的区别_Java中三种变量
  2. unordered_map 简介
  3. java实现io阻塞的代码,Java:完整的每个连接线程阻塞IO与NIO的代码示例?
  4. SSH与FTP之间的关系与区别
  5. 大数阶乘 nyoj28
  6. vue init download template_Webpack(四)Vue
  7. html5特性检测,HTML5 简介(七):在线检测、contenteditable、classList 等特性介绍
  8. cydia无法安装卸载插件_【初识太极】CAD卸载不干净无法重新安装怎么办?
  9. linux c 调用c程序,Linux C调用C++库(用C封装C++接口)
  10. java aws批量_通过 S3 Batch Operations (批量操作)功能轻松处理海量对象