eigenpy 3.12.0
Bindings between Numpy and Eigen using Boost.Python
Loading...
Searching...
No Matches
scipy-allocator.hpp
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"
9#include "eigenpy/eigen-allocator.hpp"
10#include "eigenpy/scipy-type.hpp"
11#include "eigenpy/register.hpp"
12
13namespace eigenpy {
14
15template <typename EigenType, typename BaseType>
17
18template <typename EigenType>
20
21template <typename MatType>
23 MatType,
24 Eigen::SparseMatrixBase<typename remove_const_reference<MatType>::type>>
26
27template <typename MatType>
28struct scipy_allocator_impl<const MatType,
29 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
38template <typename MatType>
39struct scipy_allocator_impl<const MatType &,
40 const Eigen::SparseMatrixBase<MatType>>
42
43template <typename EigenType,
44 typename BaseType = typename get_eigen_base_type<EigenType>::type>
45struct ScipyAllocator : scipy_allocator_impl<EigenType, BaseType> {};
46
47template <typename MatType>
49 template <typename SimilarMatrixType>
50 static PyObject *allocate(
51 const Eigen::SparseCompressedBase<SimilarMatrixType> &mat_,
52 bool copy = false) {
53 EIGENPY_UNUSED_VARIABLE(copy);
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__
Default cast algo to cast a From to To. Can be specialized for any types.
Definition user-type.hpp:18