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

[SOLVED] Sparse Matrix cwise() operations, coeff()

Tags: None
(comma "," separated)
captaincurk
Registered Member
Posts
4
Karma
0
Hello,

congratulations for creating this amazing library! I am currently writing my Bachelor's Thesis, which includes a very fast SVD Algorithm and I have just switched over from ublas :) Now I have a couple of questions/comments

1. Why does cwise() for Sparse Matrices not offer functions like log()? I suppose it would be easy to implement :/ Why is it generally not possible to use arbitrary functions on cwise() representations?

2. What is a faster way to overwrite/update a cell from a sparse matrix other than creating an iterator and changing valueRef()? Why can't I use coeff() to write to my Sparse Matrix, if I know, that I have written to that cell before?

3. Somewhat unrelated: How can I reserve memory for a matrix and subsequently fill it up by adding rows or columns? I know in advance, how large the matrix will be and I need to resize it, wthout losing or allocating memory. I was thinking of something like this:
Code: Select all
MatrixXf data;
data.reserve(max_rows. max_cols);
data.resize(1);

// during the algorithm i will simply do
data.resize(n,m); // for n<max_rows, m<max_cols
// no elements should be moved and no memory allocated


Performance is really the most important issue for me, so I dont like the thought of using proxy-objects like in boost::ublas. I guess this would work, if the matrix knew the maximum size in the beginning, so it could store the elements at their correct positions. Is something like that possible? In other words, I want to implement a Matlab like access of data(1:2,1:4) inside a much larger matrix.

Unfortunately I have only just started diving into C++ I can't really help you out with the implementation. But will gladly contribute my linear-time thin-SVD implementation for Sparse matrices.

Thank you and kind regards,

Jonas
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
1. Why does cwise() for Sparse Matrices not offer functions like log()? I suppose it would be easy to implement :/ Why is it generally not possible to use arbitrary functions on cwise() representations?


because 1) this is not automatic! and 2) I've currently added only safe cwise functions, i.e., functions f for which f(0) = 0. I'm still not sure what to do with others. Perhaps putting them in a "nonzeros()" namespace, e.g. mat.nonzeros().log() ??

2. What is a faster way to overwrite/update a cell from a sparse matrix other than creating an iterator and changing valueRef()? Why can't I use coeff() to write to my Sparse Matrix, if I know, that I have written to that cell before?


if you want to modify several values the fastest way is indeed to use an iterator. If you want to modify random coeffs, then use mat.coeffRef(i,j) = ...

3. Somewhat unrelated: How can I reserve memory for a matrix and subsequently fill it up by adding rows or columns? I know in advance, how large the matrix will be and I need to resize it, wthout losing or allocating memory. I was thinking of something like this:
Code: Select all
MatrixXf data;
data.reserve(max_rows. max_cols);
data.resize(1);

// during the algorithm i will simply do
data.resize(n,m); // for n<max_rows, m<max_cols
// no elements should be moved and no memory allocated


Performance is really the most important issue for me, so I dont like the thought of using proxy-objects like in boost::ublas. I guess this would work, if the matrix knew the maximum size in the beginning, so it could store the elements at their correct positions. Is something like that possible? In other words, I want to implement a Matlab like access of data(1:2,1:4) inside a much larger matrix.


good idea to extend reserve() with the matrix sizes. currently, reserve is only for the nonzeros. About submatrices, this will be implemented via efficient proxies, however all operations on submatrices cannot be implemented efficiently because of the way sparse matrices are stored. The main problem is not to know the max dimensions but rather to know the nonzeros pattern in advance. I recommend you to generate the API doc from svn-trunk and take a look at the sparse tutorial. Currently you can only pick a set of rows or cols but it is planed to add more flexibility. Any help is more than welcome !

Unfortunately I have only just started diving into C++ I can't really help you out with the implementation. But will gladly contribute my linear-time thin-SVD implementation for Sparse matrices.


that would be awesome !
captaincurk
Registered Member
Posts
4
Karma
0
Thanks for your quick reply!

ggael wrote:good idea to extend reserve() with the matrix sizes. currently, reserve is only for the nonzeros. About submatrices, this will be implemented via efficient proxies, however all operations on submatrices cannot be implemented efficiently because of the way sparse matrices are stored. The main problem is not to know the max dimensions but rather to know the nonzeros pattern in advance. I recommend you to generate the API doc from svn-trunk and take a look at the sparse tutorial. Currently you can only pick a set of rows or cols but it is planed to add more flexibility. Any help is more than welcome !


Now actually I meant dense matrices in my last question ;) I have found the block class in the Documentation, what does it do exactly? Is that something like an efficient proxy?

Edit: about the cwise() functions on sparse matrices. I cannot think of many situations when one has a Sparse matrix and wants to apply functions to the zero elements... I would recommend to have them operate on the nonzeroes. I don't believe that is too confusing, because whoever needs otherwise is not making efficient use of sparse storage anyway.

Another quick edit: i have just come across the stupid question, how I can convert a SparseInnerVectorSet& update_column to a regular dense vector?

Cheers, Jonas

Last edited by captaincurk on Sat Feb 14, 2009 5:34 pm, edited 1 time in total.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
captaincurk wrote:Thanks for your quick reply!

ggael wrote:good idea to extend reserve() with the matrix sizes. currently, reserve is only for the nonzeros. About submatrices, this will be implemented via efficient proxies, however all operations on submatrices cannot be implemented efficiently because of the way sparse matrices are stored. The main problem is not to know the max dimensions but rather to know the nonzeros pattern in advance. I recommend you to generate the API doc from svn-trunk and take a look at the sparse tutorial. Currently you can only pick a set of rows or cols but it is planed to add more flexibility. Any help is more than welcome !


Now actually I meant dense matrices in my last question ;) I have found the block class in the Documentation, what does it do exactly? Is that something like an efficient proxy?



ah ! then, *yes* block is very efficient because it just the same thing than a plain matrix !

Edit: about the cwise() functions on sparse matrices. I cannot think of many situations when one has a Sparse matrix and wants to apply functions to the zero elements... I would recommend to have them operate on the nonzeroes. I don't believe that is too confusing, because whoever needs otherwise is not making efficient use of sparse storage anyway.


yes of course, but still, what about:

sparse_mat.cwise() += 1;

it is clear that does not make sense to add 1 to zero coeffs, but that might still be a bit confusing compared to:

sparse_mat.nonzeros() += 1;

anyway, that's just a very minor naming debate.

Another quick edit: i have just come across the stupid question, how I can convert a SparseInnerVectorSet& update_column to a regular dense vector?


hm, currently sparse_mat.row(i).toDense() should does the job but that might change in the future.


Bookmarks



Who is online

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