.. _program_listing_file__tmp_ws_src_eigenpy_include_eigenpy_sparse_eigen-from-python.hpp: Program Listing for File eigen-from-python.hpp ============================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/eigenpy/include/eigenpy/sparse/eigen-from-python.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Copyright (c) 2024 INRIA // #ifndef __eigenpy_sparse_eigen_from_python_hpp__ #define __eigenpy_sparse_eigen_from_python_hpp__ #include "eigenpy/fwd.hpp" #include "eigenpy/eigen-allocator.hpp" #include "eigenpy/scipy-type.hpp" #include "eigenpy/scalar-conversion.hpp" namespace eigenpy { template struct expected_pytype_for_arg > { static PyTypeObject const *get_pytype() { PyTypeObject const *py_type = ScipyType::get_pytype(); return py_type; } }; } // namespace eigenpy namespace boost { namespace python { namespace converter { template struct expected_pytype_for_arg< Eigen::SparseMatrix > : eigenpy::expected_pytype_for_arg< Eigen::SparseMatrix > {}; template struct rvalue_from_python_data< Eigen::SparseMatrix const &> : ::eigenpy::rvalue_from_python_data< Eigen::SparseMatrix const &> { typedef Eigen::SparseMatrix T; EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(T const &) }; template struct rvalue_from_python_data const &> : ::eigenpy::rvalue_from_python_data { EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived const &) }; } // namespace converter } // namespace python } // namespace boost namespace boost { namespace python { namespace detail { // template // struct referent_storage &> { // typedef Eigen::TensorRef RefType; // typedef ::eigenpy::details::referent_storage_eigen_ref // StorageType; typedef typename ::eigenpy::aligned_storage< // referent_size::value>::type type; // }; // template // struct referent_storage &> { // typedef Eigen::TensorRef RefType; // typedef ::eigenpy::details::referent_storage_eigen_ref // StorageType; typedef typename ::eigenpy::aligned_storage< // referent_size::value>::type type; // }; } // namespace detail } // namespace python } // namespace boost namespace eigenpy { template struct eigen_from_py_impl > { typedef typename SparseMatrixType::Scalar Scalar; static void *convertible(PyObject *pyObj); static void construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory); static void registration(); }; template void *eigen_from_py_impl< SparseMatrixType, Eigen::SparseMatrixBase >::convertible(PyObject *pyObj) { const PyTypeObject *type = Py_TYPE(pyObj); const PyTypeObject *sparse_matrix_py_type = ScipyType::get_pytype(); typedef typename SparseMatrixType::Scalar Scalar; if (type != sparse_matrix_py_type) return 0; bp::object obj(bp::handle<>(bp::borrowed(pyObj))); const int type_num = ScipyType::get_numpy_type_num(obj); if (!np_type_is_convertible_into_scalar(type_num)) return 0; return pyObj; } template void eigen_sparse_matrix_from_py_construct( PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) { typedef typename MatOrRefType::Scalar Scalar; typedef typename MatOrRefType::StorageIndex StorageIndex; typedef Eigen::Map MapMatOrRefType; bp::converter::rvalue_from_python_storage *storage = reinterpret_cast< bp::converter::rvalue_from_python_storage *>( reinterpret_cast(memory)); void *raw_ptr = storage->storage.bytes; bp::object obj(bp::handle<>(bp::borrowed(pyObj))); const int type_num_python_sparse_matrix = ScipyType::get_numpy_type_num(obj); const int type_num_eigen_sparse_matrix = Register::getTypeCode(); if (type_num_eigen_sparse_matrix == type_num_python_sparse_matrix) { typedef Eigen::Matrix DataVector; // typedef const Eigen::Ref RefDataVector; DataVector data = bp::extract(obj.attr("data")); bp::tuple shape = bp::extract(obj.attr("shape")); typedef Eigen::Matrix StorageIndexVector; // typedef const Eigen::Ref // RefStorageIndexVector; StorageIndexVector indices = bp::extract(obj.attr("indices")); StorageIndexVector indptr = bp::extract(obj.attr("indptr")); const Eigen::Index m = bp::extract(shape[0]), n = bp::extract(shape[1]), nnz = bp::extract(obj.attr("nnz")); // Handle the specific case of the null matrix Scalar *data_ptr = nullptr; StorageIndex *indices_ptr = nullptr; if (nnz > 0) { data_ptr = data.data(); indices_ptr = indices.data(); } MapMatOrRefType sparse_map(m, n, nnz, indptr.data(), indices_ptr, data_ptr); new (raw_ptr) MatOrRefType(sparse_map); } memory->convertible = storage->storage.bytes; } template void eigen_from_py_impl >:: construct(PyObject *pyObj, bp::converter::rvalue_from_python_stage1_data *memory) { eigen_sparse_matrix_from_py_construct(pyObj, memory); } template void eigen_from_py_impl< SparseMatrixType, Eigen::SparseMatrixBase >::registration() { bp::converter::registry::push_back( reinterpret_cast(&eigen_from_py_impl::convertible), &eigen_from_py_impl::construct, bp::type_id() #ifndef BOOST_PYTHON_NO_PY_SIGNATURES , &eigenpy::expected_pytype_for_arg::get_pytype #endif ); } template struct eigen_from_py_converter_impl< SparseMatrixType, Eigen::SparseMatrixBase > { static void registration() { EigenFromPy::registration(); // Add conversion to Eigen::SparseMatrixBase typedef Eigen::SparseMatrixBase SparseMatrixBase; EigenFromPy::registration(); // // Add conversion to Eigen::Ref // typedef Eigen::Ref RefType; // EigenFromPy::registration(); // // // Add conversion to Eigen::Ref // typedef const Eigen::Ref ConstRefType; // EigenFromPy::registration(); } }; template struct EigenFromPy > : EigenFromPy { typedef EigenFromPy EigenFromPyDerived; typedef Eigen::SparseMatrixBase Base; static void registration() { bp::converter::registry::push_back( reinterpret_cast(&EigenFromPy::convertible), &EigenFromPy::construct, bp::type_id() #ifndef BOOST_PYTHON_NO_PY_SIGNATURES , &eigenpy::expected_pytype_for_arg::get_pytype #endif ); } }; // // template // struct EigenFromPy > { // typedef Eigen::TensorRef RefType; // typedef typename TensorType::Scalar Scalar; // // /// \brief Determine if pyObj can be converted into a MatType object // static void *convertible(PyObject *pyObj) { // if (!call_PyArray_Check(pyObj)) return 0; // PyArrayObject *pyArray = reinterpret_cast(pyObj); // if (!PyArray_ISWRITEABLE(pyArray)) return 0; // return EigenFromPy::convertible(pyObj); // } // // static void registration() { // bp::converter::registry::push_back( // reinterpret_cast(&EigenFromPy::convertible), // &eigen_from_py_construct, bp::type_id() // #ifndef BOOST_PYTHON_NO_PY_SIGNATURES // , // &eigenpy::expected_pytype_for_arg::get_pytype // #endif // ); // } //}; // template // struct EigenFromPy > { // typedef const Eigen::TensorRef ConstRefType; // typedef typename TensorType::Scalar Scalar; // // /// \brief Determine if pyObj can be converted into a MatType object // static void *convertible(PyObject *pyObj) { // return EigenFromPy::convertible(pyObj); // } // // static void registration() { // bp::converter::registry::push_back( // reinterpret_cast(&EigenFromPy::convertible), // &eigen_from_py_construct, bp::type_id() // #ifndef BOOST_PYTHON_NO_PY_SIGNATURES // , // &eigenpy::expected_pytype_for_arg::get_pytype // #endif // ); // } // }; } // namespace eigenpy #endif // __eigenpy_sparse_eigen_from_python_hpp__