Извлечь блок из разреженной матрицы как другую разреженную матрицу

Как извлечь блок из Eigen::SparseMatrix<double>, Кажется, что нет методов, которые я использовал для плотных.

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

Есть способ извлечь блок как Eigen::SparseMatrix<double> ?

5

Решение

Я сделал эту функцию, чтобы извлечь блоки из 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);
}
4

Другие решения

Это теперь поддерживается в Eigen 3.2.2 Документы (хотя, возможно, более ранние версии тоже это поддерживают).

#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

Существует очень редкая поддержка (извините, каламбур не предназначен) для подматрицы в разреженных матрицах. Фактически вы можете получить доступ только к непрерывному набору строк для основной строки и столбцов для основной колонки. Причина этого не в том, что матрицы могут быть пустыми, а в том, что схема индексации несколько сложнее, чем с плотными матрицами. С плотными матрицами вам нужен только дополнительный номер шага для поддержки поддержки подматрицы.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector