牛顿法 · 切线的力量,与它翻车的时候
牛顿法顺着切线滑向根,每步让正确位数翻倍——二次收敛,快得惊人。这一章手写它、打印「位数翻倍」的收敛表,也诚实展示它翻车的三种方式:导数为零、跑飞、来回震荡。快与险,是它的一体两面。
牛顿法 · 切线的力量,与它翻车的时候
二分法慢,因为它只看 的符号。牛顿法(Newton's method)快,因为它还用了 的斜率——顺着切线滑,一步到位得多。
思想:沿切线滑到 x 轴
在当前猜测 处,画一条 的切线,看这条切线和 x 轴的交点,把它当作下一个、更好的猜测 。切线方程一解,就得到牛顿法的迭代公式:
直觉很美:如果 在根附近接近一条直线,那么「沿切线滑到 x 轴」几乎就直接命中根了。
手写 + 「位数翻倍」的收敛表
还是求 (,):
def newton(f, df, x0, tol=1e-14, maxiter=50):
x = x0
for _ in range(maxiter):
fx = f(x)
if abs(fx) < tol:
return x
x = x - fx / df(x) # 沿切线滑
return x
import math
root = newton(lambda x: x*x - 2, lambda x: 2*x, x0=1.0)
print(root, abs(root - math.sqrt(2)))打印每步的误差,和二分法对比,差距惊人:
step x_n 误差 |x_n - √2|
0 1.00000000000000 4.1e-01
1 1.50000000000000 8.6e-02
2 1.41666666666667 2.5e-03
3 1.41421568627451 2.1e-06
4 1.41421356237469 1.6e-12
5 1.41421356237310 0.0看误差:0.41 → 0.086 → 0.0025 → 2e-6 → 1.6e-12——每一步大致是上一步的平方。 正确位数 大致翻倍。这叫二次收敛(quadratic convergence):
二分法砍 40 刀才到的精度,牛顿法5 步就到了。一旦进入根附近,它快得没道理。
但它会翻车
牛顿法的快,是有代价的——它不像二分法那样保证收敛。三种经典翻车方式:
① 导数为零:除以 0。 公式里除以 ,一旦迭代点撞上 (函数的水平切线),就除零崩溃,或切线几乎水平、把下一点甩到十万八千里。
② 起点不好:跑飞或跑到别的根。 牛顿法对初值敏感。起点离根太远、或函数有多个根 / 拐点,切线可能把你导向发散,或收敛到一个你没想要的根。
③ 来回震荡:陷入循环。 某些函数(如 从 出发)会让牛顿迭代在两个点之间无限来回跳,永远不收敛。
用代码亲眼看一次发散——对 从一个稍远的起点出发:
# arctan 的牛顿迭代,起点稍远就发散
f = lambda x: math.atan(x)
df = lambda x: 1 / (1 + x*x)
x = 2.0
for i in range(6):
x = x - f(x) / df(x)
print(f"step {i+1}: x = {x:.4f}")
# step 1: x = -3.5357
# step 2: x = 13.95
# step 3: x = -279.34 ← 越跑越远,发散切线把 一步步甩得越来越远——牛顿法飞了。同样的方法,起点 时几步收敛, 时直接发散。快和险,是一体两面。
实用建议:防翻车
工程上很少「裸用」牛顿法,而是给它加保险:
- 限制步长 / 加阻尼:如果一步跳得太远(比如 反而变大),就把步长砍半,别让它飞。
- 和二分法混用(safeguarded Newton):牛顿步若跳出了「夹住根的区间」,就退回去做一步稳的二分。这样既有牛顿的快、又有二分的绝不失手——鱼和熊掌兼得。成熟的库(
scipy.optimize.brentq等)内部就是这类混合方法。 - 不想手算导数:用下一章的割线法——它用差商近似导数,不需要 ,收敛也几乎和牛顿一样快。
口诀:牛顿法快,但要「牵着绳子放」——给它兜底,别让它裸奔。
小结与下一章
牛顿法沿切线滑向根,,二次收敛——每步正确位数翻倍,快得惊人。但它不保证收敛:导数为零会崩、起点不好会跑飞、某些函数会震荡。工程上要加保险(限步长、和二分混用、或用割线法免导数)。
牛顿是「二次收敛」,二分是「线性收敛」——这个「收敛阶」到底怎么定义、怎么测?还有一个「不用导数、却快过二分」的割线法,收敛阶是有趣的黄金比 。下一章把收敛阶这把尺子讲清。👉 不动点与割线法:收敛阶怎么量。
参考文献
- [1] Burden & Faires.《Numerical Analysis》, §2.3 —— 牛顿法与收敛性。
- [2] Tim Sauer.《Numerical Analysis》, §1.4 —— 牛顿法的发散与保险策略。
- [3] SciPy 文档.「scipy.optimize.newton.」https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.newton.html —— 库实现(含割线回退)。