nicer example on instantiating Eigen matrices

This commit is contained in:
Wenzel Jakob 2016-05-05 10:04:44 +02:00
parent f1032df891
commit e762853bba
1 changed files with 13 additions and 11 deletions

View File

@ -863,26 +863,28 @@ objects (e.g. a NumPy matrix).
py::class_<Eigen::MatrixXd>(m, "MatrixXd") py::class_<Eigen::MatrixXd>(m, "MatrixXd")
.def("__init__", [](Eigen::MatrixXd &m, py::buffer b) { .def("__init__", [](Eigen::MatrixXd &m, py::buffer b) {
typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;
typedef Eigen::MatrixXd Matrix;
typedef Matrix::Scalar Scalar;
/* Request a buffer descriptor from Python */ /* Request a buffer descriptor from Python */
py::buffer_info info = b.request(); py::buffer_info info = b.request();
/* Some sanity checks ... */ /* Some sanity checks ... */
if (info.format != py::format_descriptor<double>::value) if (info.format != py::format_descriptor<Scalar>::value)
throw std::runtime_error("Incompatible format: expected a double array!"); throw std::runtime_error("Incompatible format: expected a double array!");
if (info.ndim != 2) if (info.ndim != 2)
throw std::runtime_error("Incompatible buffer dimension!"); throw std::runtime_error("Incompatible buffer dimension!");
if (info.strides[0] == sizeof(double)) { auto strides = Strides(
/* Buffer has the right layout -- directly copy. */ info.strides[Matrix::Flags & Eigen::RowMajorBit ? 0 : 1] / sizeof(Scalar),
new (&m) Eigen::MatrixXd(info.shape[0], info.shape[1]); info.strides[Matrix::Flags & Eigen::RowMajorBit ? 1 : 0] / sizeof(Scalar));
memcpy(m.data(), info.ptr, sizeof(double) * m.size());
} else { auto map = Eigen::Map<Matrix, 0, Strides>(
/* Oops -- the buffer is transposed */ (Scalar *) info.ptr, info.shape[0], info.shape[1], strides);
new (&m) Eigen::MatrixXd(info.shape[1], info.shape[0]);
memcpy(m.data(), info.ptr, sizeof(double) * m.size()); new (&m) Matrix(map);
m.transposeInPlace();
}
}); });
.. seealso:: .. seealso::