Skip to content

Map<SparseMatrix> broken if inner index is not sorted

Summary

Map<SparseMatrix> behaves strange when the inner index is not sorted. This is noticeable e.g. when printing the matrix or passing them to SparseMatrix::isApprox.

Environment

  • Operating System : Ubuntu 20.04.5
  • Architecture : x64
  • Eigen Version : 3.4.90
  • Compiler Version : clang 9.4.0
  • Compile Flags : -O3
  • Vector Extension : shouldn't be relevant

Minimal Example

#include <iostream>
#include <Eigen/SparseCore>

using Matrix = Eigen::SparseMatrix<int,Eigen::RowMajor>;

int main() {
    int rows = 1;
    int cols = 4;
    int nnz = 2;
    int outer[] = {0, nnz};
    int inner1[] = {1, 2};
    int inner2[] = {2, 1};

    // should be the same:
    Eigen::Map<Matrix> X(rows, cols, nnz, outer, inner1, inner1);
    Eigen::Map<Matrix> Y(rows, cols, nnz, outer, inner2, inner2);
    std::cout << X << Y;
}

godbolt

What is the current bug behavior?

Output:

0 1 2 0 
0 0 2 1 

What is the expected correct behavior?

Output:

0 1 2 0 
0 1 2 0 

Anything else that might help

The documentation of Map<SparseMatrix> refers to the storage layout of a SparseMatrix, which says:

Currently the elements of a given inner vector are guaranteed to be always sorted by increasing inner indices.

This seems to be assumed by some other algorithms accepting SparseCompressedBase or similar, causing that property (currently) to be a requirement for data passed to Map<SparseMatrix>. If this is intentional, as it is generally good for performance/data-locality, the documentation should be explicit about it (e.g. constructor of Map<SparseMatrix>).