2012-10-26 5 views
5

So extrahieren Sie einen Block aus einer Eigen::SparseMatrix<double>. Es scheint, dass es nicht die Methoden gibt, die ich für die Dichten verwendet habe.Extrahieren Sie einen Block aus einer Sparse-Matrix als eine andere spärliche Matrize.

‘class Eigen::SparseMatrix<double>’ has no member named ‘topLeftCorner’ 
‘class Eigen::SparseMatrix<double>’ has no member named ‘block’ 

Es gibt einen Weg, um einen Block als Eigen::SparseMatrix<double> zu extrahieren?

+0

Vielleicht gibt es keine Methode, da es eine spärliche Matrix ist und könnte leer und daher nicht sehr nützlich sein, um zu extrahieren? –

Antwort

4

habe ich diese Funktionsblöcke von einem Und diese Eigen::SparseMatrix<double,ColMaior>

typedef Triplet<double> Tri; 
SparseMatrix<double> sparseBlock(SparseMatrix<double,ColMajor> M, 
     int ibegin, int jbegin, int icount, int jcount){ 
     //only for ColMajor Sparse Matrix 
    assert(ibegin+icount <= M.rows()); 
    assert(jbegin+jcount <= M.cols()); 
    int Mj,Mi,i,j,currOuterIndex,nextOuterIndex; 
    vector<Tri> tripletList; 
    tripletList.reserve(M.nonZeros()); 

    for(j=0; j<jcount; j++){ 
     Mj=j+jbegin; 
     currOuterIndex = M.outerIndexPtr()[Mj]; 
     nextOuterIndex = M.outerIndexPtr()[Mj+1]; 

     for(int a = currOuterIndex; a<nextOuterIndex; a++){ 
      Mi=M.innerIndexPtr()[a]; 

      if(Mi < ibegin) continue; 
      if(Mi >= ibegin + icount) break; 

      i=Mi-ibegin;  
      tripletList.push_back(Tri(i,j,M.valuePtr()[a])); 
     } 
    } 
    SparseMatrix<double> matS(icount,jcount); 
    matS.setFromTriplets(tripletList.begin(), tripletList.end()); 
    return matS; 
} 

zu extrahieren, wenn die Untermatrix in einer der vier Ecken ist:

SparseMatrix<double> sparseTopLeftBlock(SparseMatrix<double> M, 
     int icount, int jcount){ 
    return sparseBlock(M,0,0,icount,jcount); 
} 
SparseMatrix<double> sparseTopRightBlock(SparseMatrix<double> M, 
     int icount, int jcount){ 
    return sparseBlock(M,0,M.cols()-jcount,icount,jcount); 
} 
SparseMatrix<double> sparseBottomLeftBlock(SparseMatrix<double> M, 
     int icount, int jcount){ 
    return sparseBlock(M,M.rows()-icount,0,icount,jcount); 
} 
SparseMatrix<double> sparseBottomRightBlock(SparseMatrix<double> M, 
     int icount, int jcount){ 
    return sparseBlock(M,M.rows()-icount,M.cols()-jcount,icount,jcount); 
} 
+1

Vielleicht könnten Sie das etwas erweitern, Tests hinzufügen und an die Eigen Mailingliste senden. – Jakob

+0

werde ich tun. Es könnte für jemanden nützlich sein ... – tyranitar

1

Es gibt sehr spärliche Unterstützung (Entschuldigung, kein Wortspiel beabsichtigt) für submatrices in sparse matrices. Effektiv können Sie nur auf eine fortlaufende Reihe von Reihen für Reihenmajor und Spalten für Hauptspalte zugreifen. Der Grund dafür ist nicht, dass die Matrizen leer sein könnten, sondern dass das Indexierungsschema etwas komplizierter ist als bei dichten Matrizen. Bei dichten Matrizen benötigen Sie nur eine zusätzliche Schrittnummer, um die Submatrix-Unterstützung zu unterstützen.

+0

Die Seite, auf die Sie verlinken, zeigt die Unterstützung für die Blockierung in dünn besetzten Matrizen. Möglicherweise wurde sie seit der letzten Veröffentlichung aktualisiert. – Akavall

3

Diese jetzt in Eigen 3.2.2Docs unterstützt wird (obwohl vielleicht frühere Versionen es auch unterstützen).

#include <iostream> 
#include <Eigen/Dense> 
#include <Eigen/Sparse> 

using namespace Eigen; 

int main() 
{ 
    MatrixXd silly(6, 3); 

    silly << 0, 1, 2, 
      0, 3, 0, 
      2, 0, 0, 
      3, 2, 1, 
      0, 1, 0, 
      2, 0, 0; 



    SparseMatrix<double, RowMajor> sparse_silly = silly.sparseView(); 

    std::cout <<"Whole Matrix" << std::endl; 
    std::cout << sparse_silly << std::endl; 

    std::cout << "block of matrix" << std::endl; 
    std::cout << sparse_silly.block(1,1,3,2) << std::endl; 

    return 0; 
}