| [eigen] Extract sparse sub-matrices from a sparse matrix | 
[ Thread Index | 
Date Index
| More lists.tuxfamily.org/eigen Archives
] 
- To: eigen@xxxxxxxxxxxxxxxxxxx
 
- Subject: [eigen] Extract sparse sub-matrices from a sparse matrix
 
- From: Alberto Minetti <bangirasu@xxxxxxxxx>
 
- Date: Tue, 30 Oct 2012 14:26:29 +0100
 
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed;        d=gmail.com; s=20120113;        h=mime-version:from:date:message-id:subject:to:content-type         :content-transfer-encoding;        bh=C4kDW1g1J0gTJMsXG6dDtfDhcIfJo2GzUkFN9b3x+T0=;        b=dLy8iL9Rx4E+uwZk1mErJXLJw8a621L5soTEJ+PinsKrTvpaqgnme0geaEy0ZENbaA         WcT2yUi80GjAUPKekbqGTVwrF1HraHxY52hWWEqEroIkpiBy2VmS0qGFU4LGNScu37Ij         wBCLblNgFaRYYg5D+QSkuMqa3UNKtSGpPxXuIHX0p9at/Kn8q7yNmpteRQ+6IGpnr/LI         vVl6ZF1qq7wadVvnQOajzOT+TbNPQV/suDlwn7JyTdR0Lnjg9Ce4VOU4arw5+VnKGpD3         nG+rrFh7g9x9CeBL2/gkLIxAJGACESDsE5MimUgoqmjAGKWV0a1Eozlpx0yqTedsELGD         XM0Q==
 
I need to extract a block from a Eigen::SparseMatrix<double> but it
seems there aren't the methods I used for the dense ones.
‘class Eigen::SparseMatrix<double>’ has no member named ‘topLeftCorner’
‘class Eigen::SparseMatrix<double>’ has no member named ‘block’
So I made this function to extract blocks from the
Eigen::SparseMatrix<double> and other four functions if the sub-matrix
is in one of the four corners. The code below has a main with tests.
#include <iostream>
#include <vector>
#include <stdio.h>
#include <assert.h>
#include <Eigen/Sparse>
using namespace std;
using namespace Eigen;
#define N 30
typedef Triplet<double> Tri;
SparseMatrix<double> sparseBlock(SparseMatrix<double> M,
int ibegin, int jbegin, int icount, int jcount){
	//tested using 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);
}
int main(int argc, char *argv[]){
	
	std::vector<Tri> tripletList;
	tripletList.reserve(N*N);
	for(int i=1; i<N; i=i+2)
		for(int j=1; j<N; j=j+2)
			tripletList.push_back(Tri(i,j,i*N+j));
	
	SparseMatrix<double> M(N,N);
	M.setFromTriplets(tripletList.begin(), tripletList.end());
	// M is ready to go!
	
	cout << "Here is the matrix M("
	<<M.rows()<<"x"<<M.cols()<<"):\n" << M << endl;
	SparseMatrix<double> B=sparseBlock(M,5,3,4,9);
	cout << "Here is the matrix B("
	<<B.rows()<<"x"<<B.cols()<<"):\n" << B << endl;
	B=sparseBottomLeftBlock(M,4,2);
	cout << "Here is the Bottom Left matrix B("
	<<B.rows()<<"x"<<B.cols()<<"):\n" << B << endl;
	
	B=sparseBottomRightBlock(M,3,2);
	cout << "Here is the Bottom Right matrix B("
	<<B.rows()<<"x"<<B.cols()<<"):\n" << B << endl;
	
	B=sparseTopLeftBlock(M,6,2);
	cout << "Here is the Top Left matrix B("
	<<B.rows()<<"x"<<B.cols()<<"):\n" << B << endl;
	
	B=sparseTopRightBlock(M,2,4);
	cout << "Here is the Top Right matrix B("
	<<B.rows()<<"x"<<B.cols()<<"):\n" << B << endl;
	
	return 0;
}
--
Alberto Minetti