本文资料均来自于Timothy Sauer所著的《数值分析》。
在处理方程求解、矩阵分解、最优化等问题时,经常会用到浮点数进行数值计算。然而,由于浮点数的精度问题,可能出现无法求解的情况。我们必须了解其中可能存在的风险,这也是本文要介绍相关概念的原因。
浮点数格式与计算
本文采用 IEEE 754浮点标准,其包含一组实数的二进制表示,即:符号、尾数和指数(也称为“阶”)。
浮点数有3种常用的精度等级,即单精度、双精度和扩展精度。浮点数在这3种格式里规定的数位的数目分别是32、64和80。这些数位的分配如下所示:
标准化的IEEE浮点数表示为:
浮点数的具体舍入规则和一些特殊机器数的表示这里不做介绍,下面介绍浮点数的加法计算过程。
在进行加法计算时,机器首先对齐2个数字的小数点位,接着相加,然后再把结果保存为浮点数字。这个过程在更高精度的寄存器中进行(这一点可能导致浮点数计算结果在不同硬件平台有区别),在保存计算结果时根据舍入规则做舍入处理(注意不是截断)。
根据舍入规则,结果为1。可以发现实数计算和浮点数计算的结果并不相同。
精度的损失
有很多计算方式可能导致精度严重损失,最简单的是两个近似数字的相减。这是比较好理解的,比如,123.4567-123.4566=0.0001,这个问题在开始的时候,有2个7位有效数字的数字,但得到的数字却只有1位有效数字。
通过“共轭等式”相乘进行计算重构可以避免这个问题,如下所示:
令
但是,使用MATLAB采用双精度进行计算时得到了如下结果:
可以发现,
精度的极限
使用双精度的数字(16位十进制有效数字)进行计算是否总是可以得到16位有效数字的结果?答案是否定的,有些问题即便是最好的算法也无法避免精度的损失。
以威尔金森多项式为例,即:
假设f是一个函数,r是一个根,意味着满足f(r)=0。假设
对于一个问题,如果计算中,小的后向误差造成了很大的前向误差,那么我们称这个问题是敏感的。
假设问题是找到f(x)=0的根r,但是计算导致了误差项
一阶泰勒展开后忽略误差项可得:
所以有:
定义误差放大因子为
(相对后向误差为什么定义为
可以发现,误差放大因子与
回到威尔金森多项式,定义扰动函数
可以发现误差被放大
##################分割线##########################
楼下有同学问为什么要选15次项作为扰动函数,这个楼主也不太清楚(流下数学渣的泪水。。),书中也没有给出原因,或选择准则。
下面分别计算以18-12次项作为g(r),且r=16时,它们的绝对值:
可以发现,除了高次项,它们的值基本在同一个量级,那么计算得到的误差放大因子也应该是一个量级。
这里建议有兴趣的同学之间去看原著,楼主数学渣也能看半懂。。或者其他的数值分析资料。
##################分割线##########################
条件数
问题的条件数定义为在规定类型的变化所造成的误差放大上界。条件数高的问题称为病态问题,条件数在1附近的问题称为良态问题。
方阵A的条件数cond(A)为求解Ax=b时,对于所有的右侧向量b,可能出现的最大误差放大因子。
定义||A||为矩阵A的范数,A的条件数也可以计算为
首先给出向量范数、矩阵范数的定义如下述图片所述:
令
可得:
上式表明,
在求解病态矩阵方程时,很难避免误差,因而能够尽可能识别并避免病态矩阵很重要。