eigenc.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 
14  {
15  static PyObject* convert(Eigen::MatrixXd const& mat)
16  {
17  typedef Eigen::MatrixXd::Scalar T;
18 
19  npy_intp shape[2] = { mat.rows(), mat.cols() };
20  PyArrayObject* pyArray = (PyArrayObject*)
21  PyArray_SimpleNew(2, shape,
23 
24  T* pyData = (T*)PyArray_DATA(pyArray);
25  for(int i=0;i<mat.rows();++i)
26  for(int j=0;j<mat.cols();++j)
27  pyData[i*mat.cols()+j] = mat(i,j);
28 
29  return ((PyObject*)pyArray);
30  }
31  };
32 
33 
35  {
36 
38  {
39  bp::converter::registry
40  ::push_back(&convertible,
41  &construct,
42  bp::type_id<Eigen::MatrixXd>());
43  }
44 
45  // Determine if obj_ptr can be converted in a Eigenvec
46  static void* convertible(PyObject* obj_ptr)
47  {
48  typedef Eigen::MatrixXd::Scalar T;
49 
50  if (!PyArray_Check(obj_ptr)) {
51  return 0;
52  }
53  if (PyArray_NDIM(obj_ptr) > 2) {
54  return 0;
55  }
56  if (PyArray_ObjectType(obj_ptr, 0) != NumpyEquivalentType<T>::type_code) {
57  return 0;
58  }
59  int flags = PyArray_FLAGS(obj_ptr);
60  if (!(flags & NPY_C_CONTIGUOUS)) {
61  return 0;
62  }
63  if (!(flags & NPY_ALIGNED)) {
64  return 0;
65  }
66 
67  return obj_ptr;
68  }
69 
70  // Convert obj_ptr into a Eigenvec
71  static void construct(PyObject* pyObj,
72  bp::converter::rvalue_from_python_stage1_data* memory)
73  {
74  typedef Eigen::MatrixXd::Scalar T;
75  using namespace Eigen;
76 
77  PyArrayObject * pyArray = reinterpret_cast<PyArrayObject*>(pyObj);
78  int ndims = PyArray_NDIM(pyArray);
79  assert(ndims == 2);
80 
81  int dtype_size = (PyArray_DESCR(pyArray))->elsize;
82  int s1 = PyArray_STRIDE(pyArray, 0);
83  assert(s1 % dtype_size == 0);
84 
85  int R = MatrixXd::RowsAtCompileTime;
86  int C = MatrixXd::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  void* storage = ((bp::converter::rvalue_from_python_storage<MatrixXd>*)
96  (memory))->storage.bytes;
97  MatrixXd & mat = * new (storage) MatrixXd(R,C);
98  for(int i=0;i<R;++i)
99  for(int j=0;j<C;++j)
100  mat(i,j) = pyData[i*C+j];
101 
102  memory->convertible = storage;
103  }
104  };
105 
106 
107 }
108 
109 Eigen::MatrixXd test()
110 {
111  Eigen::MatrixXd mat = Eigen::MatrixXd::Random(5,5);
112  std::cout << "EigenMAt = " << mat << std::endl;
113  return mat;
114 }
115 
116 void test2( Eigen::MatrixXd mat )
117 {
118  std::cout << "test2: dim = " << mat.rows() << " ||| m[0,0] = " << mat(0,0) << std::endl;
119 }
120 
122 {
123  import_array();
124  namespace bp = boost::python;
125  bp::to_python_converter<Eigen::MatrixXd,
128 
129  bp::def("test", test);
130  bp::def("test2", test2);
131 }
static void * convertible(PyObject *obj_ptr)
Definition: eigenc.cpp:46
Definition: complex.cpp:7
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Definition: eigenc.cpp:71
Eigen::MatrixXd test()
Definition: eigenc.cpp:109
BOOST_PYTHON_MODULE(libeigenc)
Definition: eigenc.cpp:121
void test2(Eigen::MatrixXd mat)
Definition: eigenc.cpp:116
Definition: eigen.cpp:5
static PyObject * convert(Eigen::MatrixXd const &mat)
Definition: eigenc.cpp:15


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