This is an implementation of a class containing a vector of Eigen Matrix plus the definition of the python binding.
#include <vector>
#include <pybind11/eigen.h>
#include <Eigen/Dense>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
namespace py = pybind11;
using EMatrixDbl = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic>;
class MyMap
{
public:
MyMap(int i, int j)
{
m_matrices.resize(1);
m_matrices[0].resize(i, j);
m_matrices[0].setZero();
}
EMatrixDbl& operator[](int k)
{
return m_matrices[k];
}
EMatrixDbl& get(int k)
{
return m_matrices[k];
}
std::vector<EMatrixDbl> m_matrices;
};
PYBIND11_MODULE(MyMapPy, m) {
py::class_<MyMap> c(m, "MyMap");
c.def(py::init<int, int>());
c.def("get", &MyMap::get, py::return_value_policy::reference_internal);
c.def("get_lambda", [](MyMap& self, int k){
EMatrixDbl& m_map = self[k];
return m_map;
}, py::return_value_policy::reference_internal);
}
When I use the binding, only the method get
allow to edit the matrix.
get_lambda
is not able to do the same?MyMap::operator[]
directly to provide a writeable interface of the binding?import MyMapPy
m = MyMapPy.MyMap(3, 3)
m.get(0)[0,0] = 1
m.get(0) # [0,0] is 1
m.get_lambda(0)[0,0] = 2
m.get_lambda(0) # [0,0] is always 1...
The lambda function return type is deduced to EMatrixDbl
not EMatrixDbl&
. Easiest fix is to specify the return type:
[](MyMap& self, int k) -> EMatrixDbl&
Result
>>> m.get_lambda(0)[0,0]=2
>>> m.get(0)
array([[2., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
A more general approach is to specify the return type as decltytpe(auto)
see this answer.