非线性系统
非线性系统的核心问题是求解方程的根。一般形式为:
f(x∗)=0,f:Rm→Rm
一维情形写作 f(x∗)=0。算法通常只能输出近似解 xest,并用残差 ∣f(xest)∣ 作为可计算的成功标准。
非线性方程可能没有显式解析解。例如:
f(x)=x5−3x4+25
或:
f(x)=ex+e−x−5−x
因此需要数值方法。
正则性假设
根查找问题本身太一般,若不加假设,很难设计可靠算法。常用假设包括连续、Lipschitz、可微和高阶光滑。
连续与 Lipschitz
连续性表示当 x→y 时,f(x)→f(y)。
Lipschitz 条件要求存在常数 c,使得:
∥f(x)−f(y)∥2≤c∥x−y∥2
Lipschitz 条件比连续性更强,它控制函数值变化不会超过输入变化的常数倍。
可微与光滑
一维函数可微表示 f′(x) 存在。若 f 有 k 阶连续导数,则称 f∈Ck;若所有阶导数都存在且连续,则称 f∈C∞。
典型例子:
- f(x)=cosx 是 C∞,并且在 R 上 Lipschitz。
- g(x)=x2 是 C∞,但在 R 上不是 Lipschitz。
- h(x)=∣x∣ 连续且 Lipschitz,但在 x=0 处不可微。
二分法
二分法依赖连续性和介值定理。若 f 在 [l,r] 上连续,并且:
f(l)f(r)<0
则区间内部至少存在一个根。
算法流程
二分法每步取中点:
c=2l+r
然后根据符号变化保留仍含根的一半区间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Bisection(f, l, r, epsilon): # 要求 f 连续,并且 f(l) * f(r) < 0。 while |r - l| >= epsilon: c <- (l + r) / 2
if f(c) == 0: return c
# 根仍在 [l, c] 中。 if f(l) * f(c) < 0: r <- c else: l <- c
return (l + r) / 2
|
二分法的优点是只要初始区间满足符号变化条件,就一定收敛;缺点是速度较慢。
收敛速度
令 Ek 表示第 k 步后的区间长度,则:
Ek+1≤21Ek
因此:
Ek≤2−kE0
二分法是线性收敛。若要使误差小于 ε,迭代次数大约满足 2−kE0<ε。
固定点迭代
固定点问题写作:
g(x∗)=x∗
它可以转化为根查找问题 g(x)−x=0。反过来,根查找问题 f(x)=0 也可以改写为固定点问题。
固定点迭代的基本形式为:
xk+1=g(xk)
几何上,它不断用当前点的函数值生成下一个点。
收敛条件
若 g 在根附近 Lipschitz,且 Lipschitz 常数 c<1,则固定点迭代在足够好的初值附近收敛。
令:
Ek=∣xk−x∗∣
因为 g(x∗)=x∗,有:
Ek=∣g(xk−1)−g(x∗)∣≤c∣xk−1−x∗∣=cEk−1
因此:
Ek≤ckE0
当 c<1 时,误差趋于 0。若 ∣g′(x∗)∣<1,通常可以在根附近得到这样的局部收敛性。
收敛阶
若 g′(x∗)=0 且 ∣g′(x∗)∣<1,固定点迭代通常线性收敛。
若 g′(x∗)=0,对 g 在 x∗ 处作 Taylor 展开:
g(xk)=g(x∗)+21g′′(x∗)(xk−x∗)2+O((xk−x∗)3)
因此误差满足:
Ek+1≈21∣g′′(x∗)∣Ek2
此时可能出现二次收敛。
Newton 方法
Newton 方法适用于可微函数。它用当前点处的切线近似函数,并取切线与 x 轴的交点作为下一次迭代。
一阶近似为:
f(x)≈f(xk)+f′(xk)(x−xk)
令右侧等于 0,得到 Newton 迭代:
xk+1=xk−f′(xk)f(xk)
也可以看作固定点迭代:
g(x)=x−f′(x)f(x)
收敛性
若 x∗ 是简单根,即:
f(x∗)=0,f′(x∗)=0
则 Newton 方法在足够接近根的初值附近通常二次收敛。
对 g(x)=x−f′(x)f(x) 求导:
g′(x)=(f′(x))2f(x)f′′(x)
在简单根处 f(x∗)=0,所以 g′(x∗)=0,这解释了 Newton 方法的二次收敛。
Newton 方法并非全局可靠。若初值不好、导数接近 0、函数形状复杂,迭代可能发散、震荡,或收敛到其他根。
算法流程
1 2 3 4 5 6 7 8
| Newton(f, f_prime, x0, epsilon): x <- x0
while |f(x)| >= epsilon: # f_prime(x) 过小时不能直接除。 x <- x - f(x) / f_prime(x)
return x
|
实际实现中通常还需要设置最大迭代次数,并检查 ∣f′(x)∣ 是否过小。
割线法
Newton 方法需要计算导数。若导数难以获得,可以用有限差分近似:
f′(xk)≈xk−xk−1f(xk)−f(xk−1)
代入 Newton 公式,得到割线法:
xk+1=xk−f(xk)−f(xk−1)f(xk)(xk−xk−1)
割线法需要两个初始点 x0,x1。它通常比二分法快,不需要显式导数,但没有二分法那样的无条件收敛保证。
算法流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Secant(f, x0, x1, epsilon): prev <- x0 curr <- x1
while |f(curr)| >= epsilon: denom <- f(curr) - f(prev)
# denom 过小时,割线斜率不可靠。 next <- curr - f(curr) * (curr - prev) / denom
prev <- curr curr <- next
return curr
|
割线法可以看作“用最近两点的割线代替 Newton 切线”。它省去了导数计算,但稳定性更依赖初始点和函数形状。
方法对比
四种方法的主要差异:
- 二分法:只要求连续和初始区间异号,收敛可靠,但速度较慢。
- 固定点迭代:形式简单,收敛依赖 g 在根附近是否为压缩映射。
- Newton 方法:局部收敛很快,简单根附近通常二次收敛,但需要导数且可能失败。
- 割线法:不需要显式导数,通常比二分法快,但稳定性不如二分法。
选择方法时,应同时考虑可用信息、初始值质量、函数正则性和失败处理策略。