24 #ifndef NDARRAY_SWIG_numpy_h_INCLUDED
25 #define NDARRAY_SWIG_numpy_h_INCLUDED
50 if (
sizeof(
bool)==
sizeof(npy_bool))
return NPY_BOOL;
51 if (
sizeof(
bool)==1)
return NPY_UBYTE;
52 if (
sizeof(
bool)==2 &&
sizeof(
short)==2)
return NPY_USHORT;
53 if (
sizeof(
bool)==4 &&
sizeof(
int)==4)
return NPY_UINT;
59 template <>
struct NumpyTraits<npy_ubyte> {
static int getCode() {
return NPY_UBYTE; } };
60 template <>
struct NumpyTraits<npy_byte> {
static int getCode() {
return NPY_BYTE; } };
61 template <>
struct NumpyTraits<npy_ushort> {
static int getCode() {
return NPY_USHORT; } };
62 template <>
struct NumpyTraits<npy_short> {
static int getCode() {
return NPY_SHORT; } };
63 template <>
struct NumpyTraits<npy_uint> {
static int getCode() {
return NPY_UINT; } };
64 template <>
struct NumpyTraits<npy_int> {
static int getCode() {
return NPY_INT; } };
65 template <>
struct NumpyTraits<npy_ulong> {
static int getCode() {
return NPY_ULONG; } };
66 template <>
struct NumpyTraits<npy_long> {
static int getCode() {
return NPY_LONG; } };
67 template <>
struct NumpyTraits<npy_ulonglong> {
static int getCode() {
return NPY_ULONGLONG; } };
68 template <>
struct NumpyTraits<npy_longlong> {
static int getCode() {
return NPY_LONGLONG; } };
69 template <>
struct NumpyTraits<npy_float> {
static int getCode() {
return NPY_FLOAT; } };
70 template <>
struct NumpyTraits<npy_double> {
static int getCode() {
return NPY_DOUBLE; } };
71 template <>
struct NumpyTraits<npy_longdouble> {
static int getCode() {
return NPY_LONGDOUBLE; } };
72 template <>
struct NumpyTraits<npy_cfloat> {
static int getCode() {
return NPY_CFLOAT; } };
73 template <>
struct NumpyTraits<npy_cdouble> {
static int getCode() {
return NPY_CDOUBLE; } };
74 template <>
struct NumpyTraits<npy_clongdouble> {
static int getCode() {
return NPY_CLONGDOUBLE; } };
76 template <>
struct NumpyTraits<std::complex<float> > {
77 static int getCode() { assert(
sizeof(std::complex<float>)==
sizeof(npy_cfloat));
return NPY_CFLOAT; }
80 template <>
struct NumpyTraits<std::complex<double> > {
81 static int getCode() { assert(
sizeof(std::complex<double>)==
sizeof(npy_cdouble));
return NPY_CDOUBLE; }
84 template <>
struct NumpyTraits<std::complex<long double> > {
86 assert(
sizeof(std::complex<long double>)==
sizeof(npy_clongdouble));
87 return NPY_CLONGDOUBLE;
111 template <
typename T,
int N,
int C>
114 typedef typename boost::remove_const<Element>::type
NonConst;
130 if (!PyArray_Check(p.get())) {
131 PyErr_SetString(PyExc_TypeError,
"numpy.ndarray argument required");
134 int actualType = PyArray_TYPE(p.get());
136 if (actualType != requiredType) {
137 PyErr_SetString(PyExc_ValueError,
"numpy.ndarray argument has incorrect data type");
140 if (PyArray_NDIM(p.get()) != N) {
141 PyErr_SetString(PyExc_ValueError,
"numpy.ndarray argument has incorrect number of dimensions");
144 bool writeable = !boost::is_const<Element>::value;
145 if (writeable && !(PyArray_FLAGS(p.get()) & NPY_WRITEABLE)) {
146 PyErr_SetString(PyExc_TypeError,
"numpy.ndarray argument must be writeable");
150 int requiredStride =
sizeof(
Element);
151 for (
int i = 0; i < C; ++i) {
152 int actualStride = PyArray_STRIDE(p.get(), N-i-1);
153 if (actualStride != requiredStride) {
156 "numpy.ndarray does not have enough row-major contiguous dimensions"
160 requiredStride *= PyArray_DIM(p.get(), N-i-1);
163 int requiredStride =
sizeof(
Element);
164 for (
int i = 0; i < -C; ++i) {
165 int actualStride = PyArray_STRIDE(p.get(), i);
166 if (actualStride != requiredStride) {
169 "numpy.ndarray does not have enough column-major contiguous dimensions"
173 requiredStride *= PyArray_DIM(p.get(), i);
195 if (!(PyArray_FLAGS(input.get()) & NPY_ALIGNED)) {
196 PyErr_SetString(PyExc_ValueError,
"unaligned arrays cannot be converted to C++");
201 std::copy(PyArray_DIMS(input.get()), PyArray_DIMS(input.get()) + N, shape.
begin());
202 std::copy(PyArray_STRIDES(input.get()), PyArray_STRIDES(input.get()) + N , strides.
begin());
203 for (
int i = 0; i < N; ++i) strides[i] /=
sizeof(
Element);
205 reinterpret_cast<Element*>(PyArray_DATA(input.get())),
206 shape, strides, input
226 int flags = NPY_ALIGNED;
227 if (C==N) flags |= NPY_C_CONTIGUOUS;
228 bool writeable = !boost::is_const<Element>::value;
229 if (writeable) flags |= NPY_WRITEABLE;
230 npy_intp outShape[N];
231 npy_intp outStrides[N];
235 for (
int i = 0; i < N; ++i) outStrides[i] = inStrides[i] *
sizeof(
Element);
239 outStrides, const_cast<NonConst*>(m.
getData()),
sizeof(
Element), flags, NULL
243 if (!array)
return NULL;
245 flags = NPY_CARRAY_RO | NPY_ENSURECOPY | NPY_C_CONTIGUOUS;
246 if (writeable) flags |= NPY_WRITEABLE;
247 PyPtr r = PyArray_FROM_OF(array.get(),flags);
256 reinterpret_cast<PyArrayObject*
>(array.get())->base = owner;
258 Py_INCREF(array.get());
259 return PyArray_Return(reinterpret_cast<PyArrayObject*>(array.get()));
262 static PyTypeObject
const *
getPyType() {
return &PyArray_Type; }
267 #endif // !NDARRAY_SWIG_numpy_h_INCLUDED
void destroyCObject(void *p)
Index getStrides() const
Return a Vector of the strides of all dimensions.
boost::remove_const< Element >::type NonConst
Array< T, N, C >::Element Element
boost::intrusive_ptr< PyObject > PyPtr
A reference-counting smart pointer for PyObject.
detail::ExternalInitializer< T, N, Owner > external(T *data, Vector< int, N > const &shape, Vector< int, N > const &strides, Owner const &owner)
Create an expression that initializes an Array with externally allocated memory.
SelectEigenView< T >::Type copy(Eigen::EigenBase< T > const &other)
Copy an arbitrary Eigen expression into a new EigenView.
static PyObject * toPython(Array< T, N, C > const &m, PyObject *owner=NULL)
Create a numpy.ndarray from an ndarray::Array.
ExpressionTraits< Derived >::Element Element
Data type of expression elements.
static bool fromPythonStage2(PyPtr const &input, Array< T, N, C > &output)
Complete a Python to C++ conversion begun with fromPythonStage1().
A class providing Python conversion functions for T.
Index getShape() const
Return a Vector of the sizes of all dimensions.
boost::intrusive_ptr< Manager > Ptr
iterator begin()
Return an iterator to the beginning of the Vector.
iterator end()
Return an iterator to the end of the Vector.
Element * getData() const
Return a raw pointer to the first element of the array.
static bool fromPythonStage1(PyPtr &p)
Check if a Python object is convertible to T and optionally begin the conversion by replacing the inp...
A multidimensional strided array.
Python C-API conversions for standard numeric types.
afw::table::Key< double > b
static PyTypeObject const * getPyType()
Manager::Ptr getManager() const
Return the opaque object responsible for memory management.