主要是用来记录自己的学习过程,内容也主要来自于网上的各种资料,然后自己总结而来,参考的资料都以注明,感谢这些作者的分享。如果内容有误,请大家指点。

LU分解1

理论

定义

       将矩阵等价为两个矩阵 L L L和 U U U的乘积 ,其中 L L L和 U U U分别是单位下三角矩阵和上三角矩阵,当 A A A的前rank(A)阶顺序主子式都不为0时,矩阵 A A A可以分解为
A = L U A=LU A=LU
其中 L L L是下三角矩阵, U U U是上三角矩阵。

LU分解求线性方程组

       对于求解线性方程,将 A A A进行 L U LU LU分解,得到 L ( U x ) = b L(Ux)=b L(Ux)=b,令 y = U x y = Ux y=Ux,则有 L y = b Ly=b Ly=b,由于 L L L是下三角矩阵,可以方便求出 y y y,求出 y y y之后,在求解 U x = y Ux = y Ux=y,由于 U U U是上三角矩阵,这样就可以方便求出 x x x。

LU分解数值稳定值

       考虑一个矩阵 A = [ 0 1 1 1 ] A=\left[\begin{array}{ll}0 & 1 \\ 1 & 1\end{array}\right] A=[01​11​] ,虽然A非奇异,且条件数很小 κ ( A ) ≈ 2.62 \kappa(A) \approx 2.62 κ(A)≈2.62 ,但是LU分解算法第一次执行就失败了,因为 A 0 , 0 = 0 A_{0,0}=0 A0,0​=0 在分母上。
考虑另一个矩阵 A = [ 1 0 − 20 1 1 1 ] A=\left[\begin{array}{cc}10^{-20} & 1 \\ 1 & 1\end{array}\right] A=[10−201​11​] ,给 A 0 , 0 A_{0,0} A0,0​ 一个误差。可以计算得到 L = [ 1 0 1 0 20 1 ] L=\left[\begin{array}{cc}1 & 0 \\ 10^{20} & 1\end{array}\right] L=[11020​01​] , U = [ 1 0 − 20 1 0 1 − 1 0 20 ] U=\left[\begin{array}{cc}10^{-20} & 1 \\ 0 & 1-10^{20}\end{array}\right] U=[10−200​11−1020​] ,如果这里用的是浮点数的话,那么 U ≈ [ 1 0 − 20 1 0 − 1 0 20 ] U \approx\left[\begin{array}{cc}10^{-20} & 1 \\ 0 & -10^{20}\end{array}\right] U≈[10−200​1−1020​] , 把LU相乘得到 L U = [ 1 0 − 20 1 1 0 ] ≠ [ 1 0 − 20 1 1 1 ] = A L U=\left[\begin{array}{cc}10^{-20} & 1 \\ 1 & 0\end{array}\right] \neq\left[\begin{array}{cc}10^{-20} & 1 \\ 1 & 1\end{array}\right]=A LU=[10−201​10​]=[10−201​11​]=A 。如果用这组LU去计算问题,会出现条件数很小,但相对误差很大的情况。
注: 因为浮点数的固有问题, 在处理数值计算问题时候,一定要尽可能避免大数和小数相加减的问题。

LUP分解1

理论

       在高斯消元的时候,做一些行置换(pivoting)。

LUP分解求线性方程组

  • step1:LUP分解
  • step2:求解 L y = P b Ly = Pb Ly=Pb
  • step3:求解 U x = y Ux = y Ux=y

LUP分解数值稳定性

LUP算法比LU算法稳定

LU分解的Eigen实现

       Eigen提供了两种LU分解的方法,分别为Eigen::FullPivLU和Eigen::PartialPivLU。其中,Eigen::PartialPivLU类提供了可逆方阵的LU分解,具有部分置换(partial pivoting),将矩阵 A A A分解为 A = P L U A = PLU A=PLU, L L L为单位下三角矩阵, U U U为上三角矩阵, P P P为置换矩阵(permutation matrix)。但是,Eigen::FullPivLU类可以对任意矩阵进行LU分解,并具有完全置换(complete pivoting),矩阵 A A A分解为 A = P − 1 L U Q − 1 A=P^{-1}LUQ^{-1} A=P−1LUQ−1,其中, L L L为单位下三角矩阵, U U U为上三角矩阵, P , Q P, Q P,Q为置换矩阵。

需要注意的是:Eigen::PartialPivLU类会断言矩阵是方阵,但是不会判断矩阵是否可逆,需要在使用时我们自己去判断。Eigen::FullPivLU类非常稳定,并且在大型矩阵上经过了很好的测试。但是,在某些用例中,SVD 分解本质上更稳定和/或更灵活。例如,在计算矩阵的核时,使用 SVD 可以选择矩阵的最小奇异值,这是 LU 分解看不到的。

       接下里,具体看看这两种算法在Eigen中是如何实现。

方法一:Eigen::FullPivLU

int main(int argc, char *argv[])
{Matrix3d A = Matrix3d::Random();cout << "初始矩阵A = " << '\n'<< A << endl;Vector3d b = Vector3d::Random();cout << "b = " << '\n'<< b << endl;Eigen::FullPivLU<Matrix3d> lu(A);Matrix3d U = lu.matrixLU().triangularView<Upper>();Matrix3d L = lu.matrixLU().triangularView<UnitLower>();Matrix3d P = lu.permutationP();Matrix3d Q = lu.permutationQ();cout << "L = \n"<< L << endl;cout << "U = \n"<< U << endl;cout << "P = \n"<< P << endl;cout << "Q = \n"<< Q << endl;cout << "重构原始矩阵后的结果为:\n"<< P.inverse() * L * U * Q.inverse() << endl;cout << "x = \n"<< lu.solve(b) << endl;
}

结果分析:

初始矩阵A = 0.680375   0.59688 -0.329554
-0.211234  0.823295  0.5364590.566198 -0.604897 -0.444451
b = 0.10794
-0.04520590.257742
L = 1         0         00.72499         1         0
-0.734727  0.493089         1
U = 0.823295 -0.211234  0.5364590  0.833518 -0.7184820         0  0.303977
P =
0 1 0
1 0 0
0 0 1
Q =
0 1 0
1 0 0
0 0 1
重构原始矩阵后的结果为:0.680375   0.59688 -0.329554
-0.211234  0.823295  0.5364590.566198 -0.604897 -0.444451
x = 0.60876
-0.2312820.51038

方法二:Eigen::PartialPivLU

int main(int argc, char *argv[])
{Matrix3d A = Matrix3d::Random();cout << "A = \n"<< A << endl;cout << A.determinant() << endl;Eigen::PartialPivLU<Eigen::Matrix3d> plu(A);Matrix3d P = plu.permutationP();cout << "P = \n"<< P << endl;Matrix3d L = plu.matrixLU().triangularView<UnitLower>();Matrix3d U = plu.matrixLU().triangularView<Upper>();cout << "L = \n"<< L << endl;cout << "U = \n"<< U << endl;cout << "重构后的系统矩阵A: \n"<< P * L * U << endl;
}

结果分析:

A = 0.680375   0.59688 -0.329554
-0.211234  0.823295  0.5364590.566198 -0.604897 -0.444451
0.208598
P =
1 0 0
0 0 1
0 1 0
L = 1         0         00.832185         1         0
-0.310467 -0.915573         1
U = 0.680375   0.59688 -0.3295540  -1.10161   -0.17020         0  0.278313
重构后的系统矩阵A: 0.680375   0.59688 -0.329554
-0.211234  0.823295  0.5364590.566198 -0.604897 -0.444451

Cholesky分解1

理论

定义

是LU分解的一种特殊情况,当系统矩阵 A A A为对称正定矩阵时,此时可以得到 U = L T U = L^T U=LT,即
A = L L T A = LL^T A=LLT

Choleskyfen分解数值稳定性

不需要想普通的矩阵一样还需要置换操作,因此相比于LU,LUP分解数值更加稳定。

Cholesky分解Eigen实现

       同样地,EIgen也提供了两种方法,分别为Eigen::LDLT以及Eigen::LLT。Eigen::LLT提供了对称正定矩阵的分解方法,使得 A = L L T A=LL^T A=LLT,其中 L L L为下三角矩阵。Eigen::LDLT是EIgen提供的更加鲁棒的Cholesky分解方法,只需要矩阵为半正定或者半负定即可,将 A A A分解为 A = P T L D L ∗ P A = P^TLDL^*P A=PTLDL∗P,其中, P P P为置换矩阵, L L L 是具有单位对角线的下三角矩阵, D D D 是对角矩阵,Eigen::LDLT这个类支持就地分解机制。推荐使用Eigen::LDLT。

方法一:Eigen::LLT

int main(int argc, char *argv[])
{MatrixXd A(3, 3);A << 4, -1, 2, -1, 6, 0, 2, 0, 5;cout << "The matrix A is" << endl<< A << endl;LLT<MatrixXd> llt(A);MatrixXd L = llt.matrixL();cout << "L = \n"<< L << endl;cout << "重构后的矩阵A: \n"<< L * L.transpose() << endl;
}

结果分析:

The matrix A is4 -1  2
-1  6  02  0  5
L = 2        0        0-0.5  2.39792        01 0.208514   1.9891
重构后的矩阵A: 4 -1  2
-1  6  02  0  5

方法二:Eigen::LDLT

int main(int argc, char *argv[])
{MatrixXd A(3, 3);A << 4, -1, 2, -1, 6, 0, 2, 0, 5;Vector3d b = Vector3d::Random();cout << "The matrix A is" << endl<< A << endl;cout << "b = \n"<< b << endl;LDLT<MatrixXd> ldlt(A);MatrixXd L = ldlt.matrixL();auto D = ldlt.vectorD();cout << "L = \n"<< L << endl;cout << "D = \n"<< D << endl;cout << "x = \n"<< ldlt.solve(b);
}

结果分析:

The matrix A is4 -1  2
-1  6  02  0  5
b = 0.680375
-0.2112340.566198
L = 1         0         00         1         0
-0.166667       0.4         1
D = 65
3.03333
x = 0.13803
-0.01220070.0580278

QR分解2,3

理论

定义

一个矩阵 A ∈ R m × n , m ≥ n A \in \mathbb{R}^{m \times n}, m \geq n A∈Rm×n,m≥n 可以被分解成 A = Q R A=Q R A=QR, 其中:

  1. Q ∈ R m × m Q \in \mathbb{R}^{m \times m} Q∈Rm×m 是正交矩阵
    R ≡ [ R ^ 0 ] ∈ R m × n R \equiv\left[\begin{array}{c}\hat{R} \\ 0\end{array}\right] \in \mathbb{R}^{m \times n} R≡[R^0​]∈Rm×n
  2. R ^ ∈ R n × n \hat{R} \in \mathbb{R}^{n \times n} R^∈Rn×n 是上三角矩阵

正交矩阵的性质

  1. Q T Q = Q Q T = I Q^T Q=Q Q^T=I QTQ=QQT=I
  2. 左乘一个正交矩阵对欧式范数的结果不影响
    ∥ Q v ∥ 2 2 = v T Q T Q v = v T v = ∥ v ∥ 2 2 \|Q v\|_2^2=v^T Q^T Q v=v^T v=\|v\|_2^2 ∥Qv∥22​=vTQTQv=vTv=∥v∥22​

QR分解求解线性最小二乘

对于超定线性最小二乘问题 A x ≈ b Ax \approx b Ax≈b,目标函数为:
ϕ ( x ) = ∥ r ( x ) ∥ 2 2 = ∥ b − A x ∥ 2 2 = ∥ b − Q [ R ^ 0 ] x ∥ 2 2 = ∥ Q T ( b − Q [ R ^ 0 ] x ) ∥ 2 2 = ∥ Q T b − [ R ^ 0 ] x ∥ 2 2 \begin{aligned} \phi(x)=\|r(x)\|_2^2 & =\|b-A x\|_2^2=\left\|b-Q\left[\begin{array}{c} \hat{R} \\ 0 \end{array}\right] x\right\|_2^2 \\ & =\left\|Q^T\left(b-Q\left[\begin{array}{c} \hat{R} \\ 0 \end{array}\right] x\right)\right\|_2^2 \\ & =\left\|Q^T b-\left[\begin{array}{c} \hat{R} \\ 0 \end{array}\right] x\right\|_2^2 \end{aligned} ϕ(x)=∥r(x)∥22​​=∥b−Ax∥22​= ​b−Q[R^0​]x ​22​= ​QT(b−Q[R^0​]x) ​22​= ​QTb−[R^0​]x ​22​​
其中, Q ∈ R m × m Q \in \mathbb{R}^{m \times m} Q∈Rm×m, Q b ∈ R m × 1 Qb \in \mathbb{R}^{m \times 1} Qb∈Rm×1, [ R ^ 0 ] ∈ R m × n \left[\begin{array}{c} \hat{R} \\ 0 \end{array}\right] \in \mathbb{R}^{m \times n} [R^0​]∈Rm×n, [ R ^ 0 ] x ∈ R m × 1 \left[\begin{array}{c} \hat{R} \\ 0 \end{array}\right]x \in \mathbb{R}^{m \times 1} [R^0​]x∈Rm×1。如果把 Q T b Q^Tb QTb拆分成上下两部分,即 Q T b = [ c 1 c 2 ] Q^Tb=\left[ \begin{array}{c} c_1 \\ c_2 \end{array}\right] QTb=[c1​c2​​],其中 c 1 ∈ R n c_1 \in \mathbb{R}^n c1​∈Rn, c 2 ∈ R m − n c_2 \in \mathbb{R}^{m-n} c2​∈Rm−n。那么目标函数可转换为:
∥ r ( x ) ∥ 2 2 = ∥ c 1 − R ^ x ∥ 2 2 + ∥ c 2 ∥ 2 2 \left\| r(x) \right\|_2^2=\left\| c_1 - \hat{R}x\right\|_2^2 + \left\| c_2 \right\|_2^2 ∥r(x)∥22​= ​c1​−R^x ​22​+∥c2​∥22​
       显然, ∥ c 2 ∥ 2 2 \left\| c_2 \right\|_2^2 ∥c2​∥22​与 x x x无关,能优化的只有前半部分,使得 ∥ c 1 − R ^ x ∥ 2 2 \left\| c_1 - \hat{R}x\right\|_2^2 ​c1​−R^x ​22​等于0,即 R ^ x = c 1 \hat{R}x=c_1 R^x=c1​,\left| r(x) \right|_2^2的最小值为 ∥ c 2 ∥ 2 2 \left\| c_2 \right\|_2^2 ∥c2​∥22​。这样处理之后就可以避免正规方程中的 ( A T A ) − 1 (A^TA)^{-1} (ATA)−1,避免了条件数变成 c o n d ( A T A ) = c a n d ( A ) 2 cond(A^TA)=cand(A)^2 cond(ATA)=cand(A)2,所有QR分解比正规方程求解最小二乘问题更加稳定。

计算QR分解的方法

1 Gram–Schmidt Orthogonalization
2 Householder Triangularization
3 Givens Rotations
当A是稠密矩阵,Givens Rotations并没有比另外两种算法更高效,但如果A是稀疏矩阵,那么Givens Rotations大小为0的元素可以直接被忽略。另一个优势是,Givens Rotations更容易并行化,因为Givens Rotations只对两个元素进行操作,处理不同列的时候可以完全的独立。

QR分解的Eigen实现

Eigen提供了四种计算QR分解的方法,分别为:Eigen::ColPivHouseholderQR,Eigen::CompleteOrthogonalDecomposition,Eigen::FullPivHouseholderQR以及Eigen::HouseholderQR。

HouseholderQR ColPivHouseholderQR FullPivHouseholderQR CompleteOrthogonalDecomposition
A = Q R A=QR A=QR A P = Q R AP=QR AP=QR P A P ′ = Q R PAP^{'}=QR PAP′=QR A P = Q [ T 0 0 0 ] Z AP = Q[\begin{array}{cc} T & 0\\ 0 & 0 \end{array}]Z AP=Q[T0​00​]Z
Q Q Q为正交矩阵, R R R为上三角矩阵 Q Q Q为正交矩阵, R R R为上三角矩阵, P P P为置换矩阵 Q Q Q为正交矩阵, R R R为上三角矩阵, P , P ′ P,P^{'} P,P′为置换矩阵 Q , Z Q,Z Q,Z为正交矩阵, P P P为置换矩阵, T T T为上三角矩阵,大小为A的秩
最快,但是最不稳定 稳定性较好,比HouseholderQR慢,比FullPivHouseholderQR快 数值最稳定,但是最慢

方法一:HouseholderQR

typedef Matrix<float, 5, 1> Vector5f;
int main(int argc, char *argv[])
{MatrixXf A(MatrixXf::Random(5, 3)), Q;A.setRandom();Vector5f b = MatrixXf::Random(5, 1);HouseholderQR<MatrixXf> qr(A);Q = qr.householderQ();std::cout << "The complete unitary matrix Q is:\n"<< Q << "\n\n";cout << "x = \n"<< qr.solve(b) << endl;
}

结果分析:

The complete unitary matrix Q is:-0.676275   0.0792999    0.713112  -0.0788488   -0.147031-0.220518   -0.322306   -0.370288   -0.365561   -0.759436-0.353086   -0.344724   -0.214153      0.8414  -0.05177030.58236   -0.461852    0.555351    0.176282   -0.328724-0.173814   -0.746785 -0.00906669   -0.348021    0.539351x = -0.262592
-0.0749101-0.593202

方法二:Eigen::ColPivHouseholderQR

typedef Matrix<float, 5, 1> Vector5f;
int main(int argc, char *argv[])
{MatrixXf A(MatrixXf::Random(5, 3)), Q;A.setRandom();Vector5f b = MatrixXf::Random(5, 1);ColPivHouseholderQR<MatrixXf> cqr(A);Q = cqr.householderQ();MatrixXf R = cqr.matrixR().triangularView<Upper>();cout << "Q = \n"<< Q << endl;cout << "R = \n"<< R << endl;cout << "x = \n"<< cqr.solve(b) << endl;
}

结果分析:

Q = -0.603651   0.704296   0.334273   0.165978  -0.016934-0.320874  -0.364108  -0.232567   0.833958  -0.122029-0.45273  -0.208744  -0.202056  -0.427952  -0.7262860.379609   0.572496  -0.623708   0.173782  -0.330052-0.42846 0.00820044  -0.635875  -0.252233   0.590251
R = 1.60258     1.3316   -1.150080   0.860025 -0.01190550          0   0.4383410          0          00          0          0
x = -0.262592
-0.0749101-0.593202

方法三:Eigen::FullPivHouseholderQR

typedef Matrix<float, 5, 1> Vector5f;
int main(int argc, char *argv[])
{MatrixXf A(MatrixXf::Random(5, 3)), Q;A.setRandom();Vector5f b = MatrixXf::Random(5, 1);FullPivHouseholderQR<MatrixXf> fqr(A);Q = fqr.matrixQ();cout << "Q = \n"<< Q << endl;cout << "x = \n"<< fqr.solve(b) << endl;
}

结果分析:

Q = 0.124977  -0.919134   0.334273   0.162086 -0.03954220.467087   0.131775  -0.232567   0.826756  -0.1638640.493559 -0.0702728  -0.202056  -0.160453    0.82758-0.629484  -0.274961  -0.623708   0.274145   0.2529410.35547  -0.239345  -0.635875  -0.435088  -0.471929
x = -0.262592
-0.0749099-0.593202

方法四:CompleteOrthogonalDecomposition

typedef Matrix<float, 5, 1> Vector5f;
int main(int argc, char *argv[])
{MatrixXf A(MatrixXf::Random(5, 3)), Q;A.setRandom();Vector5f b = MatrixXf::Random(5, 1);CompleteOrthogonalDecomposition<MatrixXf> cod(A);Q = cod.householderQ();MatrixXf T = cod.matrixT().triangularView<Upper>();MatrixXf Z = cod.matrixZ();cout << "Q = \n"<< Q << endl;cout << "T = \n"<< T << endl;cout << "Z = \n"<< Z << endl;cout << "x = \n"<< cod.solve(b) << endl;
}

结果分析:

 = -0.603651   0.704296   0.334273   0.165978  -0.016934-0.320874  -0.364108  -0.232567   0.833958  -0.122029-0.45273  -0.208744  -0.202056  -0.427952  -0.7262860.379609   0.572496  -0.623708   0.173782  -0.330052-0.42846 0.00820044  -0.635875  -0.252233   0.590251
T = 1.60258     1.3316   -1.150080   0.860025 -0.01190550          0   0.4383410          0          00          0          0
Z =
1 0 0
0 1 0
0 0 1
x = -0.262592
-0.0749101-0.593202

SVD分解4,5

定义

对于任意一个矩阵 A ∈ C m × n A \in \mathbb{C}^{m \times n} A∈Cm×n,可以分解为:
A = U Σ V H A = U \Sigma V^H A=UΣVH
其中, U U U是 m × m m \times m m×m酉矩阵, V V V是 N × N N \times N N×N酉矩阵, Σ \Sigma Σ是 m × n m \times n m×n对角矩阵,对角线上的元素称为矩阵 A A A的奇异值( A T A A^TA ATA或者 A T A A^TA ATA特征值开根号),矩阵 U U U的列向量称为左奇异向量(left singular vector),矩阵 V V V的列向量称为右奇异向量(right singular vector)。 A A A的左奇异向量是 A A T AA^T AAT 的特征向量, A A A的左奇异向量是 A T A A^TA ATA 的特征向量。
       SVD的核心就是找到一组A的行空间中正交基 v 1 , v 2 , … v r \mathbf{v}_1, \mathbf{v}_2, \ldots \mathbf{v}_r v1​,v2​,…vr​ ,使得:
A [ v 1 v 2 ⋯ v r ] = [ σ 1 u 1 σ 2 u 2 ⋯ σ r u r ] = [ u 1 u 2 ⋯ u r ] [ σ 11 σ 22 ⋱ σ r r ] \begin{aligned} A[\mathbf{v}_1 \; \mathbf{v}_2 \cdots \mathbf{v}_r] &= [\sigma_1\mathbf{u}_1 \; \sigma_2\mathbf{u}_2 \cdots \sigma_r\mathbf{u}_r] \\ & = [\mathbf{u}_1 \; \mathbf{u}_2 \cdots \mathbf{u}_r] \begin{bmatrix} \sigma_{11} & & & \\ & \sigma_{22} & & \\ & & \ddots &\\ & & &\sigma_{rr} \end{bmatrix} \end{aligned} A[v1​v2​⋯vr​]​=[σ1​u1​σ2​u2​⋯σr​ur​]=[u1​u2​⋯ur​] ​σ11​​σ22​​⋱​σrr​​ ​​
其中 u 1 , u 2 , … u r \mathbf{u}_1, \mathbf{u}_2, \ldots \mathbf{u}_r u1​,u2​,…ur​ 是一组在A列空间中的正交基。写成矩阵形式: A V = U Σ A V=U \Sigma AV=UΣ 。其中 V V V和 U U U分别是行空间和列空间中的基,通常情况下: U ≠ V U \neq V U=V 。但是当A是正定矩阵的时候, V V V和 U U U是相同的。也就是说一组正交基在行空间和列空间中是一样的。所以,特征值分解或者叫对角分解实际上是SVD的一种特殊形式。

SVD求解线性最小二乘6

       用SVD求解:设 A A A 的SVD为
A = U Σ V H = ( U 1 , U 2 ) ( Σ 1 0 ) V H A=U \Sigma V^H=\left(U_1, U_2\right)\left(\begin{array}{c} \Sigma_1 \\ 0 \end{array}\right) V^H A=UΣVH=(U1​,U2​)(Σ1​0​)VH
记 V H x = y , U 1 H b = b 1 , ( U 1 为前 n 列构成的矩阵 ) , U 2 H b = b 2 V^H \boldsymbol{x}=\boldsymbol{y}, U_1^H \boldsymbol{b}=\boldsymbol{b}_1,(U_1为前n列构成的矩阵) ,U_2^H \boldsymbol{b}=\boldsymbol{b}_2 VHx=y,U1H​b=b1​,(U1​为前n列构成的矩阵),U2H​b=b2​ 则
∥ A x − b ∥ 2 2 = ∥ U Σ y − b ∥ 2 2 = ∥ Σ y − U H b ∥ 2 2 = ∥ ( Σ 1 0 ) y − ( b 1 b 2 ) ∥ 2 2 = ∥ Σ 1 y − b 1 ∥ 2 2 + ∥ b 2 ∥ 2 2 \begin{aligned} & \|A \boldsymbol{x}-\boldsymbol{b}\|_2^2=\|U \Sigma \boldsymbol{y}-\boldsymbol{b}\|_2^2=\left\|\Sigma \boldsymbol{y}-U^H \boldsymbol{b}\right\|_2^2=\left\|\left(\begin{array}{c} \Sigma_1 \\ 0 \end{array}\right) \boldsymbol{y}-\left(\begin{array}{l} \boldsymbol{b}_1 \\ \boldsymbol{b}_2 \end{array}\right)\right\|_2^2 \\ & =\left\|\Sigma_1 \boldsymbol{y}-\boldsymbol{b}_1\right\|_2^2+\left\|\boldsymbol{b}_2\right\|_2^2 \end{aligned} ​∥Ax−b∥22​=∥UΣy−b∥22​= ​Σy−UHb ​22​= ​(Σ1​0​)y−(b1​b2​​) ​22​=∥Σ1​y−b1​∥22​+∥b2​∥22​​
当 A , b A, \boldsymbol{b} A,b 给定,则 ∥ b 2 ∥ 2 2 = ∥ U 2 H b ∥ 2 2 \left\|\boldsymbol{b}_2\right\|_2^2=\left\|U_2^H \boldsymbol{b}\right\|_2^2 ∥b2​∥22​= ​U2H​b ​22​ 是一个常数,为使 ∥ A x − b ∥ 2 2 = min ⁡ \|A \boldsymbol{x}-\boldsymbol{b}\|_2^2=\min ∥Ax−b∥22​=min 只要取 Σ 1 y = b 1 ⇔ y = Σ 1 − 1 b 1 = Σ 1 − 1 U 1 H b \Sigma_1 \boldsymbol{y}=\boldsymbol{b}_1 \Leftrightarrow \boldsymbol{y}=\Sigma_1^{-1} \boldsymbol{b}_1=\Sigma_1^{-1} U_1^H \boldsymbol{b} Σ1​y=b1​⇔y=Σ1−1​b1​=Σ1−1​U1H​b
这就得到线性方程组的最小二乘解
x = V Σ 1 − 1 U 1 H b = ∑ k = 1 n u k H b σ k v k \boldsymbol{x}=V \Sigma_1^{-1} U_1^H \boldsymbol{b}=\sum_{k=1}^n \frac{\boldsymbol{u}_k^H \boldsymbol{b}}{\sigma_k} \boldsymbol{v}_k x=VΣ1−1​U1H​b=k=1∑n​σk​ukH​b​vk​

SVD分解的数值稳定性7

       稳定性: 在实际使用计算机计算时,SVD分解在数值计算上是很稳定的,这是因为SVD分解是对 A A A 进行一系列正交变换(旋转和平移就是正交变换),而正交变换在实际计算中是很稳定的(这是因为正交矩阵的条件数(酉不变范数下)都是 1 ),例如:对于一个真实数据 A A A 和扰动后的矩阵 A ^ = A + E \hat{A}=A+E A^=A+E ,其中 E E E 是误差(存储数据和对数据进行计算时都会使真实数据产生误差, 这一误差 可以在某种程度上减弱,但很难彻底消除,则有下面的式子成立:
∣ σ i − σ ^ i ∣ ≤ ∥ A ^ − A ∥ 2 = ∥ E ∥ 2 \left|\sigma_i-\hat{\sigma}_i\right| \leq\|\hat{A}-A\|_2=\|E\|_2 ∣σi​−σ^i​∣≤∥A^−A∥2​=∥E∥2​
其中, σ ^ i \hat{\sigma}_i σ^i​ 是 A ^ \hat{A} A^ 奇异值,也就是说,只要误差足够小我们算出的奇异值就会足够靠近真实矩阵的奇异值,而特征值一般是不具有的这么良好的稳定性,也就是说,即使 ∥ E ∥ 2 \|E\|_2 ∥E∥2​ 很小, A ^ \hat{A} A^ 的特征值 有可能和 A A A 的特征值相差很大,例如
A = ( 1 50000 0 1 ) , E = ( 0 0 1 0 − 6 0 ) , A ^ = ( 1 50000 1 0 − 6 1 ) A=\left(\begin{array}{cc} 1 & 50000 \\ 0 & 1 \end{array}\right), E=\left(\begin{array}{cc} 0 & 0 \\ 10^{-6} & 0 \end{array}\right), \hat{A}=\left(\begin{array}{cc} 1 & 50000 \\ 10^{-6} & 1 \end{array}\right) A=(10​500001​),E=(010−6​00​),A^=(110−6​500001​)
       不难看出 A A A 的两个特征值都是 1 ,而我们只在 A A A 的左下角的分量添加了一个很小的扰动 1 0 − 6 10^{-6} 10−6 , 但是 A ^ \hat{A} A^ 的特征值是 1.223606797749979 1.223606797749979 1.223606797749979 和 0.776393202250021 0.776393202250021 0.776393202250021 ,与 1 相差太大,根本达不到 一般情况下我们所要求的精度。但是
        A A A 两个奇异值是: 50000.00002 50000.00002 50000.00002 和 0.000020 0.000020 0.000020
        A ^ \hat{A} A^ 两个奇异值是: 50000.00002 50000.00002 50000.00002 和 0.000019 0.000019 0.000019
几乎相差无几。也正是因为SVD分解的数值稳定性,才使得其有很多广泛的应用。

SVD分解的Eigen实现

       Eigen提供了两种计算SVD分解的方法,分别为Eigen::BDCSVD和Eigen::JacobiSVD。对于小矩阵(<16),最好使用Eigen::JacobiSVD,但是对于较大的矩阵强烈建议使用BDCSVD,可以快几个数量级。

方法一:JacobiSVD

int main(int argc, char *argv[])
{MatrixXf m(3, 2);m << 0.68, 0.597, -0.211, 0.823, 0.566, -0.605;cout << "Here is the matrix m:" << endl<< m << endl;JacobiSVD<MatrixXf> svd;svd.compute(m, ComputeThinU | ComputeThinV);cout << "Its singular values are:" << endl<< svd.singularValues() << endl;cout << "Its left singular vectors are the columns of the thin U matrix:" << endl<< svd.matrixU() << endl;cout << "Its right singular vectors are the columns of the thin V matrix:" << endl<< svd.matrixV() << endl;Vector3f rhs(1, 0, 0);cout << "Now consider this rhs vector:" << endl<< rhs << endl;cout << "A least-squares solution of m*x = rhs is:" << endl<< svd.solve(rhs) << endl;
}

结果分析:

Here is the matrix m:0.68  0.597
-0.211  0.8230.566 -0.605
Its singular values are:1.19173
0.898234
Its left singular vectors are the columns of the thin U matrix:0.388338   0.8656770.711313 -0.0636487-0.585856   0.496541
Its right singular vectors are the columns of the thin V matrix:
-0.182601  0.9831870.983187  0.182601
Now consider this rhs vector:
1
0
0
A least-squares solution of m*x = rhs is:
0.888048
0.496366

方法二:BDCSVD

int main(int argc, char *argv[])
{MatrixXf m(3, 2);m << 0.68, 0.597, -0.211, 0.823, 0.566, -0.605;cout << "Here is the matrix m:" << endl<< m << endl;BDCSVD<MatrixXf> svd;svd.compute(m, ComputeThinU | ComputeThinV);cout << "Its singular values are:" << endl<< svd.singularValues() << endl;cout << "Its left singular vectors are the columns of the thin U matrix:" << endl<< svd.matrixU() << endl;cout << "Its right singular vectors are the columns of the thin V matrix:" << endl<< svd.matrixV() << endl;Vector3f rhs(1, 0, 0);cout << "Now consider this rhs vector:" << endl<< rhs << endl;cout << "A least-squares solution of m*x = rhs is:" << endl<< svd.solve(rhs) << endl;
}

结果分析:

Here is the matrix m:0.68  0.597
-0.211  0.8230.566 -0.605
Its singular values are:1.19173
0.898234
Its left singular vectors are the columns of the thin U matrix:0.388338   0.8656770.711313 -0.0636487-0.585856   0.496541
Its right singular vectors are the columns of the thin V matrix:
-0.182601  0.9831870.983187  0.182601
Now consider this rhs vector:
1
0
0
A least-squares solution of m*x = rhs is:
0.888048
0.496366

  1. 矩阵分解 ↩︎ ↩︎ ↩︎

  2. QR分解 ↩︎

  3. 常见矩阵分解 ↩︎

  4. SVD分解 ↩︎

  5. MIT线性代数笔记3.5(SVD分解) ↩︎

  6. svd求解线性最小二乘 ↩︎

  7. SVD分解数值稳定性 ↩︎

矩阵分解及其Eigen实现相关推荐

  1. Eigen密集矩阵求解 1 - 线性代数及矩阵分解

    简介 这里介绍线性系统的解析,如何进行各种分解计算,如LU,QR,SVD,特征值分解等. 简单线性求解 在一个线性系统,常如下表示,其中A,b分别是一个矩阵,需要求x: Ax=bAx \:= \: b ...

  2. tf 如何进行svd_Tensorflow快餐教程(6) - 矩阵分解

    摘要: 特征分解,奇异值分解,Moore-Penrose广义逆 矩阵分解 特征向量和特征值 我们在<线性代数>课学过方阵的特征向量和特征值. 定义:设A∈Fn×n是n阶方阵.如果存在非零向 ...

  3. Tensorflow快餐教程(6) - 矩阵分解

    摘要: 特征分解,奇异值分解,Moore-Penrose广义逆 矩阵分解 特征向量和特征值 我们在<线性代数>课学过方阵的特征向量和特征值. 定义:设A∈Fn×nA∈Fn×n是n阶方阵.如 ...

  4. 视觉SLAM中的数学——解方程AX=b与矩阵分解:奇异值分解(SVD分解) 特征值分解 QR分解 三角分解 LLT分解

    前言 本博客主要介绍在SLAM问题中常常出现的一些线性代数相关的知识,重点是如何采用矩阵分解的方法,求解线性方程组AX=B.主要参考了<计算机视觉--算法与应用>附录A以及Eigen库的方 ...

  5. java 矩阵分解_计算方法(三)矩阵分解1-正交分解(QR分解)

    正交分解 矩阵的正交分解又称为QR分解,是将矩阵分解为一个正交矩阵Q和一个上三角矩阵的乘积的形式. 任意实数方阵A,都能被分解为 .这里的Q为正交单位阵,即 R是一个上三角矩阵.这种分解被称为QR分解 ...

  6. 【机器学习的数学基础】(六)矩阵分解(Matrix Decomposition)(上)

    文章目录 4 矩阵分解(Matrix Decompositions)(上) 4.1 行列式与迹 4.2 特征值和特征向量 4 矩阵分解(Matrix Decompositions)(上) 在第2章和第 ...

  7. 特征值分解(Eigen Value Decomposition,EVD)、奇异值分解(Singular Value Decomposition,SVD)原理、公式推导及应用

    1 正交矩阵&正交变换 正交变换是保持图形形状和大小不变的几何变换,包含旋转.平移.轴对称及这些变换的复合形式,正交变换可以保持向量的长度和向量之间的角度不变.特别的,标准正交基经正交变换后仍 ...

  8. 计算方法(三)矩阵分解1-正交分解(QR分解)

    为什么80%的码农都做不了架构师?>>>    正交分解 矩阵的正交分解又称为QR分解,是将矩阵分解为一个正交矩阵Q和一个上三角矩阵的乘积的形式. 任意实数方阵A,都能被分解为 .这 ...

  9. 矩阵奇异值分解特征值分解_推荐系统中的奇异值分解与矩阵分解

    矩阵奇异值分解特征值分解 Recently, after watching the Recommender Systems class of Prof. Andrew Ng's Machine Lea ...

最新文章

  1. JDBC编程的事务处理
  2. Ajax的get、post和ajax提交
  3. 几个常见的 slice 错误
  4. 腾讯高性能分布式路由技术,亮相亚太网络研讨会APNet
  5. 使用Azure云原生构建博客是怎样一种体验?(上篇)
  6. Android环境的安装遇到的问题
  7. 阶段项目:学生信息管理系统数据库设计
  8. 产品经理学技术之数据结构
  9. 构建高性能ASP.NET站点
  10. QtCreator格式化代码---Beautifier插件使用方式
  11. 利用图片的 onerror 事件载入默认图片
  12. OC---Math公式
  13. 银行卡四要素API 方便好用
  14. 乐队设备--反馈抑制器学习笔记
  15. 【观察】西部数据:再定义分层存储架构,赋能数据中心新基建
  16. 哈尔滨工业大学计算机系统大作业2022春
  17. 前端-获取treegrid的选中数据
  18. 克隆好的CentOS6虚拟机如何联网,解决报错Device eth0 does not seem to be present, delaying initialization
  19. Google Earth Engine(GEE)——
  20. 7.动态绘制(Jig)

热门文章

  1. cadence常见技巧和错误。。。
  2. 区块链技术解决投行电子底稿监管痛点 中国证券业协会在“中证链”发布首个应用
  3. 【提前批】【第二批】CUHK CSE 面经2022.6.17
  4. 微信小程序收起键盘(微信小程序关闭键盘)
  5. 数据库 - About Redis
  6. 桌面运维之windows部分常用命令
  7. Max Script|物体选择和拷贝
  8. 滴水逆向三期笔记与作业——02C语言——02数据类型
  9. Sepic电路的参数计算及仿真
  10. iphone横竖屏切换,旋转屏幕