使用块稀疏矩阵求解大型线性系统

时间:2016-05-13 12:24:10

标签: c++ matrix linear-algebra eigen

我想解决Ax = b,其中A是一个非常大的正方形正定对称块矩阵,xb是向量。当我说大时我的意思是nxn矩阵n300,000一样大。

这是一个我想要解决的更小但有代表性的矩阵的例子。

Sparse matrix

这是同样的矩阵放大显示它是由密集的matricies块组成的。

Sparze matrix zoomed in

我之前(请参阅herehere,并且早在here)使用了Eigen的Cholesky解算器,该解算器适用于n<10000,但与n=300000 Cholesky解算器太慢了。但是,我没有利用我有块矩阵的事实。显然,存在用于求解稀疏块矩阵的算法(例如block cholesky factorization)。

我想特别知道Eigen是否使用因子分解或迭代方法对我可以使用的稀疏密集块矩阵进行了优化算法?

你也可以建议其他算法可能是解决我的矩阵的理想选择吗?我的意思是,据我所知,至少对于因子分解发现一个置换矩阵是NP难以存在许多不同的启发式方法,并且据我所知,人们建立了不同矩阵结构的直觉(例如banded matrix)和什么算法最适合他们。我还没有这种直觉。

我目前正在考虑使用conjugate gradient method。我自己用C ++实现了这个,但仍然没有利用矩阵是一个块矩阵的事实。

//solve A*rk = xk
//Eigen::SparseMatrix<double> A;
//Eigen::VectorXd rk(n);
Eigen::VectorXd pk = rk;

double rsold = rk.dot(rk);
int maxiter = rk.size();
for (int k = 0; k < maxiter; k++) {
    Eigen::VectorXd Ap = A*pk;  
    double ak = rsold /pk.dot(Ap);
    xk += ak*pk, rk += -ak*Ap;      
    double rsnew = rk.dot(rk);
    double xlength = sqrt(xk.dot(xk));
    //relaxing tolerance when x is large
    if (sqrt(rsnew) < std::max(std::min(tolerance * 10000, tolerance * 10 * xlength), tolerance)) {
        rsold = rsnew;
        break;
    }
    double bk = rsnew / rsold;
    pk *= bk;
    pk += rk;
    rsold = rsnew;
}

2 个答案:

答案 0 :(得分:1)

查看SuiteSparse,http://faculty.cse.tamu.edu/davis/suitesparse.html 作者蒂姆戴维斯在稀疏矩阵领域很有名。他还获得了谷歌颁发的代码质量奖。他的代码表现也很出色。

干杯

答案 1 :(得分:0)

我认为ARPACK被设计为对任务有效,因为在A是sparce的情况下找到方程组Ax = b的解,就像你的情况一样。 您可以找到ARPACK here的源代码。