2626#include " eigenpy/registration.hpp"
2727#include " eigenpy/map.hpp"
2828
29+ #define GET_PY_ARRAY_TYPE (array ) PyArray_ObjectType(reinterpret_cast <PyObject *>(array), 0 )
30+
2931
3032namespace eigenpy
3133{
3234 template <typename SCALAR> struct NumpyEquivalentType {};
3335 template <> struct NumpyEquivalentType <double > { enum { type_code = NPY_DOUBLE };};
3436 template <> struct NumpyEquivalentType <int > { enum { type_code = NPY_INT };};
37+ template <> struct NumpyEquivalentType <long > { enum { type_code = NPY_LONG };};
3538 template <> struct NumpyEquivalentType <float > { enum { type_code = NPY_FLOAT };};
39+
40+ template <typename SCALAR1, typename SCALAR2>
41+ struct FromTypeToType : public boost ::false_type {};
42+
43+ template <typename SCALAR>
44+ struct FromTypeToType <SCALAR,SCALAR> : public boost::true_type {};
45+
46+ template <> struct FromTypeToType <int ,long > : public boost::true_type {};
47+ template <> struct FromTypeToType <int ,float > : public boost::true_type {};
48+ template <> struct FromTypeToType <int ,double > : public boost::true_type {};
49+
50+ template <> struct FromTypeToType <long ,float > : public boost::true_type {};
51+ template <> struct FromTypeToType <long ,double > : public boost::true_type {};
52+
53+ template <> struct FromTypeToType <float ,double > : public boost::true_type {};
3654
3755 namespace bp = boost::python;
3856
@@ -72,16 +90,40 @@ namespace eigenpy
7290 struct EigenObjectAllocator
7391 {
7492 typedef MatType Type;
93+ typedef typename MatType::Scalar Scalar;
7594
7695 static void allocate (PyArrayObject * pyArray, void * storage)
7796 {
78- typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map (pyArray);
79- new (storage) MatType (numpyMap);
97+ const int rows = (int )PyArray_DIMS (pyArray)[0 ];
98+ const int cols = (int )PyArray_DIMS (pyArray)[1 ];
99+
100+ Type * mat_ptr = new (storage) Type (rows,cols);
101+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_INT)
102+ *mat_ptr = MapNumpy<MatType,int >::map (pyArray).template cast <Scalar>();
103+
104+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_LONG)
105+ *mat_ptr = MapNumpy<MatType,long >::map (pyArray).template cast <Scalar>();
106+
107+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_FLOAT)
108+ *mat_ptr = MapNumpy<MatType,float >::map (pyArray).template cast <Scalar>();
109+
110+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_DOUBLE)
111+ *mat_ptr = MapNumpy<MatType,double >::map (pyArray).template cast <Scalar>();
80112 }
81113
82114 static void convert (Type const & mat , PyArrayObject * pyArray)
83115 {
84- MapNumpy<MatType>::map (pyArray) = mat;
116+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_INT)
117+ MapNumpy<MatType,int >::map (pyArray) = mat.template cast <int >();
118+
119+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_LONG)
120+ MapNumpy<MatType,long >::map (pyArray) = mat.template cast <long >();
121+
122+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_FLOAT)
123+ MapNumpy<MatType,float >::map (pyArray) = mat.template cast <float >();
124+
125+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_DOUBLE)
126+ MapNumpy<MatType,double >::map (pyArray) = mat.template cast <double >();
85127 }
86128 };
87129
@@ -90,16 +132,27 @@ namespace eigenpy
90132 struct EigenObjectAllocator < eigenpy::Ref<MatType> >
91133 {
92134 typedef eigenpy::Ref<MatType> Type;
135+ typedef typename MatType::Scalar Scalar;
93136
94137 static void allocate (PyArrayObject * pyArray, void * storage)
95138 {
96- typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map (pyArray);
139+ typename MapNumpy<MatType,Scalar >::EigenMap numpyMap = MapNumpy<MatType,Scalar >::map (pyArray);
97140 new (storage) Type (numpyMap);
98141 }
99142
100143 static void convert (Type const & mat , PyArrayObject * pyArray)
101144 {
102- MapNumpy<MatType>::map (pyArray) = mat;
145+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_INT)
146+ MapNumpy<MatType,int >::map (pyArray) = mat.template cast <int >();
147+
148+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_LONG)
149+ MapNumpy<MatType,long >::map (pyArray) = mat.template cast <long >();
150+
151+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_FLOAT)
152+ MapNumpy<MatType,float >::map (pyArray) = mat.template cast <float >();
153+
154+ if (GET_PY_ARRAY_TYPE (pyArray) == NPY_DOUBLE)
155+ MapNumpy<MatType,double >::map (pyArray) = mat.template cast <double >();
103156 }
104157 };
105158#endif
@@ -140,19 +193,13 @@ namespace eigenpy
140193 // Determine if obj_ptr can be converted in a Eigenvec
141194 static void * convertible (PyArrayObject* obj_ptr)
142195 {
143- std::cout << " call convertible" << std::endl;
144-
145196 if (!PyArray_Check (obj_ptr))
146197 {
147198#ifndef NDEBUG
148199 std::cerr << " The python object is not a numpy array." << std::endl;
149200#endif
150201 return 0 ;
151202 }
152-
153- std::cout << " PyArray_DIMS(obj_ptr)[0]: " << PyArray_DIMS (obj_ptr)[0 ] << std::endl;
154- std::cout << " PyArray_DIMS(obj_ptr)[1]: " << PyArray_DIMS (obj_ptr)[1 ] << std::endl;
155-
156203 if (MatType::IsVectorAtCompileTime)
157204 {
158205 // Special care of scalar matrix of dimension 1x1.
@@ -171,7 +218,6 @@ namespace eigenpy
171218 || ((PyArray_DIMS (obj_ptr)[1 ] == 1 ) && (MatType::RowsAtCompileTime == 1 )))
172219 {
173220#ifndef NDEBUG
174- std::cout << " MatType::ColsAtCompileTime: " << MatType::ColsAtCompileTime << std::endl;
175221 if (MatType::ColsAtCompileTime == 1 )
176222 std::cerr << " The object is not a column vector" << std::endl;
177223 else
@@ -192,14 +238,57 @@ namespace eigenpy
192238 }
193239 }
194240
195- if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 ))
241+ // Check if the Scalar type of the obj_ptr is compatible with the Scalar type of MatType
242+ if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 )) == NPY_INT)
243+ {
244+ if (not FromTypeToType<int ,typename MatType::Scalar>::value)
245+ {
246+ #ifndef NDEBUG
247+ std::cerr << " The Python matrix scalar type (int) cannot be converted into the scalar type of the Eigen matrix. Loss of arithmetic precision" << std::endl;
248+ #endif
249+ return 0 ;
250+ }
251+ }
252+ else if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 )) == NPY_LONG)
253+ {
254+ if (not FromTypeToType<long ,typename MatType::Scalar>::value)
255+ {
256+ #ifndef NDEBUG
257+ std::cerr << " The Python matrix scalar type (long) cannot be converted into the scalar type of the Eigen matrix. Loss of arithmetic precision" << std::endl;
258+ #endif
259+ return 0 ;
260+ }
261+ }
262+ else if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 )) == NPY_FLOAT)
263+ {
264+ if (not FromTypeToType<float ,typename MatType::Scalar>::value)
265+ {
266+ #ifndef NDEBUG
267+ std::cerr << " The Python matrix scalar type (float) cannot be converted into the scalar type of the Eigen matrix. Loss of arithmetic precision" << std::endl;
268+ #endif
269+ return 0 ;
270+ }
271+ }
272+ else if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 )) == NPY_DOUBLE)
273+ {
274+ if (not FromTypeToType<double ,typename MatType::Scalar>::value)
275+ {
276+ #ifndef NDEBUG
277+ std::cerr << " The Python matrix scalar (double) type cannot be converted into the scalar type of the Eigen matrix. Loss of arithmetic precision." << std::endl;
278+ #endif
279+ return 0 ;
280+ }
281+ }
282+ else if ((PyArray_ObjectType (reinterpret_cast <PyObject *>(obj_ptr), 0 ))
196283 != NumpyEquivalentType<typename MatType::Scalar>::type_code)
197284 {
198285#ifndef NDEBUG
199286 std::cerr << " The internal type as no Eigen equivalent." << std::endl;
200287#endif
288+
201289 return 0 ;
202290 }
291+
203292#ifdef NPY_1_8_API_VERSION
204293 if (!(PyArray_FLAGS (obj_ptr)))
205294#else
0 commit comments