项目需要求解一个超大的稀疏矩阵方程组,本来是打算用opencv的Mat或者SparseMat去实现的。但是Mat是稠密矩阵,占用内存比较大;而SparseMat没有对应的求解函数。所以最后打算使用Eigen库实现这一需求。
Eigen库解方程组的官方文档如下,可以根据方程组自身的特点选择不同的求解算法:
https://eigen.tuxfamily.org/dox/group__TopicSparseSystems.html
看了之后决定使用LU分解的方法:SparseLU来求解方程组,官方文档所给的代码是:
VectorXd x(n), b(n);
SparseMatrix<double> A;
SparseLU<SparseMatrix<double>, COLAMDOrdering<int> > solver;
// fill A and b;
// Compute the ordering permutation vector from the structural pattern of A
solver.analyzePattern(A);
// Compute the numerical factorization
solver.factorize(A);
//Use the factors to solve the linear system
x = solver.solve(b);
问题就是使用了这个代码之后,在解算的时候非常慢,而且电脑内存占用一直在增加。直到半个多小时后,程序占用100%内存都还没有解出来。
之后仔细研究了一下SparseLU的参数,第二个参数COLAMDOrdering<int>是用于减少LU分解等方法时填充的元素。
于是我尝试把第二个参数改成AMDOrdering
Eigen::SparseLU<Eigen::SparseMatrix<double>, Eigen::AMDOrdering<int>> solver;
成功秒解方程组!原理不太理解,可能是我的方程组自身更加适合AMDOrdering的排序方式。