这一章的核心是:
数值计算得到的通常是近似解。学习误差,就是要知道误差从哪里来、如何度量、如何传播,以及怎样设计更可靠的计算过程。
计算链条可以概括为:
实际问题 → 抽象、简化 → 数学模型 → 数值计算 → 问题近似解
在这条链条中,误差不可避免。常见来源包括:
- 模型误差:实际问题被抽象、简化为数学模型时产生。
- 观测误差:原始数据来自测量,测量值本身不可能绝对精确。
- 截断误差 / 方法误差:用有限步骤近似无限过程,或用较易求解的问题近似原问题。
- 舍入误差:计算机只能保留有限位数字,必须对数值进行舍入。
本章重点讨论:截断误差与舍入误差如何影响计算结果。

误差的来源#
数值计算方法研究的是:怎样用计算过程求数学问题的近似解。
现实问题通常不能直接交给计算机求解,需要经历:
- 把现实问题抽象成数学模型;
- 用数值算法求数学模型的近似解;
- 在计算机中用有限精度完成计算。
每一步都会引入误差。
模型误差#
实际问题的解与数学模型的解之间的差,称为模型误差。
例如实际海域、建筑、流场、圆形边界等对象是连续的、复杂的。为了计算,往往要把区域离散成网格,把复杂条件简化为可处理的边界条件。这样得到的数学模型已经是现实问题的近似。
课堂中用“圆在网格上表示”的例子说明这一点:连续圆形边界落到离散网格上时,圆边界会被网格单元近似,几何形状本身已经发生误差。
观测误差#
数学问题中的参数常由实验或观测得到。观测值无法绝对准确,因此由观测数据带来的误差称为观测误差。
例如长度、速度、温度、流量等物理量来自仪器测量。仪器精度有限,读数本身就带有误差。
截断误差#
许多数学对象本身含有无限过程。计算时只能截取有限项或有限步,因此会产生截断误差,也称方法误差。
典型例子是用泰勒级数近似函数:
cosx=1−2!x2+4!x4−6!x6+⋯+(2n)!(−1)nx2n+⋯当 ∣x∣ 很小时,可以用
cosx≈1−2x2作为近似。由交错级数的莱布尼茨判别法可知,截断误差的绝对值不超过下一项:
∣R∣≤24x4.所以截断误差来自“无限过程被有限化”。
舍入误差#
计算机不能保存所有实数。无穷小数、位数很多的数都要舍入成有限位数字,由此产生舍入误差。
课堂一开始提到的数制转换也说明了这一点:十进制整数可以转成二进制整数,例如
1310=11012,但许多十进制小数在二进制中会成为无限循环小数。计算机只能截断或舍入到有限位,于是出现舍入误差。
TIP数值计算中最常见的危险不是“有误差”,而是误差在后续运算中被放大。所以后面要讨论误差传播、条件数和算法稳定性。
绝对误差、相对误差与有效数字#
绝对误差#
设 x 为准确值,x∗ 为 x 的一个近似值,则近似值 x∗ 的绝对误差为
e(x∗)=x−x∗.准确值 x 往往未知,所以绝对误差的准确值通常也未知。实际中常估计一个正数 ε,使
∣e(x∗)∣=∣x−x∗∣≤ε.这个 ε 称为 x∗ 的绝对误差限,简称误差限。
于是准确值 x 必在区间
x∗−ε≤x≤x∗+ε中,也可以写作
x=x∗±ε.例:圆周率近似#
若取
π≈3.14,由于 3.14 是四舍五入到小数点后两位的结果,所以误差不超过最后保留位的半个单位:
∣π−3.14∣≤0.0016<21×10−2.若取
π≈3.142,则
∣π−3.142∣≤0.00041<21×10−3.这里可以看出:误差限与保留位数有关,但它不能完全反映近似值本身的精确程度。
相对误差#
绝对误差要结合数量级才有意义。比如同样误差 0.1,对测量 1000 米来说很小,对测量 0.2 米来说很大。
设 x=0,近似值 x∗ 的相对误差定义为
er(x∗)=xe(x∗)=xx−x∗.由于准确值 x 通常未知,实际常用
er(x∗)≈x∗e(x∗)估计相对误差。
若存在正数 εr,使
∣er(x∗)∣=x∗e(x∗)≤εr,则称 εr 为 x∗ 的相对误差限。
例:光速测量#
若实验测得光速
c∗=2.997925×105 km/s,其绝对误差限为 0.1 km/s,则相对误差限为
2.997925×1050.1<4×10−7.所以 4×10−7 可作为该近似值的相对误差限。
TIP绝对误差回答“差了多少”;相对误差回答“相对于原数差了多大比例”。数值计算中判断精度时,相对误差通常更有可比性。
有效数字#
有效数字既能表示近似值的大小,也能表示近似值的精确程度。
在计算中,常按四舍五入原则取近似值。若近似值 x∗ 的误差限为
21×10−n,则称 x∗ 准确到小数点后第 n 位。
从第一个非零数字到该精确位之间的所有数字,都称为有效数字。
例:2 的近似值#
2=1.414213562⋯若取四位小数:
x∗=1.414,则
∣2−1.414∣≤21×10−3,所以 1.414 有 4 位有效数字。
若取八位小数:
x∗=1.4142136,则
∣2−1.4142136∣≤21×10−7,所以它有 8 位有效数字。
例:小数前有零时的有效数字#
若
x=0.003400±21×10−5,则该近似值准确到小数点后第 5 位。从第一个非零数字 3 到这一位共有
所以 0.003400 有 3 位有效数字。前面的零只起定位作用,不计入有效数字。
例:整数部分较大时#
若
x∗=1452.046有 7 位有效数字,则误差限为
21×10−3.若
x∗=1452.0有 5 位有效数字,则误差限为
21×10−1.注意:末尾的 0 若位于有效位范围内,也应计为有效数字。
有效数字与相对误差的关系#
若近似值的规格化形式为
x∗=±0.a1a2⋯an×10m,a1=0,并且 x∗ 有 n 位有效数字,则其相对误差限可取
εr=2a11×10−n+1.反过来,如果相对误差限满足
εr≤2(a1+1)1×10−n+1,则 x∗ 至少有 n 位有效数字。
例:e 的近似值#
若
e≈2.72,这里 a1=2,且有 3 位有效数字,所以相对误差限为
εr=2×21×10−3+1=0.25×10−2.
数值计算中误差的传播#
误差进入计算过程后,会通过函数运算继续传播。
一般函数的误差传播#
设数值计算问题为
y=f(x1,x2,⋯,xn),参数 x1,x2,⋯,xn 的近似值分别为
x1∗,x2∗,⋯,xn∗.对应的近似结果为
y∗=f(x1∗,x2∗,⋯,xn∗).当数据误差较小时,由多元函数的一阶泰勒展开,有
e(y∗)=y−y∗≈i=1∑n∂xi∂f(x1∗,⋯,xn∗)e(xi∗).这说明:
输出误差大约等于各输入误差经过偏导数加权后的和。
其相对误差为
er(y∗)=y∗e(y∗)≈i=1∑n∂xi∂f(x1∗,⋯,xn∗)f(x1∗,⋯,xn∗)xi∗er(xi∗).其中
∂xi∂ffxi∗反映了第 i 个输入相对误差对输出相对误差的放大程度。
四则运算的误差传播#
由一般公式可推出四则运算中的误差传播规律。
和、差#
e(x1±x2)=e(x1)±e(x2),er(x1±x2)=x1±x2x1er(x1)±x1±x2x2er(x2).由此可得误差限估计:
∣e(x1±x2)∣≤∣e(x1)∣+∣e(x2)∣.结论:和差的绝对误差限不超过各数绝对误差限之和。
e(x1x2)≈x2e(x1)+x1e(x2),er(x1x2)≈er(x1)+er(x2).结论:乘积的相对误差近似等于各因子相对误差之和。
e(x2x1)≈x21e(x1)−x22x1e(x2),er(x2x1)≈er(x1)−er(x2).误差限估计为
er(x2x1)≤∣er(x1)∣+∣er(x2)∣.例:y=xn#
令
y=xn.由相对误差公式:
er(y)=d(lnxn)=nd(lnx)=ner(x).所以
er(xn)≈ner(x).特别地,若
y=x=x1/2,则
er(y)≈21er(x).也就是说,开平方会把输入相对误差约缩小一半;取 n 次幂会把相对误差约放大 n 倍。
例:计算 x∗=1.21×3.65−9.81#
假定参与运算的数据都准确到两位小数,则每个输入的绝对误差限均为
21×10−2.设
f(a,b,c)=ab−c,其中 a=1.21,b=3.65,c=9.81。由误差传播公式,
e(f)≈be(a)+ae(b)−e(c).于是绝对误差限满足
∣e(f)∣≤(3.65+1.21+1)×21×10−2=0.0293.近似结果为
f∗=1.21×3.65−9.81=−5.3935.相对误差限可估计为
∣f∗∣∣e(f)∣≤5.39350.0293≈0.0054.因此该计算结果大约有两位有效数字。
线性方程组中的误差放大:条件数#
课堂还补充了线性方程组中误差放大的问题。
考虑
Ax=b.如果右端项 b 有扰动 δb,对应解的扰动为 δx,则
A(x+δx)=b+δb.由 Ax=b 得
Aδx=δb,从而
δx=A−1δb.取范数,有
∥δx∥≤∥A−1∥∥δb∥.另一方面,
∥b∥=∥Ax∥≤∥A∥∥x∥.于是得到相对误差估计:
∥x∥∥δx∥≤∥A∥∥A−1∥∥b∥∥δb∥.定义矩阵 A 的条件数为
cond(A)=∥A∥∥A−1∥.因此
∥x∥∥δx∥≤cond(A)∥b∥∥δb∥.TIP条件数衡量的是问题本身对扰动的敏感程度。
- cond(A) 小:右端项小扰动通常只导致解的小扰动。
- cond(A) 大:右端项很小的误差也可能被严重放大。
这种问题称为病态问题或病态线性方程组。
例:Hilbert 矩阵#
课堂用 Hilbert 矩阵演示病态性。Hilbert 矩阵定义为
Hij=i+j−11,1≤i,j≤n.例如
H3=12131213141314151.课堂中用软件计算得到:
结果约为
1.55×104.继续增大阶数:
结果约为
1.60×1013.这说明 Hilbert 矩阵随阶数增大迅速变得极度病态。即使输入数据只产生很小扰动,解也可能出现明显误差。
算法的数值稳定性#
什么是数值稳定性#
同一个数学问题可以有多种算法。数学上等价的算法,在有限精度计算中效果可能差别很大。
如果计算过程中产生的舍入误差不会持续放大,这类算法称为数值稳定;如果误差在递推或迭代中不断被放大,则称为数值不稳定。
WARNING要区分两个概念:
- 问题病态性:问题本身对输入扰动敏感,常用条件数衡量。
- 算法稳定性:算法在计算过程中是否放大舍入误差。
病态问题即使用稳定算法也很难算准;良态问题若选了不稳定算法,也可能算坏。
例:递推计算积分#
考虑积分
In=∫01x+5xndx,n=0,1,2,⋯由
x+5xn+5x+5xn−1=xn−1可得递推关系
In+5In−1=∫01xn−1dx=n1.另外,由于 0≤x≤1 时
5≤x+5≤6,所以有估计
6(n+1)1<In<5(n+1)1.这给出了 In 的正性和大致范围。
算法 I:正向递推#
先算
I0=∫01x+51dx=ln56=ln1.2.再由
In=n1−5In−1,n=1,2,⋯依次计算 I1,I2,⋯。
课堂演示代码可以写成:
I(n + 1) = 1/n - 5 * I(n);
问题在于:若 I0 有误差 e0,且递推中不再产生新的舍入误差,则
en=In−In∗=−5en−1.因此
en=(−5)ne0.也就是说,每向前递推一步,误差约放大 5 倍。正向递推是数值不稳定的。
算法 II:反向递推#
先取一个较大的 n,用上下界给出 In 的粗略近似。例如取
I14∗=21(6×151+5×151)≈0.01222222.再由递推式改写为
Ik−1=51(k1−Ik),k=n,n−1,⋯,1.从 I14 反推 I13,I12,⋯,I0。
课堂演示代码可以写成:
I(15) = 0.5 * (1/(6*15) + 1/(5*15));
I(k) = (1/k - I(k + 1)) / 5;
误差满足
ek−1=−51ek.所以反向递推时,误差每一步约缩小为原来的 1/5。反向递推是数值稳定的。
两种算法结果对比#
| n | 算法 I 正向递推 | 算法 II 反向递推 |
|---|
| 0 | 0.18232155 | 0.18232155 |
| 1 | 0.08839225 | 0.08839222 |
| 2 | 0.05803875 | 0.05803892 |
| 3 | 0.04313958 | 0.04313873 |
| 4 | 0.03430208 | 0.03430633 |
| 5 | 0.02848958 | 0.02846835 |
| 6 | 0.02418750 | 0.02432491 |
| 7 | 0.02176390 | 0.02123260 |
| 8 | 0.01618305 | 0.01883699 |
| 9 | 0.03019588 | 0.01692617 |
| 10 | -0.05097941 | 0.01536914 |
| 11 | 0.34580612 | 0.01406339 |
| 12 | -0.64569760 | 0.01301636 |
| 13 | 8.30540938 | 0.01184127 |
| 14 | -41.45618310 | 0.01222222 |
由积分定义可知 In>0。正向递推到后面甚至得到负数,明显错误;反向递推得到的结果保持合理。
TIP这个例子说明:算法不能只看数学等价性,还要看误差在计算过程中的传播方式。
数值计算中应注意的问题#
由于误差会传播和放大,数值计算中要尽量避免下列现象。
避免两个相近数相减#
两个相近数相减时,结果很小,而相对误差可能很大。
由差的相对误差公式,若
u=x−y,则
er(u)=x−ye(x)−e(y).当 x≈y 时,分母 x−y 很小,误差会被放大,有效数字会严重损失。这种现象称为相消误差。
例:计算 1+10−7−1#
如果直接计算
x=1+10−7−1,由于 1+10−7≈1,两个相近数相减会丢失有效数字。
可做代数变形:
1+10−7−1=1+10−7+110−7.这样避免了相近数直接相减。
例:计算 1−cos2∘#
利用四位数学表,
cos2∘≈0.9994.若直接计算
1−cos2∘≈1−0.9994=0.0006,该近似值只有一位有效数字。
若改用恒等式
1−cos2∘=2sin21∘,查表得
sin1∘≈0.0175,于是
1−cos2∘≈2(0.0175)2=0.6125×10−3.这时至少有两位有效数字。
常用的避免相消变形包括:
1−cosx=2sin22x,\frac{1-\cos x}{\sin x}=\frac{\sin x}{1+cos x},x+1−x=x+1+x1,x1−x+11=x(x+1)1.避免大数吃小数#
计算机有限位运算中,若一个很大的数与一个很小的数相加,小数部分可能被舍去。
例如
a=109+1.为了使两项数量级相同,可写成
a=0.1×1010+0.0000000001×1010.如果计算机只能保留 8 位小数,则第二项会被舍去,得到
a≈0.1×1010=109.这就是“大数吃小数”。
例:二次方程求根#
求方程
x2−(109+1)x+109=0的根。
容易看出两个根为
x1=109,x2=1.若直接使用求根公式,
x=2109+1±(109+1)2−4×109,在计算较小根时会出现两个相近大数相减,可能得到错误结果。
对于较小根,应该用等价公式
x2=109+1+(109+1)2−4×1092×109.这样避免了大数相减,能得到
x2≈1.避免除数绝对值远小于被除数#
由商的绝对误差传播公式:
e(yx)=y2ye(x)−xe(y).当 ∣y∣≪∣x∣ 时,分母 y2 很小,误差会被显著放大。
所以在数值计算中,应尽量避免把很小的数放到分母里,特别是在小分母本身还有误差时。
简化计算,减少运算次数#
运算次数越多,舍入误差累计的机会越多。选择合适公式可以同时减少计算量和误差积累。
例:计算 ln2#
若用交错级数
ln2=1−21+31−41+⋯+n(−1)n−1+⋯取前 n 项时,截断误差约不超过
n+11.若要求误差小于 10−5,需要
n≥105.这意味着要计算十万项,效率很低,而且舍入误差也会累积。
利用级数
ln1−x1+x=2(x+3x3+5x5+⋯+2n+1x2n+1+⋯),取
x=31,则
ln2=32[1+3×91+5×921+⋯+(2n+1)9n1+⋯].若只取前 5 项,截断误差满足
e<32⋅11×951(1+91+921+⋯)=12×11×941<10−5.显然,第二种算法效率更高。
例:多项式求值与秦九韶算法#
设
Pn(x)=anxn+an−1xn−1+⋯+a1x+a0.若直接按定义计算,需要约
2n(n+1)次乘法和 n 次加法。
利用秦九韶算法,将多项式写成
Pn(x)=a0+x{a1+x[a2+⋯+x(an−1+anx)]}.递推形式为
⎩⎨⎧un=an,uk=xuk+1+ak,k=n−1,n−2,⋯,0,Pn(x)=u0.这样只需 n 次乘法和 n 次加法。
选用数值稳定性好的算法#
算法的数学形式可能等价,但数值效果可能相差很大。
选择算法时应优先考虑:
- 是否会导致相近数相减;
- 是否会让小误差在递推中持续放大;
- 是否会出现大数吃小数;
- 是否可通过变形减少运算次数;
- 问题本身是否病态。
前面的积分递推例子表明:同一递推关系正向计算不稳定,反向计算稳定。
本章小结#
这一章可以抓住四条主线。
第一,误差来源:
本章重点关注截断误差和舍入误差。
第二,误差度量:
e(x∗)=x−x∗,∣e(x∗)∣≤ε,er(x∗)≈x∗e(x∗),∣er(x∗)∣≤εr.有效数字用来同时描述近似值的大小和精度。若
x∗=±0.a1a2⋯an×10m,且有 n 位有效数字,则
εr=2a11×10−n+1可作为相对误差限。
第三,误差传播:
e(y∗)≈i=1∑n∂xi∂fe(xi∗),相对误差传播由
∂xi∂ffxi∗决定放大倍数。
四则运算中:
- 和差主要看绝对误差;
- 积商主要看相对误差;
- 相近数相减最容易丢失有效数字。
第四,算法选择:
- 避免相消;
- 避免大数吃小数;
- 避免小分母放大误差;
- 简化计算、减少运算次数;
- 选数值稳定的算法;
- 对线性方程组,还要关注条件数。
本章最重要的思想是:
数值计算不仅要算出一个答案,还要知道这个答案是否可靠,以及为什么可靠。