Skip to content

Commit 52106de

Browse files
committed
core: add converter to python for Eigen::Matrix
1 parent e378427 commit 52106de

File tree

2 files changed

+72
-38
lines changed

2 files changed

+72
-38
lines changed

include/eigenpy/details.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "eigenpy/map.hpp"
2323
#include "eigenpy/exception.hpp"
2424

25-
2625
namespace boost { namespace python { namespace detail {
2726

2827
template<class MatType>

include/eigenpy/eigen-to-python.hpp

Lines changed: 72 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,88 @@
88
#include "eigenpy/fwd.hpp"
99
#include "eigenpy/numpy-type.hpp"
1010
#include "eigenpy/eigen-allocator.hpp"
11+
#include "eigenpy/numpy-allocator.hpp"
12+
13+
#include <boost/type_traits.hpp>
14+
15+
namespace boost { namespace python {
16+
17+
template<typename MatrixRef, class MakeHolder>
18+
struct to_python_indirect_eigen
19+
{
20+
template <class U>
21+
inline PyObject* operator()(U const& mat) const
22+
{
23+
return eigenpy::EigenToPy<MatrixRef>::convert(const_cast<U&>(mat));
24+
}
25+
26+
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
27+
inline PyTypeObject const*
28+
get_pytype()const
29+
{
30+
return converter::registered_pytype<MatrixRef>::get_pytype();
31+
}
32+
#endif
33+
};
34+
35+
template <typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options, int MaxRowsAtCompileTime, int MaxColsAtCompileTime, class MakeHolder>
36+
struct to_python_indirect<Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
37+
: to_python_indirect_eigen<Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
38+
{
39+
};
40+
41+
template <typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options, int MaxRowsAtCompileTime, int MaxColsAtCompileTime, class MakeHolder>
42+
struct to_python_indirect<const Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
43+
: to_python_indirect_eigen<const Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
44+
{
45+
};
46+
47+
}}
1148

1249
namespace eigenpy
1350
{
1451
namespace bp = boost::python;
1552

16-
template<typename MatType>
17-
struct EigenToPy
53+
template<typename MatType>
54+
struct EigenToPy
55+
{
56+
static PyObject* convert(typename boost::add_reference<typename boost::add_const<MatType>::type>::type mat)
1857
{
19-
static PyObject* convert(MatType const & mat)
58+
typedef typename boost::remove_const<typename boost::remove_reference<MatType>::type>::type MatrixDerived;
59+
60+
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX)
61+
&& "Matrix range larger than int ... should never happen." );
62+
const npy_intp R = (npy_intp)mat.rows(), C = (npy_intp)mat.cols();
63+
64+
PyArrayObject* pyArray;
65+
// Allocate Python memory
66+
if( ( ((!(C == 1) != !(R == 1)) && !MatrixDerived::IsVectorAtCompileTime) || MatrixDerived::IsVectorAtCompileTime)
67+
&& NumpyType::getType() == ARRAY_TYPE) // Handle array with a single dimension
2068
{
21-
typedef typename MatType::Scalar Scalar;
22-
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX)
23-
&& "Matrix range larger than int ... should never happen." );
24-
const npy_intp R = (npy_intp)mat.rows(), C = (npy_intp)mat.cols();
25-
26-
PyArrayObject* pyArray;
27-
// Allocate Python memory
28-
if( ( ((!(C == 1) != !(R == 1)) && !MatType::IsVectorAtCompileTime) || MatType::IsVectorAtCompileTime)
29-
&& NumpyType::getType() == ARRAY_TYPE) // Handle array with a single dimension
30-
{
31-
npy_intp shape[1] = { C == 1 ? R : C };
32-
pyArray = (PyArrayObject*) PyArray_SimpleNew(1, shape,
33-
NumpyEquivalentType<Scalar>::type_code);
34-
}
35-
else
36-
{
37-
npy_intp shape[2] = { R,C };
38-
pyArray = (PyArrayObject*) PyArray_SimpleNew(2, shape,
39-
NumpyEquivalentType<Scalar>::type_code);
40-
}
41-
42-
// Copy data
43-
EigenAllocator<MatType>::copy(mat,pyArray);
44-
45-
// Create an instance (either np.array or np.matrix)
46-
return NumpyType::getInstance().make(pyArray).ptr();
69+
npy_intp shape[1] = { C == 1 ? R : C };
70+
pyArray = NumpyAllocator<MatType>::allocate(const_cast<MatrixDerived &>(mat.derived()),
71+
1,shape);
4772
}
48-
};
49-
50-
template<typename MatType>
51-
struct EigenToPyConverter
52-
{
53-
static void registration()
73+
else
5474
{
55-
bp::to_python_converter<MatType,EigenToPy<MatType> >();
75+
npy_intp shape[2] = { R,C };
76+
pyArray = NumpyAllocator<MatType>::allocate(const_cast<MatrixDerived &>(mat.derived()),
77+
2,shape);
5678
}
57-
};
79+
80+
// Create an instance (either np.array or np.matrix)
81+
return NumpyType::make(pyArray).ptr();
82+
}
83+
};
84+
85+
template<typename MatType>
86+
struct EigenToPyConverter
87+
{
88+
static void registration()
89+
{
90+
bp::to_python_converter<MatType,EigenToPy<MatType> >();
91+
}
92+
};
5893

5994
#if EIGEN_VERSION_AT_LEAST(3,2,0)
6095
template<typename MatType>

0 commit comments

Comments
 (0)