矩陣QR分解的MATLAB與C 實現

2022-03-03 22:02:17 字數 3124 閱讀 2695

矩陣的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為列正交矩陣...