1. 矩陣分解
1.1相關概念
正交矩陣:
若一個方陣其行與列皆爲正交的單位向量,則該矩陣爲正交矩陣,且該矩陣的轉置和其逆相等。兩個向量正交的意思是兩個向量的內積爲 0
正定矩陣:
如果對於所有的非零實係數向量x ,都有 x’Ax>0,則稱矩陣A 是正定的。正定矩陣的行列式必然大於 0, 所有特徵值也必然 > 0。相對應的,半正定矩陣的行列式必然 ≥ 0。
反射變換:
即歐氏平面上的軸反射變換和歐氏空間中的鏡面反射變換統稱反射變換
1.2 矩陣分解概述
- SVD分解
- QR分解
- LU,LDU分解(等價於高斯消元)
- Cholesky 分解(LDLT 和LL分解合起來稱爲喬里斯基分解Cholesky decomposition)
1.3 QR分解
根據《計算機視覺中的數學方法》定義 8.1.1 如果非奇異實矩陣 A 能夠表示爲正交矩陣 Q與上三角矩陣 R 的積,即 A=QR (8.1.1) 則稱式(8.1.1)是 A 的 QR 分解。
與 QR 分解類似,還有 QL,LQ,RQ 分解,其中 L 表示下三角矩陣。矩陣的 QR 分解,RQ 分 解,QL 分解,LQ 分解統稱爲矩陣的正交三角分解。
QR分解也有若干種算法,常見的包括Gram–Schmidt、Householder和Givens算法
schmidt正交化:
非奇異的矩陣各列向量線性無關,可以利用schmidt正交化公式(再加上單位化),將每個列向量化爲相互正交的單位向量Q。則A=QR,R可以由正交化和單位化過程中生成的中間變量直接寫出。
givens變換(初等旋轉變換):
[外鏈圖片轉存失敗(img-NA1IWszB-1564388122353)(1.PNG)]
主要是利用旋轉矩陣變換不改變向量的模,所以是一種正交變換
A 是上三角矩陣 R 與Q=GxGyGz旋轉矩陣的乘積。這樣,我們就完成了 矩陣 A 的 RQ 分解。Givens 旋轉方法,對於 n 階矩陣需要作大量 Givens 旋轉矩陣的積,計算量較大
Householder變換(初等反射變換):
[外鏈圖片轉存失敗(img-b6w2V0zP-1564388122356)(2.png)]
稱爲 Householder 矩陣, Hv 是正交矩陣,更確切地說它是反射矩陣。
對 n 階非奇異方陣A 作一系列的 Householder 變換,可化將它化爲正交矩陣與上三角矩陣。
只需要作(n-1)個 Householder 矩陣的積,其計算量 大約是 Givens 旋轉方法的一半
1.4 LU,LDU分解法
LU分解, 把矩陣分成下三角矩陣(Lower)和上三角矩陣(Upper)的一種分解。 所以LU分解只用到了三角矩陣;
在LU的基礎上, 如果我們再進一步,引入對角矩陣(Diagonal)D, 那麼LU分解就變成了LDU分解。
1.5 喬里斯基(Cholesky)分解
正定對稱矩陣 A 可以唯一地分解爲對角元素均大於零的上三角矩陣 L 與其轉置 LT的乘積,其中 L爲對角元素均大於零的上三角矩陣.
對稱矩陣的LDL分解就是LDU分解的一種特例。
1.6 SVD
奇異值分解定義:
有一個m×n的實數矩陣A,我們想要把它分解成如下的形式:
其中U和V均爲單位正交陣
2.使用Eigen解Ax=b線性方程組
Decomposition | Method | Requirements on the matrix | Speed (small-to-medium) | Speed (large) | Accuracy |
---|---|---|---|---|---|
PartialPivLU | partialPivLu() | Invertible | ++ | ++ | + |
FullPivLU | fullPivLu() | None | - | - - | +++ |
HouseholderQR | householderQr() | None | ++ | ++ | + |
ColPivHouseholderQR | colPivHouseholderQr() | None | + | - | +++ |
FullPivHouseholderQR | fullPivHouseholderQr() | None | - | - - | +++ |
CompleteOrthogonalDecomposition | completeOrthogonalDecomposition() | None | + | - | +++ |
LLT | llt() | Positive definite | +++ | +++ | + |
LDLT | ldlt() | Positive or negative semidefinite | +++ | + | ++ |
BDCSVD | bdcSvd() | None | - | - | +++ |
JacobiSVD | jacobiSvd() | None | - | - - - | +++ |
- PartialPivLU
LU decomposition of a matrix with partial pivoting。LU decomposition of a square invertible matrix, with partial pivoting(部分消元): the matrix A is decomposed as A = PLU where L is unit-lower-triangular(單位下三角), U is upper-triangular(上三角), and P is a permutation matrix(置換矩陣).
- FullPivLU-比上面的要慢一些
LU decomposition of a matrix with complete pivoting。This class represents a LU decomposition of any matrix, with complete pivoting: the matrix A is decomposed as where L is unit-lower-triangular, U is upper-triangular, and P and Q are permutation matrices
- HouseholderQR
This class performs a QR decomposition of a matrix A into matrices Q and R such that
by using Householder transformations. Here, Q a unitary matrix and R an upper triangular matrix
-
ColPivHouseholderQR
Householder rank-revealing QR decomposition of a matrix with column-pivoting(列主消元法)
This class performs a rank-revealing(有置換矩陣變換的,特徵值都會進行排序,由大到小,所以HouseholderQR不支持的) QR decomposition of a matrix A into matrices P, Q and R such that
by using Householder transformations. Here, P is a permutation matrix, Q a unitary matrix and R an upper triangular matrix.
- FullPivHouseholderQR-比上面兩個要慢
Householder rank-revealing QR decomposition of a matrix with full pivoting
This class performs a rank-revealing QR decomposition of a matrix A into matrices P, P’, Q and R such that
by using Householder transformations. Here, P and P’ are permutation matrices, Q a unitary matrix and R an upper triangular matrix.
- LLT
Standard Cholesky decomposition (LL^T) of a matrix and associated features
This class performs a LL^T Cholesky decomposition of a symmetric, positive definite matrix A such that A = LL^* = U^*U, where L is lower triangular
- LDLT
Robust Cholesky decomposition of a matrix with pivoting。
Perform a robust Cholesky decomposition of a positive semidefinite or negative semidefinite matrix , where P is a permutation matrix, L is lower triangular with a unit diagonal and D is a diagonal matrix.
- BDCSVD -最快的SVD算法
class Bidiagonal Divide and Conquer SVD
http://eigen.tuxfamily.org/dox/classEigen_1_1BDCSVD.html
-
JacobiSVD-SVD方法對於小型矩陣時,速度快,大型的慢
Two-sided Jacobi SVD decomposition of a rectangular matrix
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
Matrix2f A, b;
A << 2, -1, -1, 3;
b << 1, 2, 3, 1;
cout << "Here is the matrix A:\n" << A << endl;
cout << "Here is the right hand side b:\n" << b << endl;
Matrix2f x = A.ldlt().solve(b);
cout << "The solution is:\n" << x << endl;
}
#include <iostream>
using namespace std;
#include <ctime>
// Eigen 部分
#include <Eigen/Core>
// 稠密矩陣的代數運算(逆,特徵值等)
#include <Eigen/Dense>
#define MATRIX_SIZE 100
/****************************
* 本程序演示了 Eigen 基本類型的使用
****************************/
int main( int argc, char** argv )
{
// 解方程
// 我們求解 A * x = b 這個方程
// 直接求逆自然是最直接的,但是求逆運算量大
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > A1;
A1 = Eigen::MatrixXd::Random( MATRIX_SIZE, MATRIX_SIZE );
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > b1;
b1 = Eigen::MatrixXd::Random( MATRIX_SIZE, 1 );
clock_t time_stt = clock(); // 計時
// 直接求逆
Eigen::Matrix<double,MATRIX_SIZE,1> x = A1.inverse()*b1;
cout <<"time use in normal inverse is " << 1000* (clock() - time_stt)/(double)CLOCKS_PER_SEC << "ms"<< endl;
cout<<x<<endl;
// QR分解colPivHouseholderQr()
time_stt = clock();
x = A1.colPivHouseholderQr().solve(b1);
cout <<"time use in Qr decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;
//QR分解fullPivHouseholderQr()
time_stt = clock();
x = A1.fullPivHouseholderQr().solve(b1);
cout <<"time use in Qr decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;
/* //llt分解 要求矩陣A正定
time_stt = clock();
x = A1.llt().solve(b1);
cout <<"time use in llt decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;*/
/*//ldlt分解 要求矩陣A正或負半定
time_stt = clock();
x = A1.ldlt().solve(b1);
cout <<"time use in ldlt decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;*/
//lu分解 partialPivLu()
time_stt = clock();
x = A1.partialPivLu().solve(b1);
cout <<"time use in lu decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;
//lu分解(fullPivLu()
time_stt = clock();
x = A1.fullPivLu().solve(b1);
cout <<"time use in lu decomposition is " <<1000*(clock() - time_stt)/(double)CLOCKS_PER_SEC <<"ms" << endl;
cout <<x<<endl;
return 0;
}
示例程序直接用的這個:https://blog.csdn.net/hanshihao1336295654/article/details/83512082
參考
矩陣分解 (加法篇)-講解比較基礎
《計算機視覺中的數學方法》
《計算機視覺中的多視圖幾何》
矩陣分解之Givens變換與Householder變換-講解深入淺出