2014-09-19 18 views
5

Mam pytanie dotyczące biblioteki Eigen w C++. Właściwie chcę obliczyć odwrotną macierz rzadkiej macierzy. Kiedy użyłem gęstej macierzy w Eigen, mogę użyć operacji .inverse() do obliczenia odwrotności gęstej macierzy. Ale w macierzy rzadkiej nie mogę znaleźć operacji odwrotnej w dowolnym miejscu. Czy ktoś, kto wie, aby obliczyć odwrotność rzadkiej macierzy? Pomóż mi.Jak mogę obliczyć odwrotność rzadkiej macierzy w bibliotece Eigen

+0

Dodaj więcej tagów, aby przyciągnąć możliwie bardziej wyczerpujące odpowiedzi. – Bathsheba

+0

Aha .. Dziękuję. Spróbuję tego. – kujungmul

+0

Ale moja zwięzła odpowiedź nie działa! – Bathsheba

Odpowiedz

7

Nie można tego zrobić bezpośrednio, ale zawsze można to obliczyć za pomocą jednego z rzadkich rozwiązań. Chodzi o to, aby rozwiązać A*X=I, gdzie I jest matrycą tożsamości. Jeśli istnieje rozwiązanie, X będzie twoją matrycą odwrotną. The eigen documentation ma stronę o nielicznych rozwiązują i jak z nich korzystać, ale podstawowe kroki są następujące:

SolverClassName<SparseMatrix<double> > solver; 
solver.compute(A); 
SparseMatrix<double> I(n,n); 
I.setIdentity(); 
auto A_inv = solver.solve(I); 
2

To nie ma znaczenia matematycznego.

Rzadka macierz niekoniecznie ma rzadką odwrotność.

Dlatego ta metoda nie jest dostępna.

+0

Dotyczy to również gęstych matryc, matematycznie nie ma różnicy. Jest to bardziej kosztowne, zwłaszcza, że ​​rzadkie macierze są zwykle duże. – MatthiasB

0

można znaleźć przykład około odwrotności Sparse złożonej matrycy

użyłem klasy SimplicialLLT,

można znaleźć inną klasę z mieszkiem

http://eigen.tuxfamily.org/dox-devel/group__TopicSparseSystems.html

Ta strona może pomóc w prawidłowej nazwy klasy do swojej pracy (spead, dokładności i dimmenssion swojej matrycy)

////////////////////// 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; 
} 
0

małe rozszerzenie na @Soheib i @ odpowiedzi MatthiasB, o ile używasz Eigen::SparseMatrix<float> lepiej używaj SparseLU zamiast SimplicialLLT lub SimplicialLDLT, oni stworzyli błędne odpowiedzi ze mną na macierzach pływających