矩阵分解
1. 矩阵分解
- SVD分解
- QR分解
- LU,LDU分解
- Cholesky 分解
(LDLT 和LL分解合起来称为乔里斯基分解Cholesky decomposition) - 奇异值分解
- 特征分解
- 极分解
正交矩阵
- 正交矩阵:是一个方块矩阵 Q,其元素为实数,而且行向量与列向量皆为正交的单位向量,使得该矩阵的转置矩阵为其逆矩阵:
Q T = Q − 1 ⇔ Q T Q = Q Q T = I . Q^{T}=Q^{-1}\Leftrightarrow Q^{T}Q=QQ^{T}=I.\,\! QT=Q−1⇔QTQ=QQT=I. - 行列式值为+1的正交矩阵,称为特殊正交矩阵,它是一个旋转矩阵。
- 所有特殊正交矩阵形成一个子群 {\displaystyle SO(n)} SO(n),称为特殊正交群。亦即,旋转矩阵与旋转矩阵的乘积也是一个旋转矩阵。
2. QR分解
-
QR分解把矩阵分解成一个正交矩阵与一个上三角矩阵的积。QR分解经常用来解线性最小二乘法问题。
-
QR分解也是特定特征值算法即QR算法的基础。
-
实数矩阵A的QR分解是把A分解为 A = Q R , {\displaystyle A=QR,\,} A=QR,
这里的Q是正交矩阵(意味着QTQ = I)而R是上三角矩阵。类似的,我们可以定义A的QL, RQ和LQ分解。 -
更一般的说,我们可以因数分解复数 m × n {\displaystyle m} × {\displaystyle n} m×n矩阵(有着m ≥ n)为 m × n {\displaystyle m} × {\displaystyle n} m×n 幺正矩阵(在 Q ∗ Q = I Q^∗Q = I Q∗Q=I的意义上)和 m × n {\displaystyle m} × {\displaystyle n} m×n 上三角矩阵的乘积。
-
如果A是非奇异的,且限定R 的对角线元素为正,则这个因数分解是唯一的。
2.1 QR分解的求法
- QR分解的实际计算有很多方法,例如Givens旋转、Householder变换,以及Gram-Schmidt正交化等等。每一种方法都有其优点和不足。
2.2 Eigen QR module
- 此模块提供各种QR分解。此模块还提供一些MatrixBase方法,包括:
MatrixBase::householderQr()
MatrixBase::colPivHouseholderQr()
MatrixBase::fullPivHouseholderQr() - 头文件
#include <Eigen/QR> - 得到R
MatrixXd R = qr.matrixQR().triangularViewEigen::Upper();
2.3.1 HouseholderQR()
- HouseholderQR()
- HouseholderQR(const EigenBase&)
- HouseholderQR qr(matrix.rows(), matrix.cols());
qr.compute(matrix); - HouseholderQR( EigenBase&)
1、householderQ()
-
该方法返回矩阵Q的表达式作为Householder变换的序列。
-
返回的表达式可以直接用于执行矩阵乘积。 也可以将其分配给密集的Matrix对象。
-
这是显示如何恢复完整或稀疏矩阵Q以及如何使用算子*执行矩阵乘积的示例:
MatrixXf A(MatrixXf::Random(5,3)), thinQ(MatrixXf::Identity(5,3)), Q;
A.setRandom();
HouseholderQR<MatrixXf> qr(A);
Q = qr.householderQ();
thinQ = qr.householderQ() * thinQ;
std::cout << "The complete unitary matrix Q is:\n" << Q << "\n\n";
std::cout << "The thin matrix Q is:\n" << thinQ << "\n\n";
output:
The complete unitary matrix Q is:
-0.676 0.0793 0.713 -0.0788 -0.147
-0.221 -0.322 -0.37 -0.366 -0.759
-0.353 -0.345 -0.214 0.841 -0.0518
0.582 -0.462 0.555 0.176 -0.329
-0.174 -0.747 -0.00907 -0.348 0.539
The thin matrix Q is:
-0.676 0.0793 0.713
-0.221 -0.322 -0.37
-0.353 -0.345 -0.214
0.582 -0.462 0.555
-0.174 -0.747 -0.00907
2、solve()
-
此方法找到方程Ax = b的解x,其中A是矩阵*这是QR分解(如果存在)
-
这种方法只是试图找到尽可能好的解决方案。 如果要检查解决方案是否存在或是否正确,只需调用此函数以获取结果,然后计算该结果的错误,或直接使用MatrixBase :: isApprox(),例如:
bool a_solution_exists = (A*result).isApprox(b, precision);
求解示例:
typedef Matrix<float,3,3> Matrix3x3;
Matrix3x3 m = Matrix3x3::Random();
Matrix3f y = Matrix3f::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the matrix y:" << endl << y << endl;
Matrix3f x;
x = m.householderQr().solve(y);
assert(y.isApprox(m*x));
cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
# output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the matrix y:
0.108 -0.27 0.832
-0.0452 0.0268 0.271
0.258 0.904 0.435
Here is a solution x to the equation mx=y:
0.609 2.68 1.67
-0.231 -1.57 0.0713
0.51 3.51 1.05
2.3.2 ColPivHouseholderQR()
- ColPivHouseholderQR()
- ColPivHouseholderQR qr(matrix.rows(), matrix.cols());
qr.compute(matrix); - ColPivHouseholderQR(const EigenBase&)
- ColPivHouseholderQR(EigenBase&)
利用qr 求解 Ax=y
Matrix3f m = Matrix3f::Random();
Matrix3f y = Matrix3f::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the matrix y:" << endl << y << endl;
Matrix3f x;
x = m.colPivHouseholderQr().solve(y);
assert(y.isApprox(m*x));
cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
其中解是否存在判断一样
bool a_solution_exists = (A*result).isApprox(b, precision);
2.3.3 FullPivHouseholderQR()
- FullPivHouseholderQR()
- FullPivHouseholderQR( EigenBase&)
- FullPivHouseholderQR qr(matrix.rows(), matrix.cols());
qr.compute(matrix); - FullPivHouseholderQR(const EigenBase&)
Matrix3f m = Matrix3f::Random();
Matrix3f y = Matrix3f::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the matrix y:" << endl << y << endl;
Matrix3f x;
x = m.fullPivHouseholderQr().solve(y);
assert(y.isApprox(m*x));
cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
# output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the matrix y:
0.108 -0.27 0.832
-0.0452 0.0268 0.271
0.258 0.904 0.435
Here is a solution x to the equation mx=y:
0.609 2.68 1.67
-0.231 -1.57 0.0713
0.51 3.51 1.05
3. 特征值分解 EVD
- 线性代数中,特征分解(Eigendecomposition),又称谱分解(Spectral decomposition)是将矩阵分解为由其特征值和特征向量表示的矩阵之积的方法。需要注意只有对可对角化矩阵才可以施以特征分解。
3.1 特征值与特征向量的基础理论
-
N
N
N维非零向量
v
v
v 是
N
×
N
N×N
N×N 的矩阵 A 的特征向量,当且仅当下式成立:
A v = λ v {\displaystyle \mathbf {A} \mathbf {v} =\lambda \mathbf {v} } Av=λv - 其中 λ 为一标量,称为 v 对应的特征值。也称 v 为特征值 λ 对应的特征向量。也即特征向量被施以线性变换 A 只会使向量伸长或缩短而其方向不被改变。
- 由上式可得
p ( λ ) : = det ( A − λ I ) = 0. p\left(\lambda\right) := \det\left(\mathbf{A} - \lambda \mathbf{I}\right)= 0. p(λ):=det(A−λI)=0.
称多项式 p(λ) 为矩阵的特征多项式。上式亦称为矩阵的特征方程。特征多项式是关于未知数 λ 的 N 次多项式。由代数基本定理,特征方程有 N 个解。这些解的解集也就是特征值的集合,有时也称为“谱”(Spectrum)。
3.2 矩阵的特征分解
- 令 A 是一个 N×N 的方阵,且有 N 个线性独立的特征向量 q i ( i = 1 , … , N ) {\displaystyle q_{i}\,\,(i=1,\dots ,N)} qi(i=1,…,N) 。这样, A 可以被分解为 A = Q Λ Q − 1 \mathbf{A}=\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{-1} A=QΛQ−1
- 其中 Q 是N×N方阵,且其第 i i i 列为 A 的特征向量 q i {\displaystyle q_{i}} qi。 Λ Λ Λ 是对角矩阵,其对角线上的元素为对应的特征值,也即 Λ i i = λ i {\displaystyle \Lambda _{ii}=\lambda _{i}} Λii=λi 。这里需要注意只有可对角化矩阵才可以作特征分解。比如 [ 1 1 0 1 ] {\displaystyle {\begin{bmatrix}1&1\\0&1\\\end{bmatrix}}} [1011] 不能被对角化,也就不能特征分解。
- 一般来说,特征向量 q i ( i = 1 , … , N ) {\displaystyle q_{i}\,\,(i=1,\dots ,N)} qi(i=1,…,N) 一般被单位化(但这不是必须的)。未被单位化的特征向量组 v i ( i = 1 , … , N ) , {\displaystyle v_{i}\,\,(i=1,\dots ,N),} vi(i=1,…,N), 也可以作为 Q Q Q 的列向量。这一事实可以这样理解: Q 中向量的长度都被 Q − 1 Q^{−1} Q−1 抵消了。
通过特征分解求反(逆)矩阵
- 若矩阵 A 可被特征分解并特征值中不含零,则矩阵 A 为非奇异矩阵,且其逆矩阵可以由下式给出:
A − 1 = Q Λ − 1 Q − 1 \mathbf{A}^{-1}=\mathbf{Q}\mathbf{\Lambda}^{-1}\mathbf{Q}^{-1} A−1=QΛ−1Q−1
因为 Λ 为对角矩阵,其逆矩阵容易计算出: [ Λ − 1 ] i i = 1 λ i \left[\Lambda^{-1}\right]_{ii}=\frac{1}{\lambda_i} [Λ−1]ii=λi1
3.3 对特殊矩阵的特征分解
对称矩阵
- 任意的
N
×
N
N×N
N×N 实对称矩阵都有
N
N
N 个线性无关的特征向量。并且这些特征向量都可以正交单位化而得到一组正交且模为
1
1
1 的向量。故实对称矩阵
A
A
A 可被分解成
A = Q Λ Q T \mathbf{A}=\mathbf{Q}\mathbf{\Lambda}\mathbf{Q}^{T} A=QΛQT - 其中 Q Q Q 为正交矩阵, Λ Λ Λ为实对角矩阵。
正规矩阵
- 类似地,一个复正规矩阵具有一组正交特征向量基,故正规矩阵可以被分解成
A = U Λ U H \mathbf{A}=\mathbf{U}\mathbf{\Lambda}\mathbf{U}^{H} A=UΛUH - 其中 U 为一个酉矩阵。进一步地,若 A 是埃尔米特矩阵,那么对角矩阵 Λ 的对角元全是实数。若 A 还是酉矩阵,则 Λ 的所有对角元在复平面的单位圆上取得。
3.4 Eigen 案例
# code:
Eigen::Matrix2d matrix_22;
matrix_22 << 2,3,2,1;
cout << "matrix = \n"<< matrix_22<<endl;
//Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eigen_solver1 ( matrix_22 );/这句是啥不清楚
Eigen::EigenSolver<Eigen::Matrix2d> eigen_solver ( matrix_22 );
cout << "matrix values = \n" << eigen_solver.eigenvalues() << endl;//形式为二维向量(4,0)和(-1,0)。真实值为4,-1。
cout << "matrix vectors = \n" << eigen_solver.eigenvectors() << endl;//输出为单位化之后的。形式如下:
# output:
matrix =
2 3
2 1
matrix values =
(4,0)
(-1,0)
matrix vectors =
(0.83205,0) (-0.707107,0)
(0.5547,0) (0.707107,0)
4. 奇异值分解 SVD
- 上面的特征值分解,对矩阵有着较高的要求,它需要被分解的矩阵𝐴为实对称矩阵,但是现实中,我们所遇到的问题一般不是实对称矩阵。
- 奇异值分解则是特征分解在任意矩阵上的推广。在信号处理、统计学等领域有重要应用。
4.1 定义
有一个 𝑚×𝑛 的实数矩阵𝐴,我们想要把它分解成如下的形式