天天看點

GSL 系列 6 — 線性代數 3 — QR 分解

文章目錄

    • 0 寫在前面
    • 1 QR 分解相關函數
      • 1.1 QR 分解
      • 1.2 QR 解包
      • 1.3 QR 求解線性方程組
      • 1.4 計算其他
      • 1.5 特殊矩陣 QR 分解
      • 1.6 帶列轉置的 QR 分解

0 寫在前面

關于 QR 分解的背景知識介紹,參見:GSL 系列 6 — 線性代數 1 — 背景知識 1

(QR 分解) 節,本篇隻說明相關函數

若無特别說明,本篇代碼均來自頭檔案

gsl_linalg.h

1 QR 分解相關函數

1.1 QR 分解

A = Q R A=QR A=QR

Householder 版:

将 A 分解為 Q R, Q 分别存儲在矩陣 A 的下三角部分 ( v v v) 和向量 tau ( τ \tau τ) 中,R 存儲在矩陣 A 的上三角部分(含對角)

推薦此方法用于中小型矩陣,或用于 M < N M<N M<N 時

遞歸版 (帶

_r

):

将 A 分解為 Q R, Q 分别存儲在矩陣 A 的下三角部分 ( V V V) 和矩陣 T ( T T T) 中,R 存儲在矩陣 A 的上三角部分(含對角)

此方法要求 M ≥ N M\ge N M≥N,并且該方法對于“高瘦”型矩陣 ( M ≫ N M\gg N M≫N) 表現更佳

1.2 QR 解包

根據 QR 和 tau (T) 得到矩陣 Q 和矩陣 R

int gsl_linalg_QR_unpack(const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * Q, gsl_matrix * R);
int gsl_linalg_QR_unpack_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_matrix * Q, gsl_matrix * R);
           

1.3 QR 求解線性方程組

  1. 根據 QR 分解得到的 QR 和 tau (或 T),求解線性方程組 A x = b Ax=b Ax=b
int gsl_linalg_QR_solve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, gsl_vector * x);
int gsl_linalg_QR_solve_r (const gsl_matrix * QR, const gsl_matrix * T, const gsl_vector * b, gsl_vector * x);
// 置換版本
int gsl_linalg_QR_svx (const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * x);
           
  1. 求解 A x = b Ax=b Ax=b 的最小二乘解(使用歐幾裡得範數, A ( M > N ) A(M>N) A(M>N))

    Householder 版還輸出殘差向量 (residual)

    遞歸版輸出的向量 x 包含兩個部分,x 的前 N N N 個元素為解,後 M − N M-N M−N 個元素的向量範數等于殘差範數,遞歸版還需要一個向量工作空間 (work),長度為 N N N

int gsl_linalg_QR_lssolve (const gsl_matrix * QR, const gsl_vector * tau, const gsl_vector * b, 
                           gsl_vector * x, gsl_vector * residual);
int gsl_linalg_QR_lssolve_r (const gsl_matrix * QR, const gsl_matrix * T, const gsl_vector * b,
                             gsl_vector * x, gsl_vector * work);
           
  1. 求解 R x = b Rx=b Rx=b
  • 使用 QR 矩陣中的 R
int gsl_linalg_QR_Rsolve (const gsl_matrix * QR, const gsl_vector * b, gsl_vector * x);
int gsl_linalg_QR_Rsvx (const gsl_matrix * QR, gsl_vector * x);
           
  • 直接使用 R (上三角矩陣)
int gsl_linalg_R_solve (const gsl_matrix * R, const gsl_vector * b, gsl_vector * x);
int gsl_linalg_R_svx (const gsl_matrix * R, gsl_vector * x);
           
  1. 求解 R x = Q T b Rx=Q^Tb Rx=QTb

1.4 計算其他

  1. 計算 Q T v Q^Tv QTv

    遞歸版需要一個向量工作空間,長度 N N N

int gsl_linalg_QR_QTvec(const gsl_matrix * QR, const gsl_vector * tau, gsl_vector * v);
int gsl_linalg_QR_QTvec_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_vector * b, gsl_vector * work);
           
  1. 計算 Q v Qv Qv
  1. 計算 Q T B Q^TB QTB,矩陣 B B B 次元 ( M × K M\times K M×K)

    遞歸版需要一個矩陣工作空間,次元為 N × K N\times K N×K

int gsl_linalg_QR_QTmat(const gsl_matrix * QR, const gsl_vector * tau, gsl_matrix * A);
int gsl_linalg_QR_QTmat_r(const gsl_matrix * QR, const gsl_matrix * T, gsl_matrix * B, gsl_matrix * work);
           
  1. QR 分解的秩 1 更新

    Q ′ R ′ = Q ( R + w v T ) Q^{'} R^{'}=Q(R+wv^T) Q′R′=Q(R+wvT)

  1. 計算 R R R 的倒數範數 (使用 1 範數)

    1 ∥ R ∥ 1 ∥ R − 1 ∥ 1 \frac{1}{\|R\|_1\|R^{-1}\|_1} ∥R∥1​∥R−1∥1​1​

    向量工作空間次元為 3 N 3N 3N

1.5 特殊矩陣 QR 分解

背景相關知識參見:GSL 系列 6 — 線性代數 1 — 背景知識 1 (特殊矩陣的 QR 分解) 節

将矩陣 ( S , A ) T (S,A)^T (S,A)T QR 分解,得到矩陣 R, Y, T,矩陣 R 存在矩陣 S 中,矩陣 Y 存在 A 中

1.6 帶列轉置的 QR 分解

Q R P T QRP^T QRPT 分解,

norm

是一個向量工作空間,長度為 N N N

// 分解之後 Q 的 v 部分和 R 存在 A 中 
int gsl_linalg_QRPT_decomp (gsl_matrix * A,
                            gsl_vector * tau,
                            gsl_permutation * p,
                            int *signum,
                            gsl_vector * norm);
// 分解之後Q R 分别儲在 q r 中                           
int gsl_linalg_QRPT_decomp2 (const gsl_matrix * A, 
                             gsl_matrix * q, gsl_matrix * r, 
                             gsl_vector * tau, 
                             gsl_permutation * p, 
                             int *signum,
                             gsl_vector * norm);                            
           

利用 Q R P T QRP^T QRPT 分解求解 A x = b Ax=b Ax=b

int gsl_linalg_QRPT_solve (const gsl_matrix * QR,
                           const gsl_vector * tau,
                           const gsl_permutation * p,
                           const gsl_vector * b,
                           gsl_vector * x);
                           
int gsl_linalg_QRPT_svx (const gsl_matrix * QR,
                         const gsl_vector * tau,
                         const gsl_permutation * p,
                         gsl_vector * x);                          
           

利用 Q R P T QRP^T QRPT 分解求 A x = b Ax=b Ax=b 的最小二乘解 ( A A A 滿秩, A ( M > N ) A(M>N) A(M>N))

int gsl_linalg_QRPT_lssolve (const gsl_matrix * QR,
                             const gsl_vector * tau,
                             const gsl_permutation * p,
                             const gsl_vector * b,
                             gsl_vector * x,
                             gsl_vector * residual);
           

利用 Q R P T QRP^T QRPT 分解求 A x = b Ax=b Ax=b 的最小二乘解 ( A A A 秩為

rank

, A ( M > N ) A(M>N) A(M>N))

int gsl_linalg_QRPT_lssolve2 (const gsl_matrix * QR,
                              const gsl_vector * tau,
                              const gsl_permutation * p,
                              const gsl_vector * b,
                              const size_t rank,
                              gsl_vector * x,
                              gsl_vector * residual);
           

求解 R P T x = Q T b RP^Tx=Q^Tb RPTx=QTb

int gsl_linalg_QRPT_QRsolve (const gsl_matrix * Q,
                             const gsl_matrix * R,
                             const gsl_permutation * p,
                             const gsl_vector * b,
                             gsl_vector * x);
           

求解 R P T x = b RP^Tx=b RPTx=b

int gsl_linalg_QRPT_Rsolve (const gsl_matrix * QR,
                             const gsl_permutation * p,
                             const gsl_vector * b,
                             gsl_vector * x);

int gsl_linalg_QRPT_Rsvx (const gsl_matrix * QR,
                           const gsl_permutation * p,
                           gsl_vector * x);
           

Q R P T QRP^T QRPT 分解的秩 1 更新

Q ′ R ′ = Q ( R + w v T P ) Q^{'}R^{'}=Q(R+wv^TP) Q′R′=Q(R+wvTP)

int gsl_linalg_QRPT_update (gsl_matrix * Q,
                            gsl_matrix * R,
                            const gsl_permutation * p,
                            gsl_vector * u,
                            const gsl_vector * v);
           

R R R 的倒數範數(使用 1 範數),向量工作空間

work

次元為 3 N 3N 3N

1 ∥ R ∥ 1 ∥ R − 1 ∥ 1 \frac{1}{\|R\|_1\|R^{-1}\|_1} ∥R∥1​∥R−1∥1​1​

估計 R R R 的秩,統計 R R R 的對角元素絕對值大于

tol

的個數,如果

tol

為負,使用如下預設值:

20 ( M + N ) e p s ( m a x ( ∣ d i a g ( R ) ∣ ) ) 20(M+N)eps(max(|diag(R)|)) 20(M+N)eps(max(∣diag(R)∣))

繼續閱讀