Registered Member
|
Hi,
I need to compute kronecker product matrix. so, I coded like as follows. however, its speed is quite slow. it consumes around 25000 ms (size of matrix M is 69756 x 6319 (sparse) and the value of nonzeros() is 69756, G: 4x4 sparse matrix). could you let me know why ? is there a problem or a mistake ? when I tested this in Matlab, it took around 800 ms for 48760 non-zeros. it's weird.
if you have any idea to speed-up the code, any comments are welcome. Thanks in advance.. Cheers! Yeonchool. |
Registered Member
|
|
Moderator
|
What if you change line 56 of unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h to:
AB.reserve(VectorXi::Constant(AB.outerSize(), A.nonZeros()*B.nonZeros()/AB.outerSize())); |
Registered Member
|
Thanks ggael,
I already tested "reserve" function. however its improvement is not sufficient to me. it still consumes 8 sec for the same routine even though it is 3 times faster than previous method, from 25 sec. so, I changed my plan to compute Kronecker product. I used Eigen's Triplet for multiplication. after all, its performance is amazing ! it took only 20 ms. it is 400 times faster. the code is as follows.
I think Eigen sparse still has more possibilities to improve and optimize performance. anyway thanks a lot ggael ! I thought that nobody cares my post. always appreciate your help. Yeonchool. |
Registered Member
|
Please excuse. I do not know any of your original problem *) but nevertheless or because of this I'm perplexed by some things:
a) A "4x4 sparse Matrix" : Is'nt that a contratiction in it self? b) "G.setIdentity();" => " float value = triplet_vec[i].value(); MGv.push_back(T(ri, ci, value )); MGv.push_back(T(ri+1, ci+1, value )); MGv.push_back(T(ri+2, ci+2, value )); MGv.push_back(T(ri+3, ci+3, value )); " should suffice?! c) |
Registered Member
|
actually, G is not a real identity matrix. it's diagonal but, last element is not 1. i.e., G is actually diag(1,1,1,r).
so, b) is not sufficient for my problem. however when it is only limited to my problem, you are right. of course, last element can be changed to like MGv.push_back(T(ri+3, ci+3, value*r )); and, what if G is not a diagonal matrix ? of course, the for-loop should be changed again.
|
Moderator
|
I see, you have a special case with only one element per row.
|
Registered Member
|
Hi, I am also experiencing that the Kronecker product for sparse matrices is (very) slow (I am using Eigen 3.2.0). It seems to be increasingly slow for large matrices. I suspect that it is entirely due to the poor estimation of the number of non-zeros. ggael suggests to change the reserve-statement to:
I suggest to compute the exact number non-zeros by iterating over the A and B matrix. This requires minimal overhead and will always ensure that enough memory is allocated. I have tested this on a small set of matrices with varying sizes and it performs very well. To serve as an example I have included a simple, but working "pseudo code" below. I am sure the code can be improved. Regards, Bjarne
|
Moderator
|
|
Registered Member
|
Hi,
I used your updated version (2014-02-14) of KroneckerProductSparse() with DynamicSparseMatrices. The compiler remarks the way how reserve() is used with error: no matching function for call to reserve(Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1> >::MapType) Details see KroneckerTensorProduct.h:177:5 dst.reserve(VectorXi::Map(nnzAB.data(), nnzAB.size())); instead of void reserve(Index reserveSize = 1000) Is this reproducible from your side? -- Martin |
Registered users: Baidu [Spider], Bing [Bot], Google [Bot], rblackwell