Bug 597 - Prune does not work as documented
Prune does not work as documented
Status: RESOLVED FIXED
Product: Eigen
Classification: Unclassified
Component: Sparse
3.1
All All
: Normal Unknown
Assigned To: Nobody
:
Depends on:
Blocks: 3.2
  Show dependency treegraph
 
Reported: 2013-05-08 15:15 UTC by Kolja Brix
Modified: 2013-06-10 13:11 UTC (History)
2 users (show)



Attachments
Test code for bugs in prune() method in sparse matrix (1.02 KB, text/x-c++src)
2013-05-08 15:15 UTC, Kolja Brix
no flags Details

Description Kolja Brix 2013-05-08 15:15:01 UTC
Created attachment 336 [details]
Test code for bugs in prune() method in sparse matrix

Pruning (deleting entries with an absolute value smaller than a threshold) sparse matrices does not work as documented, please see the test code attached.

The problem arises in version 3.1.6 and newer.

The documentation states (taken from current <http://eigen.tuxfamily.org/dox/TutorialSparse.html>):

***
The second algorithm prunes on the fly the explicit zeros, or the values smaller than a given threshold. It is enabled and controlled through the prune() functions:
sm3 = (sm1 * sm2).prune(); // removes numerical zeros
sm3 = (sm1 * sm2).prune(ref); // removes elements much smaller than ref
sm3 = (sm1 * sm2).prune(ref,epsilon); // removes elements smaller than ref*epsilon
***

But none of the three methods works, the code does not compile.
The compiler error is "'const Type' has no member named 'prune'" in all three cases. 


Moreover, calling the method prune for a SparseMatrix<double> does not work when no argument is specified, at least ref must be given.
The compiler error message is "no matching function for call to 'Eigen::SparseMatrix<double>::prune()'". 
I would like to propose to set the default value of ref to 1.0.


Furthermore, prune() seems to only work in-place. Would it be possible to provide also a version for assignment, e.g. "sm2 = sm1.prune();"?
Comment 1 Christoph Hertzberg 2013-05-08 16:41:35 UTC
Marked as blocking 3.2.

I guess the not in-place method should be called something like pruned() (cf. transpose() and transposed()).

Furthermore, I find the "removes elements much smaller than ref" behavior somewhat non-intuitive. 
I do see the use-case, but I would expect prune(threshold) to prune everything above threshold and not threshold*epsilon. But I guess we can't change that anymore.
Comment 2 Christoph Hertzberg 2013-05-08 16:46:20 UTC
(In reply to comment #1)
> I guess the not in-place method should be called something like pruned() (cf.
> transpose() and transposed()).

Please ignore the transpose()/transposed() part ...
But we do have normalize() vs normalized().
Comment 3 Gael Guennebaud 2013-06-10 13:07:32 UTC
This was just a typo in the tutorial. pruned() returns an expression, while prune() works inplace. I guess this close the bug:

https://bitbucket.org/eigen/eigen/commits/45129821f1d1/
Changeset:   45129821f1d1
User:        ggael
Date:        2013-06-10 12:03:55
Summary:     Fix bug 598: add explicit cast to Scalar type
Comment 4 Gael Guennebaud 2013-06-10 13:11:13 UTC
oops, the commit is:

https://bitbucket.org/eigen/eigen/commits/949ff6b4708e/
Changeset:   949ff6b4708e
User:        ggael
Date:        2013-06-10 12:13:31
Summary:     fix bug 597: typo in sparse documentation

Note You need to log in before you can comment on or make changes to this bug.