2012-10-26 19 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

これを少し拡張してテストを追加し、それを固有のメーリングリストに送ることもできます。 – Jakob

+0

とさせていただきます。それは誰かのために役立つことができます... – tyranitar

1

submatrices in sparse matricesのサポートは非​​常に疎です(申し訳ありませんが、何も意図していません)。実際には、行メジャーの場合は連続した行セットに、列メジャーの場合は列にのみアクセスできます。その理由は、行列が空になる可能性があるのではなく、索引付け方式が密行列よりも幾分複雑であるためです。密行列の場合は、サブ行列サポートをサポートするために追加のストライド番号が必要です。

+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; 
} 
関連する問題