Verified Commit 115ed938 authored by Justin Carpentier's avatar Justin Carpentier
Browse files

core: add support of Eigen::Ref to Python

parent 8b03257b
......@@ -79,7 +79,13 @@ namespace eigenpy
{
if(check_registration<MatType>()) return;
// to-python
EigenToPyConverter<MatType>::registration();
#if EIGEN_VERSION_AT_LEAST(3,2,0)
EigenToPyConverter< Eigen::Ref<MatType> >::registration();
#endif
// from-python
EigenFromPyConverter<MatType>::registration();
}
......
......@@ -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>
struct EigenToPyConverter
{
......
......@@ -57,7 +57,7 @@ namespace eigenpy
}
else
{
return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape);
return NumpyAllocator<MatType>::allocate(mat,nd,shape);
}
}
};
......@@ -65,8 +65,33 @@ namespace eigenpy
#if EIGEN_VERSION_AT_LEAST(3,2,0)
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
......@@ -88,14 +113,14 @@ namespace eigenpy
static_cast<int>(nd),
shape,
Scalar_type_code,
const_cast<SimilarMatrixType &>(mat.derived()).data(),
const_cast<Scalar *>(mat.data()),
NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED);
return pyArray;
}
else
{
return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape);
return NumpyAllocator<MatType>::allocate(mat,nd,shape);
}
}
};
......@@ -103,8 +128,34 @@ namespace eigenpy
#if EIGEN_VERSION_AT_LEAST(3,2,0)
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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment