Как я могу вычислить инверсию разреженной матрицы в библиотеке Eigen
У меня есть вопрос о библиотеке Eigen в C++. Собственно, я хочу вычислить обратную матрицу разреженной матрицы. Когда я использовал Dense matrix в Eigen, я мог использовать операцию.inverse() для вычисления инверсии плотной матрицы. Но в разреженной матрице я нигде не могу найти обратную операцию. Кто-нибудь, кто знает, для вычисления обратной разреженной матрицы? Помоги мне.
5 ответов
Вы не можете сделать это напрямую, но вы всегда можете рассчитать это, используя один из разреженных решателей. Идея состоит в том, чтобы решить A*X=I
где я - единичная матрица. Если есть решение, X будет вашей обратной матрицей. В собственной документации есть страница о разреженных решателях и о том, как их использовать, но основные шаги заключаются в следующем:
SolverClassName<SparseMatrix<double> > solver;
solver.compute(A);
SparseMatrix<double> I(n,n);
I.setIdentity();
auto A_inv = solver.solve(I);
Это не математически значимо.
Разреженная матрица не обязательно имеет разреженную обратную.
Вот почему метод не доступен.
Небольшое расширение ответов @Soheib и @MatthiasB, если вы используете Eigen::SparseMatrix<float>
лучше использовать SparseLU, а не SimplicialLLT или SimplicialLDLT, они дали мне неправильные ответы на плавающих матрицах
Имейте в виду, что инверсия разреженной матрицы не обязательно является разреженной, поэтому, если вы работаете с большими матрицами (что вполне вероятно, если вы используете разреженные представления), это будет дорого. Тщательно подумайте, действительно ли вам нужна инверсная матрица. Если вы собираетесь использовать обратную матрицу для решения системы уравнений, вам не нужно фактически вычислять обратную матрицу и умножать ее (используйте метод, обычно называемый
solve
и поставим правую часть уравнения). Если вам нужна обратная матрица Фишера для ковариаций, попробуйте приблизиться.
Вы можете найти пример обратного разреженной комплексной матрицы
Я использовал класс 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;
}