10#include <pybind11/eigen.h>
11#include <pybind11/stl.h>
18# pragma warning(disable : 4127)
20# pragma warning(disable : 4996)
23#include <Eigen/Cholesky>
25using MatrixXdR = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
31 for (
int i = 0; i < x.rows(); i++) {
32 for (
int j = 0; j < x.cols(); j++) {
33 x(i, j) = 11 + 10 * i + j;
40 static Eigen::MatrixXd *x;
42 x =
new Eigen::MatrixXd(3, 3);
63double get_elem(
const Eigen::Ref<const Eigen::MatrixXd> &m) {
return m(2, 1); };
67template <
typename MatrixArgType>
69 Eigen::MatrixXd ret(m);
70 for (
int c = 0; c < m.cols(); c++) {
71 for (
int r = 0; r < m.rows(); r++) {
72 ret(r, c) += 10 * r + 100 * c;
81 Eigen::Matrix4d
a = Eigen::Matrix4d::Zero();
82 Eigen::Matrix4d
b = Eigen::Matrix4d::Identity();
88 using FixedMatrixR = Eigen::Matrix<float, 5, 6, Eigen::RowMajor>;
89 using FixedMatrixC = Eigen::Matrix<float, 5, 6>;
90 using DenseMatrixR = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
91 using DenseMatrixC = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>;
92 using FourRowMatrixC = Eigen::Matrix<float, 4, Eigen::Dynamic>;
93 using FourColMatrixC = Eigen::Matrix<float, Eigen::Dynamic, 4>;
94 using FourRowMatrixR = Eigen::Matrix<float, 4, Eigen::Dynamic>;
95 using FourColMatrixR = Eigen::Matrix<float, Eigen::Dynamic, 4>;
96 using SparseMatrixR = Eigen::SparseMatrix<float, Eigen::RowMajor>;
97 using SparseMatrixC = Eigen::SparseMatrix<float>;
100 m.def(
"double_col", [](
const Eigen::VectorXf &x) -> Eigen::VectorXf {
return 2.0f * x; });
102 [](
const Eigen::RowVectorXf &x) -> Eigen::RowVectorXf {
return 2.0f * x; });
103 m.def(
"double_complex",
104 [](
const Eigen::VectorXcf &x) -> Eigen::VectorXcf {
return 2.0f * x; });
105 m.def(
"double_threec", [](py::EigenDRef<Eigen::Vector3f> x) { x *= 2; });
106 m.def(
"double_threer", [](py::EigenDRef<Eigen::RowVector3f> x) { x *= 2; });
107 m.def(
"double_mat_cm", [](
const Eigen::MatrixXf &x) -> Eigen::MatrixXf {
return 2.0f * x; });
108 m.def(
"double_mat_rm", [](
const DenseMatrixR &x) -> DenseMatrixR {
return 2.0f * x; });
113 [](
const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd {
return x.llt().matrixL(); });
114 m.def(
"cholesky2", [](
const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {
115 return x.llt().matrixL();
118 [](
const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd {
return x.llt().matrixL(); });
119 m.def(
"cholesky4", [](
const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {
120 return x.llt().matrixL();
128 auto add_rm = [](Eigen::Ref<MatrixXdR> x,
int r,
int c,
double v) { x(r, c) += v; };
129 auto add_cm = [](Eigen::Ref<Eigen::MatrixXd> x,
int r,
int c,
double v) { x(r, c) += v; };
132 m.def(
"add_rm", add_rm);
133 m.def(
"add_cm", add_cm);
135 m.def(
"add1", add_rm);
136 m.def(
"add1", add_cm);
137 m.def(
"add2", add_cm);
138 m.def(
"add2", add_rm);
141 [](py::EigenDRef<Eigen::MatrixXd> x,
int r,
int c,
double v) { x(r, c) += v; });
144 m.def(
"get_cm_ref", []() {
return Eigen::Ref<Eigen::MatrixXd>(
get_cm()); });
145 m.def(
"get_rm_ref", []() {
return Eigen::Ref<MatrixXdR>(
get_rm()); });
147 m.def(
"get_cm_const_ref", []() {
return Eigen::Ref<const Eigen::MatrixXd>(
get_cm()); });
148 m.def(
"get_rm_const_ref", []() {
return Eigen::Ref<const MatrixXdR>(
get_rm()); });
155 [](Eigen::Ref<Eigen::MatrixXd> m,
double v) {
156 m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);
159 py::return_value_policy::reference);
164 [](py::EigenDRef<Eigen::MatrixXd> m,
double v) {
165 m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);
168 py::return_value_policy::reference);
173 [](py::EigenDRef<Eigen::MatrixXd> m) {
174 return py::EigenDMap<Eigen::MatrixXd>(
178 py::EigenDStride(m.outerStride(), 2 * m.innerStride()));
180 py::return_value_policy::reference);
185 [](py::EigenDRef<Eigen::MatrixXd> m) {
186 return py::EigenDMap<Eigen::MatrixXd>(
190 py::EigenDStride(2 * m.outerStride(), m.innerStride()));
192 py::return_value_policy::reference);
195 m.def(
"diagonal", [](
const Eigen::Ref<const Eigen::MatrixXd> &x) {
return x.diagonal(); });
197 [](
const Eigen::Ref<const Eigen::MatrixXd> &x) {
return x.diagonal<1>(); });
199 [](
const Eigen::Ref<const Eigen::MatrixXd> &x,
int index) {
return x.diagonal(index); });
203 [](
const Eigen::Ref<const Eigen::MatrixXd> &x,
207 int block_cols) {
return x.block(start_row, start_col, block_rows, block_cols); });
212 Eigen::MatrixXd mat = create();
217 static Eigen::MatrixXd create() {
return Eigen::MatrixXd::Ones(10, 10); }
219 static const Eigen::MatrixXd createConst() {
return Eigen::MatrixXd::Ones(10, 10); }
220 Eigen::MatrixXd &get() {
return mat; }
221 Eigen::MatrixXd *getPtr() {
return &mat; }
222 const Eigen::MatrixXd &view() {
return mat; }
223 const Eigen::MatrixXd *viewPtr() {
return &mat; }
224 Eigen::Ref<Eigen::MatrixXd>
ref() {
return mat; }
225 Eigen::Ref<const Eigen::MatrixXd> refConst() {
return mat; }
226 Eigen::Block<Eigen::MatrixXd> block(
int r,
int c,
int nrow,
int ncol) {
227 return mat.block(r, c, nrow, ncol);
229 Eigen::Block<const Eigen::MatrixXd> blockConst(
int r,
int c,
int nrow,
int ncol)
const {
230 return mat.block(r, c, nrow, ncol);
232 py::EigenDMap<Eigen::Matrix2d> corners() {
233 return py::EigenDMap<Eigen::Matrix2d>(
235 py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),
236 mat.innerStride() * (mat.innerSize() - 1)));
238 py::EigenDMap<const Eigen::Matrix2d> cornersConst()
const {
239 return py::EigenDMap<const Eigen::Matrix2d>(
241 py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),
242 mat.innerStride() * (mat.innerSize() - 1)));
245 using rvp = py::return_value_policy;
246 py::class_<ReturnTester>(m,
"ReturnTester")
248 .def_static(
"create", &ReturnTester::create)
249 .def_static(
"create_const", &ReturnTester::createConst)
250 .def(
"get", &ReturnTester::get, rvp::reference_internal)
251 .def(
"get_ptr", &ReturnTester::getPtr, rvp::reference_internal)
252 .def(
"view", &ReturnTester::view, rvp::reference_internal)
253 .def(
"view_ptr", &ReturnTester::view, rvp::reference_internal)
254 .def(
"copy_get", &ReturnTester::get)
255 .def(
"copy_view", &ReturnTester::view)
256 .def(
"ref", &ReturnTester::ref)
257 .def(
"ref_const", &ReturnTester::refConst)
258 .def(
"ref_safe", &ReturnTester::ref, rvp::reference_internal)
259 .def(
"ref_const_safe", &ReturnTester::refConst, rvp::reference_internal)
260 .def(
"copy_ref", &ReturnTester::ref, rvp::copy)
261 .def(
"copy_ref_const", &ReturnTester::refConst, rvp::copy)
262 .def(
"block", &ReturnTester::block)
263 .def(
"block_safe", &ReturnTester::block, rvp::reference_internal)
264 .def(
"block_const", &ReturnTester::blockConst, rvp::reference_internal)
265 .def(
"copy_block", &ReturnTester::block, rvp::copy)
266 .def(
"corners", &ReturnTester::corners, rvp::reference_internal)
267 .def(
"corners_const", &ReturnTester::cornersConst, rvp::reference_internal);
271 m.def(
"incr_diag", [](
int k) {
272 Eigen::DiagonalMatrix<int, Eigen::Dynamic> m(k);
273 for (
int i = 0; i < k; i++) {
274 m.diagonal()[i] = i + 1;
280 m.def(
"symmetric_lower",
281 [](
const Eigen::MatrixXi &m) {
return m.selfadjointView<Eigen::Lower>(); });
283 m.def(
"symmetric_upper",
284 [](
const Eigen::MatrixXi &m) {
return m.selfadjointView<Eigen::Upper>(); });
287 Eigen::MatrixXf mat(5, 6);
288 mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 14,
292 m.def(
"fixed_r", [mat]() -> FixedMatrixR {
return FixedMatrixR(mat); });
296 m.def(
"fixed_r_const", [mat]() ->
const FixedMatrixR {
return FixedMatrixR(mat); });
297 m.def(
"fixed_c", [mat]() -> FixedMatrixC {
return FixedMatrixC(mat); });
298 m.def(
"fixed_copy_r", [](
const FixedMatrixR &m) -> FixedMatrixR {
return m; });
299 m.def(
"fixed_copy_c", [](
const FixedMatrixC &m) -> FixedMatrixC {
return m; });
301 m.def(
"fixed_mutator_r", [](
const Eigen::Ref<FixedMatrixR> &) {});
302 m.def(
"fixed_mutator_c", [](
const Eigen::Ref<FixedMatrixC> &) {});
303 m.def(
"fixed_mutator_a", [](
const py::EigenDRef<FixedMatrixC> &) {});
305 m.def(
"dense_r", [mat]() -> DenseMatrixR {
return DenseMatrixR(mat); });
306 m.def(
"dense_c", [mat]() -> DenseMatrixC {
return DenseMatrixC(mat); });
307 m.def(
"dense_copy_r", [](
const DenseMatrixR &m) -> DenseMatrixR {
return m; });
308 m.def(
"dense_copy_c", [](
const DenseMatrixC &m) -> DenseMatrixC {
return m; });
310 m.def(
"sparse_r", [mat]() -> SparseMatrixR {
312 return Eigen::SparseView<Eigen::MatrixXf>(mat);
315 [mat]() -> SparseMatrixC {
return Eigen::SparseView<Eigen::MatrixXf>(mat); });
316 m.def(
"sparse_copy_r", [](
const SparseMatrixR &m) -> SparseMatrixR {
return m; });
317 m.def(
"sparse_copy_c", [](
const SparseMatrixC &m) -> SparseMatrixC {
return m; });
319 m.def(
"partial_copy_four_rm_r", [](
const FourRowMatrixR &m) -> FourRowMatrixR {
return m; });
320 m.def(
"partial_copy_four_rm_c", [](
const FourColMatrixR &m) -> FourColMatrixR {
return m; });
321 m.def(
"partial_copy_four_cm_r", [](
const FourRowMatrixC &m) -> FourRowMatrixC {
return m; });
322 m.def(
"partial_copy_four_cm_c", [](
const FourColMatrixC &m) -> FourColMatrixC {
return m; });
326 m.def(
"cpp_copy", [](py::handle m) {
return m.cast<Eigen::MatrixXd>()(1, 0); });
327 m.def(
"cpp_ref_c", [](py::handle m) {
return m.cast<Eigen::Ref<Eigen::MatrixXd>>()(1, 0); });
328 m.def(
"cpp_ref_r", [](py::handle m) {
return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });
330 [](py::handle m) {
return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });
341 [](
const Eigen::Ref<const Eigen::MatrixXd> &m) ->
double {
return get_elem(m); },
342 py::arg{}.noconvert());
345 "get_elem_rm_nocopy",
346 [](Eigen::Ref<
const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) ->
long {
349 py::arg{}.noconvert());
357 py::arg{}.noconvert());
359 &
adjust_matrix<
const Eigen::Ref<
const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>,
360 py::arg{}.noconvert());
366 m.def(
"iss1105_col", [](
const Eigen::VectorXd &) {
return true; });
367 m.def(
"iss1105_row", [](
const Eigen::RowVectorXd &) {
return true; });
373 [](
const py::EigenDRef<const Eigen::MatrixXd> &
A,
374 const py::EigenDRef<const Eigen::MatrixXd> &
B) -> Eigen::MatrixXd {
375 if (
A.cols() !=
B.rows()) {
376 throw std::domain_error(
"Nonconformable matrices!");
384 py::class_<CustomOperatorNew>(m,
"CustomOperatorNew")
393 m.def(
"get_elem_direct", [](
const Eigen::Ref<const Eigen::VectorXd> &v) {
394 py::module_::import(
"numpy").attr(
"ones")(10);
397 m.def(
"get_elem_indirect", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) {
398 py::module_::import(
"numpy").attr(
"ones")(10);
Reference counting helper.
void print_created(T *inst, Values &&...values)
void print_destroyed(T *inst, Values &&...values)
#define TEST_SUBMODULE(name, variable)
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
CustomOperatorNew()=default
Eigen::MatrixXd adjust_matrix(MatrixArgType m)
double get_elem(const Eigen::Ref< const Eigen::MatrixXd > &m)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MatrixXdR
Eigen::MatrixXd & get_cm()