Skip to content
Snippets Groups Projects
Verified Commit 52106de3 authored by Justin Carpentier's avatar Justin Carpentier
Browse files

core: add converter to python for Eigen::Matrix

parent e3784276
No related branches found
No related tags found
No related merge requests found
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "eigenpy/map.hpp" #include "eigenpy/map.hpp"
#include "eigenpy/exception.hpp" #include "eigenpy/exception.hpp"
namespace boost { namespace python { namespace detail { namespace boost { namespace python { namespace detail {
template<class MatType> template<class MatType>
......
...@@ -8,53 +8,88 @@ ...@@ -8,53 +8,88 @@
#include "eigenpy/fwd.hpp" #include "eigenpy/fwd.hpp"
#include "eigenpy/numpy-type.hpp" #include "eigenpy/numpy-type.hpp"
#include "eigenpy/eigen-allocator.hpp" #include "eigenpy/eigen-allocator.hpp"
#include "eigenpy/numpy-allocator.hpp"
#include <boost/type_traits.hpp>
namespace boost { namespace python {
template<typename MatrixRef, class MakeHolder>
struct to_python_indirect_eigen
{
template <class U>
inline PyObject* operator()(U const& mat) const
{
return eigenpy::EigenToPy<MatrixRef>::convert(const_cast<U&>(mat));
}
#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
inline PyTypeObject const*
get_pytype()const
{
return converter::registered_pytype<MatrixRef>::get_pytype();
}
#endif
};
template <typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options, int MaxRowsAtCompileTime, int MaxColsAtCompileTime, class MakeHolder>
struct to_python_indirect<Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
: to_python_indirect_eigen<Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
{
};
template <typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime, int Options, int MaxRowsAtCompileTime, int MaxColsAtCompileTime, class MakeHolder>
struct to_python_indirect<const Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
: to_python_indirect_eigen<const Eigen::Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime,Options,MaxRowsAtCompileTime,MaxColsAtCompileTime>&,MakeHolder>
{
};
}}
namespace eigenpy namespace eigenpy
{ {
namespace bp = boost::python; namespace bp = boost::python;
template<typename MatType> template<typename MatType>
struct EigenToPy struct EigenToPy
{
static PyObject* convert(typename boost::add_reference<typename boost::add_const<MatType>::type>::type mat)
{ {
static PyObject* convert(MatType const & mat) typedef typename boost::remove_const<typename boost::remove_reference<MatType>::type>::type MatrixDerived;
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX)
&& "Matrix range larger than int ... should never happen." );
const npy_intp R = (npy_intp)mat.rows(), C = (npy_intp)mat.cols();
PyArrayObject* pyArray;
// Allocate Python memory
if( ( ((!(C == 1) != !(R == 1)) && !MatrixDerived::IsVectorAtCompileTime) || MatrixDerived::IsVectorAtCompileTime)
&& NumpyType::getType() == ARRAY_TYPE) // Handle array with a single dimension
{ {
typedef typename MatType::Scalar Scalar; npy_intp shape[1] = { C == 1 ? R : C };
assert( (mat.rows()<INT_MAX) && (mat.cols()<INT_MAX) pyArray = NumpyAllocator<MatType>::allocate(const_cast<MatrixDerived &>(mat.derived()),
&& "Matrix range larger than int ... should never happen." ); 1,shape);
const npy_intp R = (npy_intp)mat.rows(), C = (npy_intp)mat.cols();
PyArrayObject* pyArray;
// Allocate Python memory
if( ( ((!(C == 1) != !(R == 1)) && !MatType::IsVectorAtCompileTime) || MatType::IsVectorAtCompileTime)
&& NumpyType::getType() == ARRAY_TYPE) // Handle array with a single dimension
{
npy_intp shape[1] = { C == 1 ? R : C };
pyArray = (PyArrayObject*) PyArray_SimpleNew(1, shape,
NumpyEquivalentType<Scalar>::type_code);
}
else
{
npy_intp shape[2] = { R,C };
pyArray = (PyArrayObject*) PyArray_SimpleNew(2, shape,
NumpyEquivalentType<Scalar>::type_code);
}
// Copy data
EigenAllocator<MatType>::copy(mat,pyArray);
// Create an instance (either np.array or np.matrix)
return NumpyType::getInstance().make(pyArray).ptr();
} }
}; else
template<typename MatType>
struct EigenToPyConverter
{
static void registration()
{ {
bp::to_python_converter<MatType,EigenToPy<MatType> >(); npy_intp shape[2] = { R,C };
pyArray = NumpyAllocator<MatType>::allocate(const_cast<MatrixDerived &>(mat.derived()),
2,shape);
} }
};
// Create an instance (either np.array or np.matrix)
return NumpyType::make(pyArray).ptr();
}
};
template<typename MatType>
struct EigenToPyConverter
{
static void registration()
{
bp::to_python_converter<MatType,EigenToPy<MatType> >();
}
};
#if EIGEN_VERSION_AT_LEAST(3,2,0) #if EIGEN_VERSION_AT_LEAST(3,2,0)
template<typename MatType> template<typename MatType>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment