【问题标题】:Extract a block from a sparse matrix as another sparse matric从稀疏矩阵中提取一个块作为另一个稀疏矩阵
【发布时间】:2012-10-26 21:02:13
【问题描述】:

如何从Eigen::SparseMatrix<double> 中提取块。好像没有我用来处理密集的方法。

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

有一种方法可以将块提取为Eigen::SparseMatrix&lt;double&gt;

【问题讨论】:

  • 也许没有方法,因为它是一个稀疏矩阵,可能是空的,因此提取起来不是很有用?

标签: c++ matrix sparse-matrix eigen


【解决方案1】:

我做了这个函数来从Eigen::SparseMatrix&lt;double,ColMaior&gt;中提取块

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

【讨论】:

  • 也许你可以扩展一下,添加测试并将其发送到 eigen 邮件列表。
【解决方案2】:

现在 Eigen 3.2.2 Docs 支持此功能(尽管早期版本可能也支持它)。

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

【讨论】:

    【解决方案3】:

    submatrices in sparse matrices 的支持非常少(抱歉,没有双关语)。实际上,您只能访问一组连续的行为主的行和列的主列。原因不是矩阵可能为空,而是索引方案比密集矩阵复杂一些。使用密集矩阵,您只需要一个额外的步幅数即可支持子矩阵支持。

    【讨论】:

    • 您链接的页面显示支持阻塞是稀疏矩阵,可能自您上次发布以来已更新。
    猜你喜欢
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 2021-09-22
    • 2023-04-10
    • 2021-11-25
    相关资源
    最近更新 更多