2012-10-26 204 views
5

如何從Eigen::SparseMatrix<double>中提取塊。似乎沒有我用於密集的方法。從稀疏矩陣中提取一個塊作爲另一個稀疏矩陣

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

有一種方法可以將塊提取爲Eigen::SparseMatrix<double>

+0

也許沒有方法,因爲它是一個稀疏矩陣,可能是空的,因此提取不是很有用? –

回答

4

我做了這個函數從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; 
} 

而這些如果子矩陣是在四個角之一提取塊:

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

也許你可以擴展一下,添加測試並將其發送到eigen郵件列表。 – Jakob

+0

我會做的。這可能對某人有用...... – tyranitar

1

對於submatrices in sparse matrices有非常稀疏的支持(抱歉,沒有雙關語意)。實際上,您只能訪問row-major的連續行集,以及column major的列。其原因不是矩陣可能是空的,而是索引方案比密集矩陣更復雜一些。對於稠密矩陣,只需要一個額外的步長數就可以支持子矩陣支持。

+0

您要鏈接的頁面顯示對阻塞的支持是稀疏矩陣,或許自上次發佈以來已更新。 – Akavall

3

這是現在支持Eigen 3.2.2Docs (儘管也許早期版本也支持它)。

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