§6 算法的数值稳定性
通过前面对误差传播规律的分析和对§1算例的剖析,我们知道同一问题当选用不同的算法时,它们所得到的结果有时会相差很大,这是因为运算中的舍入误差在运算过程中的传播常随算法而异。凡一种算法的计算结果受舍入误差的影响小者称它为数值稳定的算法。下面再通过其他一些例子来进一步说明算法稳定性的概念。
例 4 解方程
①
解 由韦达定理可知,此方程的精确解为
如果利用求根公式
②
来编制计算机程序,在字长为8,基底为10的计算机上进行运算,则由于计算机实际上采用的是规格化浮点数的运算,这时
的第二项中最后两位数“01”,由于计算机字长的限制,在机器上表示不出来,故在计算机对阶舍入运算(用标记)时
所以
这样算出的根显然是严重失真的(因为精确解
),这说明直接利用式②求解方程式①是不稳定的。其原因是在于当计算机进行加、减运算时要对阶舍入计算,实际上是受到机器字长的限制,在计算
时绝对值小的数(1)被绝对值大的数(
)“淹没”了,在计算
时,
被
“淹没”了;这些相对小的数被“淹没”后就无法发挥其应有的影响,由此带来的误差,造成计算机结果的严重失真。
这时,如要提高计算机的数值稳定性,必须改进算法。在此例中,由于算出的根是可靠的,故可利用根与系数的关系式
来计算,有
所得结果很好。这说明第二种算法有较好的数值稳定性(注意在利用根与系数关系式求第二根时,必须先算出绝对值较大的一个根,然后再求另一个根,才能得到精度较高的结果)。同样道理,当多个数在计算机中相加时,最好从其中绝对值最小的数到绝对值最大的数依次相加,可减小和的误差。
例 5 试计算积分
解 由分部积分法可得
因此有递推公式
= 1 - n
(n = 2,3 …)
=
用上面的递推公式,在字长为6,基底为10的计算机上,从出发计算前几个积分值,其结果如表1-3。
表1-3
1 2 3 4 5 6 7 8 9 |
0.367879 0.264242 0.207274 0.170904 0.145480 0.127120 0.110160 0.118720 —0.068480 |
被积函数在积分限(0,1)区间内都是正值,积分值
取三位有效数字时的精确结果为0.0916,但表1-3中的
= -0.068480却是负值,与0.0916相差很大。怎么会出现这种现象呢?可分析如下。
由于在计算E1时有舍入误差约为
ε= 4.412
且考虑以后的计算都不再另有舍入误差。此ε对后面各项计算的影响为
这样,算到时产生的误差为
9!ε= 9! 4.412
≈0.6101
就是一个不小的数值了。
可以改进算法来提高此例的数值稳定性,即将递推公式改写为
=
从后向前递推计算时,的误差下降为原来的
,因此只要n取得足够大,误差逐次下降,其影响就会越来越小。
由
=
=
可知:当时,
。因此,可取
= 0作为初始值进行递推计算。
由于≈
,故
= 0的误差约为
。在计算
时误差下降到
到计算时,误差以下将到≯
,结果如表1-4。
表 1-4
20 19 18 17 16 15 14 13 12 11 10 9 |
0.0000000 0.0500000 0.0500000 0.0527778 0.0557190 0.0590176 0.0627322 0.0669477 0.07177733 0.0773523 0.0838771 0.0916123 |
这样得到的= 0.0916123已很精确了。可见,经过改进后的新算法具有很好的稳定性。
例6 对于小的x值,计算-1。
解 如果用-1直接进行计算,其稳定性是很差的,因为两个相近数相减会严重丢失有效数字,产生很大误差。因此,得采用合适的算法来保证计算的数值稳定性。可以把
在
点附近展开成幂级数:
则可得
按上式计算就有很好的数值稳定性。
通过以上这些例子就可以知道算法的数值稳定性对于数值计算的重要性了。如无足够的稳定性,将会导致计算的最终失败。为了防止误差传播和积累带来的危害,提高计算的稳定性,将前面分析所得的各种结果归纳起来,得到数值计算中应注意之点如下:
(1)应选用数值稳定的计算方法,避开不稳定的算式。
(2)注意简化计算步骤及公式,设法减少运算次数;选用运算次数少的算式,尤其是乘方幂次要低,乘法和加法的次数要少,以减少舍入误差的积累,同时也可节约计算机的机时。
例如,要计算的值时,如果x逐个相乘要做254次乘法,但若改写成
则只要作14次乘法运算即可。
又如前面§1引言中讲到的用秦九韶算法计算多项式,也是一个改变计算公式以减少运算次数的极好例子。
(3)应合理安排运算顺序,防止参与运算的数在数量级相差悬殊时,大数“淹没”小数的现象发生。
多个数相加时,最好从其中绝对值最小的数到绝对值最大的数依次相加;多个数相乘时,最好从其中有效位数最多的数到有效位数最少的数依次相乘。
(4)应避免两相近数相减,可用变换公式的方法来解决。
(5)绝对值太小的数不宜作为除数,否则产生的误差过大,甚至会在计算机中造成“溢出”错误。