scipy-allocator.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2024 INRIA
3  */
4 
5 #ifndef __eigenpy_scipy_allocator_hpp__
6 #define __eigenpy_scipy_allocator_hpp__
7 
8 #include "eigenpy/fwd.hpp"
10 #include "eigenpy/scipy-type.hpp"
11 #include "eigenpy/register.hpp"
12 
13 namespace eigenpy {
14 
15 template <typename EigenType, typename BaseType>
17 
18 template <typename EigenType>
20 
21 template <typename MatType>
23  MatType,
24  Eigen::SparseMatrixBase<typename remove_const_reference<MatType>::type> >
26 
27 template <typename MatType>
29  const MatType, const Eigen::SparseMatrixBase<
30  typename remove_const_reference<MatType>::type> >
31  : scipy_allocator_impl_sparse_matrix<const MatType> {};
32 
33 // template <typename MatType>
34 // struct scipy_allocator_impl<MatType &, Eigen::MatrixBase<MatType> > :
35 // scipy_allocator_impl_sparse_matrix<MatType &>
36 //{};
37 
38 template <typename MatType>
39 struct scipy_allocator_impl<const MatType &,
40  const Eigen::SparseMatrixBase<MatType> >
42 
43 template <typename EigenType,
44  typename BaseType = typename get_eigen_base_type<EigenType>::type>
45 struct ScipyAllocator : scipy_allocator_impl<EigenType, BaseType> {};
46 
47 template <typename MatType>
49  template <typename SimilarMatrixType>
50  static PyObject *allocate(
51  const Eigen::SparseCompressedBase<SimilarMatrixType> &mat_,
52  bool copy = false) {
54  typedef typename SimilarMatrixType::Scalar Scalar;
55  typedef typename SimilarMatrixType::StorageIndex StorageIndex;
56 
57  enum { IsRowMajor = SimilarMatrixType::IsRowMajor };
58 
59  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> DataVector;
60  typedef const Eigen::Map<const DataVector> MapDataVector;
61  typedef Eigen::Matrix<StorageIndex, Eigen::Dynamic, 1> StorageIndexVector;
62  typedef Eigen::Matrix<int32_t, Eigen::Dynamic, 1> ScipyStorageIndexVector;
63  typedef const Eigen::Map<const StorageIndexVector> MapStorageIndexVector;
64 
65  SimilarMatrixType &mat = mat_.const_cast_derived();
66  bp::object scipy_sparse_matrix_type =
67  ScipyType::get_pytype_object<SimilarMatrixType>();
68 
69  MapDataVector data(mat.valuePtr(), mat.nonZeros());
70  MapStorageIndexVector outer_indices(
71  mat.outerIndexPtr(), (IsRowMajor ? mat.rows() : mat.cols()) + 1);
72  MapStorageIndexVector inner_indices(mat.innerIndexPtr(), mat.nonZeros());
73 
74  bp::object scipy_sparse_matrix;
75 
76  if (mat.rows() == 0 &&
77  mat.cols() == 0) // handle the specific case of empty matrix
78  {
79  // PyArray_Descr* npy_type =
80  // Register::getPyArrayDescrFromScalarType<Scalar>(); bp::dict args;
81  // args["dtype"] =
82  // bp::object(bp::handle<>(bp::borrowed(npy_type->typeobj)));
83  // args["shape"] = bp::object(bp::handle<>(bp::borrowed(Py_None)));
84  // scipy_sparse_matrix =
85  // scipy_sparse_matrix_type(*bp::make_tuple(0,0),**args);
86  scipy_sparse_matrix = scipy_sparse_matrix_type(
87  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>(0, 0));
88  } else if (mat.nonZeros() == 0) {
89  scipy_sparse_matrix =
90  scipy_sparse_matrix_type(bp::make_tuple(mat.rows(), mat.cols()));
91  } else {
92  scipy_sparse_matrix = scipy_sparse_matrix_type(bp::make_tuple(
93  DataVector(data),
94  ScipyStorageIndexVector(inner_indices.template cast<int32_t>()),
95  ScipyStorageIndexVector(
96  outer_indices.template cast<int32_t>()))); //,
97  // bp::make_tuple(mat.rows(),
98  // mat.cols())));
99  }
100  Py_INCREF(scipy_sparse_matrix.ptr());
101  return scipy_sparse_matrix.ptr();
102  }
103 };
104 
105 // template <typename MatType>
106 // struct scipy_allocator_impl_sparse_matrix<MatType &> {
107 // template <typename SimilarMatrixType>
108 // static PyArrayObject *allocate(Eigen::PlainObjectBase<SimilarMatrixType>
109 // &mat,
110 // npy_intp nd, npy_intp *shape) {
111 // typedef typename SimilarMatrixType::Scalar Scalar;
112 // enum {
113 // NPY_ARRAY_MEMORY_CONTIGUOUS =
114 // SimilarMatrixType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY
115 // };
116 //
117 // if (NumpyType::sharedMemory()) {
118 // const int Scalar_type_code = Register::getTypeCode<Scalar>();
119 // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
120 // getPyArrayType(), static_cast<int>(nd), shape, Scalar_type_code,
121 // mat.data(), NPY_ARRAY_MEMORY_CONTIGUOUS | NPY_ARRAY_ALIGNED);
122 //
123 // return pyArray;
124 // } else {
125 // return NumpyAllocator<MatType>::allocate(mat, nd, shape);
126 // }
127 // }
128 // };
129 
130 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
131 
132 // template <typename MatType, int Options, typename Stride>
133 // struct scipy_allocator_impl_sparse_matrix<Eigen::Ref<MatType, Options,
134 // Stride> > {
135 // typedef Eigen::Ref<MatType, Options, Stride> RefType;
136 //
137 // static PyArrayObject *allocate(RefType &mat, npy_intp nd, npy_intp *shape)
138 // {
139 // typedef typename RefType::Scalar Scalar;
140 // enum {
141 // NPY_ARRAY_MEMORY_CONTIGUOUS =
142 // RefType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY
143 // };
144 //
145 // if (NumpyType::sharedMemory()) {
146 // const int Scalar_type_code = Register::getTypeCode<Scalar>();
147 // const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1);
148 // Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride()
149 // : mat.innerStride(),
150 // outer_stride = reverse_strides ? mat.innerStride()
151 // : mat.outerStride();
152 //
153 // const int elsize =
154 // call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp
155 // strides[2] = {elsize * inner_stride, elsize * outer_stride};
156 //
157 // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
158 // getPyArrayType(), static_cast<int>(nd), shape, Scalar_type_code,
159 // strides, mat.data(), NPY_ARRAY_MEMORY_CONTIGUOUS |
160 // NPY_ARRAY_ALIGNED);
161 //
162 // return pyArray;
163 // } else {
164 // return NumpyAllocator<MatType>::allocate(mat, nd, shape);
165 // }
166 // }
167 // };
168 
169 #endif
170 
171 // template <typename MatType>
172 // struct scipy_allocator_impl_sparse_matrix<const MatType &> {
173 // template <typename SimilarMatrixType>
174 // static PyArrayObject *allocate(
175 // const Eigen::PlainObjectBase<SimilarMatrixType> &mat, npy_intp nd,
176 // npy_intp *shape) {
177 // typedef typename SimilarMatrixType::Scalar Scalar;
178 // enum {
179 // NPY_ARRAY_MEMORY_CONTIGUOUS_RO = SimilarMatrixType::IsRowMajor
180 // ? NPY_ARRAY_CARRAY_RO
181 // : NPY_ARRAY_FARRAY_RO
182 // };
183 //
184 // if (NumpyType::sharedMemory()) {
185 // const int Scalar_type_code = Register::getTypeCode<Scalar>();
186 // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
187 // getPyArrayType(), static_cast<int>(nd), shape, Scalar_type_code,
188 // const_cast<Scalar *>(mat.data()),
189 // NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED);
190 //
191 // return pyArray;
192 // } else {
193 // return NumpyAllocator<MatType>::allocate(mat, nd, shape);
194 // }
195 // }
196 // };
197 
198 #if EIGEN_VERSION_AT_LEAST(3, 2, 0)
199 
200 // template <typename MatType, int Options, typename Stride>
201 // struct scipy_allocator_impl_sparse_matrix<
202 // const Eigen::Ref<const MatType, Options, Stride> > {
203 // typedef const Eigen::Ref<const MatType, Options, Stride> RefType;
204 //
205 // static PyArrayObject *allocate(RefType &mat, npy_intp nd, npy_intp *shape)
206 // {
207 // typedef typename RefType::Scalar Scalar;
208 // enum {
209 // NPY_ARRAY_MEMORY_CONTIGUOUS_RO =
210 // RefType::IsRowMajor ? NPY_ARRAY_CARRAY_RO : NPY_ARRAY_FARRAY_RO
211 // };
212 //
213 // if (NumpyType::sharedMemory()) {
214 // const int Scalar_type_code = Register::getTypeCode<Scalar>();
215 //
216 // const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1);
217 // Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride()
218 // : mat.innerStride(),
219 // outer_stride = reverse_strides ? mat.innerStride()
220 // : mat.outerStride();
221 //
222 // const int elsize =
223 // call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp
224 // strides[2] = {elsize * inner_stride, elsize * outer_stride};
225 //
226 // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
227 // getPyArrayType(), static_cast<int>(nd), shape, Scalar_type_code,
228 // strides, const_cast<Scalar *>(mat.data()),
229 // NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED);
230 //
231 // return pyArray;
232 // } else {
233 // return NumpyAllocator<MatType>::allocate(mat, nd, shape);
234 // }
235 // }
236 // };
237 
238 #endif
239 
240 } // namespace eigenpy
241 
242 #endif // ifndef __eigenpy_scipy_allocator_hpp__
Eigen
Definition: complex.cpp:7
register.hpp
eigenpy::cast
Default cast algo to cast a From to To. Can be specialized for any types.
Definition: user-type.hpp:18
EIGENPY_UNUSED_VARIABLE
#define EIGENPY_UNUSED_VARIABLE(var)
Definition: fwd.hpp:111
fwd.hpp
setup.data
data
Definition: setup.in.py:48
eigenpy::scipy_allocator_impl_sparse_matrix::allocate
static PyObject * allocate(const Eigen::SparseCompressedBase< SimilarMatrixType > &mat_, bool copy=false)
Definition: scipy-allocator.hpp:50
eigenpy::scipy_allocator_impl
Definition: scipy-allocator.hpp:16
eigenpy::get_eigen_base_type::type
boost::mpl::if_< boost::is_const< typename boost::remove_reference< EigenType >::type >, const _type, _type >::type type
Definition: fwd.hpp:166
eigenpy
Definition: alignment.hpp:14
eigen-allocator.hpp
copy
ReturnMatrix copy(const Eigen::MatrixBase< Matrix > &mat)
Definition: matrix.cpp:131
test_eigen_ref.mat
mat
Definition: test_eigen_ref.py:137
eigenpy::ScipyAllocator
Definition: scipy-allocator.hpp:45
scipy-type.hpp
eigenpy::scipy_allocator_impl_sparse_matrix
Definition: scipy-allocator.hpp:19


eigenpy
Author(s): Justin Carpentier, Nicolas Mansard
autogenerated on Fri Jun 14 2024 02:15:58