875
2014-09-12 11:25:01 +0000
SparseMatrixBase<Derived>::nonZeros() is broken for most types of Derived
2019-12-04 13:42:50 +0000
1
1
1
Unclassified
Eigen
Sparse
3.3 (current stable)
All
All
RESOLVED
FIXED
Highest
Crash
---
558
1
metronware
eigen.nobody
chtz
gael.guennebaud
oldest_to_newest
3817
0
metronware
2014-09-12 11:25:01 +0000
The call to nonZeros() on a SparseSparseProduct object leads to an infinite recursion smacking the stack. This can be seen by running valgrind with the verbose "-v" parameter on the following example:
---------------------
#include "Eigen/SparseCore"
#include <iostream>
using namespace Eigen;
typedef SparseMatrix<double, ColMajor> SpMat;
int main(int argc, char **argv)
{
const int m = 3;
SpMat A(m,m);
A.insert(0,0) = 1.0;
A.insert(1,1) = 2.0;
A.insert(2,2) = 3.0;
A.makeCompressed();
SpMat B(m,m);
B.insert(0,0) = 1.0;
B.insert(1,1) = 2.0;
B.insert(2,2) = 3.0;
B.makeCompressed();
int nnz = (A * B).nonZeros();
std::cout << nnz << std::endl;
}
---------------------
3938
1
chtz
2014-10-14 13:22:42 +0000
Another thing that is broken is TriangularView<SparseMatrix>.
This leads to an infinite recursion in many sparse_product unit tests.
Strangely, clang++ optimizes away the recursion if compiled with optimization enabled and returns -1 (maybe that value is just by accident). With optimization, g++ generates a trivial infinite loop, leading to a time-out in the unit-tests.
Are there any cases except SparseMatrix<>, (and maybe Map<SparseMatrix>, Transpose<SparseMatrix>) where nonZeros() can be determined directly? I.e. does it make sense to provide a nonZeros() from SparseMatrixBase?
3996
2
chtz
2014-10-28 13:33:36 +0000
I pushed a work-around to avoid the infinite recursion:
https://bitbucket.org/eigen/eigen/commits/9a59ef56ef
This make the sparse_product unit tests pass again.
We still need to decide if it makes sense to provide nonZeros() for other than "direct access" sparse matrices.
3999
3
gael.guennebaud
2014-10-28 17:26:47 +0000
Having an estimate of the nnz is really useful in sparse algorithms, even if it is not 100% accurate. Having nonZeros() be sometimes accurate and sometimes only an approximation is probably not very good. So, since this is essentially needed for evaluation purposes, this information could be carried out by evaluators. Evaluators should also be able to return a more accurate information when some sub-expressions are evaluated into temporaries.
4000
4
chtz
2014-10-28 17:49:29 +0000
Would it be too late to remove nonZeros() from SparseMatrixBase and only implement it for SparseMatrix (and Map<SparseMatrix>) directly (or maybe a common base class of them)?
I guess for all (?) other cases the only way to get the exact number of nonZeros basically requires to evaluate the expression.
nonZeros() has been in SparseMatrixBase at least since 2010, however it likely never worked correctly, other than for the "direct access" matrices.
Alternatively, we could deprecate it and/or let it static_assert if it is not implemented.
Regarding the approximated nnz, I guess we don't need to expose an estimateNonZeros() to the public interface, so implementing this as internal evaluator functionality sounds good to me.
4534
5
gael.guennebaud
2015-04-01 22:34:25 +0000
Removing the broken nonZeros() method from SparseMatrixBase is the only reasonable option.
https://bitbucket.org/eigen/eigen/commits/2c7c12495212/
Summary: Bug 875: remove broken SparseMatrixBase::nonZeros and introduce a nonZerosEstimate() method to sparse evaluators for internal uses.
Factorize some code in SparseCompressedBase.
9319
6
eigen.nobody
2019-12-04 13:42:50 +0000
-- GitLab Migration Automatic Message --
This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.
You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/875.