数值计算笔记-非线性方程求解

2.1根本问题

1.问题:我们经常遇到f(x) = 0求解的问题.我们想要知道当f(x)为非线性方程时有什么方法求解f(x)的零点,也就是上面方程的根.在这里会介绍二分法,不动点迭代法,牛顿法,割线法,逆二次插值法,zeroin法.

2.2问题的基本概念和敏感性

1.根的重数:对光滑函数f,若
f(x)=f(x)==fm1(x)=0fm(x)0 f(x^*) = f'(x^*) = \cdots = f^{m - 1}(x^*) = 0 \land f^m(x^*) \neq 0

xx^*为方程的m重根

2.问题的敏感性

求解非线性方程的f(x) = y问题是“已知y = 0,求x = ?”

问题条件数:cond=ΔxΔy1f(x)cond = |\frac{\Delta x}{\Delta y}| \approx \frac{1}{|f'(x^*)|}

数值计算笔记-非线性方程求解

2.3二分法

1.二分法(初中学的二分法)

输入:有根区间[a, b],函数f(x)

输出:零点xx^*

(1)x0=a,k=0,a0=a,b0=bx_0 = a, k = 0, a_0 = a, b_0 = b

(2)若bkak<ϵb_k - a_k < \epsilon,则x=xkx^* = x_k结束

(3)若sign(f(xk))=sign(f(ak))sign(f(x_k)) = sign(f(a_k)),则ak+1=xk,bk+1=bka_{k + 1} = x_k, b_{k+1} = b_k,否则ak+1=ak,bk+1=xka_{k + 1} = a_k, b_{k + 1} = x_k

(4)k = k + 1转(2)

2.误差分析,机械精度ϵ\epsilon

最终停止时:bkak=2log2x2ϵb_k - a_k = 2^{\lfloor log_2|x^*|\rfloor} \cdot 2\epsilon

绝对误差:e(xk)=xkx2log2x2ϵe(x_k) = |x_k - x^*| \leq 2^{\lfloor log_2|x^*|\rfloor} \cdot 2\epsilon

相对误差:er(xk)=xkxx2ϵe_r(x_k) = \frac{|x_k - x^*|}{|x^*|} \leq 2\epsilon

2.4不动点迭代法

1.思路:将f(x) = 0改为x=ϕ(x)x = \phi(x),构造迭代公式xk+1=ϕ(xk)x_{k + 1} = \phi(x_k),下图给出了迭代的图形解释

数值计算笔记-非线性方程求解

注:确实有可能迭代得结果越来偏离正确解,之后会用特定的算法约束迭代过程.

2.不动点迭代法

输入:函数f(x),初值x0x_0,迭代公式x=ϕ(x)x = \phi(x)

输出:零点xx^*

(1)初值x0=x0,k=0x_0 = x_0, k = 0

(2)计算xk+1=ϕ(xk)x_{k + 1} = \phi(x_{k})

(3)若f(xk)<ϵ1xk+1xk<ϵ2|f(x_k)| < \epsilon_1 \land |x_{k + 1} - x_{k}| < \epsilon_2x=xk+1x^* = x_{k + 1}结束,否则转(2)

3.收敛定理:若ϕ(x)C[a,b]\phi(x) \in C[a, b]满足,C[a, b]表示[a, b]上的连续函数

(1)x[a,b],aϕ(x)b\forall x\in [a, b], a \leq \phi(x) \leq b

(2)L(0,1),x1,x2[a,b]\exist L \in (0, 1), 对 \forall x_1, x_2 \in[a, b]ϕ(x1)ϕ(x2)Lx1x2\phi(x_1) - \phi(x_2) \leq L|x_1 - x_2|

ϕ(x)\phi(x)在[a, b]上有唯一不动点,称为全局收敛

:若ϕ(a)=a\phi(a) = aϕ(b)=b\phi(b) = b则a或b即为不动点

否则ϕ(a)>aϕ(b)<b\phi(a) > a \land \phi(b) < b

f(x)=ϕ(x)xf(x) = \phi(x) - x则f(x) < 0, f(b) > 0

f(x)为连续函数,因此x[a,b]\exist x^* \in [a, b]

定理:若将收敛定理中的(2)改为ϕ(x)<1|\phi'(x)| < 1,则同样有全局收敛性

4.局部收敛:函数ϕ(x)\phi(x)存在不动点xx^*,若存在其某个邻域D:[xδ,x+δ]D:[x^* -\delta, x^* + \delta],对于任意初值x0Dx_0 \in D,迭代法xk+1=ϕ(xk)x_{k + 1} = \phi(x_k)产生的解序列{xk}\{x_k\}收敛到xx^*,则迭代法局部收敛

定理:设xx^*为函数ϕ(x)\phi(x)的不动点,若ϕ(x)<1,x[xδ,x+δ]\phi'(x) < 1, \forall x \in [x^* - \delta, x^* + \delta],则迭代法局部收敛

5.收敛阶:迭代解序列{x0,x1,,xk,}\{x_0, x_1, \cdots, x_k, \cdots \}收敛于xx^*,误差e(xk)=xkxe(x_k) = x_k - x^*
limke(xk+1)e(xk)p=C0 \lim_{k \rightarrow \infty} \frac{|e(x_{k + 1})|}{|e(x_k)|^p} = C \neq 0
则收敛阶为p,其中C为常数

p阶收敛定理:迭代公式xk+1=ϕ(xk)x_{k + 1} = \phi(x_k),若ϕ(x)\phi(x)xx^*邻域上p阶导数连续p2p \geq 2,则该迭代法p阶收敛的充要条件为ϕ(x)==ϕp1(x)=0\phi'(x^*) = \cdots = \phi^{p - 1}(x^*) = 0

证明思路
e(xk+1)=xk+1x=ϕ(xk)ϕ(x)=ϕ(x)(xkx)++1p!ϕ(p)(ξ)(xkx)p e(x_{k + 1}) = x_{k + 1} - x^* = \phi(x_k) - \phi(x^*)\\ = \phi'(x^*)(x_k - x^*) + \cdots + \frac{1}{p!}\phi^{(p)}(\xi)(x_k - x^*)^p
在此泰勒公式的基础上再带入定义化简

2.5牛顿法

1.思路f(x)=0f(x)f(xk)+(xxk)f(xk)0f(x) = 0 \Rightarrow f(x) \approx f(x_k) + (x - x_k)f'(x_k) \approx 0

迭代公式即为:xk+1=xkf(xk)f(xk)x_{k + 1} = x_k - \frac{f(x_k)}{f'(x_k)}(牛顿法也是不动点迭代法)
数值计算笔记-非线性方程求解

2.牛顿法

输入:函数f(x) = 0,初值x0x_0,迭代公式xk+1=xkf(xk)f(xk)x_{k + 1} = x_k - \frac{f(x_k)}{f'(x_k)}

输出:输出最优值xx^*

(1)初值x0=x0x_0 = x_0,k = 0

(2)计算xk+1=xkf(xk)f(xk)x_{k + 1} = x_{k} - \frac{f(x_k)}{f'(x_k)}

(3)若f(xk)<ϵ1xk+1xk<ϵ2|f(x_k)| < \epsilon_1 \land |x_{k + 1} - x_{k}| < \epsilon_2,则x=xk+1x^* = x_{k + 1}结束

(4)k = k + 1转(2)

3.单根收敛定理:设xx^*是f(x) = 0的单跟,且f(x)在xx^*附近有2阶连续导数,则牛顿法产生的解序列2阶收敛

4.牛顿法m重根收敛定理limke(xk+1)e(xk)=11m\lim_{k\rightarrow \infty} |\frac{e(x_{k + 1})}{e(x_k)}| = 1 - \frac{1}{m},其中m为非线性方程根的重数.

2.6割线法与抛物线法

1.割线法:在牛顿法迭代时,用差商代替导数f(x)f(xk)f(xk1)xkxk1f'(x) \approx \frac{f(x_k) - f(x_{k - 1})}{x_k - x_{k - 1}},即(xk,yk),(xk1,yk1)(x_k, y_k),(x_{k - 1}, y_{k - 1})的斜率

2.抛物线法(二次插值法):带入xk,xk1,xk2x_k, x_{k - 1}, x_{k - 2}算出抛物线,用抛物线与x轴交点作为xk+1x_{k + 1}

注:抛物线有可能不与x轴相交,可以使用“侧向抛物线”把xy轴较换求抛物线,这样一定会与x轴相交(逆二次插值法)

数值计算笔记-非线性方程求解

2.7使用的方程求根基数

1.阻尼牛顿法:将牛顿法的迭代公式变为xk+1=xkλif(xk)f(xk)x_{k + 1} = x_{k} - \lambda_i\frac{f(x_{k})}{f'(x_{k})}

其中λi{λ}(0,1]\lambda_i \in \{\lambda\} \subset (0, 1],每次选择的λi\lambda_i保证f(xk+1)f(xk)|f(x_{k + 1})| \leq|f(x_k)|

2.zeroin通法

思路:综合使用逆二次插值法,割线法,二分法得到收敛速度快,稳定的算法

输入:方程f(x) = 0,有根区间[a, b]

输出:解xx^*

(1)选取初始值a和b,使得f(a)和f(b)异号

(2)将a赋值给c

(3)重复循环直到满足精度f(b)ϵ1abϵ2b|f(b) \leq \epsilon_1 \lor |a - b| \leq \epsilon_2|b|

a.若f(b)的正负号与f(a)相同,a = c;

b. 若|f(a)| < |f(b)|,则c = b,然后对调a,b;

c. 如果cac \neq a,使用a,b,c对应的点作逆二次插值法,得到与x轴交点赋值给b;否则执行割线法,得到与x轴交点赋值给b

d. 若得到的近似解“比较满意”,则赋值给b不变,否则使用a,c重新用二分法得到新的b;将3.b中得到的b赋值给c

注:3.a和3.b都是为了调整a,b,c的位置,让|f(b)| < |f(a)|;3.c和3.d则是选择最优的迭代方法.

3.zeroin例子

下面列出zeroin实际执行的每一步,每一步分别用(1),(2),(3),3.a,3.b,3.c,3.d表示

数值计算笔记-非线性方程求解

(1)初始化a0,b0a_0, b_0如上图所示

(2)初始c0=a0c_0 = a_0

(3)判断精度未达到

3.a f(b)与f(a)符号不同,无操作

3.b |f(a)| < |f(b)|,c1=b0,b1=a0,a1=b0c_1 = b_0, b_1 = a_0, a_1 = b_0(到这里已经调整好a,b,c的位置)

3.c c1=a1c_1 = a_1得到做割线法,得到上图中b2b_2

3.d 得到的结果满意,c2=b1c_2 = b_1,为了说明方便,a2=a1a_2 = a_1

(3)判断精度未达到

3.a 无操作

3.b 无操作

3.c c2a2c_2 \neq a_2,则根据逆二次插值法得到b3b_3如上图所示

3.d 得到的结果满意,c3=b2,a3=a2c_3 = b_2, a_3 = a_2

……

注:此处只是为了说明方便才列出所有的角标,实际程序运行过程中都是同一个变量,而不是数组