19 #ifndef __CXX_NUMPY_H__
20 #define __CXX_NUMPY_H__
21 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
23 #include <boost/python.hpp>
24 #include <boost/python/object.hpp>
112 namespace boost {
namespace python {
187 #define NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(T)\
188 template<> int getItemtype<T>();
190 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(PyObject*)
191 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
float)
192 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
double)
193 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
int)
194 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
long)
195 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
long long)
196 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
short)
197 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
char)
198 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
bool)
199 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
unsigned int)
200 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
unsigned long)
201 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
unsigned short)
202 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
unsigned char)
203 NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE(
unsigned long long)
204 #undef NUMPY_HPP_FWD_DECLARE_GET_ITEMTYPE
213 object zeros(
int rank,
const Py_ssize_t *dims,
int type);
220 object empty(
int rank,
const Py_ssize_t *dims,
int type);
255 void construct(
object const &a,
int typesize);
261 typedef Py_ssize_t ssize_t;
263 const ssize_t* shape()
const;
264 const ssize_t* dims()
const {
return shape(); }
265 const ssize_t*
strides()
const;
266 int itemtype()
const;
267 int itemsize()
const;
269 int ndim()
const {
return rank(); }
270 bool isWriteable()
const;
271 bool isCContiguous()
const;
272 bool isFContiguous()
const;
273 const object& getObject()
const {
return obj; }
275 #define NUMPY_HPP_OFFSET1 \
277 #define NUMPY_HPP_OFFSET2 \
278 NUMPY_HPP_OFFSET1 + y*m[1]
279 #define NUMPY_HPP_OFFSET3 \
280 NUMPY_HPP_OFFSET2 + z*m[2]
281 #define NUMPY_HPP_OFFSET4 \
282 NUMPY_HPP_OFFSET3 + w*m[3]
294 const Py_ssize_t* m =
strides();
295 assert((
unsigned int)x<shape()[0]);
296 return NUMPY_HPP_OFFSET1;
301 const Py_ssize_t* m =
strides();
302 assert((Py_ssize_t)x<shape()[0]);
303 assert((Py_ssize_t)y<shape()[1]);
304 return NUMPY_HPP_OFFSET2;
307 inline ssize_t
offset(
int x,
int y,
int z)
const
309 const Py_ssize_t* m =
strides();
310 assert((Py_ssize_t)x<shape()[0]);
311 assert((Py_ssize_t)y<shape()[1]);
312 assert((Py_ssize_t)z<shape()[2]);
313 return NUMPY_HPP_OFFSET3;
316 inline ssize_t
offset(
int x,
int y,
int z,
int w)
const
318 const Py_ssize_t* m =
strides();
319 assert((Py_ssize_t)x<shape()[0]);
320 assert((Py_ssize_t)y<shape()[1]);
321 assert((Py_ssize_t)z<shape()[2]);
322 assert((Py_ssize_t)w<shape()[3]);
323 return NUMPY_HPP_OFFSET4;
326 inline ssize_t
offset(
const int *c)
const
328 const Py_ssize_t* m =
strides();
331 for(
int i=0; i<r; ++i)
333 assert((Py_ssize_t)(c[i])<shape()[i]);
339 #undef NUMPY_HPP_OFFSET1
340 #undef NUMPY_HPP_OFFSET2
341 #undef NUMPY_HPP_OFFSET3
342 #undef NUMPY_HPP_OFFSET4
419 T* data() {
return reinterpret_cast<T*
>(
bytes()); }
437 T
operator()(
int x,
int y,
int z,
int w)
const
447 T operator[](
int i)
const
452 const T* data()
const {
return reinterpret_cast<T*
>(
bytes()); }
458 template<
class T,
class Idx1,
class Idx2,
class Idx3>
459 inline void gridded_data_ccons(T* dst,
const T* src,
461 const Idx2 *dst_strides,
462 const Idx3 *src_strides,
465 for (
int i=0; i<dims[0]; ++i)
468 dst += dst_strides[0];
469 src += src_strides[0];
473 template<
class T,
class Idx1,
class Idx2,
class Idx3,
int dim>
474 inline void gridded_data_ccons(T* dst,
const T* src,
476 const Idx2 *dst_strides,
477 const Idx3 *src_strides,
478 boost::mpl::int_<dim>)
480 for (
int i=0; i<dims[dim]; ++i)
482 gridded_data_ccons(dst, src, dims, dst_strides, src_strides, boost::mpl::int_<dim-1>());
483 dst += dst_strides[dim];
484 src += src_strides[dim];
498 template<
class T,
int rank>
499 static object copy(
const int* dims,
const T* src,
const int *strides)
501 int item_type = getItemtype<T>();
502 typename arrayt<T>::ssize_t arr_dims[MAX_DIM];
503 for (
int i=0; i<rank; ++i) arr_dims[i] = dims[i];
506 typename arrayt<T>::ssize_t arr_strides[MAX_DIM];
507 for (
int i=0; i<rank; ++i) arr_strides[i] = arr.
strides()[i]/arr.itemsize();
510 mw_py_impl::gridded_data_ccons<T>(dst, src, dims, arr_strides, strides, boost::mpl::int_<rank-1>());
512 return arr.getObject();
523 template<
class T,
int rank>
524 static void copy(T* dst,
const int *dims,
const int* strides,
const object &pyarr)
528 typename arrayt<T>::ssize_t arr_strides[MAX_DIM];
529 for (
int i=0; i<rank; ++i) {
530 assert(arr.shape()[i] == dims[i]);
531 arr_strides[i] = arr.
strides()[i]/arr.itemsize();
534 const T* src = arr.data();
535 mw_py_impl::gridded_data_ccons<T>(dst, src, arr.shape(), strides, arr_strides, boost::mpl::int_<rank-1>());
arrayt(object const &a)
Construct a new instance from a boost::python object.
ssize_t offset(int x) const
Returned in number of bytes.
arrayt(arraytbase const &a)
Construct a new instance from the base class.
int getItemtype(const object &a)
Obtain numpy's data type number from an boost-python object which should hold a ndarray.
This is the base class from which type specific variants are derived.
Py_ssize_t ssize_t
Synonymous for Py_ssize_t.
object empty(int rank, const Py_ssize_t *dims, int type)
Create a new ndarray with uninitialized memory.
char * bytes()
Access to the array's memory block.
void importNumpyAndRegisterTypes()
Initializes things.
This class defines operators () and [] to allow for direct memory access to array elements of type T...
bool isCompatibleType(int id)
Determines if a numpy data type identified by the type number id is binary compatible with the c-type...
const ssize_t * strides() const
Returned in number of bytes.
object zeros(int rank, const Py_ssize_t *dims, int type)
Creates a new ndarray filled with zeros.
ssize_t offset(const int *c) const
c must point to an array of at least rank() items.
static object copy(const int *dims, const T *src, const int *strides)
Copy contents of n-dimensional non-contiguous arrays.
void init(object const &a_)
Take hold of another array. Same rules as for the constructors apply.