Eigen gotcha: aliased copy of SparseMatrix results in empty matrix

Alec Jacobson

March 24, 2012

weblog/

Found out the hard way today that you can't copy an Eigen sparse matrix onto itself (i.e. you cannot issue A=B, where A and B are references to the same sparse matrix. The result is that both A and B end up empty. Here's a self-compiling snippet that shows what happens:
#!/bin/bash
/*/../bin/ls >/dev/null
# BEGIN BASH SCRIPT
printf "//" | cat - $0 | g++ -g -o .main -x c++ - -I/opt/local/include/eigen3/ -I/opt/local/include/eigen3/upsupported  && ./.main
rm -f .main
# END BASH SCRIPT
exit
*/
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include <Eigen/Sparse>

int main(int argc, char** argv)
{
  using namespace std;
  using namespace Eigen;
  SparseMatrix<double> I(2,2);
  I.insert(0,0) = 1;
  I.insert(1,1) = 1;
  I.finalize();
  cout<<"I.nonZeros(): "<<I.nonZeros()<<endl;
  SparseMatrix<double> Icopy;
  cout<<"Icopy=I"<<endl;
  Icopy = I;
  cout<<"I.nonZeros(): "<<I.nonZeros()<<endl;
  cout<<"Icopy.nonZeros(): "<<Icopy.nonZeros()<<endl;
  cout<<"I=I"<<endl;
  I = I;
  cout<<"I.nonZeros(): "<<I.nonZeros()<<endl;
}
Which produces:
I.nonZeros(): 2
Icopy=I
I.nonZeros(): 2
Icopy.nonZeros(): 2
I=I
I.nonZeros(): 0