矩陣的qr分解目的是將乙個列滿秩矩陣\(a\)分解成\(a=qr\)的形式,我們這裡暫時討論\(a\)為方陣的情況。其中\(q\)為正交矩陣;\(r\)為正線(主對角線元素為正)上三角矩陣,且分解是唯一的。
比如\(a= \begin
1 & 2 & 2 \\
2 & 1 & 2 \\
1 & 2 & 1 \\
\end\),我們最終要分解成如下形式:
\[a=q \cdot r =
\begin
\frac} & \frac} & \frac} \\
\frac} & -\frac} & 0 \\
\frac} & \frac} & -\frac} \\
\end
\cdot
\begin
\sqrt & \sqrt & \frac} \\
0 & \sqrt & \frac} \\
0 & 0 & \frac} \\
\end
\]現在主要的問題是如何由矩陣\(a\)計算得到矩陣\(q\)和\(r\)呢?我們將在下面討論。
首先假設初始方陣為\(a\),\(\vec\)、\(\vec\)、\(\vec\)都為列向量。我們學過斯密特正交化的步驟如下:
\[a=\begin
\vec & \vec & \vec
\end
\overset}
\begin
\vec & \vec & \vec
\end
\overset}
\begin
\vec & \vec & \vec
\end
= q\]
再具體一點(為了好寫,之後的\(\vec\)、\(\vec\)、\(\vec\)都不加箭頭了,預設為列向量):
\[y_k = x_k - \sum_^ \fracy_i =
x_k - \sum_^ \fracy_i =
x_k - \sum_^ (x_k,z_i)z_i \tag
\]\[z_k = \frac ,k=1...n \tag
\]\[q = \begin
z_1 & \cdots & z_n \tag
\end
\]\[r= \begin
||y_1|| & (x_2,z_1) & \cdots & (x_n,z_1) \\
& ||y_2|| & \cdots & (x_n,z_2) \\
& & \ddots & \vdots\\
\mathsf 0 & & &||y_n||
\end \tag
\]由上述公式寫出計算\(q\)和\(r\)的偽**為:
\[\begin
& for \quad k=1:n \notag\\
& \qquad r_=||a_|| \notag\\
& \qquad q_=a_ / r_ \notag\\
& \qquad for \quad i = k + 1 : n \notag\\
& \qquad \qquad r_ = a_' * q_ \notag\\
& \qquad \qquad a_ = a_ - r_ .* q_ \notag\\
& \qquad end \notag\\
& end \notag\\
\end
\]注:\(a_\)表示\(a\)的第\(k\)列向量。
可以看出其實矩陣的qr分解的步驟並不多,就是不斷地迴圈進行\(a\)的正交化、標準化、求\(q\)、求\(r\)這幾步。
clc, clear all, close all
% 矩陣的qr分解
a = [1 2 2;2 1 2;1 2 1] % 考慮非奇異方陣
[m,n] = size(a);
q = zeros(n,n);
x = zeros(n,1);
r = zeros(n);
for k = 1 : n
r(k,k) = norm(a(:,k)); % 計算r的對角線元素
q(:,k) = a(:,k) / r(k,k); % a已正交化,現在做標準化,得到正交矩陣q
for i = k + 1 : n
r(k,i) = a(:,i)' * q(:,k); % 計算r的上三角部分
a(:,i) = a(:,i) - r(k,i) .* q(:,k); % 更新矩陣a,斯密特正交公式
endendq
r
#include #include using namespace std;
int main() /* 矩陣a的qr分解*/
,, };
int n = a.size();
vector> q(n, vector(n));
vector> r(n, vector(n));
cout << "a:" << endl; //輸出矩陣a
for (int i = 0; i < n; i++)
cout << endl;
} for (int k = 0; k < n; k++)
r[k][k] = sqrt(mod); // 計算a第k列的模長,由公式(4)等於r的對角線元素||a:k||
for (int i = 0; i < n; i++)
for (int i = k + 1; i < n; i++)
for (int j = 0; j < n; j++)
}} cout << endl;
cout << "q:" << endl; //輸出矩陣q
for (int i = 0; i < n; i++)
cout << endl;
} cout << endl;
cout << "r:" << endl; //輸出矩陣r
for (int i = 0; i < n; i++)
cout << endl;
} return 0;
}
由下圖可以看到,由matlab和c++計算出的\(q\)和\(r\)矩陣完全相同。
matlab中qr函式 QR分解
實數矩陣a的qr分解是把a分解為 a qr 這裡的q是正交矩陣 意味著qtq i 而r是上三角矩陣。類似的,我們可以定義a的ql,rq和lq分解。更一般的說,我們可以因數分解複數m n矩陣 有著m n 為 m n 酉矩陣 在q q i的意義上 和n n上三角矩陣的乘積。如果a是非奇異的,則這個因數分...
矩陣分解(2)QR分解
qr分解法是三種將矩陣分解的方式之一。這種方式,把矩陣分解成乙個半正交矩陣與乙個上三角矩陣的積。qr分解經常用來解線性最小二乘法問題。qr分解也是特定特徵值演算法即qr演算法的基礎。實數矩陣a的qr分解是把a分解為 這裡的q是正交矩陣 意味著qtq i 而r是上三角矩陣。類似的,我們可以定義a的ql...
R中矩陣的QR分解
qr分解是常用的三種矩陣分解方法之一,qr分解經常用 來解線性最小二乘法 問題,有如下定義 1 若n階實非奇異矩陣a可以分解為正交矩陣q與實非奇異上三角矩陣r的乘積,即a qr,則稱該分解式為矩陣a的qr分解 2 進而a是m n列滿秩矩陣,若a qr,其中q是m n矩陣,q q i 稱q為列正交矩陣...