5 #ifndef __eigenpy_eigen_allocator_hpp__ 6 #define __eigenpy_eigen_allocator_hpp__ 19 template<
typename MatType,
bool IsVectorAtCompileTime = MatType::IsVectorAtCompileTime>
25 return new (storage) MatType(rows,cols);
27 return new MatType(rows,cols);
30 static MatType *
run(PyArrayObject * pyArray,
void * storage = NULL)
32 assert(PyArray_NDIM(pyArray) == 1 || PyArray_NDIM(pyArray) == 2);
35 const int ndim = PyArray_NDIM(pyArray);
38 rows = (int)PyArray_DIMS(pyArray)[0];
39 cols = (int)PyArray_DIMS(pyArray)[1];
43 rows = (int)PyArray_DIMS(pyArray)[0];
51 template<
typename MatType>
57 return new (storage) MatType(rows,cols);
59 return new MatType(rows,cols);
62 static MatType *
run(
int size,
void * storage)
65 return new (storage) MatType(size);
67 return new MatType(size);
70 static MatType *
run(PyArrayObject * pyArray,
void * storage = NULL)
72 const int ndim = PyArray_NDIM(pyArray);
75 const int size = (int)PyArray_DIMS(pyArray)[0];
76 return run(size,storage);
80 const int rows = (int)PyArray_DIMS(pyArray)[0];
81 const int cols = (int)PyArray_DIMS(pyArray)[1];
82 return run(rows,cols,storage);
87 template<
typename MatType>
89 const Eigen::MatrixBase<MatType> &
mat)
91 if(PyArray_NDIM(pyArray) == 0)
return false;
92 if(mat.rows() == PyArray_DIMS(pyArray)[0])
101 template<
typename MatrixIn,
typename MatrixOut>
102 static void run(
const Eigen::MatrixBase<MatrixIn> & input,
103 const Eigen::MatrixBase<MatrixOut> & dest)
105 MatrixOut & dest_ =
const_cast<MatrixOut &
>(dest.derived());
106 dest_ = input.template cast<NewScalar>();
110 template<
typename Scalar,
typename NewScalar>
113 template<
typename MatrixIn,
typename MatrixOut>
114 static void run(
const Eigen::MatrixBase<MatrixIn> & ,
115 const Eigen::MatrixBase<MatrixOut> & )
118 assert(
false &&
"Must never happened");
124 #define EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType,Scalar,NewScalar,pyArray,mat) \ 125 details::cast_matrix_or_array<Scalar,NewScalar>::run(NumpyMap<MatType,Scalar>::map(pyArray,details::check_swap(pyArray,mat)),mat) 127 #define EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType,Scalar,NewScalar,mat,pyArray) \ 128 details::cast_matrix_or_array<Scalar,NewScalar>::run(mat,NumpyMap<MatType,NewScalar>::map(pyArray,details::check_swap(pyArray,mat))) 130 template<
typename MatType>
137 bp::converter::rvalue_from_python_storage<MatType> * storage)
139 void * raw_ptr = storage->storage.bytes;
141 Type &
mat = *mat_ptr;
144 const int Scalar_type_code = Register::getTypeCode<Scalar>();
145 if(pyArray_type_code == Scalar_type_code)
151 switch(pyArray_type_code)
174 case NPY_CLONGDOUBLE:
178 throw Exception(
"You asked for a conversion which is not implemented.");
183 template<
typename MatrixDerived>
184 static void copy(
const Eigen::MatrixBase<MatrixDerived> & mat_,
185 PyArrayObject * pyArray)
187 const MatrixDerived &
mat =
const_cast<const MatrixDerived &
>(mat_.derived());
189 const int Scalar_type_code = Register::getTypeCode<Scalar>();
193 if(pyArray_type_code == Scalar_type_code)
200 switch(pyArray_type_code)
223 case NPY_CLONGDOUBLE:
227 throw Exception(
"You asked for a conversion which is not implemented.");
232 #if EIGEN_VERSION_AT_LEAST(3,2,0) 233 template<
typename MatType,
int Options,
typename Str
ide>
236 typedef Eigen::Ref<MatType,Options,Stride> RefType;
237 typedef typename MatType::Scalar
Scalar;
239 typedef typename ::boost::python::detail::referent_storage<RefType&>::StorageType StorageType;
241 static void allocate(PyArrayObject * pyArray,
242 bp::converter::rvalue_from_python_storage<RefType> * storage)
246 bool need_to_allocate =
false;
248 const int Scalar_type_code = Register::getTypeCode<Scalar>();
249 if(pyArray_type_code != Scalar_type_code)
250 need_to_allocate |=
true;
251 if( (MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) && !PyArray_IS_F_CONTIGUOUS(pyArray)))
252 || (!MatType::IsRowMajor && (PyArray_IS_F_CONTIGUOUS(pyArray) && !PyArray_IS_C_CONTIGUOUS(pyArray)))
253 || MatType::IsVectorAtCompileTime
254 || (PyArray_IS_F_CONTIGUOUS(pyArray) && PyArray_IS_C_CONTIGUOUS(pyArray)))
255 need_to_allocate |=
false;
257 need_to_allocate |=
true;
258 if(Options != Eigen::Unaligned)
260 void * data_ptr = PyArray_DATA(pyArray);
261 if(!PyArray_ISONESEGMENT(pyArray) || !
is_aligned(data_ptr,Options))
262 need_to_allocate |=
true;
265 void * raw_ptr = storage->storage.bytes;
270 RefType mat_ref(*mat_ptr);
272 new (raw_ptr) StorageType(mat_ref,pyArray,mat_ptr);
274 RefType &
mat = *
reinterpret_cast<RefType*
>(raw_ptr);
275 if(pyArray_type_code == Scalar_type_code)
281 switch(pyArray_type_code)
304 case NPY_CLONGDOUBLE:
308 throw Exception(
"You asked for a conversion which is not implemented.");
313 assert(pyArray_type_code == Scalar_type_code);
315 RefType mat_ref(numpyMap);
316 new (raw_ptr) StorageType(mat_ref,pyArray);
320 static void copy(RefType
const & ref, PyArrayObject * pyArray)
326 template<
typename MatType,
int Options,
typename Str
ide>
327 struct EigenAllocator<const Eigen::Ref<const MatType,Options,Stride> >
329 typedef const Eigen::Ref<const MatType,Options,Stride> RefType;
330 typedef typename MatType::Scalar
Scalar;
332 typedef typename ::boost::python::detail::referent_storage<RefType&>::StorageType StorageType;
334 static void allocate(PyArrayObject * pyArray,
335 bp::converter::rvalue_from_python_storage<RefType> * storage)
339 bool need_to_allocate =
false;
341 const int Scalar_type_code = Register::getTypeCode<Scalar>();
343 if(pyArray_type_code != Scalar_type_code)
344 need_to_allocate |=
true;
345 if( (MatType::IsRowMajor && (PyArray_IS_C_CONTIGUOUS(pyArray) && !PyArray_IS_F_CONTIGUOUS(pyArray)))
346 || (!MatType::IsRowMajor && (PyArray_IS_F_CONTIGUOUS(pyArray) && !PyArray_IS_C_CONTIGUOUS(pyArray)))
347 || MatType::IsVectorAtCompileTime
348 || (PyArray_IS_F_CONTIGUOUS(pyArray) && PyArray_IS_C_CONTIGUOUS(pyArray)))
349 need_to_allocate |=
false;
351 need_to_allocate |=
true;
352 if(Options != Eigen::Unaligned)
354 void * data_ptr = PyArray_DATA(pyArray);
355 if(!PyArray_ISONESEGMENT(pyArray) || !
is_aligned(data_ptr,Options))
356 need_to_allocate |=
true;
359 void * raw_ptr = storage->storage.bytes;
364 RefType mat_ref(*mat_ptr);
366 new (raw_ptr) StorageType(mat_ref,pyArray,mat_ptr);
368 MatType &
mat = *mat_ptr;
369 if(pyArray_type_code == Scalar_type_code)
375 switch(pyArray_type_code)
398 case NPY_CLONGDOUBLE:
402 throw Exception(
"You asked for a conversion which is not implemented.");
407 assert(pyArray_type_code == Scalar_type_code);
409 RefType mat_ref(numpyMap);
410 new (raw_ptr) StorageType(mat_ref,pyArray);
414 static void copy(RefType
const & ref, PyArrayObject * pyArray)
422 #endif // __eigenpy_eigen_allocator_hpp__ #define EIGENPY_CAST_FROM_EIGEN_MATRIX_TO_PYARRAY(MatType, Scalar, NewScalar, mat, pyArray)
static void run(const Eigen::MatrixBase< MatrixIn > &, const Eigen::MatrixBase< MatrixOut > &)
static void allocate(PyArrayObject *pyArray, bp::converter::rvalue_from_python_storage< MatType > *storage)
bool is_aligned(void *ptr, std::size_t alignment)
static MatType * run(int rows, int cols, void *storage)
#define EIGENPY_CAST_FROM_PYARRAY_TO_EIGEN_MATRIX(MatType, Scalar, NewScalar, pyArray, mat)
std::size_t size(custom_string const &s)
static MatType * run(PyArrayObject *pyArray, void *storage=NULL)
static MatType * run(PyArrayObject *pyArray, void *storage=NULL)
static MatType * run(int size, void *storage)
static MatType * run(int rows, int cols, void *storage)
static void copy(const Eigen::MatrixBase< MatrixDerived > &mat_, PyArrayObject *pyArray)
Copy mat into the Python array using Eigen::Map.
static EigenMap map(PyArrayObject *pyArray, bool swap_dimensions=false)
#define EIGENPY_GET_PY_ARRAY_TYPE(array)
static void run(const Eigen::MatrixBase< MatrixIn > &input, const Eigen::MatrixBase< MatrixOut > &dest)
bool check_swap(PyArrayObject *pyArray, const Eigen::MatrixBase< MatType > &mat)