2012-10-26 257 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; 
}