5#ifndef __eigenpy_sparse_eigen_from_python_hpp__ 6#define __eigenpy_sparse_eigen_from_python_hpp__ 8#include "eigenpy/fwd.hpp" 9#include "eigenpy/eigen-allocator.hpp" 10#include "eigenpy/scipy-type.hpp" 11#include "eigenpy/scalar-conversion.hpp" 15template <
typename SparseMatrixType>
17 Eigen::SparseMatrixBase<SparseMatrixType>> {
18 static PyTypeObject
const *get_pytype() {
19 PyTypeObject
const *py_type = ScipyType::get_pytype<SparseMatrixType>();
30template <
typename Scalar,
int Options,
typename StorageIndex>
31struct expected_pytype_for_arg<
32 Eigen::SparseMatrix<Scalar, Options, StorageIndex>>
34 Eigen::SparseMatrix<Scalar, Options, StorageIndex>> {};
36template <
typename Scalar,
int Options,
typename StorageIndex>
37struct rvalue_from_python_data<
38 Eigen::SparseMatrix<Scalar, Options, StorageIndex> const &>
40 Eigen::SparseMatrix<Scalar, Options, StorageIndex> const &> {
41 typedef Eigen::SparseMatrix<Scalar, Options, StorageIndex> T;
42 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(T
const &)
45template <
typename Derived>
46struct rvalue_from_python_data<Eigen::SparseMatrixBase<Derived> const &>
48 EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived
const &)
79template <
typename SparseMatrixType>
81 Eigen::SparseMatrixBase<SparseMatrixType>> {
82 typedef typename SparseMatrixType::Scalar Scalar;
89 bp::converter::rvalue_from_python_stage1_data *memory);
91 static void registration();
94template <
typename SparseMatrixType>
97 Eigen::SparseMatrixBase<SparseMatrixType>>
::convertible(PyObject *pyObj) {
98 const PyTypeObject *
type = Py_TYPE(pyObj);
99 const PyTypeObject *sparse_matrix_py_type =
100 ScipyType::get_pytype<SparseMatrixType>();
101 typedef typename SparseMatrixType::Scalar Scalar;
103 if (
type != sparse_matrix_py_type)
return 0;
105 bp::object obj(bp::handle<>(bp::borrowed(pyObj)));
107 const int type_num = ScipyType::get_numpy_type_num(obj);
109 if (!np_type_is_convertible_into_scalar<Scalar>(type_num))
return 0;
114template <
typename MatOrRefType>
115void eigen_sparse_matrix_from_py_construct(
116 PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) {
117 typedef typename MatOrRefType::Scalar Scalar;
118 typedef typename MatOrRefType::StorageIndex StorageIndex;
120 typedef Eigen::Map<MatOrRefType> MapMatOrRefType;
122 bp::converter::rvalue_from_python_storage<MatOrRefType> *storage =
124 bp::converter::rvalue_from_python_storage<MatOrRefType> *
>(
125 reinterpret_cast<void *
>(memory));
126 void *raw_ptr = storage->storage.bytes;
128 bp::object obj(bp::handle<>(bp::borrowed(pyObj)));
130 const int type_num_python_sparse_matrix = ScipyType::get_numpy_type_num(obj);
131 const int type_num_eigen_sparse_matrix = Register::getTypeCode<Scalar>();
133 if (type_num_eigen_sparse_matrix == type_num_python_sparse_matrix) {
134 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> DataVector;
136 DataVector data = bp::extract<DataVector>(obj.attr(
"data"));
137 bp::tuple shape = bp::extract<bp::tuple>(obj.attr(
"shape"));
138 typedef Eigen::Matrix<StorageIndex, Eigen::Dynamic, 1> StorageIndexVector;
141 StorageIndexVector indices =
142 bp::extract<StorageIndexVector>(obj.attr(
"indices"));
143 StorageIndexVector indptr =
144 bp::extract<StorageIndexVector>(obj.attr(
"indptr"));
146 const Eigen::Index m = bp::extract<Eigen::Index>(shape[0]),
147 n = bp::extract<Eigen::Index>(shape[1]),
148 nnz = bp::extract<Eigen::Index>(obj.attr(
"nnz"));
151 Scalar *data_ptr =
nullptr;
152 StorageIndex *indices_ptr =
nullptr;
154 data_ptr = data.data();
155 indices_ptr = indices.data();
157 MapMatOrRefType sparse_map(m, n, nnz, indptr.data(), indices_ptr, data_ptr);
159#if EIGEN_VERSION_AT_LEAST(3, 4, 90) 160 sparse_map.sortInnerIndices();
163 new (raw_ptr) MatOrRefType(sparse_map);
166 memory->convertible = storage->storage.bytes;
169template <
typename SparseMatrixType>
171 Eigen::SparseMatrixBase<SparseMatrixType>>::
172 construct(PyObject *pyObj,
173 bp::converter::rvalue_from_python_stage1_data *memory) {
174 eigen_sparse_matrix_from_py_construct<SparseMatrixType>(pyObj, memory);
177template <
typename SparseMatrixType>
180 Eigen::SparseMatrixBase<SparseMatrixType>>::registration() {
181 bp::converter::registry::push_back(
184#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
191template <
typename SparseMatrixType>
193 Eigen::SparseMatrixBase<SparseMatrixType>> {
194 static void registration() {
195 EigenFromPy<SparseMatrixType>::registration();
198 typedef Eigen::SparseMatrixBase<SparseMatrixType> SparseMatrixBase;
199 EigenFromPy<SparseMatrixBase>::registration();
211template <
typename SparseMatrixType>
215 typedef Eigen::SparseMatrixBase<SparseMatrixType> Base;
217 static void registration() {
218 bp::converter::registry::push_back(
221#ifndef BOOST_PYTHON_NO_PY_SIGNATURES
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.
static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory)
Allocate memory and copy pyObj in the new storage.
static void * convertible(PyObject *pyObj)
Determine if pyObj can be converted into a MatType object.