Wenzel Jakob | 9e0a056 | 2016-05-05 20:33:54 +0200 | [diff] [blame] | 1 | /* |
| 2 | example/eigen.cpp -- automatic conversion of Eigen types |
| 3 | |
| 4 | Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch> |
| 5 | |
| 6 | All rights reserved. Use of this source code is governed by a |
| 7 | BSD-style license that can be found in the LICENSE file. |
| 8 | */ |
| 9 | |
| 10 | #include "example.h" |
| 11 | #include <pybind11/eigen.h> |
Jason Rhinelander | 5fd5074 | 2016-08-03 16:50:22 -0400 | [diff] [blame] | 12 | #include <Eigen/Cholesky> |
Wenzel Jakob | 9e0a056 | 2016-05-05 20:33:54 +0200 | [diff] [blame] | 13 | |
Ben North | b063e64 | 2016-07-05 20:01:11 +0100 | [diff] [blame] | 14 | Eigen::VectorXf double_col(const Eigen::VectorXf& x) |
| 15 | { return 2.0f * x; } |
| 16 | |
| 17 | Eigen::RowVectorXf double_row(const Eigen::RowVectorXf& x) |
| 18 | { return 2.0f * x; } |
| 19 | |
Ben North | 3e0e779 | 2016-07-05 21:00:05 +0100 | [diff] [blame] | 20 | Eigen::MatrixXf double_mat_cm(const Eigen::MatrixXf& x) |
| 21 | { return 2.0f * x; } |
| 22 | |
Jason Rhinelander | 5fd5074 | 2016-08-03 16:50:22 -0400 | [diff] [blame] | 23 | // Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended |
| 24 | Eigen::MatrixXd cholesky1(Eigen::Ref<Eigen::MatrixXd> &x) { return x.llt().matrixL(); } |
| 25 | Eigen::MatrixXd cholesky2(const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.llt().matrixL(); } |
| 26 | Eigen::MatrixXd cholesky3(const Eigen::Ref<Eigen::MatrixXd> &x) { return x.llt().matrixL(); } |
| 27 | Eigen::MatrixXd cholesky4(Eigen::Ref<const Eigen::MatrixXd> &x) { return x.llt().matrixL(); } |
| 28 | Eigen::MatrixXd cholesky5(Eigen::Ref<Eigen::MatrixXd> x) { return x.llt().matrixL(); } |
| 29 | Eigen::MatrixXd cholesky6(Eigen::Ref<const Eigen::MatrixXd> x) { return x.llt().matrixL(); } |
| 30 | |
Ben North | 3e0e779 | 2016-07-05 21:00:05 +0100 | [diff] [blame] | 31 | typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatrixXfRowMajor; |
| 32 | MatrixXfRowMajor double_mat_rm(const MatrixXfRowMajor& x) |
| 33 | { return 2.0f * x; } |
| 34 | |
Wenzel Jakob | 9e0a056 | 2016-05-05 20:33:54 +0200 | [diff] [blame] | 35 | void init_eigen(py::module &m) { |
| 36 | typedef Eigen::Matrix<float, 5, 6, Eigen::RowMajor> FixedMatrixR; |
| 37 | typedef Eigen::Matrix<float, 5, 6> FixedMatrixC; |
| 38 | typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> DenseMatrixR; |
| 39 | typedef Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> DenseMatrixC; |
| 40 | typedef Eigen::SparseMatrix<float, Eigen::RowMajor> SparseMatrixR; |
| 41 | typedef Eigen::SparseMatrix<float> SparseMatrixC; |
| 42 | |
| 43 | // Non-symmetric matrix with zero elements |
| 44 | Eigen::MatrixXf mat(5, 6); |
| 45 | mat << 0, 3, 0, 0, 0, 11, 22, 0, 0, 0, 17, 11, 7, 5, 0, 1, 0, 11, 0, |
| 46 | 0, 0, 0, 0, 11, 0, 0, 14, 0, 8, 11; |
| 47 | |
Ben North | b063e64 | 2016-07-05 20:01:11 +0100 | [diff] [blame] | 48 | m.def("double_col", &double_col); |
| 49 | m.def("double_row", &double_row); |
Ben North | 3e0e779 | 2016-07-05 21:00:05 +0100 | [diff] [blame] | 50 | m.def("double_mat_cm", &double_mat_cm); |
| 51 | m.def("double_mat_rm", &double_mat_rm); |
Jason Rhinelander | 5fd5074 | 2016-08-03 16:50:22 -0400 | [diff] [blame] | 52 | m.def("cholesky1", &cholesky1); |
| 53 | m.def("cholesky2", &cholesky2); |
| 54 | m.def("cholesky3", &cholesky3); |
| 55 | m.def("cholesky4", &cholesky4); |
| 56 | m.def("cholesky5", &cholesky5); |
| 57 | m.def("cholesky6", &cholesky6); |
Ben North | b063e64 | 2016-07-05 20:01:11 +0100 | [diff] [blame] | 58 | |
Jason Rhinelander | 8657f30 | 2016-08-04 13:21:39 -0400 | [diff] [blame] | 59 | // Returns diagonals: a vector-like object with an inner stride != 1 |
| 60 | m.def("diagonal", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal(); }); |
| 61 | m.def("diagonal_1", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal<1>(); }); |
| 62 | m.def("diagonal_n", [](const Eigen::Ref<const Eigen::MatrixXd> &x, int index) { return x.diagonal(index); }); |
| 63 | |
| 64 | // Return a block of a matrix (gives non-standard strides) |
| 65 | m.def("block", [](const Eigen::Ref<const Eigen::MatrixXd> &x, int start_row, int start_col, int block_rows, int block_cols) { |
| 66 | return x.block(start_row, start_col, block_rows, block_cols); |
| 67 | }); |
| 68 | |
Jason Rhinelander | 9ffb3dd | 2016-08-04 15:24:41 -0400 | [diff] [blame] | 69 | // Returns a DiagonalMatrix with diagonal (1,2,3,...) |
| 70 | m.def("incr_diag", [](int k) { |
| 71 | Eigen::DiagonalMatrix<int, Eigen::Dynamic> m(k); |
| 72 | for (int i = 0; i < k; i++) m.diagonal()[i] = i+1; |
| 73 | return m; |
| 74 | }); |
| 75 | |
| 76 | // Returns a SelfAdjointView referencing the lower triangle of m |
| 77 | m.def("symmetric_lower", [](const Eigen::MatrixXi &m) { |
| 78 | return m.selfadjointView<Eigen::Lower>(); |
| 79 | }); |
| 80 | // Returns a SelfAdjointView referencing the lower triangle of m |
| 81 | m.def("symmetric_upper", [](const Eigen::MatrixXi &m) { |
| 82 | return m.selfadjointView<Eigen::Upper>(); |
| 83 | }); |
| 84 | |
Wenzel Jakob | 9e0a056 | 2016-05-05 20:33:54 +0200 | [diff] [blame] | 85 | m.def("fixed_r", [mat]() -> FixedMatrixR { |
| 86 | return FixedMatrixR(mat); |
| 87 | }); |
| 88 | |
| 89 | m.def("fixed_c", [mat]() -> FixedMatrixC { |
| 90 | return FixedMatrixC(mat); |
| 91 | }); |
| 92 | |
| 93 | m.def("fixed_passthrough_r", [](const FixedMatrixR &m) -> FixedMatrixR { |
| 94 | return m; |
| 95 | }); |
| 96 | |
| 97 | m.def("fixed_passthrough_c", [](const FixedMatrixC &m) -> FixedMatrixC { |
| 98 | return m; |
| 99 | }); |
| 100 | |
| 101 | m.def("dense_r", [mat]() -> DenseMatrixR { |
| 102 | return DenseMatrixR(mat); |
| 103 | }); |
| 104 | |
| 105 | m.def("dense_c", [mat]() -> DenseMatrixC { |
| 106 | return DenseMatrixC(mat); |
| 107 | }); |
| 108 | |
| 109 | m.def("dense_passthrough_r", [](const DenseMatrixR &m) -> DenseMatrixR { |
| 110 | return m; |
| 111 | }); |
| 112 | |
| 113 | m.def("dense_passthrough_c", [](const DenseMatrixC &m) -> DenseMatrixC { |
| 114 | return m; |
| 115 | }); |
| 116 | |
| 117 | m.def("sparse_r", [mat]() -> SparseMatrixR { |
| 118 | return Eigen::SparseView<Eigen::MatrixXf>(mat); |
| 119 | }); |
| 120 | |
| 121 | m.def("sparse_c", [mat]() -> SparseMatrixC { |
| 122 | return Eigen::SparseView<Eigen::MatrixXf>(mat); |
| 123 | }); |
| 124 | |
| 125 | m.def("sparse_passthrough_r", [](const SparseMatrixR &m) -> SparseMatrixR { |
| 126 | return m; |
| 127 | }); |
| 128 | |
| 129 | m.def("sparse_passthrough_c", [](const SparseMatrixC &m) -> SparseMatrixC { |
| 130 | return m; |
| 131 | }); |
| 132 | } |