eigentemplate.cpp
Go to the documentation of this file.
1 #include "eigenpy/fwd.hpp"
2 #include <numpy/arrayobject.h>
3 
4 namespace boopy
5 {
6  namespace bp = boost::python;
7 
8  template <typename SCALAR> struct NumpyEquivalentType {};
9  template <> struct NumpyEquivalentType<double> { enum { type_code = NPY_DOUBLE };};
10  template <> struct NumpyEquivalentType<int> { enum { type_code = NPY_INT };};
11  template <> struct NumpyEquivalentType<float> { enum { type_code = NPY_FLOAT };};
12 
13  /* --- TO PYTHON -------------------------------------------------------------- */
14  template< typename MatType >
15  struct EigenMatrix_to_python_matrix
16  {
17  static PyObject* convert(MatType const& mat)
18  {
19  typedef typename MatType::Scalar T;
20  const int R = mat.rows(), C = mat.cols();
21 
22  npy_intp shape[2] = { R,C };
23  PyArrayObject* pyArray = (PyArrayObject*)
24  PyArray_SimpleNew(2, shape,
26 
27  T* pyData = (T*)PyArray_DATA(pyArray);
28  Eigen::Map< Eigen::Matrix<T,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor> > pyMatrix(pyData,R,C);
29  pyMatrix = mat;
30 
31  return (PyObject*)pyArray;
32  }
33  };
34 
35  /* --- FROM PYTHON ------------------------------------------------------------ */
36  template<typename MatType>
38  {
39 
41  {
42  bp::converter::registry
43  ::push_back(&convertible,
44  &construct,
45  bp::type_id<MatType>());
46  }
47 
48  // Determine if obj_ptr can be converted in a Eigenvec
49  static void* convertible(PyObject* obj_ptr)
50  {
51  typedef typename MatType::Scalar T;
52 
53  if (!PyArray_Check(obj_ptr)) return 0;
54 
55  std::cout << "Until here ok. ndim = " << PyArray_NDIM(obj_ptr) << " isvec " << MatType::IsVectorAtCompileTime << std::endl;
56  if (PyArray_NDIM(obj_ptr) != 2)
57  if ( (PyArray_NDIM(obj_ptr) !=1) || (! MatType::IsVectorAtCompileTime) )
58  return 0;
59  std::cout << "Until here ok." << std::endl;
60 
61  if (PyArray_ObjectType(obj_ptr, 0) != NumpyEquivalentType<T>::type_code)
62  return 0;
63 
64  if (!(PyArray_FLAGS(obj_ptr) & NPY_ALIGNED))
65  {
66  std::cerr << "NPY non-aligned matrices are not implemented." << std::endl;
67  return 0;
68  }
69 
70  return obj_ptr;
71  }
72 
73  // Convert obj_ptr into a Eigenvec
74  static void construct(PyObject* pyObj,
75  bp::converter::rvalue_from_python_stage1_data* memory)
76  {
77  typedef typename MatType::Scalar T;
78  using namespace Eigen;
79 
80  std::cout << "Until here ok. Constructing..." << std::endl;
81  PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
82 
83  if ( PyArray_NDIM(pyArray) == 2 )
84  {
85  int R = MatType::RowsAtCompileTime;
86  int C = MatType::ColsAtCompileTime;
87  if (R == Eigen::Dynamic) R = PyArray_DIMS(pyArray)[0];
88  else assert(PyArray_DIMS(pyArray)[0]==R);
89 
90  if (C == Eigen::Dynamic) C = PyArray_DIMS(pyArray)[1];
91  else assert(PyArray_DIMS(pyArray)[1]==C);
92 
93  T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
94 
95  int itemsize = PyArray_ITEMSIZE(pyArray);
96  int stride1 = PyArray_STRIDE(pyArray, 0) / itemsize;
97  int stride2 = PyArray_STRIDE(pyArray, 1) / itemsize;
98  std::cout << "STRIDE = " << stride1 << " x " << stride2 << std::endl;
99  Eigen::Map<MatType,0,Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> >
100  pyMap( pyData, R,C, Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic>(stride2,stride1) );
101  std::cout << "Map = " << pyMap << std::endl;
102 
103  void* storage = ((bp::converter::rvalue_from_python_storage<MatType>*)
104  (memory))->storage.bytes;
105  MatType & mat = * new (storage) MatType(R,C);
106  mat = pyMap;
107 
108  memory->convertible = storage;
109  }
110  else
111  {
112  int R = MatType::MaxSizeAtCompileTime, C=1;
113  if(R==Eigen::Dynamic) R = PyArray_DIMS(pyArray)[0];
114  else assert(PyArray_DIMS(pyArray)[0]==R);
115 
116  T* pyData = reinterpret_cast<T*>(PyArray_DATA(pyArray));
117 
118  int itemsize = PyArray_ITEMSIZE(pyArray);
119  int stride = PyArray_STRIDE(pyArray, 0) / itemsize;
120  Eigen::Stride<Eigen::Dynamic,Eigen::Dynamic> s(stride,0);
121  Eigen::Map<MatType,0,Eigen::InnerStride<Eigen::Dynamic> >
122  pyMap( pyData, R, 1, Eigen::InnerStride<Eigen::Dynamic>(stride) );
123  std::cout << "Map = " << pyMap << std::endl;
124 
125  void* storage = ((bp::converter::rvalue_from_python_storage<MatType>*)
126  (memory))->storage.bytes;
127  MatType & mat = * new (storage) MatType(R,C);
128  mat = pyMap;
129 
130  memory->convertible = storage;
131  }
132  }
133  };
134 
135 
136 }
137 
138 Eigen::MatrixXd test()
139 {
140  Eigen::MatrixXd mat = Eigen::MatrixXd::Random(3,6);
141  std::cout << "EigenMAt = " << mat << std::endl;
142  return mat;
143 }
144 Eigen::VectorXd testVec()
145 {
146  Eigen::VectorXd mat = Eigen::VectorXd::Random(6);
147  std::cout << "EigenVec = " << mat << std::endl;
148  return mat;
149 }
150 
151 void test2( Eigen::MatrixXd mat )
152 {
153  std::cout << "Test2 mat = " << mat << std::endl;
154 }
155 void test2Vec( Eigen::VectorXd v )
156 {
157  std::cout << "Test2 vec = " << v << std::endl;
158 }
159 
160 BOOST_PYTHON_MODULE(libeigentemplate)
161 {
162  import_array();
163  namespace bp = boost::python;
164  bp::to_python_converter<Eigen::MatrixXd,
167 
168  bp::to_python_converter<Eigen::VectorXd,
171 
172  bp::def("test", test);
173  bp::def("testVec", testVec);
174  bp::def("test2", test2);
175  bp::def("test2Vec", test2Vec);
176 }
void test2(Eigen::MatrixXd mat)
static void * convertible(PyObject *obj_ptr)
Definition: complex.cpp:7
static PyObject * convert(MatType const &mat)
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
void test2Vec(Eigen::VectorXd v)
Eigen::VectorXd testVec()
BOOST_PYTHON_MODULE(libeigentemplate)
Definition: eigen.cpp:5
Eigen::MatrixXd test()


eigenpy
Author(s): Justin Carpentier, Nicolas Mansard
autogenerated on Sat Apr 17 2021 02:37:59