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

core: MapNumpy is now templatized by the Stride type

parent c34b1185
No related branches found
No related tags found
No related merge requests found
...@@ -12,18 +12,17 @@ ...@@ -12,18 +12,17 @@
namespace eigenpy namespace eigenpy
{ {
template<typename MatType, typename InputScalar, bool IsVector> template<typename MatType, typename InputScalar, typename Stride, bool IsVector = MatType::IsVectorAtCompileTime>
struct MapNumpyTraits {}; struct MapNumpyTraits {};
/* Wrap a numpy::array with an Eigen::Map. No memory copy. */ /* Wrap a numpy::array with an Eigen::Map. No memory copy. */
template<typename MatType, typename InputScalar> template<typename MatType, typename InputScalar, typename Stride = typename StrideType<MatType>::type>
struct MapNumpy struct MapNumpy
{ {
typedef MapNumpyTraits<MatType, InputScalar, MatType::IsVectorAtCompileTime> Impl; typedef MapNumpyTraits<MatType, InputScalar, Stride> Impl;
typedef typename Impl::EigenMap EigenMap; typedef typename Impl::EigenMap EigenMap;
typedef typename Impl::Stride Stride;
static inline EigenMap map( PyArrayObject* pyArray ); static EigenMap map(PyArrayObject* pyArray);
}; };
} // namespace eigenpy } // namespace eigenpy
...@@ -34,19 +33,23 @@ namespace eigenpy ...@@ -34,19 +33,23 @@ namespace eigenpy
namespace eigenpy namespace eigenpy
{ {
template<typename MatType, typename InputScalar> template<typename MatType, typename InputScalar, typename Stride>
struct MapNumpyTraits<MatType,InputScalar,false> struct MapNumpyTraits<MatType,InputScalar,Stride,false>
{ {
typedef typename StrideType<MatType>::type Stride; typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime,MatType::Options> EquivalentInputMatrixType;
typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime> EquivalentInputMatrixType;
typedef Eigen::Map<EquivalentInputMatrixType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap; typedef Eigen::Map<EquivalentInputMatrixType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
static EigenMap mapImpl( PyArrayObject* pyArray ) static EigenMap mapImpl(PyArrayObject* pyArray)
{ {
enum {
OuterStrideAtCompileTime = Stride::OuterStrideAtCompileTime,
InnerStrideAtCompileTime = Stride::InnerStrideAtCompileTime,
};
assert(PyArray_NDIM(pyArray) == 2 || PyArray_NDIM(pyArray) == 1); assert(PyArray_NDIM(pyArray) == 2 || PyArray_NDIM(pyArray) == 1);
const long int itemsize = PyArray_ITEMSIZE(pyArray); const long int itemsize = PyArray_ITEMSIZE(pyArray);
int stride1 = -1, stride2 = -1; int inner_stride = -1, outer_stride = -1;
int rows = -1, cols = -1; int rows = -1, cols = -1;
if(PyArray_NDIM(pyArray) == 2) if(PyArray_NDIM(pyArray) == 2)
{ {
...@@ -57,8 +60,9 @@ namespace eigenpy ...@@ -57,8 +60,9 @@ namespace eigenpy
rows = (int)PyArray_DIMS(pyArray)[0]; rows = (int)PyArray_DIMS(pyArray)[0];
cols = (int)PyArray_DIMS(pyArray)[1]; cols = (int)PyArray_DIMS(pyArray)[1];
stride1 = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
stride2 = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize; inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
outer_stride = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize;
} }
else if(PyArray_NDIM(pyArray) == 1) else if(PyArray_NDIM(pyArray) == 1)
{ {
...@@ -68,33 +72,40 @@ namespace eigenpy ...@@ -68,33 +72,40 @@ namespace eigenpy
rows = (int)PyArray_DIMS(pyArray)[0]; rows = (int)PyArray_DIMS(pyArray)[0];
cols = 1; cols = 1;
stride1 = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize; inner_stride = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
stride2 = 0; outer_stride = 0;
} }
Stride stride(stride2,stride1); // Specific care for Eigen::Stride<-1,0>
if(InnerStrideAtCompileTime==0 && OuterStrideAtCompileTime==Eigen::Dynamic)
{
outer_stride = std::max(inner_stride,outer_stride); inner_stride = 0;
}
if( (MatType::RowsAtCompileTime!=rows) Stride stride(OuterStrideAtCompileTime==Eigen::Dynamic?outer_stride:OuterStrideAtCompileTime,
&& (MatType::RowsAtCompileTime!=Eigen::Dynamic) ) InnerStrideAtCompileTime==Eigen::Dynamic?inner_stride:InnerStrideAtCompileTime);
if( (MatType::RowsAtCompileTime != rows)
&& (MatType::RowsAtCompileTime != Eigen::Dynamic) )
{ throw eigenpy::Exception("The number of rows does not fit with the matrix type."); } { throw eigenpy::Exception("The number of rows does not fit with the matrix type."); }
if( (MatType::ColsAtCompileTime!=cols)
&& (MatType::ColsAtCompileTime!=Eigen::Dynamic) ) if( (MatType::ColsAtCompileTime != cols)
&& (MatType::ColsAtCompileTime != Eigen::Dynamic) )
{ throw eigenpy::Exception("The number of columns does not fit with the matrix type."); } { throw eigenpy::Exception("The number of columns does not fit with the matrix type."); }
InputScalar* pyData = reinterpret_cast<InputScalar*>(PyArray_DATA(pyArray)); InputScalar* pyData = reinterpret_cast<InputScalar*>(PyArray_DATA(pyArray));
return EigenMap( pyData, rows, cols, stride ); return EigenMap(pyData, rows, cols, stride);
} }
}; };
template<typename MatType, typename InputScalar> template<typename MatType, typename InputScalar, typename Stride>
struct MapNumpyTraits<MatType,InputScalar,true> struct MapNumpyTraits<MatType,InputScalar,Stride,true>
{ {
typedef typename StrideType<MatType>::type Stride; typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime,MatType::Options> EquivalentInputMatrixType;
typedef Eigen::Matrix<InputScalar,MatType::RowsAtCompileTime,MatType::ColsAtCompileTime> EquivalentInputMatrixType;
typedef Eigen::Map<EquivalentInputMatrixType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap; typedef Eigen::Map<EquivalentInputMatrixType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
static EigenMap mapImpl( PyArrayObject* pyArray ) static EigenMap mapImpl(PyArrayObject* pyArray)
{ {
assert( PyArray_NDIM(pyArray) <= 2 ); assert( PyArray_NDIM(pyArray) <= 2 );
...@@ -110,8 +121,8 @@ namespace eigenpy ...@@ -110,8 +121,8 @@ namespace eigenpy
const long int itemsize = PyArray_ITEMSIZE(pyArray); const long int itemsize = PyArray_ITEMSIZE(pyArray);
const int stride = (int) PyArray_STRIDE(pyArray, rowMajor) / (int) itemsize;; const int stride = (int) PyArray_STRIDE(pyArray, rowMajor) / (int) itemsize;;
if( (MatType::MaxSizeAtCompileTime!=R) if( (MatType::MaxSizeAtCompileTime != R)
&& (MatType::MaxSizeAtCompileTime!=Eigen::Dynamic) ) && (MatType::MaxSizeAtCompileTime != Eigen::Dynamic) )
{ throw eigenpy::Exception("The number of elements does not fit with the vector type."); } { throw eigenpy::Exception("The number of elements does not fit with the vector type."); }
InputScalar* pyData = reinterpret_cast<InputScalar*>(PyArray_DATA(pyArray)); InputScalar* pyData = reinterpret_cast<InputScalar*>(PyArray_DATA(pyArray));
...@@ -120,11 +131,11 @@ namespace eigenpy ...@@ -120,11 +131,11 @@ namespace eigenpy
} }
}; };
template<typename MatType, typename InputScalar> template<typename MatType, typename InputScalar, typename Stride>
typename MapNumpy<MatType,InputScalar>::EigenMap typename MapNumpy<MatType,InputScalar,Stride>::EigenMap
MapNumpy<MatType,InputScalar>::map(PyArrayObject * pyArray) MapNumpy<MatType,InputScalar,Stride>::map(PyArrayObject * pyArray)
{ {
return Impl::mapImpl(pyArray); return Impl::mapImpl(pyArray);
} }
} // namespace eigenpy } // namespace eigenpy
......
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