[eigen] Eigen::Block to Eigen::MatrixBase conversion problem |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: [eigen] Eigen::Block to Eigen::MatrixBase conversion problem
- From: Peter <list@xxxxxxxxxxxxxxxxx>
- Date: Fri, 3 Feb 2023 13:53:06 +0100
- Ui-outboundreport: notjunk:1;M01:P0:oW5Ni+i9dYA=;ZtIC4Dq2wo+xb+pYYdTWavaO6Kd aaEagi7vec4h8vS8f5z/bVoAAG9SXtrq1nmnZVFq1q5zHQcpWPXoOyF8Oxamzwi1PY2LVH9xN sECuxmzoyRRbJNWLF5Ev0ktt5NCsEc7zPcGqFxbqWroI0VDQG5N4cCoeOOvYpirnMiLTCruDR vV5eYn0ZFHL46z+mA2YA/yAIDSthbwCj53J2BCIQXYt71Z/78sbi45o7Mg/WA4AabRPb0po5a eRW9U2+FoQ/VV6Kgyqjbizd+JBD/IDU/rDXOCwl6Xezo4541lGWNd5yLxixNeqVZvPr7ASvng iGKE9R4syApDyGlpPJXOd1T1s/UGViYwGliudVR26ennreGIj4AO7QlM4cHWGz6UKWcyZggGQ copW+LZaz12T9B0PRv2fNIhnr0GK9qAYzDz/+v/6HIMQ8W6Y10MLwuw7zHBeSz1hNEhfYmH2X Cg3yldPegQ7FTmHql5zPKrFazaO5RPMslxQGLCIJy+f+YtKkDHJP0Dc97rePGYeGkA5X0rF0h 0VUE4o/iKI8CXwSXkue/MWTlKcQYn7X6gvcF5Bzfa/a/LnIwPl/v56+z6vFNZDfIrAqmcpW/J CiI0thl+6FXtY5YJ5IbZwDhiulcFMrvK/Itv3KSHA6H5Ov4MYEze6bsk+NSaMtnDhVJHLZTTW qHvEkNlin4W5UePjJ1tih6Z4pixHldBnWheq38Yovw==
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