牛顿-拉夫森法模拟器 返回
数值方法模拟器

牛顿-拉夫森法模拟器 — 非线性方程的根

以 f(x)=x³−2x−5 为例,实时可视化牛顿迭代 x_{n+1}=x_n−ω·f(x_n)/f'(x_n) 的收敛过程:切线步进与对数误差曲线,初值、容差、松弛系数全部可调。

参数
初值 x_02.00
最大迭代次数20
容差 1e^−n6
松弛系数 omega1.00
计算结果
收敛的根
迭代次数
最终 |f(x)|
收敛状态
函数曲线与切线(f(x)=x³−2x−5)
误差 |f(x_n)| 的收敛曲线(log10)
理论与主要公式

$$x_{n+1} = x_n - \omega\,\frac{f(x_n)}{f'(x_n)}$$

牛顿-拉夫森迭代公式。ω 为松弛系数(1.0 为标准牛顿,<1 为阻尼牛顿)。

$$f(x) = x^{3} - 2x - 5, \qquad f'(x) = 3x^{2} - 2$$

测试函数(牛顿当年的原例题)。实根 x ≈ 2.094551482。

$$|f(x_n)| < \varepsilon \quad \text{或} \quad |x_{n+1} - x_n| < \varepsilon$$

收敛判据。容差 ε = 1e^−n,n 为容差滑块的值。

什么是牛顿-拉夫森法

用当前估计点的切线对 f(x) 做线性化,再用切线与 x 轴的交点作为下一个估计点的迭代算法。它是几乎所有非线性 CAE 求解器内部都在反复调用的"主力"数值方法。

🙋
我把初值设成 2,三次迭代就收敛了;但改成 −2 立刻就飞掉。同一个方程为什么差这么多?
🎓
牛顿法本质是"用切线去够根"。当导数 f'(x) 很小时,切线接近水平,与 x 轴的交点就跑得很远。对 f(x)=x³−2x−5,f'(x)=3x²−2 在 x = ±√(2/3)≈±0.816 处为 0。从 x_0=−2 出发,轨迹会穿过这个不稳定带,导致下一步弹到很远。拖动初值滑块、再看下面的 log10 误差曲线,就能清楚地分辨"单调下降"与"突然反弹"两种走势。
🙋
那把 omega 滑块拉到 0.5,是不是就能救回初值不好的情况?
🎓
通常可以。把每步更新乘 ω 缩小,能让本来要发散的迭代稳下来——这就是"阻尼牛顿法",Abaqus、ANSYS、OpenSees 在塑性域里都内置这种策略。不过 ω 太小会破坏二阶收敛(有效位数翻倍的速率),退化成线性收敛。把误差曲线在 ω=1.0 和 ω=0.3 下比较一下,前者形成明显的"折弯",后者几乎是直线。
🙋
把容差缩到 1e^−12,迭代次数会爆炸吗?把容差设这么小有意义吗?
🎓
几乎是"白送"。二阶收敛下,从 1e^−6 缩到 1e^−12 只多 1〜2 次迭代。真正的瓶颈在双精度浮点的机器精度(约 2.2e^−16)和模型误差。CAE 实务里,线性 FEA 取相对残差 1e^−6 就够,非线性分析常取 1e^−4〜1e^−5——再严也淹没在离散化与材料模型的不确定度里。

物理模型与主要公式

牛顿-拉夫森法是把 f(x) 在当前迭代点 x_n 做一阶泰勒展开,让线性近似为零,解出下一个估计值。

$$f(x) \approx f(x_n) + f'(x_n)(x - x_n) = 0 \;\Rightarrow\; x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$$

引入松弛系数 ω 的阻尼形式:

$$x_{n+1} = x_n - \omega\,\frac{f(x_n)}{f'(x_n)}, \quad 0 < \omega \le 1$$

二阶收敛(令误差 e_n = x_n − x*):

$$|e_{n+1}| \le \frac{|f''(x^{*})|}{2|f'(x^{*})|}\,|e_{n}|^{2}$$

在根附近,有效位数大约每迭代一次翻一倍——这就是牛顿法的核心优势。

实际应用

非线性有限元(CAE):每一荷载增量内用牛顿-拉夫森法求残差力 R(u)=F_int(u)−F_ext=0,切线刚度 K=∂R/∂u 充当 f'(x) 的角色。塑性、接触、大变形分析都依赖这一迭代。

SPICE 电路仿真:二极管、MOSFET 等非线性器件让直流工作点方程 g(V)=0 非线性化。SPICE 用牛顿-拉夫森法在每一节点电压上迭代;"Newton failed to converge" 几乎是每位电路工程师都见过的报错。

优化与机器学习:将梯度 grad f(x)=0 视为求根问题,纯牛顿法用 Hessian 矩阵能实现二阶收敛。准牛顿法(BFGS、L-BFGS)对 Hessian 做近似,适用于高维参数训练。

轨道力学:Kepler 方程 M = E − e·sin E 解偏心角 E 时,标准做法就是牛顿-拉夫森法。卫星跟踪、星历表生成都靠它。

常见误解与注意事项

最大的误区是"反正是二阶收敛,初值随便取也行"。其实牛顿法只是局部收敛——初值不好就会发散或跳到错误的根。生产代码里一般会包一层"全局化策略":先用二分法或黄金分割把根的存在区间夹住,再切换到牛顿法。Brent 方法把二分、割线、逆二次插值整合在一起,是经典的混合算法。

第二条,留意 f'(x) ≈ 0 的位置。切线接近水平时,f/f' 的更新量会爆炸。在模拟器里把 x_0 拖到 0.8 附近,f'(0.8)=3(0.64)−2=−0.08,下一步立刻飞到对面去。工业级实现一般会给分母加下限、对 ω 做线性搜索,或用信赖域(trust region)限制步长。

最后,"收敛≠正确"。多项式 x³−2x−5 只有一个实根,但一般情形下不同初值会跑向不同的根(吸引盆问题)。在后屈曲结构分析中存在多条平衡路径,工程师改用弧长法(Riks 法)让迭代沿物理上正确的分支走,而不是被牛顿法"猛地"切到另一条分支。

常见问题

把 f'(x) 用中心差分 (f(x+h)−f(x−h))/(2h) 之类的数值微分替换,就得到"割线法(Secant method)";推广到方程组就是 Broyden 法。CAE 中由于组装切线刚度矩阵代价高,工程上常用"修正牛顿法"——在几步迭代中复用同一个 Jacobian,分摊计算量。
在重数为 m 的重根 x* 处,标准牛顿法的收敛阶从二阶降为一阶(线性)。修正格式 x_{n+1}=x_n − m·f/f' 能恢复二阶收敛。如果重数未知,可以使用 Schröder 迭代 x_{n+1}=x_n − f·f'/((f')²−f·f''),无需知道 m 也能维持二阶收敛。
可以。对向量方程 F(x)=0,更新公式为 Δx = −J(x_n)⁻¹ F(x_n),其中 J 为 Jacobian 矩阵。非线性有限元里 J 就是切线刚度 K。实际实现并不显式求逆,而是把线性方程 K·Δu = −R 交给直接法(LU 分解)或迭代法(GMRES、共轭梯度等)求解。
几乎没意义。双精度浮点只能可靠表示约 15〜16 位十进制有效数字,f(x) 的舍入与积分误差更早就成为瓶颈。工程上常用相对残差(相对于初始残差)做判据,线性问题 1e^−6、非线性问题 1e^−4〜1e^−5 已经足够——再严的容差会被网格离散化与材料模型误差完全淹没。