如何求解稀疏矩阵的线性方程 AX=b

2024-01-12

我有稀疏矩阵 A(120,000*120,000) 和向量 b(120,000),我想使用 Eigen 库求解线性系统 AX=b 。我尝试按照文档进行操作,但总是出现错误。我还尝试将矩阵更改为稠密并求解系统

    Eigen::MatrixXd H(N,N);
    HH =Eigen:: MatrixXd(A);
    Eigen::ColPivHouseholderQR<Eigen::MatrixXd> dec(H);
    Eigen::VectorXd RR = dec.solve(b);  

但我有一个内存错误。 请帮我找到解决这个问题的方法。


对于稀疏系统,我们一般使用迭代的方法。原因之一是像 LU、QR... 这样的直接求解器会填充您的初始矩阵(填充的意思是最初的零分量被非零分量替换)。在大多数情况下,结果稠密矩阵无法再装入内存(->你的记忆错误)。简而言之,迭代求解器不会改变稀疏模式,因为它们只涉及矩阵向量乘积(无填充)。

也就是说,您必须首先知道您的系统是否对称正定(又名 SPD)在这种情况下您可以使用共轭梯度法 https://en.wikipedia.org/wiki/Conjugate_gradient_method。否则,您必须使用非对称系统的方法,例如BiCGSTAB https://en.wikipedia.org/wiki/Biconjugate_gradient_stabilized_method or GMRES https://en.wikipedia.org/wiki/Generalized_minimal_residual_method.

你一定知道,大多数时候我们使用的是预条件子 https://en.wikipedia.org/wiki/Preconditioner,特别是当您的系统状况不佳时。

查看 Eigen 文档,我发现(没有预处理器的示例 afaik):

  int n = 10000;
  VectorXd x(n), b(n);
  SparseMatrix<double> A(n,n);
  /* ... fill A and b ... */ 
  BiCGSTAB<SparseMatrix<double> > solver;
  solver.compute(A);
  x = solver.solve(b);
  std::cout << "#iterations:     " << solver.iterations() << std::endl;
  std::cout << "estimated error: " << solver.error()      << std::endl;

这可能是一个好的开始(如果您的矩阵是 SPD,请使用共轭梯度法)。请注意,这里没有预处理器,因此收敛速度肯定会相当慢。

回顾一下:大矩阵 -> 迭代方法 + 预处理器。

这确实是第一个“基本/天真的”解释,您可以在中找到有关该理论的更多信息Saad 的书:稀疏线性系统的迭代方法 http://www-users.cs.umn.edu/~saad/IterMethBook_2ndEd.pdf。同样,这个主题很大,你可以找到很多关于这个主题的其他书籍。

我不是 Eigen 用户,但是有预条件子在这里 https://eigen.tuxfamily.org/dox/group__IterativeLinearSolvers__Module.html。 -> 不完全 LU(非对称系统)或不完全 Cholesky(SPD 系统)通常是很好的通用预处理器,有首先进行测试。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何求解稀疏矩阵的线性方程 AX=b 的相关文章

随机推荐