Skip to content

Commit 0ad69ef

Browse files
committed
[Core] Update Map and Converter to be compatible with Eigen::Ref
1 parent 3519a39 commit 0ad69ef

File tree

2 files changed

+81
-34
lines changed

2 files changed

+81
-34
lines changed

src/details.hpp

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,7 @@
1717
#ifndef __eigenpy_details_hpp__
1818
#define __eigenpy_details_hpp__
1919

20-
#include <boost/python.hpp>
21-
#include <Eigen/Core>
22-
23-
#include <numpy/numpyconfig.h>
24-
#ifdef NPY_1_8_API_VERSION
25-
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
26-
#endif
20+
#include "eigenpy/fwd.hpp"
2721

2822
#include <numpy/arrayobject.h>
2923
#include <iostream>
@@ -73,6 +67,40 @@ namespace eigenpy
7367
bp::object pyMatrixType;
7468
bp::object pyModule;
7569
};
70+
71+
template<typename MatType>
72+
struct EigenObjectAllocator
73+
{
74+
typedef MatType Type;
75+
76+
static void allocate(PyArrayObject * pyArray, void * storage)
77+
{
78+
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
79+
new(storage) MatType(numpyMap);
80+
}
81+
82+
static void convert(Type const & mat , PyArrayObject * pyArray)
83+
{
84+
MapNumpy<MatType>::map(pyArray) = mat;
85+
}
86+
};
87+
88+
template<typename MatType>
89+
struct EigenObjectAllocator< eigenpy::Ref<MatType> >
90+
{
91+
typedef eigenpy::Ref<MatType> Type;
92+
93+
static void allocate(PyArrayObject * pyArray, void * storage)
94+
{
95+
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
96+
new(storage) Type(numpyMap);
97+
}
98+
99+
static void convert(Type const & mat , PyArrayObject * pyArray)
100+
{
101+
MapNumpy<MatType>::map(pyArray) = mat;
102+
}
103+
};
76104

77105
/* --- TO PYTHON -------------------------------------------------------------- */
78106
template<typename MatType>
@@ -89,24 +117,14 @@ namespace eigenpy
89117
PyArrayObject* pyArray = (PyArrayObject*)
90118
PyArray_SimpleNew(2, shape, NumpyEquivalentType<T>::type_code);
91119

92-
MapNumpy<MatType>::map(pyArray) = mat;
120+
EigenObjectAllocator<MatType>::convert(mat,pyArray);
93121

94122
return PyMatrixType::getInstance().make(pyArray).ptr();
95123
}
96124
};
97125

98126
/* --- FROM PYTHON ------------------------------------------------------------ */
99127

100-
template<typename MatType>
101-
struct EigenObjectAllocator
102-
{
103-
static void allocate(PyArrayObject * pyArray, void * storage)
104-
{
105-
typename MapNumpy<MatType>::EigenMap numpyMap = MapNumpy<MatType>::map(pyArray);
106-
new(storage) MatType(numpyMap);
107-
}
108-
};
109-
110128
template<typename MatType>
111129
struct EigenFromPy
112130
{
@@ -120,8 +138,6 @@ namespace eigenpy
120138
// Determine if obj_ptr can be converted in a Eigenvec
121139
static void* convertible(PyArrayObject* obj_ptr)
122140
{
123-
typedef typename MatType::Scalar T;
124-
125141
if (!PyArray_Check(obj_ptr))
126142
{
127143
#ifndef NDEBUG
@@ -130,16 +146,42 @@ namespace eigenpy
130146
return 0;
131147
}
132148

149+
if(MatType::IsVectorAtCompileTime)
150+
{
151+
if(PyArray_DIMS(obj_ptr)[0] > 1 && PyArray_DIMS(obj_ptr)[1] > 1)
152+
{
153+
#ifndef NDEBUG
154+
std::cerr << "The number of dimension of the object does not correspond to a vector" << std::endl;
155+
#endif
156+
return 0;
157+
}
158+
159+
if(((PyArray_DIMS(obj_ptr)[0] == 1) && (MatType::ColsAtCompileTime == 1))
160+
|| ((PyArray_DIMS(obj_ptr)[1] == 1) && (MatType::RowsAtCompileTime == 1)))
161+
{
162+
#ifndef NDEBUG
163+
if(MatType::ColsAtCompileTime == 1)
164+
std::cerr << "The object is not a column vector" << std::endl;
165+
else
166+
std::cerr << "The object is not a row vector" << std::endl;
167+
#endif
168+
return 0;
169+
}
170+
}
171+
133172
if (PyArray_NDIM(obj_ptr) != 2)
173+
{
134174
if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
135175
{
136176
#ifndef NDEBUG
137177
std::cerr << "The number of dimension of the object is not correct." << std::endl;
138178
#endif
139179
return 0;
140180
}
181+
}
141182

142-
if ((PyArray_ObjectType(reinterpret_cast<PyObject *>(obj_ptr), 0)) != NumpyEquivalentType<T>::type_code)
183+
if ((PyArray_ObjectType(reinterpret_cast<PyObject *>(obj_ptr), 0))
184+
!= NumpyEquivalentType<typename MatType::Scalar>::type_code)
143185
{
144186
#ifndef NDEBUG
145187
std::cerr << "The internal type as no Eigen equivalent." << std::endl;
@@ -178,6 +220,7 @@ namespace eigenpy
178220
memory->convertible = storage;
179221
}
180222
};
223+
181224
#define numpy_import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); } }
182225

183226
template<typename MatType,typename EigenEquivalentType>

src/map.hpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
* with eigenpy. If not, see <http://www.gnu.org/licenses/>.
1515
*/
1616

17-
#include <boost/python.hpp>
18-
#include <Eigen/Core>
17+
#include "eigenpy/fwd.hpp"
1918
#include <numpy/arrayobject.h>
20-
#include <eigenpy/exception.hpp>
19+
#include "eigenpy/exception.hpp"
2120

2221
namespace eigenpy
2322
{
@@ -30,6 +29,7 @@ namespace eigenpy
3029
{
3130
typedef MapNumpyTraits<MatType, MatType::IsVectorAtCompileTime> Impl;
3231
typedef typename Impl::EigenMap EigenMap;
32+
typedef typename Impl::Stride Stride;
3333

3434
static inline EigenMap map( PyArrayObject* pyArray );
3535
};
@@ -45,9 +45,9 @@ namespace eigenpy
4545
template<typename MatType>
4646
struct MapNumpyTraits<MatType,0>
4747
{
48-
typedef Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> Stride;
49-
typedef Eigen::Map<MatType,0,Stride> EigenMap;
50-
typedef typename MatType::Scalar T;
48+
typedef typename StrideType<MatType>::type Stride;
49+
typedef Eigen::Map<MatType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
50+
typedef typename MatType::Scalar Scalar;
5151

5252
static EigenMap mapImpl( PyArrayObject* pyArray )
5353
{
@@ -63,6 +63,9 @@ namespace eigenpy
6363
const long int itemsize = PyArray_ITEMSIZE(pyArray);
6464
const int stride1 = (int)PyArray_STRIDE(pyArray, 0) / (int)itemsize;
6565
const int stride2 = (int)PyArray_STRIDE(pyArray, 1) / (int)itemsize;
66+
Stride stride(stride2,stride1);
67+
68+
6669

6770
if( (MatType::RowsAtCompileTime!=R)
6871
&& (MatType::RowsAtCompileTime!=Eigen::Dynamic) )
@@ -71,17 +74,18 @@ namespace eigenpy
7174
&& (MatType::ColsAtCompileTime!=Eigen::Dynamic) )
7275
{ throw eigenpy::Exception("The number of columns does not fit with the matrix type."); }
7376

74-
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
75-
return EigenMap( pyData, R,C, Stride(stride2,stride1) );
77+
Scalar* pyData = reinterpret_cast<Scalar*>(PyArray_DATA(pyArray));
78+
79+
return EigenMap( pyData, R,C, stride );
7680
}
7781
};
7882

7983
template<typename MatType>
8084
struct MapNumpyTraits<MatType,1>
8185
{
82-
typedef Eigen::InnerStride<Eigen::Dynamic> Stride;
83-
typedef Eigen::Map<MatType,0,Stride> EigenMap;
84-
typedef typename MatType::Scalar T;
86+
typedef typename StrideType<MatType>::type Stride;
87+
typedef Eigen::Map<MatType,EIGENPY_DEFAULT_ALIGNMENT_VALUE,Stride> EigenMap;
88+
typedef typename MatType::Scalar Scalar;
8589

8690
static EigenMap mapImpl( PyArrayObject* pyArray )
8791
{
@@ -101,8 +105,8 @@ namespace eigenpy
101105
&& (MatType::MaxSizeAtCompileTime!=Eigen::Dynamic) )
102106
{ throw eigenpy::Exception("The number of elements does not fit with the vector type."); }
103107

104-
T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
105-
return EigenMap( pyData, R, 1, Stride(stride) );
108+
Scalar* pyData = reinterpret_cast<Scalar*>(PyArray_DATA(pyArray));
109+
return EigenMap( pyData, R, Stride(stride) );
106110
}
107111
};
108112

0 commit comments

Comments
 (0)