Yes, by default `Eigen::Ref` assumes the inner stride is 1 for efficiency. This is documented here <https://eigen.tuxfamily.org/dox/classEigen_1_1Ref.html>. You can specify a dynamic stride via
// Ref with dynamic stride. template<typename Derived> using StridedRef = Eigen::Ref<Derived, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>; https://godbolt.org/z/nWa9xbsa7 Though you may be better off copying the column to a vector with unit stride. On Sat, Feb 4, 2023 at 1:24 AM Peter <[email protected]> wrote: > Dear Antonio, > > Am 03.02.23 um 17:54 schrieb Antonio Sanchez: > > The `apply()` function has a different "Derived" type, which is why it > fails. MatrixBase<Matrix...> and MatrixBase<Block...> are two different > types. > > > > If you want a single manipulator like this that can take either a Matrix > or a Block, you need to use an Eigen::Ref<Matrix...> (passed by value). > See https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html > > <https://eigen.tuxfamily.org/dox/TopicFunctionTakingEigenTypes.html>. > > https://godbolt.org/z/ecxTxY1K5 <https://godbolt.org/z/ecxTxY1K5> > > > thanks for your advice and example. I had actually tried Eigen::Ref before > and failed. > So I took another look at it, and found that there is actually one edge > case, > that is failing, and I happened to test the on: < > https://godbolt.org/z/5xW8Y1sbE> > i.e. col() for RowMajor and a row() for a ColumnMajor Matrix fails for me. > > Now this is not a show stopper for my project, but I guess that's not > intended behaviour. > However the failure has some advantages, namely ruling out inefficient > code, > so this could be intended. > > Best regards > Peter > > > /// Here's the Ref version that fails with -DFAIL > > #include <iostream> > #include <Eigen/Core> > > typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, > Eigen::RowMajor> Matrix; > > /// Ref-Value call > template <typename Derived> > void mulValue_ref(Eigen::Ref<Derived> r, const double s) > { > r *= 1.0 / s; > }; > > template <typename Derived> > class Manipulator > { > public: > Manipulator(){}; > > void set_manipulator_ref(std::function<void(Eigen::Ref<Derived>, > const double)> mulValue_ref_) > { > fr = mulValue_ref_; > }; > > void apply_ref(Eigen::Ref<Derived> r, const double s) > { > fr(r, s); > }; > > private: > std::function<void(Eigen::Ref<Derived>, const double)> fr; > }; > > int main() > { > Matrix testMatrix(3, 3); > testMatrix.setOnes(); > auto B = testMatrix.block(0, 1, 3, 2); > > // ---------------- > // the Ref version > // ---------------- > > Manipulator<Matrix> m; > m.set_manipulator_ref(mulValue_ref<Matrix>); > m.apply_ref(testMatrix, 2.0); > m.apply_ref(B, 5.0); > m.apply_ref(testMatrix.block(0, 0, 2, 2), 2.0); > m.apply_ref(testMatrix.row(0), 0.1); > #ifdef FAIL > m.apply_ref(testMatrix.col(0), 0.2); > #endif > std::cout << "testMatrix after Refs:\n" << testMatrix << std::endl << > std::endl; > return 0; > } > > >
