This bugzilla service is closed. All entries have been migrated to
Bug 1574 - Adding a diagonal matrix to a sparse matrix causes assertion failed
Summary: Adding a diagonal matrix to a sparse matrix causes assertion failed
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.4 (development)
Hardware: All All
: Normal Crash
Assignee: Nobody
Depends on:
Blocks: 3.4
  Show dependency treegraph
Reported: 2018-07-17 13:25 UTC by taroxd
Modified: 2019-12-04 17:48 UTC (History)
3 users (show)


Description taroxd 2018-07-17 13:25:55 UTC
I am not able to convert a diagonal matrix to sparse matrix. Nor can I add a diagonal matrix to sparse matrix.

For example, the code:
#include <Eigen/Dense>
#include <Eigen/Sparse>
int main() {
    int n = 10;
    SparseMatrix<double> A(n, n);
    A += VectorXd::Ones(n).asDiagonal();

The program stopped and outputs
Assertion failed: p!=Dynamic && "written coefficient does not exist", file path\to\eigen\src\sparsecore\sparsecompressedbase.h, line 312

This problem exists both in Version 3.3 and in git head (currently 991ece51446ebb9214393bed838879536c800fe2). The compiler used is Microsoft Visual Studio.

I am also surprised that I cannot find a method to view a diagonal matrix as a sparse matrix (method `sparseView` does not exist). In my opinion, viewing a triangular matrix as a sparse matrix should be trivial (at least simpler than viewing a dense matrix as a sparse matrix).

If that is not a bug, how could I update the diagonal of a sparse matrix, given that the coefficients at diagonal does not exist?
Comment 1 Christoph Hertzberg 2018-07-18 11:41:19 UTC
Not super-urgent, but should be fixable until 3.4.
A similar issue is Bug 610.
Comment 2 Gael Guennebaud 2018-10-08 21:07:30 UTC
This was on purpose and this limitation is documented:

Removing this limitation is not straightforward regarding the strategy to adopt regarding memory reallocation and copies.
Comment 3 Gael Guennebaud 2019-01-25 10:52:54 UTC
I implemented an evaluator for Diagonal* so that vec.asDiagonal().sparseView() can work. Sadly, this only works with column-major sparse matrices because mixing row and column major sparse expressions is not allowed, e.g.:

row_major_sparse += vec.asDiagonal().sparseView()

won't work because by default vec.asDiagonal() is seen as column-major expression. This is a pity because here we really don't care about the storage order. This could be handled through a "symmetric" bit flag stating that calling coeff(i,j) or coeff(j,i) is exactly the same.

Actually, we already have a similar problem with sparseView on dense expressions:

   row_major_sparse + col_major_dense.sparseView()

is not allowed though it could easily be accomplished as dense expressions can be traversed row-wise or column-wise. Here the fix would be more complicated as the col_major_dense.sparseView() would has to say "can be traversed in both direction", and the iterator should have to be instantiated with the chosen order.

In both cases, that's a lot of internal design changes, so not asDiagonal().sparseView() for 3.4.
Comment 4 Gael Guennebaud 2019-01-29 08:13:53 UTC
The code is quite sophisticated but it could be reused to implement smarter versions of SparseMatrix's =, +=, -= working in-place if possible.
Comment 5 Nobody 2019-12-04 17:48:39 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to'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:

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