[數值計算] QR分解


https://zhuanlan.zhihu.com/p/84415000

0. 為什么要用QR分解

[公式] 的問題可以分成3類:

  • 情況1:A是方陣,m=n
  • 情況2:A是over-determined的,m>n
  • 情況3:A是under-determined的,m<n

[數值計算] 條件數的例子2里,遇到的情況1(A是方陣),通過構造拉格朗日插值來使得對A求逆足夠穩定。對於一般的情況下,解決思路是使用LU(LUP)分解來解決穩定性問題,在前一篇文中已經簡介過了[數值計算] LU分解、LUP分解、Cholesky分解

對於后兩種情況, [數值計算] 數據擬合——線性最小二乘法 分析了用正規方程組求解over-determined以及under-determined的問題。但在文中也提到了,對於over-determined的線性最小二乘問題,正規方程組是不穩定的,通常需要用QR分解來處理

理論很美好,在小數據量的時候沒問題,然而直接使用正規方程組求解會在數據量大(e.g. data size > 100)的時候不穩定numerically unstable。原因是 需要對 [公式] 求逆,而A我們都知道是Vandermonde矩陣的一部分,本身就是poorly conditioned,而  [公式] 只會更糟糕。解決的方法是使用QR分解,這也是Python MATLAB求解 線性最小二乘 問題的方法。

1. QR分解

1.1 定義

一個矩陣 [公式] 可以被分解成 [公式] ,其中:

  • [公式] 是正交矩陣
  • [公式]
  • [公式] 是上三角矩陣

1.2 正交矩陣的性質

  • [公式]
  • 左乘一個正交矩陣對歐式范數的結果不影響(在下面證明eq.2的時候會用到)

[公式]

1.3 從QR分解角度看線性最小二乘

對於一個over-determined線性最小二乘問題 [公式] ,其目標函數是 [公式]

這里 [公式] ,[公式], [公式] , [公式] 。

如果把 [公式] 拆分成上下兩部分,形式 [公式] 類似, [公式] 。那么目標函數可以寫成下面的形式:

[公式]

可以看到,我們只能最小化前一部分 [公式] 到0,即 [公式] , [公式] 的最小值為 [公式] 。這樣處理之后就避免了求正規方程組中的 [公式] ,避免了條件數變成 [公式] ,所以QR分解法更加數值穩定。

1.4 計算QR分解的方法

一共有三種:

  • Gram–Schmidt Orthogonalization
  • Householder Triangularization
  • Givens Rotations

1.5 Gram–Schmidt Orthogonalization

1.5.1 Reduced QR分解

GSO構建正交矩陣 [公式] 的方法是從A矩陣的n個列( [公式] )中構建互相正交的基,先選定 [公式] 為第一個基,然后把第二列 [公式] 減去平行於 [公式] 的部分,剩下的垂直於 [公式] 的部分作為下一個基,以此類推,直到生成了n個基。

[公式]

[公式]

這個方法生成的 [公式] ,[公式] ,和section1.1中定義的Q是方陣,R不是方陣有區別。這個結果被稱為Reduced QR分解,因為m>n,所以只滿足 [公式] ,而不滿足 [公式] 。

Credit to http://iacs-courses.seas.harvard.edu/courses/am205/schedule/

Reduced QR分解同樣可以求解over-determined線性最小二乘問題。形式類似Full QR分解:

[公式]

其中 [公式] , [公式] 。

1.5.2 Full QR分解

為了實現定義中的完整的QR分解,需要把上面生成Q中的n個基拓展成m個互相正交的基。但此處並沒有對額外的m-n個基的順序有特殊要求,因此任意一種順序都可以。另外還需要把 [公式] 下面加m-n行零矩陣。

在Python中,Reduced QR分解和Full QR分解對應於

q,r = np.linalg.qr(A) # reduced q,r = np.linalg.qr(A,mode="complete") # full

1.5.3 Classic Gram–Schmidt Orthogonalization算法 CGSO

觀察Eq.4可以發現,其實每一步迭代都只有一個 [公式] 未知:左邊 [公式] 已知,右邊 [公式] 已知, q的系數們[公式] 可以用公式 [公式] 求得。把 [公式] 代入Eq.4,並整理可得

[公式]

因此 [公式] , [公式] 。其中, [公式] 的符號不確定是因為,任意一個基方向反向之后,這個QR分解不會有任何問題,這個基仍然和其他基正交。為了計算方便,這里就規定 [公式] 。

整理上面計算 [公式] 和 [公式] 的過程為算法的形式:

Credit to http://iacs-courses.seas.harvard.edu/courses/am205/schedule/

觀察算法過程,可以發現,唯一可能在理論上出問題的情況就是,出現某個 [公式] =0,導致在算法第8行出現0在分母上的情況。因此只要 [公式] 是滿秩的,且每個 [公式] 都>0,那么reduced QR分解的結果是唯一的。

1.5.4 Modified Gram–Schmidt Orthogonalization算法 MGSO

由於CGSO對舍入誤差很敏感,容易導致生成的基 [公式] 的正交性隨着迭代越來越弱,因此引入改進的GSO。核心思想是,在每個 [公式] 生成后,直接把A剩下的列(下面算法第7行)都去掉 [公式] 的成分(下面算法的第8-9行)。因為只是把計算的順序變了,所以理論上計算結果是一樣的。

Credit to http://iacs-courses.seas.harvard.edu/courses/am205/schedule/

但是改進之后穩定性會好很多。從實際計算步驟上來看,CGSO和MGSO的區別在於,CGSO中,每次迭代新的一列 [公式] ,計算每個 [公式] 都是用的同一個 [公式] ,而MGSO計算 [公式] 的時候用的 [公式] 是已經減去前面j-1個基的分量之后的 [公式] 。

這樣做的好處是:誤差的傳遞是局部的。比如計算 [公式] 是精確的,計算 [公式] 出現誤差,即,[公式]在 [公式] 上存在一個微小分量。按照CGSO,接下來要分別計算 [公式] 在 [公式] 和 [公式] 的分量,最終 [公式] ;而MGSO則先計算 [公式] 在 [公式] 上的分量,去除掉這個分量之后成為 [公式] ,再計算並去除 [公式] 在[公式] 上的分量得到最終的 [公式] ,此時如果計算是精確的,那么至少可以保證 [公式] 。

直觀理解參考下面這張圖,在三維xyz坐標系里, [公式] 是帶誤差的 [公式] 。用CGSO處理[公式] 的時候,[公式] 用的是初始值 [公式] ,包含了 [公式] 和 [公式] 兩個方向的誤差,而用MGSO處理[公式] 的時候,[公式] 用的是去掉[公式] 分量之后的[公式],只有 [公式] 方向的誤差。

公式上計算這些誤差參考The modified Gram-Schmidt procedure

Credit to https://www.math.uci.edu/~ttrogdon/105A/html/Lecture23.html

1.6 Givens Rotations

1.6.1 Givens Rotation Matrix

[公式]

[公式]

1.6.2 Givens Rotations的作用

對於一個矩陣[公式],對於第i列的第j和k行 [公式] ,如果 [公式] 元素不為0,可以通過一個Givens Rotation把它轉換成0。

[公式]

當 [公式] 或者 [公式] 很小或者很大,且它們的平方不是用float表示的時候,對它們求平方會導致上溢出或者下溢出。因此更好的公式是:

  • 如果 [公式] ,那么設 [公式]

[公式]

  • 如果 [公式] ,那么設 [公式]

[公式]

不過這個問題基本只有在設計package造輪子的時候才會遇到,所以通常用Eq.10不會引起問題。詳見Scientific Computing - Heath的第128頁。

另外,在涉及反三角的數值運算的時候,建議使用atan2替代atan,范圍更大,更穩定。例如atan2(y,x)會返回一個(x,y)向量和正x軸的夾角。

the difference between atan and atan2 in C++?​stackoverflow.com圖標wikipedia Atan2​en.wikipedia.org

1.6.3 Givens Rotations 算法

對於一個稠密的矩陣[公式],逐漸把A消元成R(參考1.5.1的full QR的圖)。

Credit to http://iacs-courses.seas.harvard.edu/courses/am205/schedule/

注意第三行的循環,j是從大到小的迭代。

1.6.4 Givens Rotations 優勢

當A是稠密矩陣,Givens Rotations並沒有比另外兩種算法更高效,但如果A是稀疏矩陣,那么Givens Rotations大小為0的元素可以直接被忽略。另一個優勢是,Givens Rotations更容易並行化,因為Givens Rotations只對兩個元素進行操作,處理不同列的時候可以完全的獨立。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM