One: matrix QR decomposition
The QR decomposition of A matrix is to decompose A full rank matrix AAA into the form A=QRA=QRA=QR. Let’s discuss the case where AAA is A square matrix for the moment. QQQ is the orthogonal matrix; RRR is the upper triangular matrix of the positive line (the principal diagonal element is positive) and the decomposition is unique.
For example, A=[122212121]A= begin{bmatrix} 1&2&2\2&1&2\1&2&1 \\ end{bmatrix}A=⎣⎢, 121212221 nation ⎥⎤.
Now the main question is how do you compute the matrices QQQ and RRR from matrix AAA? We will discuss this below.
1.1 QR decomposition principle
In linear algebra or matrix theory, we must have learned Schmidt Orthogonalization, which converts any basis of a Euclidean space to an orthonormal basis, producing an orthonormal basis that forms the desired QQQ matrix, The RRR matrix can be obtained by the inverse of the orthogonalization formula.
First, assume that the initial square matrix is AAA, xi⃗\vec{x_i}xi, Yi ⃗\vec{y_i}yi, zi⃗\vec{z_i}zi are all column vectors. We learned the steps of Schmidt’s orthogonalization as follows:
To be more specific, xi⃗\vec{x_i}xi, yi⃗\vec{y_i}yi, zi⃗\vec{z_i}zi do not include arrows, and default to column vectors:
The pseudocode of QQQ and RRR calculated by the above formula is:
Note: A:kA_{:k}A:k represents the KKK column vector of AAA.
It can be seen that there are not many steps of QR decomposition of the matrix, that is, the constant cycle of AAA orthogenization, standardization, QQQ, RRR these steps.
Two: matrix QR decomposition MATLAB implementation
clc, clear all, close all
QR decomposition of % matrix
A = [1 2 2;2 1 2;1 2 1] Consider a nonsingular square matrix
[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)); % computes the diagonal element of R
Q(:,k) = A(:,k) / R(k,k); % A has been orthogonalized, and now if I normalize it, I get the orthogonal matrix Q
for i = k + 1 : n
R(k,i) = A(:,i)' * Q(:,k); % computes the upper triangle of R
A(:,i) = A(:,i) - R(k,i) .* Q(:,k); Update matrix A, Schmidt orthogonal formula
end
end
Q
R
Copy the code
Three: matrix QR decomposition of C++ implementation
#include <iostream>
#include <vector>
using namespace std;
int main(a) /* QR factorization of matrix A */
{
vector<vector<double>> a = { {1.2.2}, {2.1.2}, {1.2.1}};int n = a.size(a); vector<vector<double>> q(n, vector<double>(n));
vector<vector<double>> r(n, vector<double>(n));
cout << "A:" << endl; // Output matrix A
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%.4f ", a[i][j]);
}
cout << endl;
}
for (int k = 0; k < n; k++)
{
double MOD = 0;
for (int i = 0; i < n; i++)
{
MOD += a[i][k] * a[i][k];
}
r[k][k] = sqrt(MOD); / / calculate the first k A column length, by the formula (4) is equal to the diagonal elements of R | | A: k | |
for (int i = 0; i < n; i++)
{
q[i][k] = a[i][k] / r[k][k]; // From formula (2), the KTH column of A becomes the KTH column of Q
}
for (int i = k + 1; i < n; i++)
{
for (int j = 0; j < n; j++)
{
r[k][i] += a[j][i] * q[j][k]; // From formula (4), calculate the upper triangle of R
}
for (int j = 0; j < n; j++)
{
a[j][i] -= r[k][i] * q[j][k]; // From formula (1), calculate and update each column of A
}
}
}
cout << endl;
cout << "Q:" << endl; // Output matrix Q
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%.4f ", q[i][j]);
}
cout << endl;
}
cout << endl;
cout << "R:" << endl; // output matrix R
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%.4f ", r[i][j]);
}
cout << endl;
}
return 0;
}
Copy the code
Four: comparison of results
As can be seen from the following figure, the QQQ and RRR matrices calculated by MATLAB and C++ are exactly the same.