Re: [eigen] Eigen::Block to Eigen::MatrixBase conversion problem |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Eigen::Block to Eigen::MatrixBase conversion problem
- From: Peter <list@xxxxxxxxxxxxxxxxx>
- Date: Sat, 4 Feb 2023 10:23:20 +0100
- Ui-outboundreport: notjunk:1;M01:P0:QRHkqMxqV3g=;w9sdqmvbEEREZqypXcYmgNbbINw iNnk9e/VKBFtpEPendvWFFeEyvrEE2o1Mwf7q7QE3t1/gUUb92hfnjSqu3To6GUY/j3h3zeqW r3Ijy1a3igib0N7Ctb9ueXAXvQUub4HwdAChkGnqJCr4FDPlk2VHTGk+V3/VJo++79uuPCigZ 7AF5teLVQSxr+7fhuLIykixOpaEYmPyRQ3gWOqr/IzySZBsOTekPpzZ3WfNinA+OMJW8JcjSs 2T26ESezka9FWjcjnQcyVv17HBtP2CYPXmlvqPIJlE5xTwQ1S7DlY4nqOPYoU1Fk/o/oX/seJ 8vzBqdLihSePxBHohz3gq6tbqISvpg24aKkDZK/j8EE+dzFZ/KcHsrsOgd4eU4Y3jtOTYfpXY MjUL4Pv3mkoGNwXijeV5ZhD2U+1EQSDM+GqPncuvm6DOIqsASsLWOC8DcIA/JcnETomfU/pAA fkheGjZUx9TrNzyAXPoJN2TGUhPERJfUZIAsD7s3AT1Ej/TNbwbWuwiEF6H1X/dJM1o+QjfYq vNsgstQC+SUcLPIbd3sq0QB6LDEVkvRHh9LoXMhljDkWLNRXrUFMi3ut3AilC8dmhmfYHYGZe Q5opdmf3timJvSAKQeOjz+LAPla+DldvNSHrsGwTrbXk3IgkFU+7Wy6iSKo0SgTwn7WGa7a5p 73hhHND96/i/po0fQvMeSnNgprEKolKDu3wRmQTv5Q==
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;
}