Reputation: 41
I write a code segment:
Eigen::Matrix<float, 5, Dynamic> m(5, 5);
auto r = m.topRows<1>();
Eigen::Ref<Eigen::Matrix<float, 1, Dynamic>> r2(r)
That will cause a compile error:
error: no matching function for call to ‘Eigen::Ref<Eigen::Matrix<float, 1, -1> >::Ref(Eigen::Block<Eigen::Matrix<float, 5, -1>, 1, -1, false>&)’
46 | Eigen::Ref<Eigen::Matrix<float, 1, Dynamic>> r2(r);
But when I changed the code to:
Eigen::Matrix<float, 5, Dynamic> m(5, 5);
auto r = m.topRows<2>();
Eigen::Ref<Eigen::Matrix<float, 2, Dynamic>> r2(r)
Everything is ok.
I found the implement of block in eigen src may have a template specification when template arg row == 1
My question is:
How to walk around this case?
Upvotes: 2
Views: 38
Reputation: 18827
The problem you encounter is that Eigen consider Matrices which have one dimension equal to 1 at compile time as vectors (IsVectorAtCompileTime==true
). Therefore, the top row of a (column major) matrix is actually like a vector with inner stride (equal to the number of rows of the original matrix).
You can either make your matrices and Ref
s rowmajor,
Eigen::Matrix<float, 5, Eigen::Dynamic, Eigen::RowMajor> m(5,5);
auto r = m.topRows<1>();
Eigen::Ref<Eigen::Matrix<float, 1, Eigen::Dynamic, Eigen::RowMajor> > r2(r);
Or you need to allow Ref
to have a dynamic inner stride, if it only has one row:
Eigen::Matrix<float, 5, Eigen::Dynamic> m(5,5);
auto r = m.topRows<1>();
Ref<Eigen::Matrix<float, 1, Eigen::Dynamic>, Eigen::InnerStride<> > r2(r);
You can define yourself an alias for the latter, e.g.,
template<class Scalar, int Rows, int Cols, int Options=0>
using BlockRef = Eigen::Ref<Eigen::Matrix<Scalar, Rows, Cols>, Options,
typename Eigen::internal::conditional<Rows==1,Eigen::InnerStride<>,Eigen::OuterStride<> >::type>;
Then use it like:
BlockRef<float, 1, Eigen::Dynamic> r3(r);
Upvotes: 1