3. 数值精度基础

在动力系统仿真中,“算出来了”与“算对了”是两件不同的事。数值精度研究的就是计算结果与真实解之间的偏离程度,以及这种偏离如何随计算过程被放大或抑制。要判断一条仿真曲线是否可信,必须同时理解四类基本概念:舍入误差、截断误差、条件数与稳定性,以及它们共同决定的误差传播规律。

一、两类最基本的误差来源

舍入误差来自计算机只能用有限位二进制表示实数。例如双精度浮点数约有 15~16 位有效十进制数字,任何一次加法、乘法都可能引入约 10⁻¹⁶ 量级的相对误差。单次舍入误差极小,但在迭代成千上万步后可能累积。更隐蔽的是“大数吃小数”:当两个量级相差悬殊的数相加时,小量会被直接舍去。

截断误差则来自数值方法对数学模型的近似。以显式欧拉法求解 ẋ = f(x) 为例,其局部截断误差为 O(h²),全局误差为 O(h),其中 h 为步长。步长减半,全局误差约减半;而四阶龙格–库塔法的全局误差为 O(h⁴),步长减半误差约降为 1/16。截断误差是方法本身固有的,与浮点精度无关。

区分要点:舍入误差随“计算次数”累积,截断误差随“步长”变化。加密步长会减小截断误差,但步数增多又会放大舍入误差的累积,二者存在此消彼长的关系。

二、条件数与稳定性:问题本身与算法各自的责任

条件数刻画问题本身对输入扰动的敏感程度,是问题固有的属性,与所用算法无关。对动力系统而言,若初值的小扰动随时间被指数放大,则问题本身是病态的。以 ẋ = λx 为例,其解为 x(t) = x₀e^{λt}。当 λ > 0 时,初值相对误差 δ 会被放大为 δ·e^{λt};当 λ < 0 时扰动反而衰减。因此对不稳定系统,长期预测在原理上就不可靠,这不是换一个更精确的算法能解决的。

稳定性则是算法自身的属性,指数值解是否会在迭代中产生非物理的振荡或发散。仍以显式欧拉法求解 ẋ = λx 为例,迭代格式为 x_{n+1} = (1 + λh)x_n,稳定条件要求 |1 + λh| ≤ 1。当 λ = −100、h = 0.05 时,1 + λh = −4,模长大于 1,数值解会以交替符号迅速发散,尽管真实解是快速衰减的。此时必须把步长压到 h < 0.02 以内,或改用隐式方法(如隐式欧拉,无条件稳定)。

动力系统数值误差的来源、放大与判据 初值 / 参数扰动 δx₀, δλ 浮点表示 舍入误差 ~10⁻¹⁶ 离散格式 截断误差 O(hᵖ) 条件数 κ 问题固有敏感性 λ>0 放大, λ<0 衰减 算法稳定性 |1+λh| ≤ 1 步长约束 / 隐式格式 误差传播 e_{n+1} ≈ (1+λh)e_n + 局部截断 + 舍入 逐步累积或衰减 可信度判据 步长减半误差收敛? 能量/守恒量漂移? h↓ 截断↓ 但步数↑ 舍入↑

三、误差传播的基本规律

把上述因素串起来,可以得到误差传播的直观规律。设第 n 步的误差为 e_n,对 ẋ = λx 用显式欧拉法,误差近似满足 e_{n+1} ≈ (1 + λh)e_n + τ_n + ε_n,其中 τ_n 为局部截断误差,ε_n 为舍入误差。这个递推式说明:

  • 当 |1 + λh| > 1 时,历史误差被逐级放大,即使每步新增误差很小,总误差也会指数增长;
  • 当 |1 + λh| < 1 时,历史误差被压缩,总误差趋于由每步新增误差决定的稳态水平;
  • 对刚性系统(λ 为大的负数),显式方法的稳定步长被压得极小,此时应优先考虑隐式方法而非一味减小 h。

四、精度与效率的权衡:一个可操作的实例

考虑简单动力系统 ẋ = −50x,x(0) = 1,真解为 x(t) = e^{−50t}。要求在 t = 0.5 时得到 x ≈ e^{−25} ≈ 1.39×10⁻¹¹。用显式欧拉法,稳定条件要求 h < 2/50 = 0.04。若取 h = 0.01,需 50 步,数值解应接近真解;若取 h = 0.05,则 1 + λh = −1.5,数值解会以交替符号发散,结果完全失真。这说明稳定性是精度的前提:不稳定的格式再小心的舍入控制也无济于事。

若改用四阶龙格–库塔法,稳定域更大,可取 h = 0.02 甚至更大,在保证精度的同时减少步数。实际工程中常用的判断流程是:先用两种步长(如 h 与 h/2)各算一遍,比较结果差异;若差异随步长减小按预期阶数收敛,说明截断误差占主导且结果可信;若差异不收敛或出现振荡,则需检查稳定性或改用隐式方法。对守恒系统,还应监测能量等守恒量的长期漂移,作为独立于步长收敛性之外的第二重判据。

常见误区:认为“步长越小结果越准”。当 h 小到一定程度后,截断误差已可忽略,继续减小 h 只会增加步数,使舍入误差累积和计算量同时上升,总误差反而可能变大。合理的做法是找到误差随步长变化的“拐点”,在拐点附近选取步长。

综上,判断数值结果可信度应形成三层检查:一看问题条件数,明确长期预测的原理性上限;二看算法稳定性,确认步长落在稳定域内;三看步长收敛性,用 h 与 h/2 的对比验证截断误差是否按阶收敛。三者结合,才能在精度与效率之间做出有依据的取舍。