1# NumPy static imports for Cython
2#
3# If any of the PyArray_* functions are called, import_array must be
4# called first.
5#
6# This also defines backwards-compatibility buffer acquisition
7# code for use in Python 2.x (or Python <= 2.5 when NumPy starts
8# implementing PEP-3118 directly).
9#
10# Because of laziness, the format string of the buffer is statically
11# allocated. Increase the size if this is not enough, or submit a
12# patch to do this properly.
13#
14# Author: Dag Sverre Seljebotn
15#
16
17DEF _buffer_format_string_len = 255
18
19cimport cpython.buffer as pybuf
20from cpython.ref cimport Py_INCREF
21from cpython.mem cimport PyObject_Malloc, PyObject_Free
22from cpython.object cimport PyObject, PyTypeObject
23from cpython.type cimport type
24cimport libc.stdio as stdio
25
26cdef extern from "Python.h":
27    ctypedef int Py_intptr_t
28
29cdef extern from "numpy/arrayobject.h":
30    ctypedef Py_intptr_t npy_intp
31    ctypedef size_t npy_uintp
32
33    cdef enum NPY_TYPES:
34        NPY_BOOL
35        NPY_BYTE
36        NPY_UBYTE
37        NPY_SHORT
38        NPY_USHORT
39        NPY_INT
40        NPY_UINT
41        NPY_LONG
42        NPY_ULONG
43        NPY_LONGLONG
44        NPY_ULONGLONG
45        NPY_FLOAT
46        NPY_DOUBLE
47        NPY_LONGDOUBLE
48        NPY_CFLOAT
49        NPY_CDOUBLE
50        NPY_CLONGDOUBLE
51        NPY_OBJECT
52        NPY_STRING
53        NPY_UNICODE
54        NPY_VOID
55        NPY_DATETIME
56        NPY_TIMEDELTA
57        NPY_NTYPES
58        NPY_NOTYPE
59
60        NPY_INT8
61        NPY_INT16
62        NPY_INT32
63        NPY_INT64
64        NPY_INT128
65        NPY_INT256
66        NPY_UINT8
67        NPY_UINT16
68        NPY_UINT32
69        NPY_UINT64
70        NPY_UINT128
71        NPY_UINT256
72        NPY_FLOAT16
73        NPY_FLOAT32
74        NPY_FLOAT64
75        NPY_FLOAT80
76        NPY_FLOAT96
77        NPY_FLOAT128
78        NPY_FLOAT256
79        NPY_COMPLEX32
80        NPY_COMPLEX64
81        NPY_COMPLEX128
82        NPY_COMPLEX160
83        NPY_COMPLEX192
84        NPY_COMPLEX256
85        NPY_COMPLEX512
86
87        NPY_INTP
88
89    ctypedef enum NPY_ORDER:
90        NPY_ANYORDER
91        NPY_CORDER
92        NPY_FORTRANORDER
93        NPY_KEEPORDER
94
95    ctypedef enum NPY_CASTING:
96        NPY_NO_CASTING
97        NPY_EQUIV_CASTING
98        NPY_SAFE_CASTING
99        NPY_SAME_KIND_CASTING
100        NPY_UNSAFE_CASTING
101
102    ctypedef enum NPY_CLIPMODE:
103        NPY_CLIP
104        NPY_WRAP
105        NPY_RAISE
106
107    ctypedef enum NPY_SCALARKIND:
108        NPY_NOSCALAR,
109        NPY_BOOL_SCALAR,
110        NPY_INTPOS_SCALAR,
111        NPY_INTNEG_SCALAR,
112        NPY_FLOAT_SCALAR,
113        NPY_COMPLEX_SCALAR,
114        NPY_OBJECT_SCALAR
115
116    ctypedef enum NPY_SORTKIND:
117        NPY_QUICKSORT
118        NPY_HEAPSORT
119        NPY_MERGESORT
120
121    ctypedef enum NPY_SEARCHSIDE:
122        NPY_SEARCHLEFT
123        NPY_SEARCHRIGHT
124
125    enum:
126        # DEPRECATED since NumPy 1.7 ! Do not use in new code!
127        NPY_C_CONTIGUOUS
128        NPY_F_CONTIGUOUS
129        NPY_CONTIGUOUS
130        NPY_FORTRAN
131        NPY_OWNDATA
132        NPY_FORCECAST
133        NPY_ENSURECOPY
134        NPY_ENSUREARRAY
135        NPY_ELEMENTSTRIDES
136        NPY_ALIGNED
137        NPY_NOTSWAPPED
138        NPY_WRITEABLE
139        NPY_UPDATEIFCOPY
140        NPY_ARR_HAS_DESCR
141
142        NPY_BEHAVED
143        NPY_BEHAVED_NS
144        NPY_CARRAY
145        NPY_CARRAY_RO
146        NPY_FARRAY
147        NPY_FARRAY_RO
148        NPY_DEFAULT
149
150        NPY_IN_ARRAY
151        NPY_OUT_ARRAY
152        NPY_INOUT_ARRAY
153        NPY_IN_FARRAY
154        NPY_OUT_FARRAY
155        NPY_INOUT_FARRAY
156
157        NPY_UPDATE_ALL
158
159    enum:
160        # Added in NumPy 1.7 to replace the deprecated enums above.
161        NPY_ARRAY_C_CONTIGUOUS
162        NPY_ARRAY_F_CONTIGUOUS
163        NPY_ARRAY_OWNDATA
164        NPY_ARRAY_FORCECAST
165        NPY_ARRAY_ENSURECOPY
166        NPY_ARRAY_ENSUREARRAY
167        NPY_ARRAY_ELEMENTSTRIDES
168        NPY_ARRAY_ALIGNED
169        NPY_ARRAY_NOTSWAPPED
170        NPY_ARRAY_WRITEABLE
171        NPY_ARRAY_UPDATEIFCOPY
172
173        NPY_ARRAY_BEHAVED
174        NPY_ARRAY_BEHAVED_NS
175        NPY_ARRAY_CARRAY
176        NPY_ARRAY_CARRAY_RO
177        NPY_ARRAY_FARRAY
178        NPY_ARRAY_FARRAY_RO
179        NPY_ARRAY_DEFAULT
180
181        NPY_ARRAY_IN_ARRAY
182        NPY_ARRAY_OUT_ARRAY
183        NPY_ARRAY_INOUT_ARRAY
184        NPY_ARRAY_IN_FARRAY
185        NPY_ARRAY_OUT_FARRAY
186        NPY_ARRAY_INOUT_FARRAY
187
188        NPY_ARRAY_UPDATE_ALL
189
190    cdef enum:
191        NPY_MAXDIMS
192
193    npy_intp NPY_MAX_ELSIZE
194
195    ctypedef void (*PyArray_VectorUnaryFunc)(void *, void *, npy_intp, void *,  void *)
196
197    ctypedef struct PyArray_ArrayDescr:
198        # shape is a tuple, but Cython doesn't support "tuple shape"
199        # inside a non-PyObject declaration, so we have to declare it
200        # as just a PyObject*.
201        PyObject* shape
202
203    ctypedef struct PyArray_Descr:
204        pass
205
206    ctypedef class numpy.dtype [object PyArray_Descr, check_size ignore]:
207        # Use PyDataType_* macros when possible, however there are no macros
208        # for accessing some of the fields, so some are defined.
209        cdef PyTypeObject* typeobj
210        cdef char kind
211        cdef char type
212        # Numpy sometimes mutates this without warning (e.g. it'll
213        # sometimes change "|" to "<" in shared dtype objects on
214        # little-endian machines). If this matters to you, use
215        # PyArray_IsNativeByteOrder(dtype.byteorder) instead of
216        # directly accessing this field.
217        cdef char byteorder
218        cdef char flags
219        cdef int type_num
220        cdef int itemsize "elsize"
221        cdef int alignment
222        cdef dict fields
223        cdef tuple names
224        # Use PyDataType_HASSUBARRAY to test whether this field is
225        # valid (the pointer can be NULL). Most users should access
226        # this field via the inline helper method PyDataType_SHAPE.
227        cdef PyArray_ArrayDescr* subarray
228
229    ctypedef class numpy.flatiter [object PyArrayIterObject, check_size ignore]:
230        # Use through macros
231        pass
232
233    ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]:
234        # Use through macros
235        pass
236
237    ctypedef struct PyArrayObject:
238        # For use in situations where ndarray can't replace PyArrayObject*,
239        # like PyArrayObject**.
240        pass
241
242    ctypedef class numpy.ndarray [object PyArrayObject, check_size ignore]:
243        cdef __cythonbufferdefaults__ = {"mode": "strided"}
244
245        cdef:
246            # Only taking a few of the most commonly used and stable fields.
247            # One should use PyArray_* macros instead to access the C fields.
248            char *data
249            int ndim "nd"
250            npy_intp *shape "dimensions"
251            npy_intp *strides
252            dtype descr  # deprecated since NumPy 1.7 !
253            PyObject* base
254
255        # Note: This syntax (function definition in pxd files) is an
256        # experimental exception made for __getbuffer__ and __releasebuffer__
257        # -- the details of this may change.
258        def __getbuffer__(ndarray self, Py_buffer* info, int flags):
259            # This implementation of getbuffer is geared towards Cython
260            # requirements, and does not yet fulfill the PEP.
261            # In particular strided access is always provided regardless
262            # of flags
263
264            cdef int i, ndim
265            cdef int endian_detector = 1
266            cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
267
268            ndim = PyArray_NDIM(self)
269
270            if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
271                and not PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)):
272                raise ValueError(u"ndarray is not C contiguous")
273
274            if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
275                and not PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)):
276                raise ValueError(u"ndarray is not Fortran contiguous")
277
278            info.buf = PyArray_DATA(self)
279            info.ndim = ndim
280            if sizeof(npy_intp) != sizeof(Py_ssize_t):
281                # Allocate new buffer for strides and shape info.
282                # This is allocated as one block, strides first.
283                info.strides = <Py_ssize_t*>PyObject_Malloc(sizeof(Py_ssize_t) * 2 * <size_t>ndim)
284                info.shape = info.strides + ndim
285                for i in range(ndim):
286                    info.strides[i] = PyArray_STRIDES(self)[i]
287                    info.shape[i] = PyArray_DIMS(self)[i]
288            else:
289                info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
290                info.shape = <Py_ssize_t*>PyArray_DIMS(self)
291            info.suboffsets = NULL
292            info.itemsize = PyArray_ITEMSIZE(self)
293            info.readonly = not PyArray_ISWRITEABLE(self)
294
295            cdef int t
296            cdef char* f = NULL
297            cdef dtype descr = <dtype>PyArray_DESCR(self)
298            cdef int offset
299
300            info.obj = self
301
302            if not PyDataType_HASFIELDS(descr):
303                t = descr.type_num
304                if ((descr.byteorder == c'>' and little_endian) or
305                    (descr.byteorder == c'<' and not little_endian)):
306                    raise ValueError(u"Non-native byte order not supported")
307                if   t == NPY_BYTE:        f = "b"
308                elif t == NPY_UBYTE:       f = "B"
309                elif t == NPY_SHORT:       f = "h"
310                elif t == NPY_USHORT:      f = "H"
311                elif t == NPY_INT:         f = "i"
312                elif t == NPY_UINT:        f = "I"
313                elif t == NPY_LONG:        f = "l"
314                elif t == NPY_ULONG:       f = "L"
315                elif t == NPY_LONGLONG:    f = "q"
316                elif t == NPY_ULONGLONG:   f = "Q"
317                elif t == NPY_FLOAT:       f = "f"
318                elif t == NPY_DOUBLE:      f = "d"
319                elif t == NPY_LONGDOUBLE:  f = "g"
320                elif t == NPY_CFLOAT:      f = "Zf"
321                elif t == NPY_CDOUBLE:     f = "Zd"
322                elif t == NPY_CLONGDOUBLE: f = "Zg"
323                elif t == NPY_OBJECT:      f = "O"
324                else:
325                    raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
326                info.format = f
327                return
328            else:
329                info.format = <char*>PyObject_Malloc(_buffer_format_string_len)
330                info.format[0] = c'^' # Native data types, manual alignment
331                offset = 0
332                f = _util_dtypestring(descr, info.format + 1,
333                                      info.format + _buffer_format_string_len,
334                                      &offset)
335                f[0] = c'\0' # Terminate format string
336
337        def __releasebuffer__(ndarray self, Py_buffer* info):
338            if PyArray_HASFIELDS(self):
339                PyObject_Free(info.format)
340            if sizeof(npy_intp) != sizeof(Py_ssize_t):
341                PyObject_Free(info.strides)
342                # info.shape was stored after info.strides in the same block
343
344    ctypedef unsigned char      npy_bool
345
346    ctypedef signed char      npy_byte
347    ctypedef signed short     npy_short
348    ctypedef signed int       npy_int
349    ctypedef signed long      npy_long
350    ctypedef signed long long npy_longlong
351
352    ctypedef unsigned char      npy_ubyte
353    ctypedef unsigned short     npy_ushort
354    ctypedef unsigned int       npy_uint
355    ctypedef unsigned long      npy_ulong
356    ctypedef unsigned long long npy_ulonglong
357
358    ctypedef float        npy_float
359    ctypedef double       npy_double
360    ctypedef long double  npy_longdouble
361
362    ctypedef signed char        npy_int8
363    ctypedef signed short       npy_int16
364    ctypedef signed int         npy_int32
365    ctypedef signed long long   npy_int64
366    ctypedef signed long long   npy_int96
367    ctypedef signed long long   npy_int128
368
369    ctypedef unsigned char      npy_uint8
370    ctypedef unsigned short     npy_uint16
371    ctypedef unsigned int       npy_uint32
372    ctypedef unsigned long long npy_uint64
373    ctypedef unsigned long long npy_uint96
374    ctypedef unsigned long long npy_uint128
375
376    ctypedef float        npy_float32
377    ctypedef double       npy_float64
378    ctypedef long double  npy_float80
379    ctypedef long double  npy_float96
380    ctypedef long double  npy_float128
381
382    ctypedef struct npy_cfloat:
383        double real
384        double imag
385
386    ctypedef struct npy_cdouble:
387        double real
388        double imag
389
390    ctypedef struct npy_clongdouble:
391        long double real
392        long double imag
393
394    ctypedef struct npy_complex64:
395        float real
396        float imag
397
398    ctypedef struct npy_complex128:
399        double real
400        double imag
401
402    ctypedef struct npy_complex160:
403        long double real
404        long double imag
405
406    ctypedef struct npy_complex192:
407        long double real
408        long double imag
409
410    ctypedef struct npy_complex256:
411        long double real
412        long double imag
413
414    ctypedef struct PyArray_Dims:
415        npy_intp *ptr
416        int len
417
418    int _import_array() except -1
419
420    #
421    # Macros from ndarrayobject.h
422    #
423    bint PyArray_CHKFLAGS(ndarray m, int flags)
424    bint PyArray_IS_C_CONTIGUOUS(ndarray arr)
425    bint PyArray_IS_F_CONTIGUOUS(ndarray arr)
426    bint PyArray_ISCONTIGUOUS(ndarray m)
427    bint PyArray_ISWRITEABLE(ndarray m)
428    bint PyArray_ISALIGNED(ndarray m)
429
430    int PyArray_NDIM(ndarray)
431    bint PyArray_ISONESEGMENT(ndarray)
432    bint PyArray_ISFORTRAN(ndarray)
433    int PyArray_FORTRANIF(ndarray)
434
435    void* PyArray_DATA(ndarray)
436    char* PyArray_BYTES(ndarray)
437    npy_intp* PyArray_DIMS(ndarray)
438    npy_intp* PyArray_STRIDES(ndarray)
439    npy_intp PyArray_DIM(ndarray, size_t)
440    npy_intp PyArray_STRIDE(ndarray, size_t)
441
442    PyObject *PyArray_BASE(ndarray)  # returns borrowed reference!
443    PyArray_Descr *PyArray_DESCR(ndarray) # returns borrowed reference to dtype!
444    int PyArray_FLAGS(ndarray)
445    npy_intp PyArray_ITEMSIZE(ndarray)
446    int PyArray_TYPE(ndarray arr)
447
448    object PyArray_GETITEM(ndarray arr, void *itemptr)
449    int PyArray_SETITEM(ndarray arr, void *itemptr, object obj)
450
451    bint PyTypeNum_ISBOOL(int)
452    bint PyTypeNum_ISUNSIGNED(int)
453    bint PyTypeNum_ISSIGNED(int)
454    bint PyTypeNum_ISINTEGER(int)
455    bint PyTypeNum_ISFLOAT(int)
456    bint PyTypeNum_ISNUMBER(int)
457    bint PyTypeNum_ISSTRING(int)
458    bint PyTypeNum_ISCOMPLEX(int)
459    bint PyTypeNum_ISPYTHON(int)
460    bint PyTypeNum_ISFLEXIBLE(int)
461    bint PyTypeNum_ISUSERDEF(int)
462    bint PyTypeNum_ISEXTENDED(int)
463    bint PyTypeNum_ISOBJECT(int)
464
465    bint PyDataType_ISBOOL(dtype)
466    bint PyDataType_ISUNSIGNED(dtype)
467    bint PyDataType_ISSIGNED(dtype)
468    bint PyDataType_ISINTEGER(dtype)
469    bint PyDataType_ISFLOAT(dtype)
470    bint PyDataType_ISNUMBER(dtype)
471    bint PyDataType_ISSTRING(dtype)
472    bint PyDataType_ISCOMPLEX(dtype)
473    bint PyDataType_ISPYTHON(dtype)
474    bint PyDataType_ISFLEXIBLE(dtype)
475    bint PyDataType_ISUSERDEF(dtype)
476    bint PyDataType_ISEXTENDED(dtype)
477    bint PyDataType_ISOBJECT(dtype)
478    bint PyDataType_HASFIELDS(dtype)
479    bint PyDataType_HASSUBARRAY(dtype)
480
481    bint PyArray_ISBOOL(ndarray)
482    bint PyArray_ISUNSIGNED(ndarray)
483    bint PyArray_ISSIGNED(ndarray)
484    bint PyArray_ISINTEGER(ndarray)
485    bint PyArray_ISFLOAT(ndarray)
486    bint PyArray_ISNUMBER(ndarray)
487    bint PyArray_ISSTRING(ndarray)
488    bint PyArray_ISCOMPLEX(ndarray)
489    bint PyArray_ISPYTHON(ndarray)
490    bint PyArray_ISFLEXIBLE(ndarray)
491    bint PyArray_ISUSERDEF(ndarray)
492    bint PyArray_ISEXTENDED(ndarray)
493    bint PyArray_ISOBJECT(ndarray)
494    bint PyArray_HASFIELDS(ndarray)
495
496    bint PyArray_ISVARIABLE(ndarray)
497
498    bint PyArray_SAFEALIGNEDCOPY(ndarray)
499    bint PyArray_ISNBO(char)              # works on ndarray.byteorder
500    bint PyArray_IsNativeByteOrder(char)  # works on ndarray.byteorder
501    bint PyArray_ISNOTSWAPPED(ndarray)
502    bint PyArray_ISBYTESWAPPED(ndarray)
503
504    bint PyArray_FLAGSWAP(ndarray, int)
505
506    bint PyArray_ISCARRAY(ndarray)
507    bint PyArray_ISCARRAY_RO(ndarray)
508    bint PyArray_ISFARRAY(ndarray)
509    bint PyArray_ISFARRAY_RO(ndarray)
510    bint PyArray_ISBEHAVED(ndarray)
511    bint PyArray_ISBEHAVED_RO(ndarray)
512
513
514    bint PyDataType_ISNOTSWAPPED(dtype)
515    bint PyDataType_ISBYTESWAPPED(dtype)
516
517    bint PyArray_DescrCheck(object)
518
519    bint PyArray_Check(object)
520    bint PyArray_CheckExact(object)
521
522    # Cannot be supported due to out arg:
523    # bint PyArray_HasArrayInterfaceType(object, dtype, object, object&)
524    # bint PyArray_HasArrayInterface(op, out)
525
526
527    bint PyArray_IsZeroDim(object)
528    # Cannot be supported due to ## ## in macro:
529    # bint PyArray_IsScalar(object, verbatim work)
530    bint PyArray_CheckScalar(object)
531    bint PyArray_IsPythonNumber(object)
532    bint PyArray_IsPythonScalar(object)
533    bint PyArray_IsAnyScalar(object)
534    bint PyArray_CheckAnyScalar(object)
535    ndarray PyArray_GETCONTIGUOUS(ndarray)
536    bint PyArray_SAMESHAPE(ndarray, ndarray)
537    npy_intp PyArray_SIZE(ndarray)
538    npy_intp PyArray_NBYTES(ndarray)
539
540    object PyArray_FROM_O(object)
541    object PyArray_FROM_OF(object m, int flags)
542    object PyArray_FROM_OT(object m, int type)
543    object PyArray_FROM_OTF(object m, int type, int flags)
544    object PyArray_FROMANY(object m, int type, int min, int max, int flags)
545    object PyArray_ZEROS(int nd, npy_intp* dims, int type, int fortran)
546    object PyArray_EMPTY(int nd, npy_intp* dims, int type, int fortran)
547    void PyArray_FILLWBYTE(object, int val)
548    npy_intp PyArray_REFCOUNT(object)
549    object PyArray_ContiguousFromAny(op, int, int min_depth, int max_depth)
550    unsigned char PyArray_EquivArrTypes(ndarray a1, ndarray a2)
551    bint PyArray_EquivByteorders(int b1, int b2)
552    object PyArray_SimpleNew(int nd, npy_intp* dims, int typenum)
553    object PyArray_SimpleNewFromData(int nd, npy_intp* dims, int typenum, void* data)
554    #object PyArray_SimpleNewFromDescr(int nd, npy_intp* dims, dtype descr)
555    object PyArray_ToScalar(void* data, ndarray arr)
556
557    void* PyArray_GETPTR1(ndarray m, npy_intp i)
558    void* PyArray_GETPTR2(ndarray m, npy_intp i, npy_intp j)
559    void* PyArray_GETPTR3(ndarray m, npy_intp i, npy_intp j, npy_intp k)
560    void* PyArray_GETPTR4(ndarray m, npy_intp i, npy_intp j, npy_intp k, npy_intp l)
561
562    void PyArray_XDECREF_ERR(ndarray)
563    # Cannot be supported due to out arg
564    # void PyArray_DESCR_REPLACE(descr)
565
566
567    object PyArray_Copy(ndarray)
568    object PyArray_FromObject(object op, int type, int min_depth, int max_depth)
569    object PyArray_ContiguousFromObject(object op, int type, int min_depth, int max_depth)
570    object PyArray_CopyFromObject(object op, int type, int min_depth, int max_depth)
571
572    object PyArray_Cast(ndarray mp, int type_num)
573    object PyArray_Take(ndarray ap, object items, int axis)
574    object PyArray_Put(ndarray ap, object items, object values)
575
576    void PyArray_ITER_RESET(flatiter it) nogil
577    void PyArray_ITER_NEXT(flatiter it) nogil
578    void PyArray_ITER_GOTO(flatiter it, npy_intp* destination) nogil
579    void PyArray_ITER_GOTO1D(flatiter it, npy_intp ind) nogil
580    void* PyArray_ITER_DATA(flatiter it) nogil
581    bint PyArray_ITER_NOTDONE(flatiter it) nogil
582
583    void PyArray_MultiIter_RESET(broadcast multi) nogil
584    void PyArray_MultiIter_NEXT(broadcast multi) nogil
585    void PyArray_MultiIter_GOTO(broadcast multi, npy_intp dest) nogil
586    void PyArray_MultiIter_GOTO1D(broadcast multi, npy_intp ind) nogil
587    void* PyArray_MultiIter_DATA(broadcast multi, npy_intp i) nogil
588    void PyArray_MultiIter_NEXTi(broadcast multi, npy_intp i) nogil
589    bint PyArray_MultiIter_NOTDONE(broadcast multi) nogil
590
591    # Functions from __multiarray_api.h
592
593    # Functions taking dtype and returning object/ndarray are disabled
594    # for now as they steal dtype references. I'm conservative and disable
595    # more than is probably needed until it can be checked further.
596    int PyArray_SetNumericOps        (object)
597    object PyArray_GetNumericOps ()
598    int PyArray_INCREF (ndarray)
599    int PyArray_XDECREF (ndarray)
600    void PyArray_SetStringFunction (object, int)
601    dtype PyArray_DescrFromType (int)
602    object PyArray_TypeObjectFromType (int)
603    char * PyArray_Zero (ndarray)
604    char * PyArray_One (ndarray)
605    #object PyArray_CastToType (ndarray, dtype, int)
606    int PyArray_CastTo (ndarray, ndarray)
607    int PyArray_CastAnyTo (ndarray, ndarray)
608    int PyArray_CanCastSafely (int, int)
609    npy_bool PyArray_CanCastTo (dtype, dtype)
610    int PyArray_ObjectType (object, int)
611    dtype PyArray_DescrFromObject (object, dtype)
612    #ndarray* PyArray_ConvertToCommonType (object, int *)
613    dtype PyArray_DescrFromScalar (object)
614    dtype PyArray_DescrFromTypeObject (object)
615    npy_intp PyArray_Size (object)
616    #object PyArray_Scalar (void *, dtype, object)
617    #object PyArray_FromScalar (object, dtype)
618    void PyArray_ScalarAsCtype (object, void *)
619    #int PyArray_CastScalarToCtype (object, void *, dtype)
620    #int PyArray_CastScalarDirect (object, dtype, void *, int)
621    object PyArray_ScalarFromObject (object)
622    #PyArray_VectorUnaryFunc * PyArray_GetCastFunc (dtype, int)
623    object PyArray_FromDims (int, int *, int)
624    #object PyArray_FromDimsAndDataAndDescr (int, int *, dtype, char *)
625    #object PyArray_FromAny (object, dtype, int, int, int, object)
626    object PyArray_EnsureArray (object)
627    object PyArray_EnsureAnyArray (object)
628    #object PyArray_FromFile (stdio.FILE *, dtype, npy_intp, char *)
629    #object PyArray_FromString (char *, npy_intp, dtype, npy_intp, char *)
630    #object PyArray_FromBuffer (object, dtype, npy_intp, npy_intp)
631    #object PyArray_FromIter (object, dtype, npy_intp)
632    object PyArray_Return (ndarray)
633    #object PyArray_GetField (ndarray, dtype, int)
634    #int PyArray_SetField (ndarray, dtype, int, object)
635    object PyArray_Byteswap (ndarray, npy_bool)
636    object PyArray_Resize (ndarray, PyArray_Dims *, int, NPY_ORDER)
637    int PyArray_MoveInto (ndarray, ndarray)
638    int PyArray_CopyInto (ndarray, ndarray)
639    int PyArray_CopyAnyInto (ndarray, ndarray)
640    int PyArray_CopyObject (ndarray, object)
641    object PyArray_NewCopy (ndarray, NPY_ORDER)
642    object PyArray_ToList (ndarray)
643    object PyArray_ToString (ndarray, NPY_ORDER)
644    int PyArray_ToFile (ndarray, stdio.FILE *, char *, char *)
645    int PyArray_Dump (object, object, int)
646    object PyArray_Dumps (object, int)
647    int PyArray_ValidType (int)
648    void PyArray_UpdateFlags (ndarray, int)
649    object PyArray_New (type, int, npy_intp *, int, npy_intp *, void *, int, int, object)
650    #object PyArray_NewFromDescr (type, dtype, int, npy_intp *, npy_intp *, void *, int, object)
651    #dtype PyArray_DescrNew (dtype)
652    dtype PyArray_DescrNewFromType (int)
653    double PyArray_GetPriority (object, double)
654    object PyArray_IterNew (object)
655    object PyArray_MultiIterNew (int, ...)
656
657    int PyArray_PyIntAsInt (object)
658    npy_intp PyArray_PyIntAsIntp (object)
659    int PyArray_Broadcast (broadcast)
660    void PyArray_FillObjectArray (ndarray, object)
661    int PyArray_FillWithScalar (ndarray, object)
662    npy_bool PyArray_CheckStrides (int, int, npy_intp, npy_intp, npy_intp *, npy_intp *)
663    dtype PyArray_DescrNewByteorder (dtype, char)
664    object PyArray_IterAllButAxis (object, int *)
665    #object PyArray_CheckFromAny (object, dtype, int, int, int, object)
666    #object PyArray_FromArray (ndarray, dtype, int)
667    object PyArray_FromInterface (object)
668    object PyArray_FromStructInterface (object)
669    #object PyArray_FromArrayAttr (object, dtype, object)
670    #NPY_SCALARKIND PyArray_ScalarKind (int, ndarray*)
671    int PyArray_CanCoerceScalar (int, int, NPY_SCALARKIND)
672    object PyArray_NewFlagsObject (object)
673    npy_bool PyArray_CanCastScalar (type, type)
674    #int PyArray_CompareUCS4 (npy_ucs4 *, npy_ucs4 *, register size_t)
675    int PyArray_RemoveSmallest (broadcast)
676    int PyArray_ElementStrides (object)
677    void PyArray_Item_INCREF (char *, dtype)
678    void PyArray_Item_XDECREF (char *, dtype)
679    object PyArray_FieldNames (object)
680    object PyArray_Transpose (ndarray, PyArray_Dims *)
681    object PyArray_TakeFrom (ndarray, object, int, ndarray, NPY_CLIPMODE)
682    object PyArray_PutTo (ndarray, object, object, NPY_CLIPMODE)
683    object PyArray_PutMask (ndarray, object, object)
684    object PyArray_Repeat (ndarray, object, int)
685    object PyArray_Choose (ndarray, object, ndarray, NPY_CLIPMODE)
686    int PyArray_Sort (ndarray, int, NPY_SORTKIND)
687    object PyArray_ArgSort (ndarray, int, NPY_SORTKIND)
688    object PyArray_SearchSorted (ndarray, object, NPY_SEARCHSIDE, PyObject*)
689    object PyArray_ArgMax (ndarray, int, ndarray)
690    object PyArray_ArgMin (ndarray, int, ndarray)
691    object PyArray_Reshape (ndarray, object)
692    object PyArray_Newshape (ndarray, PyArray_Dims *, NPY_ORDER)
693    object PyArray_Squeeze (ndarray)
694    #object PyArray_View (ndarray, dtype, type)
695    object PyArray_SwapAxes (ndarray, int, int)
696    object PyArray_Max (ndarray, int, ndarray)
697    object PyArray_Min (ndarray, int, ndarray)
698    object PyArray_Ptp (ndarray, int, ndarray)
699    object PyArray_Mean (ndarray, int, int, ndarray)
700    object PyArray_Trace (ndarray, int, int, int, int, ndarray)
701    object PyArray_Diagonal (ndarray, int, int, int)
702    object PyArray_Clip (ndarray, object, object, ndarray)
703    object PyArray_Conjugate (ndarray, ndarray)
704    object PyArray_Nonzero (ndarray)
705    object PyArray_Std (ndarray, int, int, ndarray, int)
706    object PyArray_Sum (ndarray, int, int, ndarray)
707    object PyArray_CumSum (ndarray, int, int, ndarray)
708    object PyArray_Prod (ndarray, int, int, ndarray)
709    object PyArray_CumProd (ndarray, int, int, ndarray)
710    object PyArray_All (ndarray, int, ndarray)
711    object PyArray_Any (ndarray, int, ndarray)
712    object PyArray_Compress (ndarray, object, int, ndarray)
713    object PyArray_Flatten (ndarray, NPY_ORDER)
714    object PyArray_Ravel (ndarray, NPY_ORDER)
715    npy_intp PyArray_MultiplyList (npy_intp *, int)
716    int PyArray_MultiplyIntList (int *, int)
717    void * PyArray_GetPtr (ndarray, npy_intp*)
718    int PyArray_CompareLists (npy_intp *, npy_intp *, int)
719    #int PyArray_AsCArray (object*, void *, npy_intp *, int, dtype)
720    #int PyArray_As1D (object*, char **, int *, int)
721    #int PyArray_As2D (object*, char ***, int *, int *, int)
722    int PyArray_Free (object, void *)
723    #int PyArray_Converter (object, object*)
724    int PyArray_IntpFromSequence (object, npy_intp *, int)
725    object PyArray_Concatenate (object, int)
726    object PyArray_InnerProduct (object, object)
727    object PyArray_MatrixProduct (object, object)
728    object PyArray_CopyAndTranspose (object)
729    object PyArray_Correlate (object, object, int)
730    int PyArray_TypestrConvert (int, int)
731    #int PyArray_DescrConverter (object, dtype*)
732    #int PyArray_DescrConverter2 (object, dtype*)
733    int PyArray_IntpConverter (object, PyArray_Dims *)
734    #int PyArray_BufferConverter (object, chunk)
735    int PyArray_AxisConverter (object, int *)
736    int PyArray_BoolConverter (object, npy_bool *)
737    int PyArray_ByteorderConverter (object, char *)
738    int PyArray_OrderConverter (object, NPY_ORDER *)
739    unsigned char PyArray_EquivTypes (dtype, dtype)
740    #object PyArray_Zeros (int, npy_intp *, dtype, int)
741    #object PyArray_Empty (int, npy_intp *, dtype, int)
742    object PyArray_Where (object, object, object)
743    object PyArray_Arange (double, double, double, int)
744    #object PyArray_ArangeObj (object, object, object, dtype)
745    int PyArray_SortkindConverter (object, NPY_SORTKIND *)
746    object PyArray_LexSort (object, int)
747    object PyArray_Round (ndarray, int, ndarray)
748    unsigned char PyArray_EquivTypenums (int, int)
749    int PyArray_RegisterDataType (dtype)
750    int PyArray_RegisterCastFunc (dtype, int, PyArray_VectorUnaryFunc *)
751    int PyArray_RegisterCanCast (dtype, int, NPY_SCALARKIND)
752    #void PyArray_InitArrFuncs (PyArray_ArrFuncs *)
753    object PyArray_IntTupleFromIntp (int, npy_intp *)
754    int PyArray_TypeNumFromName (char *)
755    int PyArray_ClipmodeConverter (object, NPY_CLIPMODE *)
756    #int PyArray_OutputConverter (object, ndarray*)
757    object PyArray_BroadcastToShape (object, npy_intp *, int)
758    void _PyArray_SigintHandler (int)
759    void* _PyArray_GetSigintBuf ()
760    #int PyArray_DescrAlignConverter (object, dtype*)
761    #int PyArray_DescrAlignConverter2 (object, dtype*)
762    int PyArray_SearchsideConverter (object, void *)
763    object PyArray_CheckAxis (ndarray, int *, int)
764    npy_intp PyArray_OverflowMultiplyList (npy_intp *, int)
765    int PyArray_CompareString (char *, char *, size_t)
766    int PyArray_SetBaseObject(ndarray, base)  # NOTE: steals a reference to base! Use "set_array_base()" instead.
767
768
769# Typedefs that matches the runtime dtype objects in
770# the numpy module.
771
772# The ones that are commented out needs an IFDEF function
773# in Cython to enable them only on the right systems.
774
775ctypedef npy_int8       int8_t
776ctypedef npy_int16      int16_t
777ctypedef npy_int32      int32_t
778ctypedef npy_int64      int64_t
779#ctypedef npy_int96      int96_t
780#ctypedef npy_int128     int128_t
781
782ctypedef npy_uint8      uint8_t
783ctypedef npy_uint16     uint16_t
784ctypedef npy_uint32     uint32_t
785ctypedef npy_uint64     uint64_t
786#ctypedef npy_uint96     uint96_t
787#ctypedef npy_uint128    uint128_t
788
789ctypedef npy_float32    float32_t
790ctypedef npy_float64    float64_t
791#ctypedef npy_float80    float80_t
792#ctypedef npy_float128   float128_t
793
794ctypedef float complex  complex64_t
795ctypedef double complex complex128_t
796
797# The int types are mapped a bit surprising --
798# numpy.int corresponds to 'l' and numpy.long to 'q'
799ctypedef npy_long       int_t
800ctypedef npy_longlong   long_t
801ctypedef npy_longlong   longlong_t
802
803ctypedef npy_ulong      uint_t
804ctypedef npy_ulonglong  ulong_t
805ctypedef npy_ulonglong  ulonglong_t
806
807ctypedef npy_intp       intp_t
808ctypedef npy_uintp      uintp_t
809
810ctypedef npy_double     float_t
811ctypedef npy_double     double_t
812ctypedef npy_longdouble longdouble_t
813
814ctypedef npy_cfloat      cfloat_t
815ctypedef npy_cdouble     cdouble_t
816ctypedef npy_clongdouble clongdouble_t
817
818ctypedef npy_cdouble     complex_t
819
820cdef inline object PyArray_MultiIterNew1(a):
821    return PyArray_MultiIterNew(1, <void*>a)
822
823cdef inline object PyArray_MultiIterNew2(a, b):
824    return PyArray_MultiIterNew(2, <void*>a, <void*>b)
825
826cdef inline object PyArray_MultiIterNew3(a, b, c):
827    return PyArray_MultiIterNew(3, <void*>a, <void*>b, <void*> c)
828
829cdef inline object PyArray_MultiIterNew4(a, b, c, d):
830    return PyArray_MultiIterNew(4, <void*>a, <void*>b, <void*>c, <void*> d)
831
832cdef inline object PyArray_MultiIterNew5(a, b, c, d, e):
833    return PyArray_MultiIterNew(5, <void*>a, <void*>b, <void*>c, <void*> d, <void*> e)
834
835cdef inline tuple PyDataType_SHAPE(dtype d):
836    if PyDataType_HASSUBARRAY(d):
837        return <tuple>d.subarray.shape
838    else:
839        return ()
840
841cdef inline char* _util_dtypestring(dtype descr, char* f, char* end, int* offset) except NULL:
842    # Recursive utility function used in __getbuffer__ to get format
843    # string. The new location in the format string is returned.
844
845    cdef dtype child
846    cdef int endian_detector = 1
847    cdef bint little_endian = ((<char*>&endian_detector)[0] != 0)
848    cdef tuple fields
849
850    for childname in descr.names:
851        fields = descr.fields[childname]
852        child, new_offset = fields
853
854        if (end - f) - <int>(new_offset - offset[0]) < 15:
855            raise RuntimeError(u"Format string allocated too short, see comment in numpy.pxd")
856
857        if ((child.byteorder == c'>' and little_endian) or
858            (child.byteorder == c'<' and not little_endian)):
859            raise ValueError(u"Non-native byte order not supported")
860            # One could encode it in the format string and have Cython
861            # complain instead, BUT: < and > in format strings also imply
862            # standardized sizes for datatypes, and we rely on native in
863            # order to avoid reencoding data types based on their size.
864            #
865            # A proper PEP 3118 exporter for other clients than Cython
866            # must deal properly with this!
867
868        # Output padding bytes
869        while offset[0] < new_offset:
870            f[0] = 120 # "x"; pad byte
871            f += 1
872            offset[0] += 1
873
874        offset[0] += child.itemsize
875
876        if not PyDataType_HASFIELDS(child):
877            t = child.type_num
878            if end - f < 5:
879                raise RuntimeError(u"Format string allocated too short.")
880
881            # Until ticket #99 is fixed, use integers to avoid warnings
882            if   t == NPY_BYTE:        f[0] =  98 #"b"
883            elif t == NPY_UBYTE:       f[0] =  66 #"B"
884            elif t == NPY_SHORT:       f[0] = 104 #"h"
885            elif t == NPY_USHORT:      f[0] =  72 #"H"
886            elif t == NPY_INT:         f[0] = 105 #"i"
887            elif t == NPY_UINT:        f[0] =  73 #"I"
888            elif t == NPY_LONG:        f[0] = 108 #"l"
889            elif t == NPY_ULONG:       f[0] = 76  #"L"
890            elif t == NPY_LONGLONG:    f[0] = 113 #"q"
891            elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
892            elif t == NPY_FLOAT:       f[0] = 102 #"f"
893            elif t == NPY_DOUBLE:      f[0] = 100 #"d"
894            elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
895            elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1 # Zf
896            elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1 # Zd
897            elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1 # Zg
898            elif t == NPY_OBJECT:      f[0] = 79 #"O"
899            else:
900                raise ValueError(u"unknown dtype code in numpy.pxd (%d)" % t)
901            f += 1
902        else:
903            # Cython ignores struct boundary information ("T{...}"),
904            # so don't output it
905            f = _util_dtypestring(child, f, end, offset)
906    return f
907
908
909#
910# ufunc API
911#
912
913cdef extern from "numpy/ufuncobject.h":
914
915    ctypedef void (*PyUFuncGenericFunction) (char **, npy_intp *, npy_intp *, void *)
916
917    ctypedef class numpy.ufunc [object PyUFuncObject, check_size ignore]:
918        cdef:
919            int nin, nout, nargs
920            int identity
921            PyUFuncGenericFunction *functions
922            void **data
923            int ntypes
924            int check_return
925            char *name
926            char *types
927            char *doc
928            void *ptr
929            PyObject *obj
930            PyObject *userloops
931
932    cdef enum:
933        PyUFunc_Zero
934        PyUFunc_One
935        PyUFunc_None
936        UFUNC_ERR_IGNORE
937        UFUNC_ERR_WARN
938        UFUNC_ERR_RAISE
939        UFUNC_ERR_CALL
940        UFUNC_ERR_PRINT
941        UFUNC_ERR_LOG
942        UFUNC_MASK_DIVIDEBYZERO
943        UFUNC_MASK_OVERFLOW
944        UFUNC_MASK_UNDERFLOW
945        UFUNC_MASK_INVALID
946        UFUNC_SHIFT_DIVIDEBYZERO
947        UFUNC_SHIFT_OVERFLOW
948        UFUNC_SHIFT_UNDERFLOW
949        UFUNC_SHIFT_INVALID
950        UFUNC_FPE_DIVIDEBYZERO
951        UFUNC_FPE_OVERFLOW
952        UFUNC_FPE_UNDERFLOW
953        UFUNC_FPE_INVALID
954        UFUNC_ERR_DEFAULT
955        UFUNC_ERR_DEFAULT2
956
957    object PyUFunc_FromFuncAndData(PyUFuncGenericFunction *,
958          void **, char *, int, int, int, int, char *, char *, int)
959    int PyUFunc_RegisterLoopForType(ufunc, int,
960                                    PyUFuncGenericFunction, int *, void *)
961    int PyUFunc_GenericFunction \
962        (ufunc, PyObject *, PyObject *, PyArrayObject **)
963    void PyUFunc_f_f_As_d_d \
964         (char **, npy_intp *, npy_intp *, void *)
965    void PyUFunc_d_d \
966         (char **, npy_intp *, npy_intp *, void *)
967    void PyUFunc_f_f \
968         (char **, npy_intp *, npy_intp *, void *)
969    void PyUFunc_g_g \
970         (char **, npy_intp *, npy_intp *, void *)
971    void PyUFunc_F_F_As_D_D \
972         (char **, npy_intp *, npy_intp *, void *)
973    void PyUFunc_F_F \
974         (char **, npy_intp *, npy_intp *, void *)
975    void PyUFunc_D_D \
976         (char **, npy_intp *, npy_intp *, void *)
977    void PyUFunc_G_G \
978         (char **, npy_intp *, npy_intp *, void *)
979    void PyUFunc_O_O \
980         (char **, npy_intp *, npy_intp *, void *)
981    void PyUFunc_ff_f_As_dd_d \
982         (char **, npy_intp *, npy_intp *, void *)
983    void PyUFunc_ff_f \
984         (char **, npy_intp *, npy_intp *, void *)
985    void PyUFunc_dd_d \
986         (char **, npy_intp *, npy_intp *, void *)
987    void PyUFunc_gg_g \
988         (char **, npy_intp *, npy_intp *, void *)
989    void PyUFunc_FF_F_As_DD_D \
990         (char **, npy_intp *, npy_intp *, void *)
991    void PyUFunc_DD_D \
992         (char **, npy_intp *, npy_intp *, void *)
993    void PyUFunc_FF_F \
994         (char **, npy_intp *, npy_intp *, void *)
995    void PyUFunc_GG_G \
996         (char **, npy_intp *, npy_intp *, void *)
997    void PyUFunc_OO_O \
998         (char **, npy_intp *, npy_intp *, void *)
999    void PyUFunc_O_O_method \
1000         (char **, npy_intp *, npy_intp *, void *)
1001    void PyUFunc_OO_O_method \
1002         (char **, npy_intp *, npy_intp *, void *)
1003    void PyUFunc_On_Om \
1004         (char **, npy_intp *, npy_intp *, void *)
1005    int PyUFunc_GetPyValues \
1006        (char *, int *, int *, PyObject **)
1007    int PyUFunc_checkfperr \
1008           (int, PyObject *, int *)
1009    void PyUFunc_clearfperr()
1010    int PyUFunc_getfperr()
1011    int PyUFunc_handlefperr \
1012        (int, PyObject *, int, int *)
1013    int PyUFunc_ReplaceLoopBySignature \
1014        (ufunc, PyUFuncGenericFunction, int *, PyUFuncGenericFunction *)
1015    object PyUFunc_FromFuncAndDataAndSignature \
1016             (PyUFuncGenericFunction *, void **, char *, int, int, int,
1017              int, char *, char *, int, char *)
1018
1019    int _import_umath() except -1
1020
1021cdef inline void set_array_base(ndarray arr, object base):
1022    Py_INCREF(base) # important to do this before stealing the reference below!
1023    PyArray_SetBaseObject(arr, base)
1024
1025cdef inline object get_array_base(ndarray arr):
1026    base = PyArray_BASE(arr)
1027    if base is NULL:
1028        return None
1029    return <object>base
1030
1031# Versions of the import_* functions which are more suitable for
1032# Cython code.
1033cdef inline int import_array() except -1:
1034    try:
1035        _import_array()
1036    except Exception:
1037        raise ImportError("numpy.core.multiarray failed to import")
1038
1039cdef inline int import_umath() except -1:
1040    try:
1041        _import_umath()
1042    except Exception:
1043        raise ImportError("numpy.core.umath failed to import")
1044
1045cdef inline int import_ufunc() except -1:
1046    try:
1047        _import_umath()
1048    except Exception:
1049        raise ImportError("numpy.core.umath failed to import")
1050