00001
00002
00003
00004
00005 #ifndef BOOST_NUMPY_NDARRAY_HPP_INCLUDED
00006 #define BOOST_NUMPY_NDARRAY_HPP_INCLUDED
00007
00013 #include <boost/python.hpp>
00014 #include <boost/utility/enable_if.hpp>
00015 #include <boost/type_traits/is_integral.hpp>
00016 #include <boost/numpy/numpy_object_mgr_traits.hpp>
00017 #include <boost/numpy/dtype.hpp>
00018
00019 #include <vector>
00020
00021 namespace boost
00022 {
00023 namespace numpy
00024 {
00025
00032 class ndarray : public python::object
00033 {
00034
00041 struct array_struct
00042 {
00043 PyObject_HEAD
00044 char * data;
00045 int nd;
00046 Py_intptr_t * shape;
00047 Py_intptr_t * strides;
00048 PyObject * base;
00049 PyObject * descr;
00050 int flags;
00051 PyObject * weakreflist;
00052 };
00053
00055 array_struct * get_struct() const { return reinterpret_cast<array_struct*>(this->ptr()); }
00056
00057 public:
00058
00069 enum bitflag
00070 {
00071 NONE=0x0, C_CONTIGUOUS=0x1, F_CONTIGUOUS=0x2, V_CONTIGUOUS=0x1|0x2,
00072 ALIGNED=0x4, WRITEABLE=0x8, BEHAVED=0x4|0x8,
00073 CARRAY_RO=0x1|0x4, CARRAY=0x1|0x4|0x8, CARRAY_MIS=0x1|0x8,
00074 FARRAY_RO=0x2|0x4, FARRAY=0x2|0x4|0x8, FARRAY_MIS=0x2|0x8,
00075 UPDATE_ALL=0x1|0x2|0x4, VARRAY=0x1|0x2|0x8, ALL=0x1|0x2|0x4|0x8
00076 };
00077
00078 BOOST_PYTHON_FORWARD_OBJECT_CONSTRUCTORS(ndarray, object);
00079
00081 ndarray view(dtype const & dt) const;
00082
00084 ndarray astype(dtype const & dt) const;
00085
00087 ndarray copy() const;
00088
00090 int const shape(int n) const { return get_shape()[n]; }
00091
00093 int const strides(int n) const { return get_strides()[n]; }
00094
00101 char * get_data() const { return get_struct()->data; }
00102
00104 dtype get_dtype() const;
00105
00107 python::object get_base() const;
00108
00110 void set_base(object const & base);
00111
00113 Py_intptr_t const * get_shape() const { return get_struct()->shape; }
00114
00116 Py_intptr_t const * get_strides() const { return get_struct()->strides; }
00117
00119 int const get_nd() const { return get_struct()->nd; }
00120
00122 bitflag const get_flags() const;
00123
00125 ndarray transpose() const;
00126
00128 ndarray squeeze() const;
00129
00131 ndarray reshape(python::tuple const & shape) const;
00132
00139 python::object scalarize() const;
00140 };
00141
00145 ndarray zeros(python::tuple const & shape, dtype const & dt);
00146 ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt);
00147
00151 ndarray empty(python::tuple const & shape, dtype const & dt);
00152 ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt);
00153
00159 ndarray array(python::object const & obj);
00160 ndarray array(python::object const & obj, dtype const & dt);
00161
00162 namespace detail
00163 {
00164
00165 ndarray from_data_impl(void * data,
00166 dtype const & dt,
00167 std::vector<Py_intptr_t> const & shape,
00168 std::vector<Py_intptr_t> const & strides,
00169 python::object const & owner,
00170 bool writeable);
00171
00172 template <typename Container>
00173 ndarray from_data_impl(void * data,
00174 dtype const & dt,
00175 Container shape,
00176 Container strides,
00177 python::object const & owner,
00178 bool writeable,
00179 typename boost::enable_if< boost::is_integral<typename Container::value_type> >::type * enabled = NULL)
00180 {
00181 std::vector<Py_intptr_t> shape_(shape.begin(),shape.end());
00182 std::vector<Py_intptr_t> strides_(strides.begin(), strides.end());
00183 return from_data_impl(data, dt, shape_, strides_, owner, writeable);
00184 }
00185
00186 ndarray from_data_impl(void * data,
00187 dtype const & dt,
00188 python::object const & shape,
00189 python::object const & strides,
00190 python::object const & owner,
00191 bool writeable);
00192
00193 }
00194
00208 template <typename Container>
00209 inline ndarray from_data(void * data,
00210 dtype const & dt,
00211 Container shape,
00212 Container strides,
00213 python::object const & owner)
00214 {
00215 return numpy::detail::from_data_impl(data, dt, shape, strides, owner, true);
00216 }
00217
00233 template <typename Container>
00234 inline ndarray from_data(void const * data,
00235 dtype const & dt,
00236 Container shape,
00237 Container strides,
00238 python::object const & owner)
00239 {
00240 return numpy::detail::from_data_impl(const_cast<void*>(data), dt, shape, strides, owner, false);
00241 }
00242
00253 ndarray from_object(python::object const & obj, dtype const & dt,
00254 int nd_min, int nd_max, ndarray::bitflag flags=ndarray::NONE);
00255
00256 inline ndarray from_object(python::object const & obj, dtype const & dt,
00257 int nd, ndarray::bitflag flags=ndarray::NONE)
00258 {
00259 return from_object(obj, dt, nd, nd, flags);
00260 }
00261
00262 inline ndarray from_object(python::object const & obj, dtype const & dt, ndarray::bitflag flags=ndarray::NONE)
00263 {
00264 return from_object(obj, dt, 0, 0, flags);
00265 }
00266
00267 ndarray from_object(python::object const & obj, int nd_min, int nd_max,
00268 ndarray::bitflag flags=ndarray::NONE);
00269
00270 inline ndarray from_object(python::object const & obj, int nd, ndarray::bitflag flags=ndarray::NONE)
00271 {
00272 return from_object(obj, nd, nd, flags);
00273 }
00274
00275 inline ndarray from_object(python::object const & obj, ndarray::bitflag flags=ndarray::NONE)
00276 {
00277 return from_object(obj, 0, 0, flags);
00278 }
00279
00280 inline ndarray::bitflag operator|(ndarray::bitflag a, ndarray::bitflag b)
00281 {
00282 return ndarray::bitflag(int(a) | int(b));
00283 }
00284
00285 inline ndarray::bitflag operator&(ndarray::bitflag a, ndarray::bitflag b)
00286 {
00287 return ndarray::bitflag(int(a) & int(b));
00288 }
00289
00290 }
00291
00292 namespace python
00293 {
00294 namespace converter
00295 {
00296
00297 NUMPY_OBJECT_MANAGER_TRAITS(numpy::ndarray);
00298
00299 }
00300 }
00301 }
00302
00303 #endif // !BOOST_NUMPY_NDARRAY_HPP_INCLUDED