This forum has been archived. All content is frozen. Please use KDE Discuss instead.

concatenate two sparse matrices

Tags: None
(comma "," separated)
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

concatenate two sparse matrices

Wed Jul 18, 2012 1:47 pm
Hi,

I would like to concatenate two sparse matrices or sparse+dense matrices like as follows as in matlab.

A=sparse(A);
B=sparse(B);
C = [A; B]

A=sparse(A);
B=full(B);
C= [A; B]

is there any way ?
thanks in advance.

Best Regards,
Yeonchool Park
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

Re: concatenate two sparse matrices

Fri Jul 20, 2012 10:08 am
nobody knows ? :-(
please somebody help me.
User avatar
dzenanz
Registered Member
Posts
35
Karma
0
OS

Re: concatenate two sparse matrices

Fri Jul 20, 2012 1:45 pm
Probably something like this should work:
Code: Select all
matrix c(w1+w2,h);
c.submatrix(0,0,w1,h)=a;
c.submatrix(w1,0,w2,h)=b;

But the exact syntax is obviously wrong (parameter order etc). I am not an expert for Eigen.
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

Re: concatenate two sparse matrices

Fri Jul 20, 2012 1:51 pm
Thanks dzenanz,

However, unfortunately, Eigen sparse seems not to support yet block assignment. that's the problem.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: concatenate two sparse matrices

Fri Jul 20, 2012 9:19 pm
You can do it manually:

C.resize(A.rows, A.cols()+B.cols());
C.middleCols(0,A.cols()) = A;
C.middleCols(A.cols(),B.cols()) = B;

If B is dense, then call B.sparseView() to remove the explicit zeros.
zoharl
Registered Member
Posts
55
Karma
0
OS

Re: concatenate two sparse matrices

Sat Jul 21, 2012 8:42 am
And you know, writing a block copy function should be quite simple. Just two canonical loops to iterate and copy the block.
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

Re: concatenate two sparse matrices

Sat Jul 21, 2012 9:16 am
Thanks ggael,

I will try your approach. it looks nice. :)
I didn't know that Eigen has this kind of function. where can I find this kind of information ? from Classes pages ?
I am not used to reading Classes pages.

Yeonchool

ggael wrote:You can do it manually:
C.resize(A.rows, A.cols()+B.cols());
C.middleCols(0,A.cols()) = A;
C.middleCols(A.cols(),B.cols()) = B;
If B is dense, then call B.sparseView() to remove the explicit zeros.
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

Re: concatenate two sparse matrices

Sat Jul 21, 2012 9:30 am
Thanks zoharl,

however I doubted the performance of my implementation because I need quite fast performance.
so, if Eigen had any function, I believed it could be more faster than my implementation.
from now on, I am going to check Eigen source code too to see if there is possibility of improving performance.

have a nice weekend ;)
zoharl wrote:And you know, writing a block copy function should be quite simple. Just two canonical loops to iterate and copy the block.
User avatar
fearhope
Registered Member
Posts
20
Karma
0
OS

Re: concatenate two sparse matrices

Sat Jul 21, 2012 12:45 pm
Hi ggael,

I tested your approach. and, it works. however it has two weird things.

First, when I added reserve function, no values were assigned in the matrix(nonzeros() = 0) while it worked well without the function.
it seems to be a bug.
Code: Select all
   SpMat B(4, MGr+WUr);   //SpMat B=[Z;WU]   Z: null matrix (MGr x 4)
   B.reserve(Eigen::VectorXi::Constant(B.outerSize(), WU.nonZeros()/B.outerSize()));             //  <-- this line
   B.middleCols(MGr, WUr) = ((WU.transpose()).eval()).sparseView();     // I couldn't use middleRows() because B is a column-major matrix
   B = (B.transpose()).eval();

Second, speed.
computation time was slower than copying each element like as follows (2ms: the below code vs. 8ms: the above code).
I think it is caused by transpose() and sparseView() function.
Code: Select all
   for (int kA=0; kA<WU.outerSize(); ++kA)
   {
      for (Eigen::MatrixXf::InnerIterator itA(WU,kA); itA; ++itA)
      {
         const unsigned int   iA = itA.row(),    jA = itA.col();
         B.insert(iA+WUr,jA) = itA.value();
      }
   }

[Question] is it possible to copy one rows or one cols of Eigen matrix by using memcpy function ?

Best Regards,
Yeonchool

ggael wrote:You can do it manually:
C.resize(A.rows, A.cols()+B.cols());
C.middleCols(0,A.cols()) = A;
C.middleCols(A.cols(),B.cols()) = B;
If B is dense, then call B.sparseView() to remove the explicit zeros.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: concatenate two sparse matrices

Sat Jul 21, 2012 9:16 pm
oh, I did not see that you wanted a vertical arrangement. Then you indeed need to do it with a manual for loop. Sparse transposition is expensive.

Also note that reserve only reserve memory. It does not create nonzeros.

However, I have some doubts about what you are trying to achieve. What's the point of inserting a dense matrix into a sparse representation? If you can, I would rather try to keep them separated even if that complexify a little the rest of the code. Dense representations are an order of magnitude faster than sparse one (unless the matrix is big and very sparse of course).
davidwang
Registered Member
Posts
12
Karma
0

Re: concatenate two sparse matrices

Wed Jan 29, 2014 8:16 pm
Interesting. I want to solve a similar problem, but
cannot even find the middleCols() as well as the other block matrix operation
functions under SparseMatrix class.

I am using the most recent eigen package.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: concatenate two sparse matrices

Thu Jan 30, 2014 8:38 am
You won't find them in the SparseMatrix.h file, but if you are using Eigen3.2, then they are accessible and documented: http://eigen.tuxfamily.org/dox/classEig ... atrix.html.

Make sure you are including Eigen 3.2 headers and not another one.
davidwang
Registered Member
Posts
12
Karma
0

Re: concatenate two sparse matrices

Thu Jan 30, 2014 4:47 pm
Thank you for the reply, but it is still not clear to me how to get access to those block functions.

The following is a simple test code I just wrote. I also use -I to include /users/dwang/eigen/.
I thought I should be able to use sm.block(..) after sm is declared, but I cannot,. sm does not
have have that function. Anything else should I do? Thanks!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
#include <iostream>
#include <Eigen/Sparse>
#include <Eigen/Eigen>
#include <Eigen/Core>

using namespace Eigen;
using namespace std;
typedef Eigen::SparseMatrix<double> SpMat;

int main(int argc, char ** argv)
{
SpMat sm (100,100);
//I hope to call sm.block(...) here, but sm does not have block(...)
}
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS

Re: concatenate two sparse matrices

Sat Feb 01, 2014 9:26 am
Try this:
Code: Select all
#include <Eigen/Sparse>

#if EIGEN_MAJOR_VERSION<2
#error wrong eigen version
#endif

typedef Eigen::SparseMatrix<double> SpMat;

int main(int argc, char ** argv)
{
  SpMat A(100,100), B;
  B = A.block(10,10,10,10);
}
davidwang
Registered Member
Posts
12
Karma
0

Re: concatenate two sparse matrices

Fri Feb 07, 2014 2:56 am
Ah, I found that even though that function is not visible under eclipse,
the program still runs without any issue.

problem solved!


Bookmarks



Who is online

Registered users: Bing [Bot], claydoh, Google [Bot], rblackwell