條件數、穩定性與向後誤差分析
數值不穩定性(numerical instability)
不穩定的演算法就是那個粗心的廚師:就算用一份寬容的食譜,技法本身也會把小誤差製造成大誤差。數值不穩定性是一種失敗模式:演算法把浮點運算無可避免的捨入誤差放大到毀掉答案的程度——即使底層問題完全良態,換個演算法本來能輕鬆解對。這份損害是方法自己造成的,不是問題造成的。
不穩定通常來自一連串運算,把小誤差餵進一個會放大它們的步驟,最常見的就是災難性抵消:相減兩個幾乎相等、各自已帶捨入誤差的數,會消滅掉前導位數,把捨入雜訊推到前導位置。經典案例是二次公式:當 b^2 遠大於 4ac 時,計算根 (-b + sqrt(b^2 - 4ac))/(2a) 相減兩個近乎相等的量,會損失大部分位數——然而用「根之積」做數學上等價的重排,就能把它們救回來。同一個問題、同樣的精度,但一種運算次序不穩定,另一種卻沒問題。
誠實的說法:來自不穩定演算法的大誤差,是可修的毛病——換演算法,誤差就消失。這恰恰與病態問題相反,後者沒有任何演算法救得了。所以當答案看起來不對時,診斷的問題是:是「問題」病態(那就接受或重新表述)還是「演算法」不穩定(那就選一個向後穩定的)?把兩者搞混,會讓人不是放棄了可解的問題,就是繼續信任一個壞掉的方法。
用 (-b + sqrt(b^2-4ac))/(2a) 計算 x^2 - 200x + 1 = 0 的較小根,得到 200 - sqrt(39996) ~ 200 - 199.98999...——災難性抵消只剩下寥寥幾位好數字。改為先算大根,再用「根1 乘 根2 = c/a」精確得出小根。
一個良態問題,純粹被所選的運算次序毀掉。
不穩定是演算法的錯,可以靠重新表述計算來修復;別把它和病態混淆,病態是問題的錯,沒有任何演算法能治。
又称
另见