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

Rank of zero matrix using SparseQR

Tags: None
(comma "," separated)
eteufl
Registered Member
Posts
5
Karma
0
OS

Rank of zero matrix using SparseQR

Fri Oct 17, 2014 10:08 pm
More or less by accident I computed the rank of a zero matrix using SparseQR. The result is surprising:
Code: Select all
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/Sparse>

using namespace std;
using namespace Eigen;

int main() {
   MatrixXd m=MatrixXd::Zero(2,2);
   cout << m << endl;
   cout << "rank=" << m.fullPivHouseholderQr().rank() << endl;
   SparseMatrix<double> sm = m.sparseView();
   cout << sm << endl;
   SparseQR<SparseMatrix<double>, Eigen::COLAMDOrdering<int> > sqr;
   sqr.compute(sm);
   if(sqr.info()==Success) cout << "rank=" << sqr.rank() << endl;
   else cout << sqr.lastErrorMessage() << endl;
}

This gives rank=0 using dense QR, but rank=2 for sparse QR. The rank of a zero matrix using SparseQR is always full! This is a (stupid) special case, but it would be nice to a correct result.

BTW, is there a possibility to print a sparse matrix but not the information about nonzero elemts etc? I searched the documentation without success. Also I searched for a format() for sparse matrices without success.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
The fix was easy:
https://bitbucket.org/eigen/eigen/commits/1b9354d43709/

To print a sparse matrix as a dense one, simply copy it to a dense one, like:

cout << MatrixXd(sm);
eteufl
Registered Member
Posts
5
Karma
0
OS
Thanks a lot for the fix. I really appreciate your help.

Concerning printing of a sparse matrix, conversion to a dense matrix is not always an option due to memory limits. At the moment, I use a little helper function to output a sparse matrix in my desired format by traversing the non-zero entries. A .format() would be nice to have for sparse matrices, too.
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Is it really useful to print a sparse matrix so big that its dense counter part would not fit in memory? How would you print it? list of pairs of value,col_id with a newline for each row?
eteufl
Registered Member
Posts
5
Karma
0
OS
In fact, I write the sparse matrix to a (compressed) file. It is written in the form of a dense matrix with a very simple "IOFormat" (no line breaks, no alignment). To be honest, my matrices would fit as dense matrices into the memory (although this would consume most of the memory). In order to do computations I create the matrices as sparse matrices. For communication with other software I need to write a "dense" representation to a file. It seems unnecessary to create a dense matrix object in memory just to output.
I also use a "dictionary" based representation for communication, i.e. a simple list of triplets in in the format "(row,col,entry)" with different kinds of prefix, suffix and two kinds of separators.
For both tasks I have small routines for the desired output which traverse the non-zero entries (and fill in the zeroes in the first case). BTW, is there an iterator which traverses all nonzero entries of a sparse matrix?

If m is a sparse matrix, cout << m yields, e.g.,
Nonzero entries:
(2,0) (1,1) (1,0) (1,1)

Outer pointers:
0 2 $

2 1
1 1
The indices of the nonzero entries are "strange", e.g. (2,0) should be (1,0)? By inspection of Eigen's source code, I found that
Code: Select all
cout << static_cast<const SparseMatrixBase<SparseMatrix<double> >&>(m)
prints this human readable form of a sparse matrix without conversion to a dense one. (Is there a shorter way to do this?) So, the output of a SparseMatrixBase has almost the form I use in the first case (up to specific prefix, suffix and separator).

Of course, other textual output formats for sparse matrices, like a textual representation of Eigen's internal representation or the one you mentioned, might be useful as well.

I'm just curious how to accomplish my tasks in a decent way (using the many nice features of Eigen).


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]