Skip to content
Snippets Groups Projects
Commit 0ad69ef3 authored by jcarpent's avatar jcarpent
Browse files

[Core] Update Map and Converter to be compatible with Eigen::Ref

parent 3519a39b
No related branches found
No related tags found
No related merge requests found
......@@ -17,13 +17,7 @@
#ifndef __eigenpy_details_hpp__
#define __eigenpy_details_hpp__
#include <boost/python.hpp>
#include <Eigen/Core>
#include <numpy/numpyconfig.h>
#ifdef NPY_1_8_API_VERSION
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#endif
#include "eigenpy/fwd.hpp"
#include <numpy/arrayobject.h>
#include <iostream>
......@@ -73,6 +67,40 @@ namespace eigenpy
bp::object pyMatrixType;
bp::object pyModule;
};
template<typename MatType>
struct EigenObjectAllocator
{
typedef MatType Type;
static void allocate(PyArrayObject * pyArray, void * storage)
{
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
new(storage) MatType(numpyMap);
}
static void convert(Type const & mat , PyArrayObject * pyArray)
{
MapNumpy<MatType>::map(pyArray) = mat;
}
};
template<typename MatType>
struct EigenObjectAllocator< eigenpy::Ref<MatType> >
{
typedef eigenpy::Ref<MatType> Type;
static void allocate(PyArrayObject * pyArray, void * storage)
{
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
new(storage) Type(numpyMap);
}
static void convert(Type const & mat , PyArrayObject * pyArray)
{
MapNumpy<MatType>::map(pyArray) = mat;
}
};
/* --- TO PYTHON -------------------------------------------------------------- */
template<typename MatType>
......@@ -89,7 +117,7 @@ namespace eigenpy
PyArrayObject* pyArray = (PyArrayObject*)
PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
MapNumpy<MatType>::map(pyArray) = mat;
EigenObjectAllocator<MatType>::convert(mat,pyArray);
return PyMatrixType::getInstance().make(pyArray).ptr();
}
......@@ -97,16 +125,6 @@ namespace eigenpy
/* --- FROM PYTHON ------------------------------------------------------------ */
template<typename MatType>
struct EigenObjectAllocator
{
static void allocate(PyArrayObject * pyArray, void * storage)
{
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
new(storage) MatType(numpyMap);
}
};
template<typename MatType>
struct EigenFromPy
{
......@@ -120,8 +138,6 @@ namespace eigenpy
// Determine if obj_ptr can be converted in a Eigenvec
static void* convertible(PyArrayObject* obj_ptr)
{
typedef typename MatType::Scalar T;
if (!PyArray_Check(obj_ptr))
{
#ifndef NDEBUG
......@@ -130,7 +146,31 @@ namespace eigenpy
return 0;
}
if(MatType::IsVectorAtCompileTime)
{
if(PyArray_DIMS(obj_ptr)[0] > 1 && PyArray_DIMS(obj_ptr)[1] > 1)
{
#ifndef NDEBUG
std::cerr << "The number of dimension of the object does not correspond to a vector" << std::endl;
#endif
return 0;
}
if(((PyArray_DIMS(obj_ptr)[0] == 1) && (MatType::ColsAtCompileTime == 1))
|| ((PyArray_DIMS(obj_ptr)[1] == 1) && (MatType::RowsAtCompileTime == 1)))
{
#ifndef NDEBUG
if(MatType::ColsAtCompileTime == 1)
std::cerr << "The object is not a column vector" << std::endl;
else
std::cerr << "The object is not a row vector" << std::endl;
#endif
return 0;
}
}
if (PyArray_NDIM(obj_ptr) != 2)
{
if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
{
#ifndef NDEBUG
......@@ -138,8 +178,10 @@ namespace eigenpy
#endif
return 0;
}
}
if ((PyArray_ObjectType(reinterpret_cast<PyObject *>(obj_ptr), 0)) != NumpyEquivalentType<T>::type_code)
if ((PyArray_ObjectType(reinterpret_cast<PyObject *>(obj_ptr), 0))
!= NumpyEquivalentType<typename MatType::Scalar>::type_code)
{
#ifndef NDEBUG
std::cerr << "The internal type as no Eigen equivalent." << std::endl;
......@@ -178,6 +220,7 @@ namespace eigenpy
memory->convertible = storage;
}
};
#define numpy_import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
template<typename MatType,typename EigenEquivalentType>
......
......@@ -14,10 +14,9 @@
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
*/
#include <boost/python.hpp>
#include <Eigen/Core>
#include "eigenpy/fwd.hpp"
#include <numpy/arrayobject.h>
#include <eigenpy/exception.hpp>
#include "eigenpy/exception.hpp"
namespace eigenpy
{
......@@ -30,6 +29,7 @@ namespace eigenpy
{
typedef MapNumpyTraits<MatType, MatType::IsVectorAtCompileTime> Impl;
typedef typename Impl::EigenMap EigenMap;
typedef typename Impl::Stride Stride;
static inline EigenMap map( PyArrayObject* pyArray );
};
......@@ -45,9 +45,9 @@ namespace eigenpy
template<typename MatType>
struct MapNumpyTraits<MatType,0>
{
typedef Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> Stride;
typedef Eigen::Map<MatType,0,Stride> EigenMap;
typedef typename MatType::Scalar T;
typedef typename StrideType<MatType>::type Stride;
typedef Eigen::Map<MatType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
typedef typename MatType::Scalar Scalar;
static EigenMap mapImpl( PyArrayObject* pyArray )
{
......@@ -63,6 +63,9 @@ namespace eigenpy
const long int itemsize = PyArray_ITEMSIZE(pyArray);
const int stride1 = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
const int stride2 = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize;
Stride stride(stride2,stride1);
if( (MatType::RowsAtCompileTime!=R)
&& (MatType::RowsAtCompileTime!=Eigen::Dynamic) )
......@@ -71,17 +74,18 @@ namespace eigenpy
&& (MatType::ColsAtCompileTime!=Eigen::Dynamic) )
{ throw eigenpy::Exception("The number of columns does not fit with the matrix type."); }
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
return EigenMap( pyData, R,C, Stride(stride2,stride1) );
Scalar* pyData = reinterpret_cast<Scalar*>(PyArray_DATA(pyArray));
return EigenMap( pyData, R,C, stride );
}
};
template<typename MatType>
struct MapNumpyTraits<MatType,1>
{
typedef Eigen::InnerStride<Eigen::Dynamic> Stride;
typedef Eigen::Map<MatType,0,Stride> EigenMap;
typedef typename MatType::Scalar T;
typedef typename StrideType<MatType>::type Stride;
typedef Eigen::Map<MatType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
typedef typename MatType::Scalar Scalar;
static EigenMap mapImpl( PyArrayObject* pyArray )
{
......@@ -101,8 +105,8 @@ namespace eigenpy
&& (MatType::MaxSizeAtCompileTime!=Eigen::Dynamic) )
{ throw eigenpy::Exception("The number of elements does not fit with the vector type."); }
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
return EigenMap( pyData, R, 1, Stride(stride) );
Scalar* pyData = reinterpret_cast<Scalar*>(PyArray_DATA(pyArray));
return EigenMap( pyData, R, Stride(stride) );
}
};
......
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