1. 二分法(Bisection)

1) 原理

  【介值定理】 对于连续的一元非线性函数,若其在两个点的取值异号,则在两点间必定存在零点。

  【迭代流程】 若左右两端取值不同,则取其中点,求其函数值,取中点和与中点取值异号的端点构成新的区间(其中必有零点)。进行下一次迭代。

2) 实现二分求根算法

  使用MATLAB实现二分法代码如下。捕捉异常主要是为了在无法进行二分法的区间内发生输出zeropt为空的错误。

function [ zeropt ] = bisection( func, left, right, prec )
%  二分法找非线性函数零点
%   输入4参数:函数句柄func,上/下界left/right,要求绝对精度prec
%   返回1参数:零点
leftVal = func(left);
rightVal = func(right);
if leftVal*rightVal >= 0        % 捕捉异常:若上下界处符号非相反error('Function vals at the boundaries are of the same sign, bisection unable to continue!');
end
flag = 0;
while (right - left) > prec     % 当区间长度大于精度时mid = (left + right)/2;midVal = func(mid);if midVal == 0              % 若中点值恰好为零则直接得到该值zeropt = mid;flag = 1;break;endif midVal*leftVal < 0       % 否则找到取值与中点取值异号的端点,将该区间作为新的查找区间right = mid;elseleft = mid;leftVal = midVal;end
end
if flag == 0                    % 若由于区间长度满足精度而退出循环,则取区间中点为零点zeropt = (left + right)/2;
end

 

  对于任意满足要求的函数(连续)和区间(两端函数值异号),二分法保证能够找到一个满足要求的解。比如输入函数句柄,并执行调用二分法函数,就得到如下结果:

func = @(x)x^3 - 20*x^2 - 25*x + 500;
bisection(func, 0, 15, 0.0001)
ans = 5.0000

  即算出该函数在(0, 15)区间上的一个零点是5.0000.

3) 二分法的迭代步复杂度、收敛速度及其他性质

  【迭代步复杂度】一次求中点,一次函数值求值(由x求y为一次求值)。注意由于每次迭代时只有中点值是没算过的,其他两个值之前都算过可以继续使用,故每次迭代仅一次函数值求值。

  【收敛速度】最大可预期的误差上限为区间长度,而每次迭代恒定地将区间长度减半。$\Rightarrow$ 线性收敛且收敛常数为0.5( $r=1, C=0.5$ ).

  【二分法的优点】1)安全可控:区间总是减半缩小,在区间缩小过程中总是至少有一个零点存在于区间中;2)迭代复杂度很低,完全不考虑函数的性质,仅仅使用一次函数值求值。之后在其他更高效的方法之中,二分法经常被作为起安全保护作用的算法,避免其他算法迭代产生的点位置过于离谱。

  【二分法的缺点】1)完全没有利用函数的性质!太可惜了,放弃了很重要的信息!2)收敛率仅为1,收敛速度缓慢。事实上是几种迭代方法中收敛最慢的两种之一;3)需要一个两端异号的区间作为开头,那如果是一个仅仅在中间较小的一段区域小于零,两侧均为正的函数呢?等到人工搜寻到异号的区间几乎都已经找到零点了!

2. 不动点迭代(Fixed Point Iteration)

1) 原理

  【不动点】 $x=g(x)$ 的解称为函数 $g(x)$ 的不动点,几何图像为函数图像与正比例函数 $y=x$ 的交点。

  【不动点迭代】 迭代形式为:$x_{k+1}=g(x_k)$ 。设函数的不动点为 $x^*$ ,当 $|g'(x^*)|<1$ 时,在不动点附近的存在一个领域,使得从领域内的某个值开始的不动点迭代收敛,收敛到不动点。通过 $\delta x_{k+1}\approx g'(x^*) \delta x_{k}$ 式,当导数绝对值小于1时,迭代后误差的线性主部较迭代前误差小,以导数绝对值为收敛常数线性收敛。唯一不同的是若导数值为零,此时该迭代至少二次收敛。用不动点迭代解非线性方程的核心在于将非线性方程转化为一个收敛的不动点迭代。

  例如,求解一元二次方程:$f(x)=x^2-x-2$ 时,可以分别将其转化为解等价的不动点迭代:$g(x)=x^2-2,x=g(x)$或$g(x)=\sqrt{x+2},x=g(x)$ 。但是,前者在2附近发散,只有后者收敛。

2) 实现不动点迭代算法

  不动点迭代的算法可谓没有任何技术含量,但构造不动点迭代倒是颇有些技术含量。以下为MATLAB代码,其中iteration只是用于标识迭代次数

function [ zeropt, iteration ] = fixed_point( func, seed, prec )
prev = seed;
next = func(prev);
iteration = 1;
while abs(next - prev) >= prec && iteration < 500prev = next;next = func(prev);iteration = iteration + 1;
end
zeropt = next;
if iteration >= 500error('Method fails to converge.');
end
end

  

  以上文的两个不动点函数为例:$g(x)=x^2-2, g(x)=\sqrt{x+2}$ ,均满足 $g(2)=2$ ,即2均为不动点。分别从偏离2一定距离的点开始进行试验:

func1 = @(x)x^2 - 2;
func2 = @(x)sqrt(x+2);% 命令行输入
[zero, iteration] = fixed_point(func1, 1, 0.0001)
% 命令行输出
zero = -1, iteration = 2% 命令行输入
[zero, iteration] = fixed_point(func1, 1.9, 0.0001)
% 命令行输出
错误使用 fixed_point (line 12)
Method fails to converge.% 命令行输入
[zero, iteration] = fixed_point(func1, 2.1, 0.0001)
% 命令行输出
zero = Inf, iteration = 13% 命令行输入
[zero, iteration] = fixed_point(func2, 1.9, 0.0001)
% 命令行输出
zero = 2.0000, iteration = 6% 命令行输入
[zero, iteration] = fixed_point(func2, 2.1, 0.0001)
% 命令行输出
zero = 2.0000, iteration = 6

    显示出前一个函数func1由于2附近不动点迭代不收敛,会出现:跳跃到另一个零点;超过迭代步数;上溢出 的情形。而func2在2附近开始进行不动点迭代总能快速达到2.

3) 不动点迭代的迭代步复杂度、收敛速度及其他性质

  【迭代步复杂度】 一次函数值求值

  【收敛速度】 如上所述,若导数为零则至少二次收敛,若导数非零则以导数绝对值为收敛常数线性收敛。

  【优点】 1)迭代复杂度很低;2)若已知迭代函数,则实现起来没有任何技术含量,只需要不断调用函数即可。

  【缺点】 1)收敛速度很低,除非导数恰好为零,否则收敛率仅为1;2)对于一个非线性方程,必须先找到它对应的一个收敛的不动点迭代,否则一切都没用;3)必须从距离真解足够近开始迭代才有效!不过这也不只是不动点迭代的问题。

3. 牛顿法(Newton)

1) 原理

  设函数 $f(x)$ 零点的真解 $x^*$ ,即 $f(x^*)=0$,则在其一个领域内应有:$$f(x^*)\approx f(x^*-h)+f'(x^*-h)h=0$$  那么假设函数表达式已知,而又已知当前的值x在真解附近,为了估计真解的值就可以利用上式反解出 $x^*$:$$x^*=x+h=x-\frac{f(x)}{f'(x)}$$  若经过该计算,新的值距离真值更接近了,就可以把该过程写成不断迭代的形式来获得更好的精度,即:$$ x_{k+1}=x_k-\frac{f(x_k)}{f'(x_k)}$$  牛顿法的几何图像为用当前点的切线与x轴的交点估计零点的位置。

2) 牛顿法的实现

  在一般的迭代方法中,若要确定是否已经达到收敛,可以采用相邻两点间隔是否小于要求精度的方法,虽然这样的方法并不严格。在牛顿法的实现中,目前使用了待定精度(手动控制精度)的方法。另外,牛顿法中如果出现零斜率的情形(虽然在绝大多数情况下都不会出现)如何处理也是一个问题,在这里采用了“向右移动一个单位”选取下一个点的比较随意的方法。

function [ zeropt ] = nonlinNewton( func, prec, seed )
%   牛顿法求零点,输入3个参数:函数句柄func,精度prec,起始点seed;返回零点
syms f x;
f(x) = func(x);             % 生成符号函数类型f
fdiff(x) = diff(f);         % 生成f的符号函数类型导数fdiff
while fdiff(seed) == 0seed = seed + 1;
end
prev = seed;
next = prev - double(f(prev)/fdiff(prev));
while abs(next - prev) >= prec  % 执行迭代,直到精度符合要求prev = next;if fdiff(prev) == 0 % 若斜率为零则用任意算法取下一个点next = prev + 1;elsenext = prev - double(f(prev)/fdiff(prev));end
end
zeropt = next;
end

  同样用测试不动点迭代方法的函数(原函数)$f(x)=x^2-x-2$ 进行测试:

func = @(x)x^2-x-2;% 命令行输入
nonlinNewton(func, 0.0001, 1)
% 命令行输出
ans = 2.0000%命令行输入
nonlinNewton(func, 0.0001, 3)
% 命令行输出
ans = 2.0000

  

3) 牛顿法的迭代步复杂度、收敛速度及其他性质

  【迭代步复杂度】 一次原函数的求值,一次导函数的求值,以及不超过三次的四则运算。需要注意的是,牛顿法需要求导函数,并且要求可以得到导函数在任意一点的取值,这本身将耗费很大的时间代价。以上实现的算法只适用于已知解析式(符号表达式)、可以求函数的导函数的情形。

  【收敛速度】 考虑牛顿法和不动点迭代的关系,可知牛顿法的迭代公式等价于不动点迭代:$g(x)=x-f(x)/f'(x)$ 。按照不动点迭代收敛速度的分析方法,可以将 $g(x)$ 求导,结果得到 $g'(x)=f(x)f''(x)/(f'(x))^2$ ,在 $f(x)=0,f'(x)\neq 0$ 的条件下,必然有 $g'(x)=0$,因此在多数情况下牛顿法都是二次收敛的。而在零点处 $f'(x)=0$ 的情形不是别的,正是多重根的情形,该情形下问题本身的条件就属病态。

  【优点】 收敛速度比较快,对于单根均满足二次收敛。

  【缺点】 1)需要求导数,时间代价大;2)和不动点迭代类似,也需要选取合适的起点,这本身就是一件非常微妙玄学的事情。到了高维情况下,起点的选择还会显得玄学得多。

  牛顿法用一条切线进行估值。可以想见:对于凹凸性不发生变化且存在零点的函数,牛顿法从任意起点都一定收敛。另外,对于线性函数,牛顿法一步迭代立即收敛,因为这步迭代形成的切线就是函数本身了。

  最后,如果func函数只能得到它的数值输入输出而没有显式的符号表达式,如何得到可以确定它在任意一点导数值的函数呢?思路:先进行数值微分 $\rightarrow$ 转化为数值求导 $\rightarrow$ 对结果进行插值形成完整的函数。

转载于:https://www.cnblogs.com/gentle-min-601/p/9645452.html

非线性方程(组):一维非线性方程(一)二分法、不动点迭代、牛顿法 [MATLAB]...相关推荐

  1. 非线性方程的几种线性解法(二分法,不动点法和牛顿法)

    非线性方程的几种线性解法 对于线性方程我们有很多方法来解,比如简单的线性方程都会有公式直接来计算.但是涉及到复杂的线性方程比如高阶多项式方程,非线性性方程也是很那直接求解的,在数值分析的角度就很容易来 ...

  2. 非线性方程(组):计算基本理论

    1. 非线性方程(组)及其解 对于非线性函数 $f(x)$ ,方程 $f(x)=0$ 为非线性方程( $f:\mathbb{R} \rightarrow \mathbb{R}$ ). 对于n维向量 $ ...

  3. 非线性方程(组):高维方程解法

    非线性方程的高维情形和一维情形既有相似处也有差异.首当其中的区别即在高维情形中不再存在介值定理,从而使得二分法不再可推广到高维.不过,仍然有许多方法可以推广. 1. 不动点迭代(高维) 寻找方程 $\ ...

  4. 不动点迭代以及其收敛性

    不动点迭代以及其收敛性 对于迭代的理解 不动点迭代 迭代的收敛性 区间收敛 局部收敛 对于迭代的理解   所谓迭代就是反复使用执行某一个过程,并且用本次执行该过程的结果作为下一次执行的起点,不断推进, ...

  5. 其他算法-不动点迭代

    不动点迭代 不动点迭代法(Fixed Point Iteration)又叫简单迭代法,对于一个非线性方程 f(x)=0f(x)=0f(x)=0 将其转换成以下形式: x=φ(x)x=\varphi ( ...

  6. 最优化算法python实现篇(2)—无约束一维极值(二分法)

    最优化算法python实现篇(2)--无约束一维极值(二分法) 算法适用问题 python实现 示例运行结果 算法适用问题 搜索给定单峰区间的极值问题,一般对凸优化问题比较适用. python实现 # ...

  7. 不动点迭代 开平方 Excel演示

    不动点迭代的精髓在于可以从任意值收敛. 难点在于配这个方程.详细技巧请参阅 数值分析 内容. X 代表初始值

  8. 不动点迭代(Fixed Point Iteration)

    题目:不动点迭代(Fixed Point Iteration) 本篇介绍不动点迭代(Fixed Point Iteration).之所以学习不动点迭代是由于近来看到了FPC算法,即Fixed Poin ...

  9. 不动点迭代求解方程数值解

    求解方程 2x−x3=0 解:可以采用不动点迭代的方式求出数值解. 其不动点是 x=3log2x ,故可以采用下式进行不动点迭代: xn+1=3log2xn 初始值为 x0=2 ,迭代终止条件是 |x ...

最新文章

  1. 自然语言处理的蓬勃发展及其未来
  2. 配置sctp_5G站点网优参数配置指导书
  3. python三个点画正弦线_python3绘图示例5(基于matplotlib:正弦图等)
  4. Restful风格,PUT修改功能请求,表单中存在文件报错-HTTP Status 405 - Request method 'POST' not supported...
  5. 异步EJB只是一个Gi头吗?
  6. Description Resource Path Location Type Java compiler level does not match the version of the insta
  7. curl txt批量_curl与wget高级用法
  8. python基础系列教程——python中的字符串和正则表达式全解
  9. 【摘要】抽取式摘要:TextRank和BertSum。
  10. iphone ping_如何在iPhone上运行Ping(网络诊断)
  11. ffmpeg录制麦克风声音和pc内部声音(如播放歌曲)---混音--修正
  12. 蓝桥杯之单片机学习(十八)——555定时器与频率测量
  13. 【苹果开发者账号】记一次苹果账号付款失败,报 未完成付款 的问题,全网都没解决办法!
  14. MATLAB中的三次样条插值spline函数
  15. Photoshop-为图像添加一个真实投影
  16. OrangePIPC2---bootrom
  17. mysql按天,小时,半小时,N分钟,分钟进行数据分组统计
  18. mysql 数据库基本知识
  19. 病毒、木马、蠕虫与恶意代码关键点
  20. Visio2016软件分享

热门文章

  1. 时间戳转换年月日——记一次字节面试题(C++实现)
  2. java rxtx version_RXTX实现JAVA串口编程
  3. 前端图片上传并且裁切
  4. 此战成硕,我成功上岸西南交通大学了~~~
  5. 如何使用Elasticsearch构建强大的搜索和分析应用程序(2023年最新ES新手教程)
  6. 小米面试题:手机分身,电话号码隐藏。
  7. C/C++ 函数出入口
  8. 提交代码时用prettier自动格式化
  9. js 树形结构数据 已知某一子节点 一次向上获取所有父节点
  10. excel无法打开文件,因为文件格式或文件扩展名无效