我对 C++ 中的 Eigen 库有疑问。实际上,我想计算稀疏矩阵的逆矩阵。当我在 Eigen 中使用密集矩阵时,我可以使用 .inverse() 运算来计算密集矩阵的逆。但是在稀疏矩阵中,我在任何地方都找不到逆运算。有谁知道计算稀疏矩阵的逆?帮我。
5 回答
您不能直接执行此操作,但您始终可以使用其中一种稀疏求解器进行计算。这个想法是解决A*X=I
,其中 I 是单位矩阵。如果有解决方案,X 将是您的逆矩阵。
eigen 文档有一个关于稀疏求解器以及如何使用它们的页面,但基本步骤如下:
SolverClassName<SparseMatrix<double> > solver;
solver.compute(A);
SparseMatrix<double> I(n,n);
I.setIdentity();
auto A_inv = solver.solve(I);
这在数学上没有意义。
稀疏矩阵不一定具有稀疏逆矩阵。
这就是该方法不可用的原因。
你可以找到一个关于稀疏复数矩阵逆的例子
我使用了 SimplicialLLT 类,
你可以从下面找到其他课程
http://eigen.tuxfamily.org/dox-devel/group__TopicSparseSystems.html
此页面可以帮助您为您的工作选择正确的班级名称(矩阵的速度、准确性和维度)
////////////////////// In His Name \\\\\\\\\\\\\\\\\\\\\\\\\\\
#include <iostream>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
using namespace std;
using namespace Eigen;
int main()
{
SparseMatrix< complex<float> > A(4,4);
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
A.coeffRef(i, i) = i+j;
}
}
A.insert(2,1) = {2,1};
A.insert(3,0) = {0,0};
A.insert(3,1) = {2.5,1};
A.insert(1,3) = {2.5,1};
SimplicialLLT<SparseMatrix<complex<float> > > solverA;
A.makeCompressed();
solverA.compute(A);
if(solverA.info()!=Success) {
cout << "Oh: Very bad" << endl;
}
SparseMatrix<float> eye(4,4);
eye.setIdentity();
SparseMatrix<complex<float> > inv_A = solverA.solve(eye);
cout << "A:\n" << A << endl;
cout << "inv_A\n" << inv_A << endl;
}
@Soheib 和 @MatthiasB 的答案的一个小扩展,如果你使用Eigen::SparseMatrix<float>
它最好使用 SparseLU 而不是 SimplicialLLT 或 SimplicialLDLT,他们在浮点矩阵上对我产生了错误的答案
请注意,稀疏矩阵的逆矩阵不一定是稀疏的,因此如果您正在使用大型矩阵(如果您使用的是稀疏表示,这很可能),那么这将是昂贵的。仔细考虑您是否真的需要实际的逆矩阵。如果您要使用矩阵逆来求解方程组,那么您不需要实际计算矩阵逆并将其相乘(使用通常命名的方法solve
并提供方程的右侧)。如果您需要协方差的 Fisher 矩阵的逆矩阵,请尝试近似。