2
votes

I recently updated to recent Eigen version (3.3.90) and it looks like it broke stuff I though was working before (prior that I was using an Eigen version 3.2.10 shipped with the libigl library).

I would like to store the result of a block into a ref object that will be passed around and ultimately used to update the internals of the matrix form which the block was extracted.

A minimal example which does not compile anymore:

#include <Eigen/Dense>

int main(int argc, char *argv[])
{
  typedef Eigen::Matrix<bool, Eigen::Dynamic, 1> Mtype;
  typedef Eigen::Block<Mtype> Btype;
  typedef Eigen::Ref<Mtype> Rtype;
  Mtype m(2, 1);
  Btype bm = m.block(0, 0, 1, 1);
  Rtype rm = m; // OK
  Rtype rbm = bm; // Visual studio 2017 error C2440: 'initialisation' : impossible conversion
}

Note that the const version does work, I think this is due to the specialization of Ref for const which recreates a temporary copy:

typedef Eigen::Ref<const Mtype> CRtype;
CRtype crbm = bm; // OK

Similarly using a Matrix type with both number of rows and cols Dynamic, also compiles:

typedef Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic> Mtype;
typedef Eigen::Block<Mtype> Btype;
typedef Eigen::Ref<Mtype> Rtype;
Mtype m(2, 1);
Btype bm = m.block(0, 0, 1, 1);
Rtype rbm = bm;

Any clues?

Thanks a lot!

Best regards,

Jerome

2
Sorry, It was in french : ) anyway it said the conversion from Btype to Rtype was impossible. Switching to an oldest Eigen version did the trick.jerome

2 Answers

2
votes

My previous answer was too fast in its conclusion. This is now fixed: https://bitbucket.org/eigen/eigen/commits/cacb7b4ace39/

Nonetheless, it's still better to keep compile-time vector as compile-time vectors. This information is lost by Block<VectorXd> (and m.block(0, 0, 1, 0)) because it might have 1 or 0 column at runtime, e.g.:

Block<VectorXd> bm = m.block(0, 0, 1, 0);

is perfectly fine. So in your case, I would still recommend to preserve this information, e.g.:

auto bm = m.segment(0,1);
auto bm = m.block(0,0,1,fix<1>);       // fix is new in Eigen 3.4
auto bm = m.block<Dynamic,1>(0,0,1,1); // <3.4 version of the above cleaner line

This is a typical situation where you should really use auto. You can also directly initialize the Ref, e.g.:

Ref<MType> rm = m.segment(0,1);
0
votes

Eigen version 3.3.90 is a development branch and things there may be broken. Using the latest stable release (3.3.7) solves this issue. That being said, you can file a bug report with the Eigen devs to ensure that this is noticed (although, by the time you do, they'll likely have seen this post).