Re: [eigen] Eigen::Block to Eigen::MatrixBase conversion problem |
[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]
Dear All,
I'd like to write a class that takes a function and let this function
operate on matrices, or blocks of matrices including columns and rows..
Think of it like scipys LinearOperator, just that we can decide
on which part of a matrix we apply it.
In trying to implement this we struggled with a conversion problem, that we do not understand.
In essence it boils down to the following examples, which compiles fine as is, while it
fails to compile when -DFAIL is set. Note that for simplicity I only used lvalue calls, in
order to avoid lvalues vs. rvalues problems here.
In this example I define a functions `mulValue`that just multiplies the object with a given scalar.
In encapsulating it I'd like to call `mulValue`, that is expects an Eigen::MatrixBase<Eigen::Matrix>>,
with an Eigen::MatrixBase<Eigen::Block<Matrix>>, which fails to compiles.
I'm surprised by this, as I thought that this is the goal of MatrixBase, or did I misunderstand it?
In addition, is there a function declaration that allows me to do that? Possibly in a way that
allows me to set the manipulation function in python via pybind11?
#include <iostream>
#include <Eigen/Core>
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> Matrix;
/// L-Value call
template <typename Derived>
void mulValue(Eigen::MatrixBase<Derived>& m, const double s)
{
m *= s;
};
template <typename Derived>
class Manipulator
{
public:
Manipulator(){};
void set_manipulator(std::function<void(Eigen::MatrixBase<Derived>&, const double)> mulValue_l_)
{
f = mulValue_l_;
};
void apply(Eigen::MatrixBase<Derived>& m, const double s) ///< line 25
{
f(m, s);
};
private:
std::function<void(Eigen::MatrixBase<Derived>&, const double)> f;
};
int main()
{
Matrix testMatrix(3, 3);
testMatrix.setOnes();
auto B = testMatrix.block(0, 1, 3, 2);
/// functional approach works for matrices and blocks
mulValue(testMatrix, 2.0);
mulValue(B, 3.0);
std::cout << testMatrix << std::endl << std::endl;
/// init Maipulator with class
Manipulator<Matrix> m;
m.set_manipulator(mulValue<Matrix>);
/// works fine on matrices
std::cout << "testMatrix before m:\n" << testMatrix << std::endl << std::endl;
m.apply(testMatrix, 3.0);
std::cout << "testMatrix after m:\n" << testMatrix << std::endl << std::endl;
/// works for Blocks
Manipulator<Eigen::Block<Matrix>> mB;
mB.set_manipulator(mulValue<Eigen::Block<Matrix>>);
std::cout << "testMatrix before: mB\n" << testMatrix << std::endl << std::endl;
mB.apply(B, 2.0);
std::cout << "testMatrix aftermpl:\n" << testMatrix << std::endl << std::endl;
#ifdef FAIL
/// fails for Blocks
std::cout << "testMatrix before m:\n" << testMatrix << std::endl << std::endl;
m.apply(B, 2.0); ///< line 65
std::cout << "testMatrix after m:\n" << testMatrix << std::endl << std::endl;
#endif
return 0;
}
Compiling with -DFAIL leads to
block.C: In function ‘int main()’:
block.C:65:13: error: cannot convert ‘Eigen::Block<Eigen::Matrix<double, -1, -1>, -1, -1, false>’ to ‘Eigen::MatrixBase<Eigen::Matrix<double, -1, -1> >&’
65 | m.apply(B, 2.0); ///< line 65
| ^
| |
| Eigen::Block<Eigen::Matrix<double, -1, -1>, -1, -1, false>
block.C:25:48: note: initializing argument 1 of ‘void Manipulator<Derived>::apply(Eigen::MatrixBase<Derived>&, double) [with Derived = Eigen::Matrix<double, -1, -1>]’
25 | void apply(Eigen::MatrixBase<Derived>& m, const double s)
|
Best regards,
Peter
Mail converted by MHonArc 2.6.19+ | http://listengine.tuxfamily.org/ |