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

core: add support of Eigen::Ref to Python

parent 8b03257b
No related branches found
No related tags found
No related merge requests found
...@@ -79,7 +79,13 @@ namespace eigenpy ...@@ -79,7 +79,13 @@ namespace eigenpy
{ {
if(check_registration<MatType>()) return; if(check_registration<MatType>()) return;
// to-python
EigenToPyConverter<MatType>::registration(); EigenToPyConverter<MatType>::registration();
#if EIGEN_VERSION_AT_LEAST(3,2,0)
EigenToPyConverter< Eigen::Ref<MatType> >::registration();
#endif
// from-python
EigenFromPyConverter<MatType>::registration(); EigenFromPyConverter<MatType>::registration();
} }
......
...@@ -82,6 +82,36 @@ namespace eigenpy ...@@ -82,6 +82,36 @@ namespace eigenpy
} }
}; };
template<typename MatType, int Options, typename Stride>
struct EigenToPy< Eigen::Ref<MatType,Options,Stride> >
{
static PyObject* convert(const Eigen::Ref<MatType,Options,Stride> & mat)
{
typedef Eigen::Ref<MatType,Options,Stride> EigenRef;
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)) && !MatType::IsVectorAtCompileTime) || MatType::IsVectorAtCompileTime)
&& NumpyType::getType() == ARRAY_TYPE) // Handle array with a single dimension
{
npy_intp shape[1] = { C == 1 ? R : C };
pyArray = NumpyAllocator<EigenRef>::allocate(const_cast<EigenRef &>(mat),1,shape);
}
else
{
npy_intp shape[2] = { R,C };
pyArray = NumpyAllocator<EigenRef>::allocate(const_cast<EigenRef &>(mat),2,shape);
}
// Create an instance (either np.array or np.matrix)
return NumpyType::make(pyArray).ptr();
}
};
template<typename MatType> template<typename MatType>
struct EigenToPyConverter struct EigenToPyConverter
{ {
......
...@@ -57,7 +57,7 @@ namespace eigenpy ...@@ -57,7 +57,7 @@ namespace eigenpy
} }
else else
{ {
return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape); return NumpyAllocator<MatType>::allocate(mat,nd,shape);
} }
} }
}; };
...@@ -65,8 +65,33 @@ namespace eigenpy ...@@ -65,8 +65,33 @@ namespace eigenpy
#if EIGEN_VERSION_AT_LEAST(3,2,0) #if EIGEN_VERSION_AT_LEAST(3,2,0)
template<typename MatType, int Options, typename Stride> template<typename MatType, int Options, typename Stride>
struct NumpyAllocator<Eigen::Ref<MatType,Options,Stride> > : NumpyAllocator<MatType &> struct NumpyAllocator<Eigen::Ref<MatType,Options,Stride> >
{ {
typedef Eigen::Ref<MatType,Options,Stride> RefType;
static PyArrayObject * allocate(RefType & mat,
npy_intp nd, npy_intp * shape)
{
typedef typename RefType::Scalar Scalar;
enum { NPY_ARRAY_MEMORY_CONTIGUOUS = RefType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY };
if(NumpyType::sharedMemory())
{
const int Scalar_type_code = Register::getTypeCode<Scalar>();
PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(getPyArrayType(),
static_cast<int>(nd),
shape,
Scalar_type_code,
mat.data(),
NPY_ARRAY_MEMORY_CONTIGUOUS | NPY_ARRAY_ALIGNED);
return pyArray;
}
else
{
return NumpyAllocator<MatType>::allocate(mat,nd,shape);
}
}
}; };
#endif #endif
...@@ -88,14 +113,14 @@ namespace eigenpy ...@@ -88,14 +113,14 @@ namespace eigenpy
static_cast<int>(nd), static_cast<int>(nd),
shape, shape,
Scalar_type_code, Scalar_type_code,
const_cast<SimilarMatrixType &>(mat.derived()).data(), const_cast<Scalar *>(mat.data()),
NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED); NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED);
return pyArray; return pyArray;
} }
else else
{ {
return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape); return NumpyAllocator<MatType>::allocate(mat,nd,shape);
} }
} }
}; };
...@@ -103,8 +128,34 @@ namespace eigenpy ...@@ -103,8 +128,34 @@ namespace eigenpy
#if EIGEN_VERSION_AT_LEAST(3,2,0) #if EIGEN_VERSION_AT_LEAST(3,2,0)
template<typename MatType, int Options, typename Stride> template<typename MatType, int Options, typename Stride>
struct NumpyAllocator<const Eigen::Ref<const MatType,Options,Stride> > : NumpyAllocator<const MatType &> struct NumpyAllocator<const Eigen::Ref<const MatType,Options,Stride> >
{ {
typedef const Eigen::Ref<const MatType,Options,Stride> RefType;
template<typename SimilarMatrixType>
static PyArrayObject * allocate(RefType & mat,
npy_intp nd, npy_intp * shape)
{
typedef typename SimilarMatrixType::Scalar Scalar;
enum { NPY_ARRAY_MEMORY_CONTIGUOUS_RO = SimilarMatrixType::IsRowMajor ? NPY_ARRAY_CARRAY_RO : NPY_ARRAY_FARRAY_RO };
if(NumpyType::sharedMemory())
{
const int Scalar_type_code = Register::getTypeCode<Scalar>();
PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(getPyArrayType(),
static_cast<int>(nd),
shape,
Scalar_type_code,
const_cast<Scalar *>(mat.data()),
NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED);
return pyArray;
}
else
{
return NumpyAllocator<MatType>::allocate(mat,nd,shape);
}
}
}; };
#endif #endif
......
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