Skip to content

Incorrect sparse assignment from Map to SparseMatrix

Summary

The last element of the value array is set to zero when mapping from raw buffers (using column compressed storage) to a SparseMatrix (Map -> SparseMatrix).

Environment

  • Operating System : macOS Big Sur 11.7
  • Architecture : x64
  • Eigen Version : 3.3.9
  • Compiler Version : clang 12.0.5
  • Compile Flags : irrelevant
  • Vector Extension : none

Minimal Example

#include "Eigen/Sparse"
#include <iostream>

int main()
{
    /** create a 3x3 diagonal matrix (with {1,2,3} on the diagonal) using column compressed storage format. */
    int* outter = new int [3];
    int* inner  = new int [3];
    double* values = new double [3];

    outter[0] = 0; outter[1] = 1; outter[2] = 2;
    inner[0] = 0; inner[1] = 1; inner[2] = 2;
    values[0] = 1; values[1] = 2; values[2] = 3;

    Eigen::SparseMatrix<double> mat = Eigen::Map<Eigen::SparseMatrix<double>>(3,3,3,outter,inner,values);
    std::cout << mat << "\n";

    return 0;
}

Steps to reproduce

  1. Compile and run the minimal example.
  2. Observe the output:
1 0 0 
0 2 0 
0 0 0 
  1. The correct output should be:
1 0 0 
0 2 0 
0 0 3 

What is the current bug behavior?

The last element of the value array is replaced by zero (0), perhaps, during the sparse assignment. In this example, a temporary object is also created during the assignment, whereas it should not? I could not track down where exactly this happens but the Map object is created correctly.

What is the expected correct behavior?

We should see:

1 0 0 
0 2 0 
0 0 3 

The values array of mat should contain {1,2,3}, instead it is {1,2,0}.