條件數(condition number)
如果說條件性是「有些問題會放大輸入誤差」這個概念,那麼條件數就是那個告訴你「放大多少倍」的單一數字。它是問題的「增益旋鈕」:在輸入端餵入大小為 epsilon 的抖動,輸出就大約抖動(條件數)乘以 epsilon。條件數為 1 表示問題原封不動地把誤差傳過去;條件數為 10^6 則表示它把誤差放大一百萬倍。
標準的含義是相對條件數。對於問題 y = f(x),它回答:當 x 有微小的相對變化時,在擾動趨於極小的極限下,y 最壞情況的相對變化是多少?用符號寫,kappa =(輸出的相對變化)/(輸入的相對變化),並在擾動方向上取最大值。對於光滑的純量函數,這算出來是 kappa = |x f'(x) / f(x)|,可以用導數算出。也有一個絕對版本,但你通常要的是相對版本,因為電腦保留的是固定的有效位數,而不是固定的絕對誤差。
條件數給出著名的「位數損失」經驗法則:一個條件數約為 10^k 的問題,無論你用什麼演算法,大約會損失 k 位有效數字的準確度。雙精度一開始約有 16 位,所以條件數接近 10^16 時可能讓你幾乎一位都不剩。關鍵在於這種損失純粹是問題的性質——就算用一個完美、無限謹慎的演算法也會發生——這就是為什麼估計條件數是信任任何數值答案的一環。
對 f(x) = sqrt(x),kappa = |x f'(x)/f(x)| = |x (1/(2 sqrt(x))) / sqrt(x)| = 1/2——開平方在各處都是良態的。而對於減法 f(a,b) = a - b 且 a 與 b 相近時,當 a 趨近 b,條件數會爆增,正是災難性抵消的訊號。
一個以導數為基礎的小公式,事先就告訴你哪些輸入是危險的。
條件數很大是對「問題」的判決,不是對你程式的判決。它無法靠更好的演算法修好——只能靠重新表述問題或採用更高的精度。