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/