Re: [eigen] Eigen::Block to Eigen::MatrixBase conversion problem |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
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;
}
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |