ndarray.cpp
Go to the documentation of this file.
00001 // Copyright Jim Bosch 2010-2012.
00002 // Distributed under the Boost Software License, Version 1.0.
00003 //    (See accompanying file LICENSE_1_0.txt or copy at
00004 //          http://www.boost.org/LICENSE_1_0.txt)
00005 
00006 #define BOOST_NUMPY_INTERNAL
00007 #include <boost/numpy/internal.hpp>
00008 #include <boost/scoped_array.hpp>
00009 
00010 namespace boost 
00011 { 
00012 namespace python 
00013 {
00014 namespace converter 
00015 {
00016 NUMPY_OBJECT_MANAGER_TRAITS_IMPL(PyArray_Type, numpy::ndarray)
00017 } // namespace boost::python::converter
00018 } // namespace boost::python
00019 
00020 namespace numpy 
00021 {
00022 namespace detail 
00023 {
00024 
00025 ndarray::bitflag numpy_to_bitflag(int const f) 
00026 {
00027   ndarray::bitflag r = ndarray::NONE;
00028   if (f & NPY_C_CONTIGUOUS) r = (r | ndarray::C_CONTIGUOUS);
00029   if (f & NPY_F_CONTIGUOUS) r = (r | ndarray::F_CONTIGUOUS);
00030   if (f & NPY_ALIGNED) r = (r | ndarray::ALIGNED);
00031   if (f & NPY_WRITEABLE) r = (r | ndarray::WRITEABLE);
00032   return r;
00033 }
00034 
00035 int const bitflag_to_numpy(ndarray::bitflag f) 
00036 {
00037   int r = 0;
00038   if (f & ndarray::C_CONTIGUOUS) r |= NPY_C_CONTIGUOUS;
00039   if (f & ndarray::F_CONTIGUOUS) r |= NPY_F_CONTIGUOUS;
00040   if (f & ndarray::ALIGNED) r |= NPY_ALIGNED;
00041   if (f & ndarray::WRITEABLE) r |= NPY_WRITEABLE;
00042   return r;
00043 }
00044 
00045 bool is_c_contiguous(std::vector<Py_intptr_t> const & shape,
00046                      std::vector<Py_intptr_t> const & strides,
00047                      int itemsize)
00048 {
00049   std::vector<Py_intptr_t>::const_reverse_iterator j = strides.rbegin();
00050   int total = itemsize;
00051   for (std::vector<Py_intptr_t>::const_reverse_iterator i = shape.rbegin(); i != shape.rend(); ++i, ++j) 
00052   {
00053     if (total != *j) return false;
00054     total *= (*i);
00055   }
00056   return true;
00057 }
00058 
00059 bool is_f_contiguous(std::vector<Py_intptr_t> const & shape,
00060                      std::vector<Py_intptr_t> const & strides,
00061                      int itemsize)
00062 {
00063   std::vector<Py_intptr_t>::const_iterator j = strides.begin();
00064   int total = itemsize;
00065   for (std::vector<Py_intptr_t>::const_iterator i = shape.begin(); i != shape.end(); ++i, ++j)
00066   {
00067     if (total != *j) return false;
00068     total *= (*i);
00069   }
00070   return true;
00071 }
00072 
00073 bool is_aligned(std::vector<Py_intptr_t> const & strides,
00074                 int itemsize)
00075 {
00076   for (std::vector<Py_intptr_t>::const_iterator i = strides.begin(); i != strides.end(); ++i) 
00077   {
00078     if (*i % itemsize) return false;
00079   }
00080   return true;
00081 }
00082 
00083 inline PyArray_Descr * incref_dtype(dtype const & dt) 
00084 {
00085   Py_INCREF(dt.ptr());
00086   return reinterpret_cast<PyArray_Descr*>(dt.ptr());
00087 }
00088 
00089 ndarray from_data_impl(void * data, 
00090                        dtype const & dt, 
00091                        python::object const & shape,
00092                        python::object const & strides,
00093                        python::object const & owner,
00094                        bool writeable)
00095 {
00096   std::vector<Py_intptr_t> shape_(len(shape));
00097   std::vector<Py_intptr_t> strides_(len(strides));
00098   if (shape_.size() != strides_.size()) 
00099   {
00100     PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
00101     python::throw_error_already_set();
00102   }
00103   for (std::size_t i = 0; i < shape_.size(); ++i) 
00104   {
00105     shape_[i] = python::extract<Py_intptr_t>(shape[i]);
00106     strides_[i] = python::extract<Py_intptr_t>(strides[i]);
00107   }
00108   return from_data_impl(data, dt, shape_, strides_, owner, writeable);
00109 }
00110 
00111 ndarray from_data_impl(void * data, 
00112                        dtype const & dt, 
00113                        std::vector<Py_intptr_t> const & shape,
00114                        std::vector<Py_intptr_t> const & strides,
00115                        python::object const & owner,
00116                        bool writeable)
00117 {
00118   if (shape.size() != strides.size()) 
00119   {
00120     PyErr_SetString(PyExc_ValueError, "Length of shape and strides arrays do not match.");
00121     python::throw_error_already_set();
00122   }
00123   int itemsize = dt.get_itemsize();
00124   int flags = 0;
00125   if (writeable) flags |= NPY_WRITEABLE;
00126   if (is_c_contiguous(shape, strides, itemsize)) flags |= NPY_C_CONTIGUOUS;
00127   if (is_f_contiguous(shape, strides, itemsize)) flags |= NPY_F_CONTIGUOUS;
00128   if (is_aligned(strides, itemsize)) flags |= NPY_ALIGNED;
00129   ndarray r(python::detail::new_reference
00130     (PyArray_NewFromDescr(&PyArray_Type,
00131                           incref_dtype(dt),
00132                           shape.size(),
00133                           const_cast<Py_intptr_t*>(&shape.front()),
00134                           const_cast<Py_intptr_t*>(&strides.front()),
00135                           data,
00136                           flags,
00137                           NULL)));
00138     r.set_base(owner);
00139     return r;
00140 }
00141 
00142 } // namespace detail
00143 
00144 ndarray ndarray::view(dtype const & dt) const
00145 {
00146   return ndarray(python::detail::new_reference
00147     (PyObject_CallMethod(this->ptr(), const_cast<char*>("view"), const_cast<char*>("O"), dt.ptr())));
00148 }
00149     
00150 ndarray ndarray::astype(dtype const & dt) const
00151 {
00152   return ndarray(python::detail::new_reference
00153     (PyObject_CallMethod(this->ptr(), const_cast<char*>("astype"), const_cast<char*>("O"), dt.ptr())));
00154 }
00155 
00156 ndarray ndarray::copy() const 
00157 {
00158   return ndarray(python::detail::new_reference
00159     (PyObject_CallMethod(this->ptr(), const_cast<char*>("copy"), const_cast<char*>(""))));
00160 }
00161 
00162 dtype ndarray::get_dtype() const 
00163 {
00164   return dtype(python::detail::borrowed_reference(get_struct()->descr));
00165 }
00166 
00167 python::object ndarray::get_base() const 
00168 {
00169   if (get_struct()->base == NULL) return object();
00170   return python::object(python::detail::borrowed_reference(get_struct()->base));
00171 }
00172 
00173 void ndarray::set_base(object const & base) 
00174 {
00175   Py_XDECREF(get_struct()->base);
00176   if (base != object()) 
00177   {
00178     Py_INCREF(base.ptr());
00179     get_struct()->base = base.ptr();
00180   }
00181   else
00182   {
00183     get_struct()->base = NULL;
00184   }
00185 }
00186 
00187 ndarray::bitflag const ndarray::get_flags() const 
00188 {
00189   return numpy::detail::numpy_to_bitflag(get_struct()->flags);
00190 }
00191 
00192 ndarray ndarray::transpose() const 
00193 {
00194   return ndarray(python::detail::new_reference
00195     (PyArray_Transpose(reinterpret_cast<PyArrayObject*>(this->ptr()), NULL)));
00196 }
00197 
00198 ndarray ndarray::squeeze() const 
00199 {
00200   return ndarray(python::detail::new_reference
00201     (PyArray_Squeeze(reinterpret_cast<PyArrayObject*>(this->ptr()))));
00202 }
00203 
00204 ndarray ndarray::reshape(python::tuple const & shape) const 
00205 {
00206   return ndarray(python::detail::new_reference
00207     (PyArray_Reshape(reinterpret_cast<PyArrayObject*>(this->ptr()), shape.ptr())));
00208 }
00209 
00210 python::object ndarray::scalarize() const 
00211 {
00212   Py_INCREF(ptr());
00213   return python::object(python::detail::new_reference(PyArray_Return(reinterpret_cast<PyArrayObject*>(ptr()))));
00214 }
00215 
00216 ndarray zeros(python::tuple const & shape, dtype const & dt) 
00217 {
00218   int nd = len(shape);
00219   boost::scoped_array<Py_intptr_t> dims(new Py_intptr_t[nd]);
00220   for (int n=0; n<nd; ++n) dims[n] = python::extract<Py_intptr_t>(shape[n]);
00221   return ndarray(python::detail::new_reference
00222                  (PyArray_Zeros(nd, dims.get(), detail::incref_dtype(dt), 0)));
00223 }
00224 
00225 ndarray zeros(int nd, Py_intptr_t const * shape, dtype const & dt) 
00226 {
00227   return ndarray(python::detail::new_reference
00228     (PyArray_Zeros(nd, const_cast<Py_intptr_t*>(shape), detail::incref_dtype(dt), 0)));
00229 }
00230 
00231 ndarray empty(python::tuple const & shape, dtype const & dt) 
00232 {
00233   int nd = len(shape);
00234   boost::scoped_array<Py_intptr_t> dims(new Py_intptr_t[nd]);
00235   for (int n=0; n<nd; ++n) dims[n] = python::extract<Py_intptr_t>(shape[n]);
00236   return ndarray(python::detail::new_reference
00237                  (PyArray_Empty(nd, dims.get(), detail::incref_dtype(dt), 0)));    
00238 }
00239 
00240 ndarray empty(int nd, Py_intptr_t const * shape, dtype const & dt)
00241 {
00242   return ndarray(python::detail::new_reference
00243     (PyArray_Empty(nd, const_cast<Py_intptr_t*>(shape), detail::incref_dtype(dt), 0)));
00244 }
00245 
00246 ndarray array(python::object const & obj) 
00247 {
00248   return ndarray(python::detail::new_reference
00249     (PyArray_FromAny(obj.ptr(), NULL, 0, 0, NPY_ENSUREARRAY, NULL)));
00250 }
00251 
00252 ndarray array(python::object const & obj, dtype const & dt) 
00253 {
00254   return ndarray(python::detail::new_reference
00255     (PyArray_FromAny(obj.ptr(), detail::incref_dtype(dt), 0, 0, NPY_ENSUREARRAY, NULL)));
00256 }
00257 
00258 ndarray from_object(python::object const & obj, dtype const & dt, int nd_min, int nd_max, ndarray::bitflag flags)
00259 {
00260   int requirements = detail::bitflag_to_numpy(flags);
00261   return ndarray(python::detail::new_reference
00262     (PyArray_FromAny(obj.ptr(),
00263                      detail::incref_dtype(dt),
00264                      nd_min, nd_max,
00265                      requirements,
00266                      NULL)));
00267 }
00268 
00269 ndarray from_object(python::object const & obj, int nd_min, int nd_max, ndarray::bitflag flags) 
00270 {
00271   int requirements = detail::bitflag_to_numpy(flags);
00272   return ndarray(python::detail::new_reference
00273     (PyArray_FromAny(obj.ptr(),
00274                      NULL,
00275                      nd_min, nd_max,
00276                      requirements,
00277                      NULL)));
00278 }
00279 
00280 }
00281 }


boost_numpy
Author(s): Jim Bosch, Ankit Daftery
autogenerated on Fri Aug 28 2015 10:10:40