2012-10-26 19 views
5

Come estrarre un blocco da un Eigen::SparseMatrix<double>. Sembra che non ci siano i metodi che ho usato per quelli densi.Estrarre un blocco da una matrice sparsa come un'altra matrice sparsa

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

C'è un modo per estrarre un blocco come Eigen::SparseMatrix<double>?

+0

Forse non esiste un metodo poiché è una matrice sparsa e potrebbe essere vuoto e quindi non molto utile da estrarre? –

risposta

4

ho fatto questa funzione per estrarre blocchi da un 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; 
} 

E questi se il sub-matrice è in uno dei quattro angoli:

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

Forse potresti estendere un po 'questo, aggiungere test e inviarlo alla mailing list di eigen. – Jakob

+0

Lo farò. Potrebbe essere utile per qualcuno ... – tyranitar

1

C'è un supporto molto scarso (scusate, nessun gioco di parole) per submatrices in sparse matrices. In effetti è possibile accedere solo a un insieme continuo di righe per riga maggiore e colonne per colonna maggiore. La ragione di ciò non è che le matrici possano essere vuote, ma piuttosto che lo schema di indicizzazione è un po 'più complicato che con matrici dense. Con matrici dense è necessario solo un numero di falcata aggiuntivo per supportare il supporto della sottomatrice.

+0

La pagina a cui stai collegando mostra il supporto per il blocco è matrici sparse, forse è stata aggiornata dall'ultima volta che hai postato. – Akavall

3

Questo è ora supportata in Eigen 3.2.2Docs (anche se forse le versioni precedenti lo supportano).

#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; 
} 
Problemi correlati