前段时间遇到一些稀疏矩阵的问题,主要是求解大型的非齐次线性方程组:Ax = b, 其中 A是一个大型的稀疏矩阵,可能有上万或十万阶,根据A的特点可能有下面一些求解方法:
1. A 是一个对称正定矩阵,可以用Cholesky分解求解。
2. A 是一个方阵,但是不知道是否对称,也不知道是否正定,则可用 LU分解。
3. A 是一个长方形的矩阵,且行数要大于列数(列数大于行数的没有定解),则用QR分解。
这里面第三种情况是最慢的,对于8000 * 500 的矩阵,需要50ms左右。但是在一种情况下可以加速,即如果A是列满秩的,则可以将方程两端同乘以 A^T:
A^T * Ax = A^T b
这样就变成了一个新的方程组,新的系数矩阵是 A^T * A, 可以证明在列满秩的情况下,A^T * A 是一个对称正定的矩阵,因此可以用case 1 或 case 2的方法求解。
实验表明,对于8000 * 500 左右的稀疏矩阵,采用这种方法只需要 4ms左右,可以极大的提高效率(A^T * A 只是一个 500 * 500 的矩阵,阶数变小了很多)。
下面是几个常用的稀疏矩阵的求解库:
1. Eigen : http://eigen.tuxfamily.org/dox/group__TutorialSparse.html
这是一个完全由类模板写成的轻量级的求解库,可以很方便的使用,不用编译。接口做的非常好,易懂易用,但是求解器效率不是很高。幸运的是他们给出了与其他高效求解库的接口,只需要把其他求解库比如 superLU 和 SuiteSparse加入进来,就可以非常方便的使用了,比原来的接口易用的多。
2. SuiteSparse: http://faculty.cse.tamu.edu/davis/suitesparse.html
正如他的名字一样,这个库集成了多个求解器,基本可以应会所有的稀疏矩阵求解,而且还有牛人做了vs版 本:
https://github.com/jlblancoc/suitesparse-metis-for-windows
3. SuperLU:
http://crd-legacy.lbl.gov/~xiaoye/SuperLU/
用LU分解的求解稀疏矩阵的库,速度没得说,可以直接用vs进行编译:
http://blog.csdn.net/gindar/article/details/8010794
“1)新建一个工程A(这里命名为SuperLU),先将**\SuperLU_4.0\SRC 中的所有的.c文件添加到源文件文件夹中,所有的.h文件添加到头文件文件夹中。
2)然后在工程右击->属性->配置属性->general->Configeration Type->选择static Liarary(.lib)这个,单击apply.(或者在建立工程的时候直接选创建的是静态库也可以)
3)将文件夹**\SuperLU_4.0\SRC 添加到右击->属性->C++->general->Additional Include Directories中”
推荐使用Eigen + SuperLu + SuiteSparse,这样可以使用Eigen封装好的接口。