7 #ifndef MDS_UTILS_PYTHON_UBLAS_MATRIX_SPARSE_HPP_INCLUDED     8 #define MDS_UTILS_PYTHON_UBLAS_MATRIX_SPARSE_HPP_INCLUDED    27 #include <mds_utils/python/ublas/detail/common.hpp>    31 #include <boost/numeric/ublas/matrix_sparse.hpp>    32 #include <boost/fusion/container/vector.hpp>    33 #include <boost/numeric/conversion/cast.hpp>    37 namespace mds_utils { 
namespace python { 
namespace ublas {
    42 template<
class orientation_category>
    43 struct scipy_sparse_mtx;
    46 struct scipy_sparse_mtx<
boost::numeric::ublas::row_major_tag> {
    48     static const std::string    name;
    51 const std::string scipy_sparse_mtx<boost::numeric::ublas::row_major_tag>::name(
"csr_matrix");
    54 struct scipy_sparse_mtx<
boost::numeric::ublas::column_major_tag> {
    56     static const std::string    name;
    59 const std::string scipy_sparse_mtx<boost::numeric::ublas::column_major_tag>::name(
"csc_matrix");
    85 inline typename std::enable_if<
    86     mds_utils::ublas::is_compressed_matrix<M>::value,M>::type
    91     Obj module(PyImport_ImportModule(
"scipy.sparse"));
    95     Obj type_obj(module.
attr(detail::scipy_sparse_mtx<
    96             typename M::orientation_category>::name));
    99     if (!PyType_Check(type_obj) ||
   100         !PyObject_TypeCheck(po,
   101                 reinterpret_cast<PyTypeObject*>(static_cast<PyObject*>(type_obj)))) {
   103         throw std::invalid_argument(
   104                 "Cannot get a uBLAS compressed matrix from the given parameter.\n"   105                 "Check the data type and the storage layout (i.e. csr or csc).");
   113             indices(o.
attr(
"indices")),
   114             indptr(o.
attr(
"indptr"));
   117         Nr(get<size_t>(shape[0])),
   118         Nc(get<size_t>(shape[1])),
   119         nnz(get<size_t>(o.
attr(
"nnz")));
   121     if (Nr == 0 || Nc == 0) 
return M();
   126         it_data(reinterpret_cast<PyArrayObject*>(static_cast<PyObject*>(data))),
   127         it_data_end(it_data,
true);
   129         it_inds(reinterpret_cast<PyArrayObject*>(static_cast<PyObject*>(indices))),
   130         it_inds_end(it_inds,
true),
   131         it_indptr(reinterpret_cast<PyArrayObject*>(static_cast<PyObject*>(indptr))),
   132         it_indptr_end(it_indptr,
true);
   134     std::copy(it_data,it_data_end,mout.value_data().begin());
   135     std::copy(it_inds,it_inds_end,mout.index2_data().begin());
   136     std::copy(it_indptr,it_indptr_end,mout.index1_data().begin());
   138     mout.set_filled(
len(indptr),
len(data));
   158 template<
class ublas_mat_T>
   159 inline typename std::enable_if<
   160         mds_utils::ublas::is_compressed_matrix<ublas_mat_T>::value,
   165     namespace fus = boost::fusion;
   167     Obj module(PyImport_ImportModule(
"scipy.sparse"));
   171     Obj type_obj(module.
attr(detail::scipy_sparse_mtx<
   172             typename ublas_mat_T::orientation_category>::name));
   174     if (!PyType_Check(type_obj)) {
   176         throw std::runtime_error(
   177                 "Cannot create a " + detail::scipy_sparse_mtx<
   178                     typename ublas_mat_T::orientation_category>::name + 
" object.");
   182         flags(detail::numpy_flags<
   183             typename ublas_mat_T::orientation_category>());
   186         data_dims[] = {boost::numeric_cast<npy_intp>(mat.filled2())},
   187         indptr_dims[] = {boost::numeric_cast<npy_intp>(mat.filled1())},
   189             boost::numeric_cast<npy_intp>(mat.size1()),
   190             boost::numeric_cast<npy_intp>(mat.size2())
   194         *pdata(PyArray_New(&PyArray_Type,1,data_dims,
   196                 typename ublas_mat_T::value_type>::typenum,
   197             NULL,NULL,0,flags,NULL)),
   198         *pindices(PyArray_New(&PyArray_Type,1,data_dims,
   200             NULL,NULL,0,flags,NULL)),
   201         *pindptr(PyArray_New(&PyArray_Type,1,indptr_dims,
   203             NULL,NULL,0,flags,NULL));
   206         throw std::runtime_error(
"Could not create the data array.");
   208     if (pindices == NULL) {
   209         throw std::runtime_error(
"Could not create the indices array.");
   211     if (pindptr == NULL) {
   212         throw std::runtime_error(
"Could not create the indptr array.");
   216         it_data(reinterpret_cast<PyArrayObject*>(pdata));
   219         it_indices(reinterpret_cast<PyArrayObject*>(pindices)),
   220         it_indptr(reinterpret_cast<PyArrayObject*>(pindptr));
   223     typename ublas_mat_T::index_array_type::const_iterator
   224         mat_it_indices(mat.index2_data().begin()),
   225         mat_it_indptr(mat.index1_data().begin());
   226     typename ublas_mat_T::value_array_type::const_iterator
   227         mat_it_data(mat.value_data().begin());
   229     for (k=0;k < *indptr_dims;++k,++mat_it_indptr,++it_indptr) {
   230         *it_indptr = *mat_it_indptr;
   232     for (k=0;k < *data_dims;++k,++mat_it_indices,++mat_it_data,++it_indices,++it_data) {
   233         *it_indices = *mat_it_indices;
   234         *it_data = *mat_it_data;
   238     fus::vector<PyObject*,PyObject*,PyObject*>
   239         mstruct(pdata,pindices,pindptr);
   242         tup_mstruct,tup_sizes,tup_args;
   244     tup_mstruct.
set(mstruct);
   245     tup_sizes.
set(mat_shape,mat_shape+2);
   248         args(tup_mstruct,tup_sizes);
   252     Obj out_mtx(type_obj(tup_args));
 
Contains the wrapper for the NumPy iterator for ndarray objects. 
 
Iterator on a NumPy ndarray. 
 
Main namespace of all Michele De Stefano's C++ utilities. 
 
Contains utilities for the Boost uBLAS library. 
 
Contains a wrapper class for the Python tuple datatype. 
 
void get_ownership()
Used in place of incref, when the wrapped PyObject* was increfed already. 
 
size_t len(PyObject *o)
Retrieves the length of a sequence object. 
 
Contains utilities for the creation of NumPy extensions. 
 
virtual PyObject * transfer()
Returns the Python object with transferred ownership. 
 
void set(const seq_T &seq)
Sets a Python sequence from a Boost Fusion sequence. 
 
ProxyAttr attr(const std::string &name)
Retrieves an attribute. 
 
std::enable_if< mds_utils::ublas::is_matrix< ublas_mat_T >::value, PyObject * >::type to_python(const ublas_mat_T &mat)
"To python" converter for Boost uBLAS matrices. 
 
Provides traits for a specific C/C++ datatype. 
 
This is a simple wrapper around the PyObject* datatype.