在设计算法时,必须充分注意舍入误差对计算结果的影响。对于同一个计算问题,不同的算法,由于舍入误差的积累不同,其计算结果可能大不相同,即使一个非常良态的问题,由于使用的方法不当,也可使计算结果完全失真,而变得毫无用处。
【例】考虑线性方程组Ax=b,其中
A=[1e-11 1;1+1e-11 1];b=[1 2]
容易验证这是一个十分良态的矩阵计算问题
现在假设我们是在十位十进制浮点数下求解这一方程组。若按自然顺序有第二个方程减去第一个方程两边乘以1e11消去x1来求解,则得x1=0,x2=1;而若用第一个方程减去第二个方程消去x2来求解,则得x1=1,x2=1,这个与方程的精确解x1=1,x2=1-1e-11来比可知,前者已面貌全非,而后者却已精确到小数点之后第十位,已是能够得到的最好结果。
上例说明,对于同一计算问题,使用的方法不同,效果也大不相同。一个算法,如果计算过程的舍入误差的积累不大,就是这一算法具有较好的数值稳定性;反之,如果计算过程的舍入误差的积累很大,就是说该算法数值稳定性不好,或者说其实数值不稳定的。
要想判定一个算法的数值稳定性的好坏,需要应用舍入误差分析的方法。关于舍入误差分析,通常有两种分析方法:一种是向前误差分析法,是根据浮点运算的舍入误差规律,直接估计计算结果和真实结果之间的误差。例如,对于加法运算,要估计|fl(x+y)-(x+y)|的上界,其中fl(x+y)表示x+y在浮点数系下的计算结果。另外一种是向后误差分析法,是根据浮点运算的舍入误差规律,把计算过程的误差返回到原始数据的误差。例如,对于加法运算,首先将x和y的实际浮点运算表示为
fl(x+y)=x(1+δ)+y(1+δ),
即看做是对x(1+δ)和y(1+δ)的精确加法运算;然后再对δ的大小给出估计。由于向后误差分析法将计算机中的浮点数的实际运算转化为通常的实数的精确运算,所以在分析过程中就可毫无困难地使用实数运算的代数运算法则,而向前误差分析就没有这一优点。因此在实际分析时,经常使用的是向后误差分析法。
算法的数值稳定性的好坏与问题的病态性一样,也是就相互对比而言的,是算法本身所固有的属性,与所要计算的具体问题是否病态无关。