Michele De Stefano's C++ Utilities
vector.hpp
Go to the documentation of this file.
1 // vector.hpp
2 //
3 // Copyright (c) 2009 - Michele De Stefano (micdestefano@users.sourceforge.net)
4 //
5 // Distributed under the MIT License (See accompanying file LICENSE)
6 
7 #ifndef MDS_UTILS_PYTHON_UBLAS_VECTOR_HPP_INCLUDED
8 #define MDS_UTILS_PYTHON_UBLAS_VECTOR_HPP_INCLUDED
9 
29 #include <boost/numeric/ublas/vector.hpp>
30 #include <mds_utils/python/ublas/detail/common.hpp>
32 #include <type_traits>
33 
34 
35 namespace mds_utils { namespace python {
36 
46  namespace ublas {
47 
61 template<class ublas_vec_T>
62 inline typename std::enable_if<
63  mds_utils::ublas::is_vector<ublas_vec_T>::value,ublas_vec_T>::type
64  get(PyObject *po) {
65 
66  using namespace mds_utils::python::numpy;
67  using namespace std;
68 
69  if (!PyArray_Check(po)) {
70  throw std::invalid_argument("Cannot convert to "
71  "boost::numeric::ublas::vector: not a numpy array.");
72  }
73 
74  PyArrayObject *m_po(reinterpret_cast<PyArrayObject*>(po));
75 
76 
77  int ndim(PyArray_NDIM(m_po));
78 
79  if (ndim != 1 && ndim != 2) {
80  throw std::invalid_argument("Cannot convert from an "
81  "array with num. of dims. different from 2.");
82  }
83 
84  npy_intp *dims(PyArray_DIMS(m_po));
85 
86  if (!(ndim == 1 || std::min(dims[0],dims[1]) == 1)) {
87  throw std::invalid_argument("Cannot convert from a non-vector");
88  }
89 
90  ublas_vec_T
91  vout((ndim == 1) ? *dims : *std::max_element(dims,dims+2));
92 
94  typename ublas_vec_T::value_type,
95  typename detail::ublas_to_npy_storage<
96  boost::numeric::ublas::row_major_tag>::tag,NPY_ITER_READONLY>
97  it_beg(m_po),it_end(it_beg,true);
98 
99  copy(it_beg,it_end,vout.begin());
100 
101  return vout;
102 }
103 
104 
116 template<class ublas_vec_T>
117 inline typename std::enable_if<
118  mds_utils::ublas::is_vector<ublas_vec_T>::value,
119  PyObject*
120  >::type to_python(const ublas_vec_T& v) {
121 
122  using namespace mds_utils::python::numpy;
123  using namespace std;
124 
125  int
126  nd(1),
127  flags(0);
128 
129  npy_intp
130  dims[] = {
131  boost::numeric_cast<npy_intp>(v.size())
132  };
133 
134  int dtype(numpy_dtype_traits<
135  typename ublas_vec_T::value_type>::typenum);
136 
137  PyObject *pout(PyArray_New(&PyArray_Type,nd,dims,dtype,
138  NULL,NULL,0,flags,NULL));
139 
140  if (pout == NULL) {
141  throw std::runtime_error("Could not create output numpy array.");
142  }
143 
144  PyArrayObject *m_po(reinterpret_cast<PyArrayObject*>(pout));
145 
146  typedef typename ublas_vec_T::value_type value_type;
147  typedef typename detail::ublas_to_npy_storage<
148  boost::numeric::ublas::row_major_tag>::tag storage;
149 
151 
152  copy(v.begin(),v.end(),it_beg);
153 
154  return pout;
155 }
156 
157  }
158 
159 }}
160 
161 
162 #endif
Main namespace of all Michele De Stefano&#39;s C++ utilities.
Definition: endian.hpp:30
Contains utilities for the Boost uBLAS library.
Contains utilities for the creation of NumPy extensions.
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.
Definition: matrix.hpp:108
Provides traits for a specific C/C++ datatype.
Definition: traits.hpp:48