乘、歸一、再來一次:冪法的全部
上一篇留給我們一個承諾:既然你無法可靠地去解特徵多項式,那就改用迭代去逼近特徵值。冪法(也叫冪迭代)是真能交差的迭代法裡最精簡的一個,它的規則一口氣就講得完:隨便挑一個起始向量,乘上矩陣 A,把它縮回長度 1,然後重複。做夠多次,這個向量就不再移動了——而它最後停下的地方,就是 A 的一個特徵向量。沒有系統要解、沒有分解、什麼都沒有,只有矩陣乘向量、一遍又一遍。
choose q_0 (any nonzero vector, e.g. all ones)
for n = 0, 1, 2, ... :
z = A q_n # one matrix-vector product
q_{n+1} = z / ||z|| # rescale back to length 1
lambda_estimate = q_{n+1}^T A q_{n+1} # Rayleigh quotient
stop when q_{n+1} stops moving (residual small)到底為什麼一次又一次乘上 A,會把某個特別的方向挑出來?這樣看就懂了。假設 A 有一整組特徵向量,把你的起始向量寫成它們的混合——每個方向各佔一點。每乘一次 A,每種成分就各自被自己的特徵值拉伸。屬於絕對值最大特徵值的那個方向被拉得最多,於是乘了很多次之後,它就把其他所有方向都壓了過去,像合唱團裡最響亮的那把嗓子最終蓋過全場。歸一化那一步只是讓長度維持在可控範圍;它從來不會改變是哪個方向在贏。
有多快,以及什麼時候卡住
佔據主導的速度,由單單一個比值決定。把絕對值最大的兩個特徵值叫做 lambda_1 與 lambda_2。每一步,不想要的 lambda_2 方向相對於想要的 lambda_1 方向,會以 |lambda_2 / lambda_1| 這個倍率縮小。所以特徵向量的誤差大致像 (|lambda_2/lambda_1|)^n 那樣下降——幾何式、也就是線性的收斂。如果 lambda_1 = 4 而 lambda_2 = 1,比值是 1/4,你大概每兩步就賺到一位十進位數字,很美。但如果 lambda_1 = 4.01、lambda_2 = 4.00,比值是 0.9975,你就只能用爬的,得花上幾千步才換到幾位數字。這跟線性系統那一階的譜比故事如出一轍:收斂是線性的,而它的速率是特徵值的一個比值。
把這些陷阱講老實話,因為它們都是真的、而且會咬人。第一,冪法只找得到絕對值最大的那一個特徵值——對其他所有特徵值都是瞎的。第二,如果最大的兩個在絕對值上相等或幾乎相等,比值就接近 1,收斂慢得像冰川。第三,一對絕對值相等的共軛複數特徵值,會讓迭代向量打轉而不是穩定下來,於是它根本不收斂。最後,如果你運氣差,起始向量剛好在主特徵向量方向上的分量是零,在精確算術裡冪法就看不見它了——不過在實務上,浮點算術那一點點捨入誤差會把一個非零分量灑回去,方法就悄悄地復原了。
反向迭代:想瞄哪裡就瞄哪裡
冪法只看得到最大特徵值的那種瞎眼,被一段乾淨的代數修好了。A 的特徵向量,恰好就是 (A - mu I)^{-1} 的特徵向量,其中 mu 是你任意選定的目標數。但特徵值被變換了:如果 A 有特徵值 lambda,那麼 (A - mu I)^{-1} 就有特徵值 1/(lambda - mu)。於是 A 中最靠近你目標 mu 的那個特徵值,就變成了 (A - mu I)^{-1} 的最大特徵值——而永遠抓最大值的冪法,現在就會剛好抓到你瞄準的那一個。這就是反向迭代(也叫帶平移的反向迭代),它讓你只要把 mu 選在某個特徵值附近,就能釣出任何一個特徵值,無論是中間的還是最小的。
- 挑一個靠近你想要的特徵值的目標 mu,再挑一個起始向量 q_0。
- 解線性系統 (A - mu I) z = q_n 求出 z——這就是那個反向乘法,但是用「解」做的,絕不去真的構造一個反矩陣。
- 歸一化:q_{n+1} = z / ||z||。
- 用瑞利商 lambda = q_{n+1}^T A q_{n+1} 更新特徵值估計,當殘差 ||A q - lambda q|| 很小時就停。
兩個實務要點能防止這招出錯。第一,你不要去算 (A - mu I)^{-1};你要在每一步去解系統 (A - mu I) z = q_n。把 A - mu I 用LU 分解一次性地分解掉,之後每次迭代就只是便宜的前向與回代——線性系統那一階「分解一次、多次求解」的習慣再度得利。去構造顯式反矩陣會更慢、更不準,正是你早已學過的避免求反矩陣那一課。第二,現在的收斂速率是 |(lambda_target - mu)/(lambda_second - mu)|:把 mu 選得非常靠近你想要的特徵值,分子就很小,於是方法飛快。
一個誠實的擔憂:A - mu I 快要奇異了
這裡有個應該一直在你心裡嘀咕的反對意見。為了快速收斂,我們想要 mu 極度靠近某個真正的特徵值 lambda。但當 mu 逼近 lambda,矩陣 A - mu I 就逼近一個奇異矩陣——它最小的奇異值朝零縮小,於是它的條件數暴增。我們在整個條件數那一階都在警告:用一個巨大條件數的系統去求解會丟失位數。我們難道不是在鋸自己坐著的那根樹枝嗎?這是個合理的擔憂,而初學者「為了安全」把 mu 從 lambda 退開的直覺,正好是完全錯誤的一步。
化解之道是數值線性代數裡最可愛的事實之一。沒錯,這個系統是病態的,所以解 z 帶著很大的相對誤差被算出來。但這個誤差幾乎完全指向你正在追的那個特徵向量——因為那正是這個快要奇異的矩陣放大得最多的方向。所以 z 裡那個「錯」的部分,其實大半就是更多份的正確答案。等你歸一化之後,那份污染就被洗掉了,而那次不準的求解仍然交給你一個極好的特徵向量。一個向後穩定的求解器給的是某個鄰近系統的精確解,而對這個特殊問題來說,「鄰近」就已經夠好了:病態在這裡是幫忙,不是添亂。
瑞利商迭代:每一步都重新瞄準
反向迭代在 mu 靠近特徵值時收斂得快——那為什麼還要把 mu 釘死?每一步本來就會產出一個更好的特徵向量,而從更好的特徵向量、瑞利商又給出更好的特徵值估計。那就把它回饋進去:每一步之後,把新的平移 mu 設成當前的瑞利商,重新瞄準。隨著你的特徵向量變好,你的目標就朝真正的特徵值步步逼近,收斂比的分子崩塌,迭代毫不留情地加速。這個回饋迴圈就是瑞利商迭代(RQI),它是特徵值問題版的牛頓法的精神近親。
回報極為驚人。對一個對稱矩陣,RQI 在接近答案時是立方收斂的:正確位數大約每一步翻三倍。看一次典型的執行——誤差像 1e-2、然後 1e-6、然後 1e-18 那樣縮小——三步你就到了機器精度。那一陣立方爆發,正是瑞利商 eps 變 eps^2 的魔法,與反向迭代加速兩者複利相乘的結果。代價跟前面剛好相反:因為 mu 每一步都變,你不能只把 A - mu I 分解一次了;你得在每次迭代都付一次新的LU 分解。但當只需要兩三次迭代時,這筆交易沒人會拒絕。