[关闭]
@gunshooter 2019-07-31T13:57:43.000000Z 字数 1598 阅读 1181

矩阵的分解和线性方程组直接求解

数值方法


方程组的直接解法

方程组的直接解法与其系数矩阵的分解直接相关。因此首先我们必须了解一些常用的分解方法。

LU分解(Doolittle分解)

名称: LU分解,三角分解,Doolittle分解
方法: Doolittle算法
类别: 直接法----
存在性: 若方阵非奇异,则LU分解存在
特点:

  • L为下三角阵,对角线是1;U为上三角阵,对角线是主元。
  • 由于U是上三角阵,因此很容易求其对应的线性方程组的解。
  • LU本质上是高斯消元的表达形式
  • LU分解常用来求行列式:三角阵的行列式等于对角元之积

QR分解(HouseHolder变换)

名称: QR分解
方法: HouseHolder变换
类别: 直接法
特点:

  • Q为z正交阵();R为上三角阵。
  • 由于R是上三角阵,因此很容易求其对应的线性方程组的解。
  • QR分解常用来求线性最小二乘问题

SVD分解

Eigen库中的直接解法

  1. #include <iostream>
  2. #include <Eigen/Dense>
  3. using namespace std;
  4. using namespace Eigen;
  5. int main()
  6. {
  7. Matrix3f A;//对于n维矩阵,可以写成 MatrixXd A(n,n)
  8. Vector3f b;//同理,VectorXd b(n)
  9. A << 1,2,3, 4,5,6, 7,8,10;
  10. b << 3, 3, 4;
  11. cout << "Here is the matrix A:\n" << A << endl;
  12. cout << "Here is the vector b:\n" << b << endl;
  13. Vector3f x = A.colPivHouseholderQr().solve(b);
  14. cout << "The solution is:\n" << x << endl;
  15. }

核心语句是Vector3f x = A.colPivHouseholderQr().solve(b);,这句话先调用一个函数对A进行分解,然后再调用solve()求解方程组。两步求解方程的思路在后面稀疏矩阵操作中也是这样用的。
此处的colPivHouseholderQr显然是一种QR分解,相应的可以替换成许多种不同的分解方法,其名称与特点如下:

Decomposition Method Requirements on the matrix
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

上表以及更多内容见官方教程。

为什么不用直接解法

矩阵的病态程度

待续

稀疏矩阵面临什么问题?

稀疏矩阵中有大量0元素,使用适当的方式存储可以节省大量空间。然而矩阵分解之后会产生许多非0元素,因此使用直接解法无疑不是最好的办法。
解决的方案就是迭代法,包括

静态迭代法 非静态迭代法
雅可比法 共轭梯度法(CG)
高斯赛德尔法 稳定双共轭梯度法(BiCGSTAB)
松弛法


参考资料:
常见的几种矩阵分解方式(LU分解、QR分解)
知乎专栏:数值计算实验室
如果没有知乎,我将一无所知。。。这一系列后续的文章目测是这个专栏的删减搬运 阿西吧
官方例程:Linear algebra and decompositions
Eigen学习(九)稠密问题之线性代数和分解

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注